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 "contacteditor/frmContactEditor.h"
58 #include "import/import.h"
59 #include "export/export.h"
60 #include "widgets/XABContactMenu.h"
61 #include "widgets/XABAccountView.h"
65 // Define the event types.
67 DEFINE_EVENT_TYPE(CE_UPDATECONTACTLIST);
68 DEFINE_EVENT_TYPE(SE_UPDATECONTACTNOTIF);
69 DEFINE_EVENT_TYPE(CE_OPENCONTACT);
70 DEFINE_EVENT_TYPE(CE_OPENCONTACTLIST);
71 DEFINE_EVENT_TYPE(CE_NEWCONTACT);
72 DEFINE_EVENT_TYPE(CE_EDITCONTACT);
73 DEFINE_EVENT_TYPE(CE_DELETECONTACT);
74 DEFINE_EVENT_TYPE(CE_REVEALCONTACT);
75 DEFINE_EVENT_TYPE(CE_REMOVECONTACT);
76 DEFINE_EVENT_TYPE(CE_REMOVESEARCH);
77 DEFINE_EVENT_TYPE(SYNC_EMPTYSERVER);
78 DEFINE_EVENT_TYPE(ACTMGR_START);
79 DEFINE_EVENT_TYPE(ACTMGR_SHUFFLE);
80 DEFINE_EVENT_TYPE(ACTMGR_STOP);
81 DEFINE_EVENT_TYPE(WINDOW_ADD);
82 DEFINE_EVENT_TYPE(WINDOW_EDIT);
83 DEFINE_EVENT_TYPE(WINDOW_CLOSE);
84 DEFINE_EVENT_TYPE(CONNSTAT_UPDATE);
85 DEFINE_EVENT_TYPE(INVALIDSSLCERT);
86 DEFINE_EVENT_TYPE(INVALIDSSLCERTSTRING);
87 DEFINE_EVENT_TYPE(GETSELECTEDLIST);
88 DEFINE_EVENT_TYPE(SYNCACCOUNT);
89 DEFINE_EVENT_TYPE(IMPORT_RESULTSSHOW);
90 DEFINE_EVENT_TYPE(RELOADCONTACTLIST);
91 DEFINE_EVENT_TYPE(REFRESHADDRESSBOOK);
92 #if defined(__APPLE__)
93 DEFINE_EVENT_TYPE(INVALIDSSLTRUST);
96 // Setup the event table using the event types.
98 BEGIN_EVENT_TABLE(frmMain, wxFrame)
99 EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, frmMain::ConflictResolution)
100 EVT_COMMAND(wxID_ANY, CE_UPDATECONTACTLIST, frmMain::UpdateContactList)
101 EVT_COMMAND(wxID_ANY, SE_UPDATECONTACTNOTIF, frmMain::UpdateSearchContactLists)
102 EVT_COMMAND(wxID_ANY, CE_OPENCONTACT, frmMain::OpenContactInfo)
103 EVT_COMMAND(wxID_ANY, CE_OPENCONTACTLIST, frmMain::OpenContactInfoList)
104 EVT_COMMAND(wxID_ANY, CE_NEWCONTACT, frmMain::ShowContactEditorNew)
105 EVT_COMMAND(wxID_ANY, CE_EDITCONTACT, frmMain::ShowContactEditorEdit)
106 EVT_COMMAND(wxID_ANY, CE_DELETECONTACT, frmMain::DeleteContact)
107 EVT_COMMAND(wxID_ANY, CE_REVEALCONTACT, frmMain::RevealContact)
108 EVT_COMMAND(wxID_ANY, CE_REMOVESEARCH, frmMain::RemoveContactsWindowPointer)
109 EVT_COMMAND(wxID_ANY, SYNC_EMPTYSERVER, frmMain::EmptyServerDialog)
110 EVT_COMMAND(wxID_ANY, ACTMGR_START, frmMain::ActivityIconStart)
111 EVT_COMMAND(wxID_ANY, ACTMGR_SHUFFLE, frmMain::ActivityIconShuffle)
112 EVT_COMMAND(wxID_ANY, ACTMGR_STOP, frmMain::ActivityIconStop)
113 EVT_COMMAND(wxID_ANY, WINDOW_ADD, frmMain::WindowAdd)
114 EVT_COMMAND(wxID_ANY, WINDOW_EDIT, frmMain::WindowEdit)
115 EVT_COMMAND(wxID_ANY, WINDOW_CLOSE, frmMain::WindowDelete)
116 EVT_COMMAND(wxID_ANY, CONNSTAT_UPDATE, frmMain::UpdateConnectionStatus)
117 EVT_COMMAND(wxID_ANY, INVALIDSSLCERT, frmMain::InvalidSSLCertificate)
118 EVT_COMMAND(wxID_ANY, INVALIDSSLCERTSTRING, frmMain::InvalidSSLCertificateString)
119 EVT_COMMAND(wxID_ANY, GETSELECTEDLIST, frmMain::GetSelectedList)
120 EVT_COMMAND(wxID_ANY, SYNCACCOUNT, frmMain::SyncAccount)
121 EVT_COMMAND(wxID_ANY, IMPORT_RESULTSSHOW, frmMain::ShowImportResults)
122 EVT_COMMAND(wxID_ANY, RELOADCONTACTLIST, frmMain::ReloadContactList)
123 EVT_COMMAND(wxID_ANY, REFRESHADDRESSBOOK, frmMain::RefreshAddressBook)
124 #if defined(__APPLE__)
125 EVT_COMMAND(wxID_ANY, INVALIDSSLTRUST, frmMain::DisplayTrustPanel)
129 frmMain::frmMain( wxWindow* parent )
134 // Setup the account icons.
136 wxMemoryInputStream astream(icons_accinet_png, sizeof(icons_accinet_png));
137 wxMemoryInputStream bstream(icons_acclocal_png, sizeof(icons_acclocal_png));
138 wxMemoryInputStream cstream(icons_accgroup_png, sizeof(icons_accgroup_png));
139 wxMemoryInputStream dstream(icons_accnone_png, sizeof(icons_accnone_png));
140 wxMemoryInputStream estream(icons_accunsupported_png, sizeof(icons_accunsupported_png));
142 wxImage icons_accinet_png(astream, wxBITMAP_TYPE_PNG);
143 wxBitmap AccInet(icons_accinet_png, -1);
145 wxIAccInet.CopyFromBitmap(AccInet);
147 wxImage icons_acclocal_png(bstream, wxBITMAP_TYPE_PNG);
148 wxBitmap AccNIcon(icons_acclocal_png, -1);
150 wxIAccNIcon.CopyFromBitmap(AccNIcon);
152 wxImage icons_accgroup_png(cstream, wxBITMAP_TYPE_PNG);
153 wxBitmap AccGrp(icons_accgroup_png, -1);
155 wxIAccGrp.CopyFromBitmap(AccGrp);
157 wxImage icons_accnone_png(dstream, wxBITMAP_TYPE_PNG);
158 wxBitmap AccNone(icons_accnone_png, -1);
160 wxIAccNone.CopyFromBitmap(AccNone);
162 wxImage icons_accunsupported_png(estream, wxBITMAP_TYPE_PNG);
163 wxBitmap AccUnsupported(icons_accunsupported_png, -1);
164 wxIcon wxIAccUnsupported;
165 wxIAccUnsupported.CopyFromBitmap(AccUnsupported);
167 AccountID = AccImgList->Add(wxIAccNIcon);
168 AccountNetID = AccImgList->Add(wxIAccInet);
169 AccountGrpID = AccImgList->Add(wxIAccGrp);
170 AccountNoneID = AccImgList->Add(wxIAccNone);
171 AccountUnsupportedID = AccImgList->Add(wxIAccUnsupported);
173 bmpIcon->SetIcon(AccImgList->GetIcon(AccountNoneID));
175 // Setup the status bar icons.
179 wxMemoryInputStream sslstream(icons_ssl_png, sizeof(icons_ssl_png));
180 wxMemoryInputStream sslwarningstream(icons_sslwarning_png, sizeof(icons_sslwarning_png));
181 wxMemoryInputStream nosslstream(icons_nossl_png, sizeof(icons_nossl_png));
183 wxImage icons_ssl_png(sslstream, wxBITMAP_TYPE_PNG);
184 imgSSL = new wxBitmap(icons_ssl_png, -1);
186 wxImage icons_sslwarning_png(sslwarningstream, wxBITMAP_TYPE_PNG);
187 imgSSLWarning = new wxBitmap(icons_sslwarning_png, -1);
189 wxImage icons_nossl_png(nosslstream, wxBITMAP_TYPE_PNG);
190 imgNoSSL = new wxBitmap(icons_nossl_png, -1);
194 wxMemoryInputStream addaddressbook(toolbar_addaddressbook_png, sizeof(toolbar_addaddressbook_png));
195 wxMemoryInputStream preferences(toolbar_preferences_png, sizeof(toolbar_preferences_png));
196 wxMemoryInputStream searchcontacts(toolbar_searchcontacts_png, sizeof(toolbar_searchcontacts_png));
197 wxMemoryInputStream addcontact(toolbar_addcontact_png, sizeof(toolbar_addcontact_png));
198 wxMemoryInputStream editcontact(toolbar_editcontact_png, sizeof(toolbar_editcontact_png));
199 wxMemoryInputStream deletecontact(toolbar_deletecontact_png, sizeof(toolbar_deletecontact_png));
201 wxImage toolbar_addaddressbook_png(addaddressbook, wxBITMAP_TYPE_PNG);
202 imgAddAddressBook = new wxBitmap (toolbar_addaddressbook_png, -1);
203 tblMain->SetToolNormalBitmap(tbtNewAccount->GetId(), *imgAddAddressBook);
205 wxImage toolbar_preferences_png(preferences, wxBITMAP_TYPE_PNG);
206 imgPreferences = new wxBitmap (toolbar_preferences_png, -1);
207 tblMain->SetToolNormalBitmap(tbtPreferences->GetId(), *imgPreferences);
209 wxImage toolbar_searchcontacts_png(searchcontacts, wxBITMAP_TYPE_PNG);
210 imgSearchContacts = new wxBitmap (toolbar_searchcontacts_png, -1);
211 tblMain->SetToolNormalBitmap(tbtSearch->GetId(), *imgSearchContacts);
213 wxImage toolbar_addcontact_png(addcontact, wxBITMAP_TYPE_PNG);
214 imgAddContact = new wxBitmap (toolbar_addcontact_png, -1);
215 tblMain->SetToolNormalBitmap(tbtAddContact->GetId(), *imgAddContact);
217 wxImage toolbar_editcontact_png(editcontact, wxBITMAP_TYPE_PNG);
218 imgEditContact = new wxBitmap (toolbar_editcontact_png, -1);
219 tblMain->SetToolNormalBitmap(tbtEditContact->GetId(), *imgEditContact);
221 wxImage toolbar_deletecontact_png(deletecontact, wxBITMAP_TYPE_PNG);
222 imgDeleteContact = new wxBitmap (toolbar_deletecontact_png, -1);
223 tblMain->SetToolNormalBitmap(tbtDeleteContact->GetId(), *imgDeleteContact);
227 wxMemoryInputStream act1(icons_act1_png, sizeof(icons_act1_png));
228 wxMemoryInputStream act2(icons_act2_png, sizeof(icons_act2_png));
229 wxMemoryInputStream act3(icons_act3_png, sizeof(icons_act3_png));
230 wxMemoryInputStream act4(icons_act4_png, sizeof(icons_act4_png));
231 wxMemoryInputStream actsleep(icons_actsleep_png, sizeof(icons_actsleep_png));
233 wxImage icons_actsleep_png(actsleep, wxBITMAP_TYPE_PNG);
234 imgActIconSleep = new wxBitmap (icons_actsleep_png, -1);
236 wxImage icons_act1_png(act1, wxBITMAP_TYPE_PNG);
237 imgActIcon1 = new wxBitmap (icons_act1_png, -1);
239 wxIAct1icon.CopyFromBitmap(*imgActIcon1);
241 wxImage icons_act2_png(act2, wxBITMAP_TYPE_PNG);
242 imgActIcon2 = new wxBitmap (icons_act2_png, -1);
244 wxIAct2icon.CopyFromBitmap(*imgActIcon2);
246 wxImage icons_act3_png(act3, wxBITMAP_TYPE_PNG);
247 imgActIcon3 = new wxBitmap (icons_act3_png, -1);
249 wxIAct3icon.CopyFromBitmap(*imgActIcon3);
251 wxImage icons_act4_png(act4, wxBITMAP_TYPE_PNG);
252 imgActIcon4 = new wxBitmap (icons_act4_png, -1);
254 wxIAct4icon.CopyFromBitmap(*imgActIcon4);
256 // Online/Offline icons.
258 wxMemoryInputStream onlinestream(icons_online_png, sizeof(icons_online_png));
259 wxMemoryInputStream offlinestream(icons_offline_png, sizeof(icons_offline_png));
261 wxImage icons_online_png(onlinestream, wxBITMAP_TYPE_PNG);
262 imgOnline = new wxBitmap(icons_online_png, -1);
264 wxImage icons_offline_png(offlinestream, wxBITMAP_TYPE_PNG);
265 imgOffline = new wxBitmap(icons_offline_png, -1);
267 // Setup the account view.
269 AccCtrl->SetPopupControl(treAccounts);
270 AccCtrl->SetPopupMaxHeight(175);
271 AccCtrl->SetPopupMinWidth(250);
272 treAccounts->AssignImageList(AccImgList);
274 wxListItem ColumnData;
276 ColumnData.SetText(wxT("Name0"));
277 ColumnData.SetWidth(320);
278 lstContacts->InsertColumn(0, ColumnData);
280 treAccounts->Connect(wxEVT_LEFT_DCLICK, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
281 treAccounts->Connect(wxEVT_TREE_SEL_CHANGED, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
283 #if defined(__HAIKU__)
285 #elif defined(__WIN32__)
287 int stbBottomData [4] = { -1, 8, 8, 8 };
291 int stbBottomData [4] = { -1, 20, 20, 20 };
295 stbBottom->SetFieldsCount(4, stbBottomData);
296 stbBottom->SetMinHeight(16);
301 stbBottom->GetFieldRect(1, rectOnline);
302 stbBottom->GetFieldRect(2, rectSSL);
303 stbBottom->GetFieldRect(3, rectActivity);
305 SSLToolTip = new wxToolTip(wxT(""));
307 imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectOnline.GetX()),(rectOnline.GetY())), wxDefaultSize, 0 );
308 imgConnStatus->SetBitmap(*imgOnline);
309 imgConnStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ToggleConnectionStatus ), NULL, this );
311 imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()),(rectSSL.GetY())), wxDefaultSize, 0 );
312 imgSSLStatus->SetBitmap(*imgNoSSL);
313 imgSSLStatus->SetToolTip(SSLToolTip);
314 imgSSLStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowSSLCertificates ), NULL, this );
316 imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()),(rectActivity.GetY())), wxDefaultSize, 0);
317 imgActivityStatus->SetBitmap(*imgActIconSleep);
318 imgActivityStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowActivityWindow ), NULL, this );
320 // Setup the window menu.
322 // By default should be:
327 // Contact editor windows:
333 mnuContactWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact windows:") ), wxEmptyString, wxITEM_NORMAL );
334 mnuWindow->Append( mnuContactWindows );
336 mnuWindow->AppendSeparator();
338 mnuContactEditorWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact editor windows:") ), wxEmptyString, wxITEM_NORMAL );
339 mnuWindow->Append( mnuContactEditorWindows );
341 mnuWindow->AppendSeparator();
343 mnuSearchWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( wxT("Search windows:") ), wxEmptyString, wxITEM_NORMAL );
344 mnuWindow->Append( mnuSearchWindows );
346 #if defined(__WIN32__)
351 mnuContactWindows->SetFont(fontstyle);
352 mnuContactEditorWindows->SetFont(fontstyle);
353 mnuSearchWindows->SetFont(fontstyle);
357 mnuContactWindows->Enable(FALSE);
358 mnuContactEditorWindows->Enable(FALSE);
359 mnuSearchWindows->Enable(FALSE);
363 // Hide unimplemented functions.
369 void frmMain::QuitApp( wxCloseEvent& event )
372 // Run the QuitApp function.
378 void frmMain::QuitApp( wxCommandEvent& event )
381 // Run the QuitApp function.
387 void frmMain::QuitApp()
390 // Function to run when quitting.
392 // Write out the ETag databases.
394 ETagProcTimer.Stop();
395 ETagProcTimer.Notify();
397 // Save Preferences: Save the window position if that option is enabled.
399 wxString SetFilename = GetUserPrefDir();
401 #if defined(__HAIKU__)
405 #elif defined(__WIN32__)
407 SetFilename.Append(wxT("settings"));
413 SetFilename.Append(wxT("settings"));
417 wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
419 bool SaveWindowPos = FALSE;
420 wxString SaveWindowInc;
421 cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
423 if (SaveWindowInc == wxT("true")){
425 SaveWindowPos = TRUE;
429 if (SaveWindowPos == TRUE){
431 wxRect frmMainPos = GetRect();
433 cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
434 cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
435 cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
436 cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
443 // Everything closed... exit.
451 void frmMain::ShowActivityWindow( wxCommandEvent& event )
454 // Open the activity manager window.
456 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
457 frameActMgr->OpenWindow();
462 void frmMain::ShowAboutWindow( wxCommandEvent& event )
465 // Show the about window.
467 frmAbout *frameAbout = new frmAbout ( this );
468 frameAbout->SetupAboutWindow();
469 frameAbout->ShowModal();
475 void frmMain::OpenPreferences( wxCommandEvent& event)
478 // Close all windows first.
480 if (CloseAllWindows() == false)
485 // Open the preferences window.
487 ReloadAccounts = FALSE;
489 frmPreferences *framePreferences = new frmPreferences ( this );
490 framePreferences->SetupPointers(&ReloadAccounts);
491 framePreferences->ShowModal();
492 delete framePreferences;
493 framePreferences = NULL;
495 if (ReloadAccounts == TRUE){
497 // Reload the accounts as a change has been made within
498 // the application and clear the current contact information.
500 this->LoadPreferences(true);
501 this->ResetContactInfo();
507 void frmMain::OpenNewABDialog( wxCommandEvent& event)
510 // Open the new account dialog.
512 ReloadAccounts = FALSE;
514 frmNewAccount *frameNewAccount = new frmNewAccount ( this );
515 frameNewAccount->SetupPointers(&ReloadAccounts);
516 frameNewAccount->ShowModal();
517 delete frameNewAccount;
518 frameNewAccount = NULL;
520 if (ReloadAccounts == TRUE){
522 // Reload the accounts as a change has been made within
525 this->LoadPreferences(true);
531 void frmMain::LoadContactList( wxTreeEvent& event )
534 // Load the contact list.
536 // Clear all existing variables.
538 lstContacts->DeleteAllItems();
540 treAccounts->SetAccount();
542 wxTreeItemIdValue cookie;
543 wxTreeItemId next = treAccounts->GetRootItem();
544 wxString AccountName;
545 wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
546 wxString AccountDirCmb;
547 long selectedaccount = 0;
549 wxTreeItemId selectedChild = treAccounts->GetSelection();
550 wxTreeItemId nextChild;
552 wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
553 int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
555 int SCImg = treAccounts->GetItemImage(selectedChild);
556 int AccountIndex = 0;
558 bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
560 // Process each account.
562 for (int i = 0; i < prefaccounts.GetCount(); i++){
564 if (ActiveItemIcon == 2){
566 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
567 std::multimap<int, int>::iterator AGLiter = AccountGroupList.find(AGTiter->second);
568 int ActiveAccountG = AGLiter->second;
570 if (i == ActiveAccountG){
572 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
573 AccountType.Append(prefaccounts.GetAccountType(i));
578 if (AccountType == wxT("CardDAV")){
579 AccountTypeFinal.Append(wxT("carddav"));
580 } else if (AccountType == wxT("Local")){
581 imgSSLStatus->SetBitmap(*imgOffline);
582 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
583 AccountTypeFinal.Append(wxT("local"));
585 imgSSLStatus->SetBitmap(*imgOffline);
586 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
587 AccountTypeFinal.Append(AccountType.Lower());
598 nextChild = treAccounts->GetFirstChild(next, cookie);
600 nextChild = treAccounts->GetNextSibling(nextChild);
603 AccountName = treAccounts->GetItemText(nextChild);
605 if (nextChild == selectedChild){
607 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
608 AccountType.Append(prefaccounts.GetAccountType(i));
613 if (AccountType == wxT("CardDAV")){
614 AccountTypeFinal.Append(wxT("carddav"));
615 } else if (AccountType == wxT("Local")){
616 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
617 AccountTypeFinal.Append(wxT("local"));
619 AccountTypeFinal.Append(AccountType.Lower());
628 if (selectedaccount >= prefaccounts.GetCount()){
630 // The account selected isn't there so return.
638 // Open the directory and get the list of .vcf files
639 // in that directory.
641 ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
642 ActiveAccountType = AccountType;
644 SetupSSLStatus(AccountIndex);
646 AccountDirFinal.Clear();
647 AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
649 ContactsFileIndex.Clear();
651 wxString vCardFilename;
652 wxString vCardFilenameFull;
653 wxString vCardDataString;
654 wxStringTokenizer vcardfileline;
656 wxString setname, setvalue;
657 std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
658 std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
659 long ContactIndex = 1;
660 long ContactSeekPoint = 0;
662 wxDir vcardaccdir(AccountDirFinal);
664 // Get the wxTreeItemId and image icon and compare it to the list.
666 if (ActiveItemIcon == AccountGrpID){
668 // It's a group so load the file containing the group and
669 // get the members of the group.
674 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
675 std::multimap<int, wxString>::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
677 Group.LoadFile(AGFiter->second);
679 ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
681 for (int i = 0; i < vCardMember.PropCount; i++){
683 vCardMember.PropValues[i].Trim();
684 if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
686 wxString NewPropValue;
687 NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
688 vCardMember.PropValues[i] = NewPropValue;
694 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
698 if (vCardFilename.Right(4) == wxT(".vcf") ||
699 vCardFilename.Right(4) == wxT(".VCF") ||
700 vCardFilename.Right(5) == wxT(".vcard") ||
701 vCardFilename.Right(5) == wxT(".VCARD")){
704 bool FoundMember = FALSE;
706 vCardFilenameFull.Append(AccountDirFinal);
707 vCardFilenameFull.Append(wxT("/"));
708 vCardFilenameFull.Append(vCardFilename);
710 Person.LoadFile(vCardFilenameFull);
712 UIDCode = Person.Get(wxT("UID"));
714 for (int i = 0; i < vCardMember.PropCount; i++){
716 if (vCardMember.PropValues[i] == UIDCode){
724 if (FoundMember == FALSE){
726 vCardFilename.Clear();
727 vCardFilenameFull.Clear();
728 vCardDataString.Clear();
729 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
734 if (Person.MeetBaseSpecification()){
738 // Split the name into sections.
740 vCardName NameData = Person.GetName();
742 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
744 } else if (SortMode == 2){
746 // Split the name into sections.
748 vCardName NameData = Person.GetName();
750 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
752 } else if (SortMode == 3){
754 // Check and make sure that the top most nickname is used.
756 vCardDataString = Person.Get(wxT("NICKNAME"));
758 if (vCardDataString.IsEmpty()){
760 vCardDataString = wxT("(no nickname)");
764 } else if (SortMode == 4){
766 vCardDataString = Person.Get(wxT("FN"));
770 if (AscendingMode == TRUE){
771 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
773 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
780 vCardFilename.Clear();
781 vCardFilenameFull.Clear();
782 vCardDataString.Clear();
783 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
789 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
792 if (vCardFilename.Right(4) == wxT(".vcf") ||
793 vCardFilename.Right(4) == wxT(".VCF") ||
794 vCardFilename.Right(5) == wxT(".vcard") ||
795 vCardFilename.Right(5) == wxT(".VCARD")){
799 vCardFilenameFull.Append(AccountDirFinal);
800 vCardFilenameFull.Append(vCardFilename);
802 Person.LoadFile(vCardFilenameFull);
804 if (Person.MeetBaseSpecification()){
808 // Split the name into sections.
810 vCardDataString = Person.Get(wxT("N"));
812 vCardName NameData = Person.GetName();
814 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
816 } else if (SortMode == 2){
818 // Split the name into sections.
820 vCardName NameData = Person.GetName();
822 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
824 } else if (SortMode == 3){
826 // Check and make sure that the top most nickname is used.
828 vCardDataString = Person.Get(wxT("NICKNAME"));
830 if (vCardDataString.IsEmpty()){
832 vCardDataString = wxT("(no nickname)");
836 } else if (SortMode == 4){
838 vCardDataString = Person.Get(wxT("FN"));
842 if (AscendingMode == TRUE){
844 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
848 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
856 vCardFilename.Clear();
857 vCardFilenameFull.Clear();
858 vCardDataString.Clear();
859 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
866 // Insert the data into the control.
868 if (AscendingMode == TRUE){
869 for (std::map<wxString, wxString>::iterator iter = vCardNamesAsc.begin();
870 iter != vCardNamesAsc.end(); ++iter){
872 wxListItem ContactInfo;
874 ContactInfo.SetId(0);
875 ContactInfo.SetText(_("Mooo"));
876 ContactInfo.SetData(ContactSeekPoint);
877 ContactIndex = lstContacts->InsertItem(ContactInfo);
879 lstContacts->SetItem(ContactIndex, 0, iter->first);
881 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
888 for (std::map<wxString, wxString>::iterator iter = vCardNamesDsc.begin();
889 iter != vCardNamesDsc.end(); ++iter){
891 wxListItem ContactInfo;
893 ContactInfo.SetId(0);
894 ContactInfo.SetText(_("Mooo"));
895 ContactInfo.SetData(ContactSeekPoint);
896 ContactIndex = lstContacts->InsertItem(ContactInfo);
898 lstContacts->SetItem(ContactIndex, 0, iter->first);
899 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
908 void frmMain::ShowContactInfo( wxListEvent& event )
911 // Display the contact information.
913 long intSelected = -1;
914 long ContactSeekNum = -1;
916 // Check if several contacts have been selected.
918 int ContactTotal = 0;
922 intSelected = lstContacts->GetNextItem(intSelected,
924 wxLIST_STATE_SELECTED);
926 if (intSelected == -1){
936 if (ContactTotal == 0){
937 htmContactData->SetPage(wxT(""));
941 if (ContactTotal > 1){
943 htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
944 ActiveFilename.Clear();
949 intSelected = lstContacts->GetNextItem(intSelected,
951 wxLIST_STATE_SELECTED);
953 ContactSeekNum = lstContacts->GetItemData(intSelected);
956 wxString wxSContactString;
957 wxString ContactLine;
960 size_t ContactLineLen;
961 bool ExtraLineSeek = FALSE;
962 int QuoteBreakPoint = 0;
964 bool PropertyFind = FALSE;
965 bool QuoteMode = FALSE;
967 wxString wxSPropertyNextLine;
968 wxString wxSProperty;
969 wxString wxSPropertySeg1;
970 wxString wxSPropertySeg2;
972 // Check if we are using wxWidgets version 2.8 or less and
973 // execute the required command accordingly.
975 #if wxABI_VERSION < 20900
976 ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
978 ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
981 if (ContactFile.IsOpened() == FALSE){
987 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
991 std::map<int, wxString> ContactFileLines;
992 std::map<int, wxString>::iterator striter;
994 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
996 int ContactLineSeek = 0;
998 while (wSTContactFileLines.HasMoreTokens() == TRUE){
1000 ContactLine = wSTContactFileLines.GetNextToken();
1001 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
1006 if (ContactSeekNum < 0){
1010 for (std::map<int, wxString>::iterator iter = ContactFileLines.begin();
1011 iter != ContactFileLines.end(); ++iter){
1013 // Find the colon which splits the start bit from the data part.
1015 ContactLine = iter->second;
1017 while (ExtraLineSeek == TRUE){
1019 // Check if there is extra data on the next line
1020 // (indicated by space or tab at the start) and add data.
1024 if (iter == ContactFileLines.end()){
1031 wxSPropertyNextLine = iter->second;
1034 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1036 wxSPropertyNextLine.Remove(0, 1);
1037 ContactLine.Append(wxSPropertyNextLine);
1042 ExtraLineSeek = FALSE;
1048 ContactLineLen = ContactLine.Len();
1050 // Make sure we are not in quotation mode.
1051 // Make sure colon does not have \ or \\ before it.
1053 for (int i = 0; i <= ContactLineLen; i++){
1055 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1057 PropertyFind = FALSE;
1059 } else if (PropertyFind == TRUE){
1061 wxSProperty.Append(ContactLine.Mid(i, 1));
1065 if (ContactLine.Mid(i, 1) == wxT("\"")){
1067 if (QuoteMode == TRUE){
1079 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1081 QuoteBreakPoint = i;
1088 // Split that line at the point into two variables (ignore the colon).
1090 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1091 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1093 // Insert both into the vCard data file.
1095 Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
1098 PropertyFind = TRUE;
1099 ExtraLineSeek = TRUE;
1101 QuoteBreakPoint = 0;
1102 ContactLine.Clear();
1103 wxSProperty.Clear();
1107 OldSessionID = SessionID;
1108 SessionID = wxString::Format(wxT("%i"), rand() % 32768);
1109 LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList, ContactBackgroundColour);
1110 ActiveFilename = ContactsFileIndex[ContactSeekNum];
1114 void frmMain::ShowContactEditorNew( wxCommandEvent& event )
1117 // Open a contact editor window to write a new contact with.
1119 // Check if there is an account selected and if not
1120 // return immediately.
1122 if (ActiveAccount.IsEmpty()){
1128 // Check if the account type is a valid account type, otherwise
1129 // display an error message.
1131 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1132 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1134 wxMessageBox(_("Cannot add a new contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1139 // Add Pointer to SetupPointers for the ETagDB.
1141 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1142 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1143 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1145 contacticon.CopyFromBitmap(contacticonbmp);
1147 frmContactEditor *ContactEditor = new frmContactEditor( this );
1151 ContactEditor->SetUID(WindowMenuItemID);
1153 WindowData *WData = new WindowData;
1155 WData->DataType = 1;
1156 WData->WindowPointer = (void*)ContactEditor;
1157 WData->WindowID = WindowMenuItemID;
1159 wxCommandEvent addevent(WINDOW_ADD);
1160 addevent.SetClientData(WData);
1161 wxPostEvent(this, addevent);
1163 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1164 ContactEditor->SetupHeaders();
1165 ContactEditor->SetupContact(ActiveAccount);
1166 ContactEditor->SetIcon(contacticon);
1167 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1168 ContactEditor->Show(true);
1172 void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
1175 // Open a contact editor window for editing an existing contact
1178 // Check if there is an account selected and if not
1179 // return immediately.
1181 int DataCheck = event.GetInt();
1183 if (ActiveAccount.IsEmpty() && DataCheck == 0){
1189 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1190 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1191 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1193 contacticon.CopyFromBitmap(contacticonbmp);
1195 // Check if a contact has been selected.
1197 long intSelected = -1;
1198 long intContactSeekNum = -1;
1200 intSelected = lstContacts->GetNextItem(intSelected,
1202 wxLIST_STATE_SELECTED);
1204 if (intSelected == -1){
1210 intContactSeekNum = lstContacts->GetItemData(intSelected);
1212 // Get the filename of the selected contact.
1214 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1215 frmContactEditor *ContactEditor = new frmContactEditor( this );
1219 ContactEditor->SetUID(WindowMenuItemID);
1221 WindowData *WData = new WindowData;
1223 WData->DataType = 1;
1224 WData->WindowPointer = (void*)ContactEditor;
1225 WData->WindowID = WindowMenuItemID;
1227 wxCommandEvent addevent(WINDOW_ADD);
1228 addevent.SetClientData(WData);
1229 wxPostEvent(this, addevent);
1231 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1232 ContactEditor->SetupHeaders();
1234 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1235 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1237 ContactEditor->SetupAccountData(true);
1241 // Check if pointer is NULL (not from the search forms) or not.
1243 if (DataCheck == 0){
1245 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1246 ContactEditor->SetupContact(ActiveAccount);
1250 UCNotif *uc = (UCNotif*)event.GetClientData();
1254 ContactEditor->SetupContact(ActiveAccount);
1255 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1259 ContactEditor->SetupContact(uc->ContactAccount);
1260 ContactEditor->LoadContact(uc->ContactFilename);
1269 ContactEditor->SetIcon(contacticon);
1270 ContactEditor->Show(true);
1274 void frmMain::RefreshAddressBook( wxCommandEvent& event ){
1276 // Refresh the address book data.
1278 // Check if ActiveAccount is empty. If not then check if
1279 // account type is not local otherwise continue.
1281 if (!ActiveAccount.IsEmpty()){
1283 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
1285 // Account type is not local.
1287 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1288 frameActMgr->AddTask(3, wxT(""), ActiveAccount,
1289 wxT(""), wxT(""), wxT(""), wxT(""));
1293 wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported"), wxICON_ERROR);
1301 void frmMain::OpenContactInfoList( wxListEvent& event )
1304 // Open the contact information window.
1306 wxStringTokenizer vcardfileline;
1309 wxString setname, setvalue;
1313 long intSelected = -1;
1314 long intContactSeekNum = -1;
1316 intSelected = lstContacts->GetNextItem(intSelected,
1318 wxLIST_STATE_SELECTED);
1320 intContactSeekNum = lstContacts->GetItemData(intSelected);
1322 if (intContactSeekNum == -1){
1328 Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
1330 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1331 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1332 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1334 contacticon.CopyFromBitmap(contacticonbmp);
1336 frmContact *Contact = new frmContact( this );
1338 // Add to window list.
1342 Contact->SetUID(WindowMenuItemID);
1344 WindowData *WData = new WindowData;
1346 WData->DataType = 0;
1347 WData->WindowPointer = (void*)Contact;
1348 WData->WindowID = WindowMenuItemID;
1350 wxCommandEvent addevent(WINDOW_ADD);
1351 addevent.SetClientData(WData);
1352 wxPostEvent(this, addevent);
1354 Contact->SetupPointers(&MemoryFileList);
1355 Contact->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1356 Contact->SetupContactData(&Person);
1358 Contact->SetIcon(contacticon);
1359 Contact->Show(true);
1363 void frmMain::OpenContactInfoList( wxCommandEvent& event ){
1365 // Open a list of contact information windows.
1368 OpenContactInfoList(pevent);
1372 void frmMain::OpenContactInfo( wxCommandEvent& event )
1375 // Open the contact information window.
1377 UCNotif *uc = (UCNotif*)event.GetClientData();
1379 wxStringTokenizer vcardfileline;
1382 wxString setname, setvalue;
1386 Person.LoadFile(uc->ContactFilename);
1388 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1389 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1390 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1392 contacticon.CopyFromBitmap(contacticonbmp);
1394 frmContact *Contact = new frmContact( this );
1396 // Add to window list.
1400 Contact->SetUID(WindowMenuItemID);
1402 WindowData *WData = new WindowData;
1404 WData->DataType = 0;
1405 WData->WindowPointer = (void*)Contact;
1406 WData->WindowID = WindowMenuItemID;
1408 wxCommandEvent addevent(WINDOW_ADD);
1409 addevent.SetClientData(WData);
1410 wxPostEvent(this, addevent);
1412 Contact->SetupPointers(&MemoryFileList);
1413 Contact->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1414 Contact->SetupContactData(&Person);
1416 Contact->SetIcon(contacticon);
1417 Contact->Show(true);
1422 void frmMain::LoadPreferences( wxActivateEvent& event)
1425 // Load the preferences.
1427 this->LoadPreferences(true);
1431 void frmMain::LoadPreferences(bool skipWindowSizeReload){
1433 // Load the preferences.
1435 wxString preffilename = GetUserPrefDir();
1437 XABPreferences preferences(preffilename);
1439 // Clear the active account/filename information and account list.
1442 ActiveAccountType = "";
1443 ActiveFilename = "";
1444 lstContacts->DeleteAllItems();
1446 // Setup the main window position (if needed).
1448 bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
1449 bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
1450 bool UseBackgroundContactColour = preferences.GetBoolData(wxT("UseBackgroundContactColour"));
1452 if (SaveWindowPos == true && skipWindowSizeReload == false){
1454 this->SetSize(preferences.GetMainWindowData());
1458 if (UseBackgroundContactColour == true){
1460 ContactBackgroundColour = preferences.GetBackgroundContactColourData();
1464 ContactBackgroundColour = wxTransparentColour;
1468 treAccounts->DeleteAllItems();
1470 wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
1472 // Stop all account timers and remove the accounts.
1474 for (std::map<wxString, wxAccountSyncTimer*>::iterator iter = AccountSyncTimers.begin();
1475 iter != AccountSyncTimers.end(); iter++){
1477 wxAccountSyncTimer *AccTmrPtr = iter->second;
1485 #if defined(__WIN32__)
1487 for (std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.begin();
1488 CertificateIter != AccountCertificateData.end(); CertificateIter++){
1490 CertFreeCertificateContext(CertificateIter->second);
1494 AccountCertificateData.clear();
1498 AccountSyncTimers.clear();
1501 wxString AccDirFull;
1502 wxString AccDirFullSfx;
1504 wxString AccDirFinal;
1505 AccountAccDirList.clear();
1506 AccountGroupList.clear();
1507 AccountGroupFilename.clear();
1508 AccountGroupTreeId.clear();
1509 wxTreeItemId AccountTreeId;
1510 wxTreeItemId GroupTreeId;
1513 // Relaod the accounts for the ETagProcTimer.
1515 ETagProcTimer.ReloadAccounts();
1517 for (int i = 0; i < preferences.accounts.GetCount(); i++){
1519 if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
1520 preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == true){
1526 if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
1532 AccDir = preferences.accounts.GetAccountDirectory(i);
1533 AccDirFull = preferences.accounts.GetAccountDirectory(i);
1535 AccDirFull.Append(wxT("."));
1536 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
1537 AccDirFullSfx.LowerCase();
1538 AccDirFullSfx.Trim();
1539 AccDirFull.Append(AccDirFullSfx);
1540 AccName = preferences.accounts.GetAccountName(i);
1542 AccountAccDirList.insert(std::make_pair(i, AccDirFull));
1544 if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
1545 preferences.accounts.GetAccountType(i) == wxT("carddav")){
1547 // TODO: Check if the directory exists before doing anything.
1551 // Add a new timer using the existing account details.
1553 wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
1555 ActTmrPtr->SetupData(AccDirFull, AccName);
1556 ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
1557 ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
1558 ActTmrPtr->SetOwner(this);
1559 ActTmrPtr->Notify();
1561 // Add the timer to the list of timers.
1563 AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
1565 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
1567 } else if (preferences.accounts.GetAccountType(i) == wxT("Local") ||
1568 preferences.accounts.GetAccountType(i) == wxT("local")) {
1570 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
1574 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountUnsupportedID, -1);
1578 // Go through the account directory and find contact files with
1579 // 'KIND:group' set and add them to the list of groups for the account.
1581 AccDirFinal = GetAccountDir(AccDirFull, FALSE);
1583 wxDir vcardaccdir(AccDirFinal);
1585 wxString vCardFilename;
1586 wxString vCardDataString;
1587 wxString vCardFilenameFull;
1589 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1593 if (vCardFilename.Right(4) == wxT(".vcf") ||
1594 vCardFilename.Right(4) == wxT(".VCF") ||
1595 vCardFilename.Right(5) == wxT(".vcard") ||
1596 vCardFilename.Right(5) == wxT(".VCARD")){
1600 vCardFilenameFull.Append(AccDirFinal);
1601 vCardFilenameFull.Append(wxT("/"));
1602 vCardFilenameFull.Append(vCardFilename);
1604 Person.LoadFile(vCardFilenameFull);
1606 if (Person.MeetBaseSpecification()){
1608 vCardDataString = Person.Get(wxT("KIND"));
1610 if (vCardDataString == wxT("group")){
1612 // The vCard kind is a group. Add to the account's group list.
1614 GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
1615 treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
1616 AccountGroupList.insert(std::make_pair(intGroupID, i));
1617 AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
1618 AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
1628 vCardFilename.Clear();
1629 vCardFilenameFull.Clear();
1630 vCardDataString.Clear();
1631 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1635 // Clearup for next account.
1639 AccDirFullSfx.clear();
1640 AccDirFinal.clear();
1645 // Load the account settings as they are needed for connecting
1648 prefaccounts = preferences.accounts;
1652 void frmMain::ConflictResolution(wxCommandEvent& event){
1654 // Display the conflict resolution window.
1656 frmConflictResolution *frameCR = new frmConflictResolution ( this );
1657 vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
1658 vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
1659 vCard *ServerDataPtr = vCardConfObj->vCardServerData;
1660 frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList, ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1661 frameCR->ShowModal();
1663 int FinalConflictResult = frameCR->GetResult();
1665 wxCommandEvent event2(ACTMGR_RESUMEPROC);
1666 event2.SetClientData(vCardConfObj->QRNotifData);
1667 event2.SetInt(FinalConflictResult);
1672 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1673 wxPostEvent(frameActMgr, event2);
1677 void frmMain::UpdateContactList(wxCommandEvent& event){
1679 // Update the contact list in the main window.
1681 UCNotif *ucd = (UCNotif*)event.GetClientData();
1683 // Check if the active account is being displayed in the
1684 // main window. If not, skip and delete the data.
1686 long longSelected = -1;
1687 int intSelectedData = 0;
1689 if (ActiveAccount == ucd->ContactAccount){
1691 // Look at the list of contacts and if it matches the
1692 // filename then update the name.
1696 longSelected = lstContacts->GetNextItem(longSelected,
1698 wxLIST_STATE_DONTCARE);
1700 if (longSelected == -1){
1706 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1708 if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
1710 // Work out which sorting mode we are in.
1714 // First Name, Last Name.
1716 if (ucd->ContactNameArray.Forename == wxT("") && ucd->ContactNameArray.Surname == wxT(""))
1718 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1722 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
1725 } else if (SortMode == 2){
1727 // Last Name, First Name.
1729 if (ucd->ContactNameArray.Forename == wxT("") && ucd->ContactNameArray.Surname == wxT(""))
1731 lstContacts->SetItem(longSelected, 0, wxT(", ") + ucd->ContactName);
1735 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
1738 } else if (SortMode == 3){
1742 if (ucd->ContactNickname == wxT(""))
1744 lstContacts->SetItem(longSelected, 0, _("(no nickname)"));
1748 lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
1751 } else if (SortMode == 4){
1755 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1762 // If the filename is the one loaded into the
1763 // browser control, then update this too.
1765 if (ActiveFilename == ContactsFileIndex[intSelectedData]){
1767 wxListEvent nullevent;
1768 ShowContactInfo(nullevent);
1776 for (std::map<int, void*>::iterator WindowIter = WindowListPointers.begin();
1777 WindowIter != WindowListPointers.end(); WindowIter++){
1779 if (WindowListType[WindowIter->first] != 0){
1785 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
1787 if (frmContactPtr->GetFilename() == ucd->ContactFilename){
1789 vCard UpdatedPerson;
1790 UpdatedPerson.LoadFile(ucd->ContactFilename);
1791 frmContactPtr->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1792 frmContactPtr->SetupContactData(&UpdatedPerson);
1798 // Send message to search window controller subroutine and
1799 // pass that notification onto the search windows.
1801 // Setup the new pointer to use the existing UCNotif without
1804 UCNotif *ucd2 = ucd;
1806 wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
1807 sup.SetClientData(ucd2);
1808 wxPostEvent(this, sup);
1810 // Clear up the unused pointer.
1816 void frmMain::SetupPointers(void *ActMgrPtrInc){
1818 // Setup the pointers for the main window.
1820 ActMgrPtr = ActMgrPtrInc;
1824 void frmMain::SetupForm(){
1826 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1827 frameActMgr->SetupPointers(&ETagProcTimer, this);
1829 // Setup the contact information icons for later.
1831 wxFileSystem::AddHandler(new wxMemoryFSHandler);
1835 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
1836 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
1837 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1839 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
1840 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
1841 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1843 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
1844 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
1845 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1847 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
1848 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
1849 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1851 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
1852 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
1853 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1855 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
1856 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
1857 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1859 LoadPreferences(false);
1863 void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
1865 // Update the contact lists in the search windows.
1867 // Go through each of the search windows and
1868 // send the required notification to update the
1869 // contact information.
1871 // Get the event notification data.
1873 UCNotif *ucd = (UCNotif*)event.GetClientData();
1875 // Process each search window giving the new details.
1877 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1878 switer != SearchWindowList.end(); switer++){
1880 // Duplicate the event notification data.
1882 UCNotif *ucd2 = new UCNotif;
1884 ucd2->ContactAccount = ucd->ContactAccount;
1885 ucd2->ContactFilename = ucd->ContactFilename;
1886 ucd2->ContactName = ucd->ContactName;
1887 ucd2->ContactNickname = ucd->ContactNickname;
1888 ucd2->ContactNameArray = ucd->ContactNameArray;
1890 // Pass the data to the search window for processing.
1892 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
1893 wxCommandEvent schupdate(SE_UPDATERESULT);
1894 schupdate.SetClientData(ucd2);
1895 wxPostEvent(frameSCH, schupdate);
1897 // Clear up the pointer prior to variable deletion.
1908 void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
1910 // Open a new search window.
1914 frmSearch *frameSCH = new frmSearch ( this );
1915 frameSCH->SetUID(WindowMenuItemID);
1916 frameSCH->Show(true);
1918 WindowData *WData = new WindowData;
1920 WData->DataType = 2;
1921 WData->WindowPointer = (void*)frameSCH;
1922 WData->WindowID = WindowMenuItemID;
1924 wxCommandEvent addevent(WINDOW_ADD);
1925 addevent.SetClientData(WData);
1926 wxPostEvent(this, addevent);
1928 // Add pointer to the list of open search windows.
1930 SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
1936 void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
1938 // Remove the pointer for a contact window from the
1941 void *frameSCH = (void*)event.GetClientData();
1943 SearchWindowList.erase(frameSCH);
1949 void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
1951 // Remove the pointer for a contact editor window from
1954 void *frameSCH = (void*)event.GetClientData();
1956 SearchWindowList.erase(frameSCH);
1962 void frmMain::RevealContact(wxCommandEvent& event){
1964 // Reveal a contact in the main window.
1966 UCNotif *uc = (UCNotif*)event.GetClientData();
1968 // Switch the account to the one passed.
1970 wxTreeItemIdValue cookie;
1971 wxTreeItemId next = treAccounts->GetRootItem();
1972 wxTreeItemId nextChild;
1974 for (int i = 0; i < prefaccounts.GetCount(); i++){
1977 nextChild = treAccounts->GetFirstChild(next, cookie);
1979 nextChild = treAccounts->GetNextSibling(nextChild);
1982 if (uc->ContactAccount == AccountAccDirList[i]){
1984 treAccounts->SelectItem(nextChild, TRUE);
1985 AccCtrl->SetText(treAccounts->GetItemText(nextChild));
1991 // Switch the contact to the one passed.
1993 long longSelected = -1;
1994 int intSelectedData = 0;
1998 longSelected = lstContacts->GetNextItem(longSelected,
2000 wxLIST_STATE_DONTCARE);
2002 if (longSelected == -1){
2008 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2010 // Compare the filename with the one received.
2011 // If they match then select it.
2013 if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
2017 lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
2018 lstContacts->EnsureVisible(longSelected);
2022 lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
2030 void frmMain::DeleteContact(wxCommandEvent& event){
2032 // Delete a contact from the main window.
2034 // Check if a contact is selected.
2036 long intSelected = -1;
2037 long intContactSeekNum = -1;
2038 wxString wxSContactName;
2040 intSelected = lstContacts->GetNextItem(intSelected,
2042 wxLIST_STATE_SELECTED);
2044 if (intSelected == -1){
2048 // Check if the account type is a valid account type, otherwise
2049 // display an error message.
2051 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
2052 ActiveAccountType != "Local" && ActiveAccountType != "local"){
2054 wxMessageBox(_("Cannot delete contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
2059 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2061 // Get the item data of the contact.
2063 intContactSeekNum = lstContacts->GetItemData(intSelected);
2065 // Get the name of the contact.
2067 wxSContactName = lstContacts->GetItemText(intSelected);
2069 // Display a message confirming if the contact should
2072 int QuestionResponse;
2074 QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
2076 if (QuestionResponse == wxNO){
2078 // Exit the subroutine
2084 // Delete the contact.
2086 if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
2088 wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
2093 // Remove the contact from the list.
2095 lstContacts->DeleteItem(intSelected);
2097 // Update the search windows, removing the deleted
2100 UCNotif *ucd = new UCNotif;
2102 ucd->ContactAccount = ActiveAccount;
2103 ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
2105 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
2106 switer != SearchWindowList.end(); switer++){
2108 // Duplicate the event notification data.
2110 UCNotif *ucd2 = new UCNotif;
2112 ucd2->ContactAccount = ucd->ContactAccount;
2113 ucd2->ContactFilename = ucd->ContactFilename;
2115 // Pass the data to the search window for processing.
2117 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
2118 wxCommandEvent schdelete(SE_DELETERESULT);
2119 schdelete.SetClientData(ucd2);
2120 wxPostEvent(frameSCH, schdelete);
2122 // Clear up the pointer prior to variable deletion.
2129 // Clear the wxHTMLWindow.
2131 wxString EmptyPage = wxT("");
2133 htmContactData->SetPage(EmptyPage);
2135 wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
2137 wxString wxSplitFilename;
2138 wxString wxSDataURL;
2140 while(wSTFilename.HasMoreTokens()){
2142 wxSplitFilename = wSTFilename.GetNextToken();
2146 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
2148 // Update the ETagDB and mark it as deleted.
2150 ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
2152 ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
2154 // Get the Data URL.
2156 wxTreeItemIdValue cookie;
2157 wxTreeItemId next = treAccounts->GetRootItem();
2159 wxTreeItemId selectedChild = treAccounts->GetSelection();
2160 wxTreeItemId nextChild;
2162 for (int i = 0; i < prefaccounts.GetCount(); i++){
2165 nextChild = treAccounts->GetFirstChild(next, cookie);
2167 nextChild = treAccounts->GetNextSibling(nextChild);
2170 if (nextChild == selectedChild){
2172 wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
2179 // Add task to the activity monitor to delete the contact.
2181 frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
2185 // Clear the variable. Don't delete as it will mess things up.
2187 ContactsFileIndex[intContactSeekNum] = wxT("");
2194 void frmMain::EmptyServerDialog(wxCommandEvent& event){
2196 // Display this message when the server information has changed
2199 QRNotif *qrn = (QRNotif *)event.GetClientData();
2201 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);
2203 if (QResponse == wxNO){
2209 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2210 event2.SetInt(*qrn->QResponse);
2211 event2.SetClientData(qrn->PausePtr);
2213 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2215 wxPostEvent(frameActMgr, event2);
2219 void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
2221 // Remove the contact from the window after syncronising.
2223 // Check which account is currently active in the window.
2224 // If it is different from the one passed to this subroutine then
2225 // exit from the subroutine.
2227 if (Account != ActiveAccount){
2231 long longSelected = -1;
2232 int intSelectedData = 0;
2236 longSelected = lstContacts->GetNextItem(longSelected,
2238 wxLIST_STATE_DONTCARE);
2240 if (longSelected == -1){
2246 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2248 // Compare the filename with the one received.
2249 // If they match then select it.
2251 if (ContactsFileIndex[intSelectedData] == Filename){
2253 // Remove the contact from the window.
2255 lstContacts->DeleteItem(intSelectedData);
2257 // Check if contact is the selected contact in the HTML window and
2258 // if it is then clear the window.
2260 if (ActiveFilename == Filename){
2262 wxString EmptyPage = wxT("");
2263 htmContactData->SetPage(EmptyPage);
2277 void frmMain::SortFNLN( wxCommandEvent& event ) {
2279 // Sort first name then last name.
2281 wxTreeEvent NullEvent;
2283 LoadContactList(NullEvent);
2287 void frmMain::SortLNFN( wxCommandEvent& event ) {
2289 // Sort last name then first name.
2291 wxTreeEvent NullEvent;
2293 LoadContactList(NullEvent);
2297 void frmMain::SortNickname( wxCommandEvent& event ) {
2299 // Sort by nickname.
2301 wxTreeEvent NullEvent;
2303 LoadContactList(NullEvent);
2307 void frmMain::SortDisplayAs( wxCommandEvent& event ) {
2309 // Sort by Display As name.
2311 wxTreeEvent NullEvent;
2313 LoadContactList(NullEvent);
2317 void frmMain::SortAscending( wxCommandEvent& event ) {
2321 wxTreeEvent NullEvent;
2322 AscendingMode = TRUE;
2323 LoadContactList(NullEvent);
2327 void frmMain::SortDescending( wxCommandEvent& event ) {
2331 wxTreeEvent NullEvent;
2332 AscendingMode = FALSE;
2333 LoadContactList(NullEvent);
2337 void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
2339 // Toggle the appearance of the status bar.
2341 if (stbBottom->IsShown() == TRUE){
2355 void frmMain::ActivityIconStart( wxCommandEvent& event ){
2357 // Display the activity icon.
2359 imgActivityStatus->SetBitmap(*imgActIcon1);
2360 ActivityIconStatus = 0;
2364 void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
2366 // Shuffle through the activity icons.
2368 switch (ActivityIconStatus){
2371 imgActivityStatus->SetBitmap(*imgActIcon1);
2372 ActivityIconStatus = 1;
2375 imgActivityStatus->SetBitmap(*imgActIcon2);
2376 ActivityIconStatus = 2;
2379 imgActivityStatus->SetBitmap(*imgActIcon3);
2380 ActivityIconStatus = 3;
2383 imgActivityStatus->SetBitmap(*imgActIcon4);
2384 ActivityIconStatus = 0;
2387 ActivityIconStatus = 0;
2393 void frmMain::ActivityIconStop( wxCommandEvent& event ){
2395 // Display the sleep icon.
2397 imgActivityStatus->SetBitmap(*imgActIconSleep);
2401 void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
2403 // Set the placement of the status bar icons.
2405 if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
2413 wxRect rectActivity;
2414 stbBottom->GetFieldRect(1, rectOnline);
2415 stbBottom->GetFieldRect(2, rectSSL);
2416 stbBottom->GetFieldRect(3, rectActivity);
2418 imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
2419 imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
2420 imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
2424 XABViewMode frmMain::GetViewMode(){
2426 // Set the view mode of the contact list.
2430 xvm.SortMode = SortMode;
2431 xvm.AscendingMode = AscendingMode;
2437 void frmMain::WindowAdd( wxCommandEvent &event ){
2439 // Add a window to the window list.
2441 WindowData *WData = (WindowData*)event.GetClientData();
2445 if (WData->DataType == 0){
2449 int intID = mnuContactWindows->GetId();
2451 mnuWindow->FindChildItem(intID, &pos);
2452 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2453 mnuNewItem->SetId(WData->WindowID);
2454 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2455 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2456 WindowListType.insert(std::make_pair(WData->WindowID, 0));
2457 mnuWindow->Insert((pos + 1), mnuNewItem);
2458 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
2460 } else if (WData->DataType == 1){
2462 // Contact Editor Window
2464 int intID = mnuContactEditorWindows->GetId();
2466 mnuWindow->FindChildItem(intID, &pos);
2467 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2468 mnuNewItem->SetId(WData->WindowID);
2469 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2470 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2471 WindowListType.insert(std::make_pair(WData->WindowID, 1));
2472 mnuWindow->Insert((pos + 1), mnuNewItem);
2473 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
2475 } else if (WData->DataType == 2){
2479 int intID = mnuSearchWindows->GetId();
2481 mnuWindow->FindChildItem(intID, &pos);
2482 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2483 mnuNewItem->SetId(WData->WindowID);
2484 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2485 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2486 WindowListType.insert(std::make_pair(WData->WindowID, 2));
2487 mnuWindow->Insert((pos + 1), mnuNewItem);
2488 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
2497 void frmMain::WindowEdit( wxCommandEvent &event ){
2499 // Edit a window in the window list.
2501 WindowData *WData = (WindowData*)event.GetClientData();
2503 if (WData->DataType == 0){
2505 // Get the window title and use that.
2507 frmContact *frmContactPtr = static_cast<frmContact*>(WData->WindowPointer);
2509 wxString WindowTitle = frmContactPtr->GetTitle();
2511 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2513 MenuIter->second->SetItemLabel(WindowTitle);
2515 } else if (WData->DataType == 1){
2517 // Get the window title and use that.
2519 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WData->WindowPointer);
2521 wxString WindowTitle = frmCEPtr->GetTitle();
2523 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2525 if (WindowTitle.IsEmpty()){
2527 MenuIter->second->SetItemLabel(_("Unnamed Contact"));
2531 MenuIter->second->SetItemLabel(WindowTitle);
2542 void frmMain::WindowDelete( wxCommandEvent &event ){
2544 // Delete a window from the window list.
2546 WindowData *WData = (WindowData*)event.GetClientData();
2548 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2550 mnuWindow->Remove(MenuIter->second);
2552 delete MenuIter->second;
2553 MenuIter->second = NULL;
2555 WindowListPointersMenu.erase(WData->WindowID);
2556 WindowListPointers.erase(WData->WindowID);
2557 WindowListType.erase(WData->WindowID);
2564 void frmMain::ShowContactWindow( wxCommandEvent &event ){
2566 // Show a contact window from the window list.
2568 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2570 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
2572 frmContactPtr->Show();
2573 frmContactPtr->Raise();
2577 void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
2579 // Show a contact editor window from the window list.
2581 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2583 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WindowIter->second);
2590 void frmMain::ShowSearchWindow( wxCommandEvent &event ){
2592 // Show a search window from the window list.
2594 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2596 frmSearch *frmSearchPtr = static_cast<frmSearch*>(WindowIter->second);
2598 frmSearchPtr->Show();
2599 frmSearchPtr->Raise();
2603 void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
2605 // Toggle the online/offline connection status.
2607 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2608 wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
2609 wxPostEvent(frameActMgr, toggconn);
2613 void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
2615 // Check the account type before continuing.
2617 wxString SeekAccount;
2618 wxString AccTypeLower;
2622 #if defined(__APPLE__)
2624 std::map<int, SecTrustRef>::iterator SSLTrustIter;
2626 for (int i = 0; i < prefaccounts.GetCount(); i++){
2628 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2629 AccType.Append(prefaccounts.GetAccountType(i));
2630 AccountSSL = prefaccounts.GetAccountSSL(i);
2631 AccTypeLower = AccType.MakeLower();
2632 SeekAccount.Append(wxT("."));
2633 SeekAccount.Append(AccTypeLower);
2635 if (SeekAccount == ActiveAccount){
2637 if (AccTypeLower == wxT("local")){
2643 if (AccountSSL == false){
2649 SSLTrustIter = AccountTrustData.find(i);
2651 // Setup and display the form.
2653 DisplayCertificate(SSLTrustIter->second);
2657 SeekAccount.Clear();
2658 AccTypeLower.Clear();
2663 #elif defined(__WIN32__)
2665 std::map<int, PCCERT_CONTEXT>::iterator SSLCertificateIter;
2667 for (int i = 0; i < prefaccounts.GetCount(); i++){
2669 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2670 AccType.Append(prefaccounts.GetAccountType(i));
2671 AccountSSL = prefaccounts.GetAccountSSL(i);
2672 AccTypeLower = AccType.MakeLower();
2673 SeekAccount.Append(wxT("."));
2674 SeekAccount.Append(AccTypeLower);
2676 if (SeekAccount == ActiveAccount){
2678 if (AccTypeLower == wxT("local")){
2684 if (AccountSSL == false){
2690 SSLCertificateIter = AccountCertificateData.find(i);
2692 // Setup and display the form.
2694 if (SSLCertificateIter->second->pCertInfo == NULL){
2696 wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
2700 BOOL ModifiedCertificateData;
2701 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
2703 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
2704 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
2709 //DisplayCertificate(SSLTrustIter->second);
2713 SeekAccount.Clear();
2714 AccTypeLower.Clear();
2721 std::map<int, SSLCertCollectionString>::iterator SSLColIter;
2723 for (int i = 0; i < prefaccounts.GetCount(); i++){
2725 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2726 AccType.Append(prefaccounts.GetAccountType(i));
2727 AccountSSL = prefaccounts.GetAccountSSL(i);
2728 AccTypeLower = AccType.MakeLower();
2729 SeekAccount.Append(wxT("."));
2730 SeekAccount.Append(AccTypeLower);
2732 if (SeekAccount == ActiveAccount){
2734 if (AccTypeLower == wxT("local")){
2740 if (AccountSSL == false){
2746 SSLColIter = AccountSSLData.find(i);
2748 SSLCertCollectionString SSLCertInfo = SSLColIter->second;
2750 frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
2751 frameSSLCert->StartCertFrom(0);
2752 frameSSLCert->SetupCertsString(SSLCertInfo);
2753 frameSSLCert->ShowModal();
2755 delete frameSSLCert;
2756 frameSSLCert = NULL;
2760 SeekAccount.Clear();
2761 AccTypeLower.Clear();
2770 void frmMain::ShowSSLInfo( wxCommandEvent &event ){
2772 // Check the account type before continuing.
2776 void frmMain::HideSSLInfo( wxCommandEvent &event ){
2778 // Check the account type before continuing.
2782 void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
2784 if (event.GetInt() == 0){
2786 imgConnStatus->SetBitmap(*imgOnline);
2790 imgConnStatus->SetBitmap(*imgOffline);
2796 void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
2798 // Display the form for showing an invalid SSL certificate.
2800 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2801 SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
2802 SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
2803 wxString AccountName = SSLICNObj->AccountName;
2804 frameISC->LoadData(SSLCCData, AccountName);
2805 frameISC->ShowModal();
2807 int FinalConflictResult = frameISC->GetResult();
2809 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2810 event2.SetClientData(SSLICNObj->QRNotifData);
2811 event2.SetInt(FinalConflictResult);
2816 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2817 wxPostEvent(frameActMgr, event2);
2821 void frmMain::InvalidSSLCertificateString( wxCommandEvent &event ){
2823 // Display the form for showing an invalid SSL certificate.
2825 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2826 SSLInvalidCertNotifObjString *SSLICNObj = (SSLInvalidCertNotifObjString*)event.GetClientData();
2827 SSLCertCollectionString SSLCCData = SSLICNObj->CertCollection;
2828 wxString AccountName = SSLICNObj->AccountName;
2829 frameISC->LoadData(SSLCCData, AccountName);
2830 frameISC->ShowModal();
2832 int FinalConflictResult = frameISC->GetResult();
2834 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2835 event2.SetClientData(SSLICNObj->QRNotifData);
2836 event2.SetInt(FinalConflictResult);
2841 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2842 wxPostEvent(frameActMgr, event2);
2846 void frmMain::PauseAllTimers(){
2848 // Pause all the account timers.
2850 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2851 ASTiter != AccountSyncTimers.end(); ASTiter++){
2853 ASTiter->second->Stop();
2859 void frmMain::ResumeAllTimers(){
2861 // Resume all the account timers.
2863 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2864 ASTiter != AccountSyncTimers.end(); ASTiter++){
2866 ASTiter->second->Start();
2872 #if defined(__APPLE__)
2874 #elif defined(__WIN32__)
2876 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
2878 // Delete existing data.
2880 std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.find(AccountID);
2882 if (CertificateIter != AccountCertificateData.end()){
2883 CertFreeCertificateContext(CertificateIter->second);
2886 AccountCertificateData.erase(AccountID);
2887 AccountSSLResult.erase(AccountID);
2891 AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
2892 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2898 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollectionString SSLCertInc){
2900 // Delete existing data.
2902 AccountSSLData.erase(AccountID);
2903 AccountSSLResult.erase(AccountID);
2907 AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
2908 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2914 void frmMain::SetupSSLStatus( int AccountID ){
2916 // Check if account ID given is
2917 // the active account and if not, do nothing.
2920 wxString AccTypeLower;
2922 AccType = prefaccounts.GetAccountType(AccountID);
2923 AccTypeLower = AccType.MakeLower();
2925 wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
2928 if (AccountIDName != ActiveAccount){
2934 // Check the account type is a supported account type.
2936 if (AccType != "CardDAV" && AccType != "carddav" &&
2937 AccType != "Local" && AccType != "local"){
2939 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2940 imgSSLStatus->SetBitmap(*imgNoSSL);
2945 // Check if the account has SSL enabled.
2947 bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
2949 if (SSLInUse == FALSE){
2951 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2952 imgSSLStatus->SetBitmap(*imgNoSSL);
2956 // Get the SSL Collection Data.
2958 std::map<int,int>::iterator SSLResultIter = AccountSSLResult.find(AccountID);
2960 // Check if a result value has been set.
2962 if (SSLResultIter == AccountSSLResult.end()){
2964 imgSSLStatus->SetBitmap(*imgSSLWarning);
2965 SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
2970 if (SSLResultIter->second == 1){
2972 imgSSLStatus->SetBitmap(*imgSSLWarning);
2973 SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
2974 prefaccounts.GetAccountName(AccountID) +
2975 wxT("' (Connection denied by user)\n\nDouble click for more information."));
2977 } else if (SSLResultIter->second == 0){
2979 imgSSLStatus->SetBitmap(*imgSSL);
2980 SSLToolTip->SetTip(wxT("Account '") +
2981 prefaccounts.GetAccountName(AccountID) +
2982 wxT("' secured using SSL\n\nDouble click for more information."));
2990 void frmMain::CheckUpdates( wxCommandEvent& event ){
2992 // Check for updates to Xestia Address Book.
2994 frmUpdate *frameUpdate = new frmUpdate ( this );
2995 frameUpdate->FetchData();
2996 frameUpdate->ShowModal();
3000 void frmMain::OpenImportDialog( wxCommandEvent& event ){
3002 // Run the import contacts function.
3008 void frmMain::OpenExportDialog( wxCommandEvent& event ){
3010 // Check if an account and at least one contact is selected
3011 // before continuing.
3013 wxArrayString ArrData;
3015 if (ActiveAccount.IsEmpty()){
3021 int ContactSelected = 0;
3022 int ContactsCollected = 0;
3023 long longSelected = -1;
3027 longSelected = lstContacts->GetNextItem(longSelected,
3029 wxLIST_STATE_SELECTED);
3031 if (longSelected == -1){
3037 int FileID = (int)lstContacts->GetItemData(longSelected);
3039 ArrData.Insert(ContactsFileIndex[FileID],
3040 ContactsCollected, 1);
3046 if (ContactSelected == 0){
3052 // Run the export contacts system.
3054 ExportRun(this, &ArrData);
3058 void frmMain::GetListControl(wxListCtrl *lstContactsPtr,
3059 wxArrayString *ContactsFileIndexPtr){
3061 // Set the list control pointers.
3063 lstContactsPtr = lstContacts;
3064 ContactsFileIndexPtr = &ContactsFileIndex;
3068 void frmMain::GetSelectedList( wxCommandEvent& event ){
3070 // Get the array of contact filenames.
3072 wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
3074 // Process them into an array of files.
3076 long longSelected = -1;
3077 int ContactsCollected = 0;
3078 wxString ContactFilename;
3082 longSelected = lstContacts->GetNextItem(longSelected,
3084 wxLIST_STATE_SELECTED);
3086 if (longSelected == -1){
3092 // Get the file information and add to the list.
3094 int FileID = (int)lstContacts->GetItemData(longSelected);
3096 ArrData->Insert(ContactsFileIndex[FileID],
3097 ContactsCollected, 1);
3099 ContactsCollected++;
3100 ContactFilename.Clear();
3108 void frmMain::SyncAccount( wxCommandEvent& event ){
3110 // Syncronise the selected account.
3112 wxString AccNameInc = event.GetString();
3114 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
3115 frameActMgr->AddTask(3, wxT(""), AccNameInc,
3116 wxT(""), wxT(""), wxT(""), wxT(""));
3120 void frmMain::ShowHelp( wxCommandEvent& event ){
3122 // Based on the operating system, work out where
3123 // the documentation should be.
3127 #if defined(__HAIKU__)
3129 #elif defined(__WIN32__)
3135 if (wxFileExists("/usr/share/doc/xestiaab/index.html")){
3137 wxLaunchDefaultBrowser(wxT("file:///usr/share/doc/xestiaab/index.html"));
3140 #if XSDAB_RELEASE == 0
3142 } else if (wxFileExists("/usr/local/share/doc/xestiaab/index.html")){
3144 wxLaunchDefaultBrowser(wxT("file:///usr/local/share/doc/xestiaab/index.html"));
3153 #if XSDAB_RELEASE == 0
3155 wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
3159 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!"));
3165 void frmMain::ShowImportResults( wxCommandEvent &event ){
3167 // Show the results of importing contacts.
3169 std::map<int,wxString> *ResultData = (std::map<int,wxString>*)event.GetClientData();
3171 frmImportResults *frmIR = new frmImportResults(this);
3172 frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
3183 void frmMain::ReloadContactList( wxCommandEvent &event ){
3185 // Check if the account name given is the current
3186 // account selected.
3188 if (ActiveAccount == event.GetString()){
3190 wxTreeEvent NullEvent;
3191 LoadContactList(NullEvent);
3197 void frmMain::ShowContactMenu( wxMouseEvent& event ){
3199 // Show the contact menu when a right click occurs
3200 // in the contacts list.
3202 bool EnableRefresh = FALSE;
3204 if (!ActiveAccount.IsEmpty() && (ActiveAccountType == "CardDAV" ||
3205 ActiveAccountType == "carddav" ||
3206 ActiveAccountType == "Local" ||
3207 ActiveAccountType == "local")){
3209 EnableRefresh = TRUE;
3213 ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
3215 this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
3219 void frmMain::ResetContactInfo(){
3221 // Reset the contact information to an empty page.
3223 wxString EmptyPage = wxT("");
3224 htmContactData->SetPage(EmptyPage);
3225 AccCtrl->SetValue("");
3229 bool frmMain::CloseAllWindows()
3231 // Attempt to close all windows.
3233 if (WindowListPointersMenu.size() == 0)
3238 if (wxMessageBox(_("Before preforming the action, all windows that are open will need to close. Do you wish to continue?"), _("Close All Windowss"), wxYES_NO) == wxYES)
3240 for(std::map<int, void*>::iterator windowIter = WindowListPointers.begin();
3241 windowIter != WindowListPointers.end(); windowIter++)
3243 wxWindow *windowPointer = static_cast<wxWindow*>(windowIter->second);
3244 windowPointer->Close();