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(CE_UPDATEACCOUNTLIST);
69 DEFINE_EVENT_TYPE(SE_UPDATECONTACTNOTIF);
70 DEFINE_EVENT_TYPE(CE_OPENCONTACT);
71 DEFINE_EVENT_TYPE(CE_OPENCONTACTLIST);
72 DEFINE_EVENT_TYPE(CE_NEWCONTACT);
73 DEFINE_EVENT_TYPE(CE_EDITCONTACT);
74 DEFINE_EVENT_TYPE(CE_DELETECONTACT);
75 DEFINE_EVENT_TYPE(CE_REVEALCONTACT);
76 DEFINE_EVENT_TYPE(CE_REMOVECONTACT);
77 DEFINE_EVENT_TYPE(CE_REMOVESEARCH);
78 DEFINE_EVENT_TYPE(SYNC_EMPTYSERVER);
79 DEFINE_EVENT_TYPE(ACTMGR_START);
80 DEFINE_EVENT_TYPE(ACTMGR_SHUFFLE);
81 DEFINE_EVENT_TYPE(ACTMGR_STOP);
82 DEFINE_EVENT_TYPE(WINDOW_ADD);
83 DEFINE_EVENT_TYPE(WINDOW_EDIT);
84 DEFINE_EVENT_TYPE(WINDOW_CLOSE);
85 DEFINE_EVENT_TYPE(CONNSTAT_UPDATE);
86 DEFINE_EVENT_TYPE(INVALIDSSLCERT);
87 DEFINE_EVENT_TYPE(INVALIDSSLCERTSTRING);
88 DEFINE_EVENT_TYPE(GETSELECTEDLIST);
89 DEFINE_EVENT_TYPE(SYNCACCOUNT);
90 DEFINE_EVENT_TYPE(IMPORT_RESULTSSHOW);
91 DEFINE_EVENT_TYPE(RELOADCONTACTLIST);
92 DEFINE_EVENT_TYPE(REFRESHADDRESSBOOK);
93 #if defined(__APPLE__)
94 DEFINE_EVENT_TYPE(INVALIDSSLTRUST);
97 // Setup the event table using the event types.
99 BEGIN_EVENT_TABLE(frmMain, wxFrame)
100 EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, frmMain::ConflictResolution)
101 EVT_COMMAND(wxID_ANY, CE_UPDATECONTACTLIST, frmMain::UpdateContactList)
102 EVT_COMMAND(wxID_ANY, CE_UPDATEACCOUNTLIST, frmMain::UpdateAccountList)
103 EVT_COMMAND(wxID_ANY, SE_UPDATECONTACTNOTIF, frmMain::UpdateSearchContactLists)
104 EVT_COMMAND(wxID_ANY, CE_OPENCONTACT, frmMain::OpenContactInfo)
105 EVT_COMMAND(wxID_ANY, CE_OPENCONTACTLIST, frmMain::OpenContactInfoList)
106 EVT_COMMAND(wxID_ANY, CE_NEWCONTACT, frmMain::ShowContactEditorNew)
107 EVT_COMMAND(wxID_ANY, CE_EDITCONTACT, frmMain::ShowContactEditorEdit)
108 EVT_COMMAND(wxID_ANY, CE_DELETECONTACT, frmMain::DeleteContact)
109 EVT_COMMAND(wxID_ANY, CE_REVEALCONTACT, frmMain::RevealContact)
110 EVT_COMMAND(wxID_ANY, CE_REMOVESEARCH, frmMain::RemoveContactsWindowPointer)
111 EVT_COMMAND(wxID_ANY, SYNC_EMPTYSERVER, frmMain::EmptyServerDialog)
112 EVT_COMMAND(wxID_ANY, ACTMGR_START, frmMain::ActivityIconStart)
113 EVT_COMMAND(wxID_ANY, ACTMGR_SHUFFLE, frmMain::ActivityIconShuffle)
114 EVT_COMMAND(wxID_ANY, ACTMGR_STOP, frmMain::ActivityIconStop)
115 EVT_COMMAND(wxID_ANY, WINDOW_ADD, frmMain::WindowAdd)
116 EVT_COMMAND(wxID_ANY, WINDOW_EDIT, frmMain::WindowEdit)
117 EVT_COMMAND(wxID_ANY, WINDOW_CLOSE, frmMain::WindowDelete)
118 EVT_COMMAND(wxID_ANY, CONNSTAT_UPDATE, frmMain::UpdateConnectionStatus)
119 EVT_COMMAND(wxID_ANY, INVALIDSSLCERT, frmMain::InvalidSSLCertificate)
120 EVT_COMMAND(wxID_ANY, INVALIDSSLCERTSTRING, frmMain::InvalidSSLCertificateString)
121 EVT_COMMAND(wxID_ANY, GETSELECTEDLIST, frmMain::GetSelectedList)
122 EVT_COMMAND(wxID_ANY, SYNCACCOUNT, frmMain::SyncAccount)
123 EVT_COMMAND(wxID_ANY, IMPORT_RESULTSSHOW, frmMain::ShowImportResults)
124 EVT_COMMAND(wxID_ANY, RELOADCONTACTLIST, frmMain::ReloadContactList)
125 EVT_COMMAND(wxID_ANY, REFRESHADDRESSBOOK, frmMain::RefreshAddressBook)
126 #if defined(__APPLE__)
127 EVT_COMMAND(wxID_ANY, INVALIDSSLTRUST, frmMain::DisplayTrustPanel)
131 frmMain::frmMain( wxWindow* parent )
136 // Setup the account icons.
138 wxMemoryInputStream astream(icons_accinet_png, sizeof(icons_accinet_png));
139 wxMemoryInputStream bstream(icons_acclocal_png, sizeof(icons_acclocal_png));
140 wxMemoryInputStream cstream(icons_accgroup_png, sizeof(icons_accgroup_png));
141 wxMemoryInputStream dstream(icons_accnone_png, sizeof(icons_accnone_png));
142 wxMemoryInputStream estream(icons_accunsupported_png, sizeof(icons_accunsupported_png));
144 wxImage icons_accinet_png(astream, wxBITMAP_TYPE_PNG);
145 wxBitmap AccInet(icons_accinet_png, -1);
147 wxIAccInet.CopyFromBitmap(AccInet);
149 wxImage icons_acclocal_png(bstream, wxBITMAP_TYPE_PNG);
150 wxBitmap AccNIcon(icons_acclocal_png, -1);
152 wxIAccNIcon.CopyFromBitmap(AccNIcon);
154 wxImage icons_accgroup_png(cstream, wxBITMAP_TYPE_PNG);
155 wxBitmap AccGrp(icons_accgroup_png, -1);
157 wxIAccGrp.CopyFromBitmap(AccGrp);
159 wxImage icons_accnone_png(dstream, wxBITMAP_TYPE_PNG);
160 wxBitmap AccNone(icons_accnone_png, -1);
162 wxIAccNone.CopyFromBitmap(AccNone);
164 wxImage icons_accunsupported_png(estream, wxBITMAP_TYPE_PNG);
165 wxBitmap AccUnsupported(icons_accunsupported_png, -1);
166 wxIcon wxIAccUnsupported;
167 wxIAccUnsupported.CopyFromBitmap(AccUnsupported);
169 AccountID = AccImgList->Add(wxIAccNIcon);
170 AccountNetID = AccImgList->Add(wxIAccInet);
171 AccountGrpID = AccImgList->Add(wxIAccGrp);
172 AccountNoneID = AccImgList->Add(wxIAccNone);
173 AccountUnsupportedID = AccImgList->Add(wxIAccUnsupported);
175 bmpIcon->SetIcon(AccImgList->GetIcon(AccountNoneID));
177 // Setup the status bar icons.
181 wxMemoryInputStream sslstream(icons_ssl_png, sizeof(icons_ssl_png));
182 wxMemoryInputStream sslwarningstream(icons_sslwarning_png, sizeof(icons_sslwarning_png));
183 wxMemoryInputStream nosslstream(icons_nossl_png, sizeof(icons_nossl_png));
185 wxImage icons_ssl_png(sslstream, wxBITMAP_TYPE_PNG);
186 imgSSL = new wxBitmap(icons_ssl_png, -1);
188 wxImage icons_sslwarning_png(sslwarningstream, wxBITMAP_TYPE_PNG);
189 imgSSLWarning = new wxBitmap(icons_sslwarning_png, -1);
191 wxImage icons_nossl_png(nosslstream, wxBITMAP_TYPE_PNG);
192 imgNoSSL = new wxBitmap(icons_nossl_png, -1);
196 wxMemoryInputStream addaddressbook(toolbar_addaddressbook_png, sizeof(toolbar_addaddressbook_png));
197 wxMemoryInputStream preferences(toolbar_preferences_png, sizeof(toolbar_preferences_png));
198 wxMemoryInputStream searchcontacts(toolbar_searchcontacts_png, sizeof(toolbar_searchcontacts_png));
199 wxMemoryInputStream addcontact(toolbar_addcontact_png, sizeof(toolbar_addcontact_png));
200 wxMemoryInputStream editcontact(toolbar_editcontact_png, sizeof(toolbar_editcontact_png));
201 wxMemoryInputStream deletecontact(toolbar_deletecontact_png, sizeof(toolbar_deletecontact_png));
203 wxImage toolbar_addaddressbook_png(addaddressbook, wxBITMAP_TYPE_PNG);
204 imgAddAddressBook = new wxBitmap (toolbar_addaddressbook_png, -1);
205 tblMain->SetToolNormalBitmap(tbtNewAccount->GetId(), *imgAddAddressBook);
207 wxImage toolbar_preferences_png(preferences, wxBITMAP_TYPE_PNG);
208 imgPreferences = new wxBitmap (toolbar_preferences_png, -1);
209 tblMain->SetToolNormalBitmap(tbtPreferences->GetId(), *imgPreferences);
211 wxImage toolbar_searchcontacts_png(searchcontacts, wxBITMAP_TYPE_PNG);
212 imgSearchContacts = new wxBitmap (toolbar_searchcontacts_png, -1);
213 tblMain->SetToolNormalBitmap(tbtSearch->GetId(), *imgSearchContacts);
215 wxImage toolbar_addcontact_png(addcontact, wxBITMAP_TYPE_PNG);
216 imgAddContact = new wxBitmap (toolbar_addcontact_png, -1);
217 tblMain->SetToolNormalBitmap(tbtAddContact->GetId(), *imgAddContact);
219 wxImage toolbar_editcontact_png(editcontact, wxBITMAP_TYPE_PNG);
220 imgEditContact = new wxBitmap (toolbar_editcontact_png, -1);
221 tblMain->SetToolNormalBitmap(tbtEditContact->GetId(), *imgEditContact);
223 wxImage toolbar_deletecontact_png(deletecontact, wxBITMAP_TYPE_PNG);
224 imgDeleteContact = new wxBitmap (toolbar_deletecontact_png, -1);
225 tblMain->SetToolNormalBitmap(tbtDeleteContact->GetId(), *imgDeleteContact);
229 wxMemoryInputStream act1(icons_act1_png, sizeof(icons_act1_png));
230 wxMemoryInputStream act2(icons_act2_png, sizeof(icons_act2_png));
231 wxMemoryInputStream act3(icons_act3_png, sizeof(icons_act3_png));
232 wxMemoryInputStream act4(icons_act4_png, sizeof(icons_act4_png));
233 wxMemoryInputStream actsleep(icons_actsleep_png, sizeof(icons_actsleep_png));
235 wxImage icons_actsleep_png(actsleep, wxBITMAP_TYPE_PNG);
236 imgActIconSleep = new wxBitmap (icons_actsleep_png, -1);
238 wxImage icons_act1_png(act1, wxBITMAP_TYPE_PNG);
239 imgActIcon1 = new wxBitmap (icons_act1_png, -1);
241 wxIAct1icon.CopyFromBitmap(*imgActIcon1);
243 wxImage icons_act2_png(act2, wxBITMAP_TYPE_PNG);
244 imgActIcon2 = new wxBitmap (icons_act2_png, -1);
246 wxIAct2icon.CopyFromBitmap(*imgActIcon2);
248 wxImage icons_act3_png(act3, wxBITMAP_TYPE_PNG);
249 imgActIcon3 = new wxBitmap (icons_act3_png, -1);
251 wxIAct3icon.CopyFromBitmap(*imgActIcon3);
253 wxImage icons_act4_png(act4, wxBITMAP_TYPE_PNG);
254 imgActIcon4 = new wxBitmap (icons_act4_png, -1);
256 wxIAct4icon.CopyFromBitmap(*imgActIcon4);
258 // Online/Offline icons.
260 wxMemoryInputStream onlinestream(icons_online_png, sizeof(icons_online_png));
261 wxMemoryInputStream offlinestream(icons_offline_png, sizeof(icons_offline_png));
263 wxImage icons_online_png(onlinestream, wxBITMAP_TYPE_PNG);
264 imgOnline = new wxBitmap(icons_online_png, -1);
266 wxImage icons_offline_png(offlinestream, wxBITMAP_TYPE_PNG);
267 imgOffline = new wxBitmap(icons_offline_png, -1);
269 // Setup the account view.
271 AccCtrl->SetPopupControl(treAccounts);
272 AccCtrl->SetPopupMaxHeight(175);
273 AccCtrl->SetPopupMinWidth(250);
274 treAccounts->AssignImageList(AccImgList);
276 wxListItem ColumnData;
278 ColumnData.SetText(wxT("Name0"));
279 ColumnData.SetWidth(320);
280 lstContacts->InsertColumn(0, ColumnData);
282 treAccounts->Connect(wxEVT_LEFT_DCLICK, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
283 treAccounts->Connect(wxEVT_TREE_SEL_CHANGED, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
285 #if defined(__HAIKU__)
287 #elif defined(__WIN32__)
289 int stbBottomData [4] = { -1, 8, 8, 8 };
293 int stbBottomData [4] = { -1, 20, 20, 20 };
297 stbBottom->SetFieldsCount(4, stbBottomData);
298 stbBottom->SetMinHeight(16);
303 stbBottom->GetFieldRect(1, rectOnline);
304 stbBottom->GetFieldRect(2, rectSSL);
305 stbBottom->GetFieldRect(3, rectActivity);
307 SSLToolTip = new wxToolTip(wxT(""));
309 imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectOnline.GetX()),(rectOnline.GetY())), wxDefaultSize, 0 );
310 imgConnStatus->SetBitmap(*imgOnline);
311 imgConnStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ToggleConnectionStatus ), NULL, this );
313 imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()),(rectSSL.GetY())), wxDefaultSize, 0 );
314 imgSSLStatus->SetBitmap(*imgNoSSL);
315 imgSSLStatus->SetToolTip(SSLToolTip);
316 imgSSLStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowSSLCertificates ), NULL, this );
318 imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()),(rectActivity.GetY())), wxDefaultSize, 0);
319 imgActivityStatus->SetBitmap(*imgActIconSleep);
320 imgActivityStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowActivityWindow ), NULL, this );
322 // Setup the window menu.
324 // By default should be:
329 // Contact editor windows:
335 mnuContactWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact windows:") ), wxEmptyString, wxITEM_NORMAL );
336 mnuWindow->Append( mnuContactWindows );
338 mnuWindow->AppendSeparator();
340 mnuContactEditorWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact editor windows:") ), wxEmptyString, wxITEM_NORMAL );
341 mnuWindow->Append( mnuContactEditorWindows );
343 mnuWindow->AppendSeparator();
345 mnuSearchWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( wxT("Search windows:") ), wxEmptyString, wxITEM_NORMAL );
346 mnuWindow->Append( mnuSearchWindows );
348 #if defined(__WIN32__)
353 mnuContactWindows->SetFont(fontstyle);
354 mnuContactEditorWindows->SetFont(fontstyle);
355 mnuSearchWindows->SetFont(fontstyle);
359 mnuContactWindows->Enable(FALSE);
360 mnuContactEditorWindows->Enable(FALSE);
361 mnuSearchWindows->Enable(FALSE);
365 // Hide unimplemented functions.
371 void frmMain::QuitApp( wxCloseEvent& event )
374 // Run the QuitApp function.
380 void frmMain::QuitApp( wxCommandEvent& event )
383 // Run the QuitApp function.
389 void frmMain::QuitApp()
392 // Function to run when quitting.
394 // Write out the ETag databases.
396 ETagProcTimer.Stop();
397 ETagProcTimer.Notify();
399 // Save Preferences: Save the window position if that option is enabled.
401 wxString SetFilename = GetUserPrefDir();
403 #if defined(__HAIKU__)
407 #elif defined(__WIN32__)
409 SetFilename.Append(wxT("settings"));
415 SetFilename.Append(wxT("settings"));
419 wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
421 bool SaveWindowPos = FALSE;
422 wxString SaveWindowInc;
423 cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
425 if (SaveWindowInc == wxT("true")){
427 SaveWindowPos = TRUE;
431 if (SaveWindowPos == TRUE){
433 wxRect frmMainPos = this->GetRect();
435 cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
436 cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
437 cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
438 cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
445 //Everything closed... exit.
453 void frmMain::ShowActivityWindow( wxCommandEvent& event )
456 // Open the activity manager window.
458 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
459 frameActMgr->OpenWindow();
464 void frmMain::ShowAboutWindow( wxCommandEvent& event )
467 // Show the about window.
469 frmAbout *frameAbout = new frmAbout ( this );
470 frameAbout->SetupAboutWindow();
471 frameAbout->ShowModal();
477 void frmMain::OpenPreferences( wxCommandEvent& event)
480 // Close all windows first.
482 if (CloseAllWindows() == false)
487 // Open the preferences window.
489 ReloadAccounts = FALSE;
491 frmPreferences *framePreferences = new frmPreferences ( this );
492 framePreferences->SetupPointers(&ReloadAccounts);
493 framePreferences->ShowModal();
494 delete framePreferences;
495 framePreferences = NULL;
497 if (ReloadAccounts == TRUE){
499 // Reload the accounts as a change has been made within
500 // the application and clear the current contact information.
502 this->LoadPreferences();
503 this->ResetContactInfo();
509 void frmMain::OpenNewABDialog( wxCommandEvent& event)
512 // Open the new account dialog.
514 ReloadAccounts = FALSE;
516 frmNewAccount *frameNewAccount = new frmNewAccount ( this );
517 frameNewAccount->SetupPointers(&ReloadAccounts);
518 frameNewAccount->ShowModal();
519 delete frameNewAccount;
520 frameNewAccount = NULL;
522 if (ReloadAccounts == TRUE){
524 // Reload the accounts as a change has been made within
527 this->LoadPreferences();
533 void frmMain::LoadContactList( wxTreeEvent& event )
536 // Load the contact list.
538 // Clear all existing variables.
540 lstContacts->DeleteAllItems();
542 treAccounts->SetAccount();
544 wxTreeItemIdValue cookie;
545 wxTreeItemId next = treAccounts->GetRootItem();
546 wxString AccountName;
547 wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
548 wxString AccountDirCmb;
549 long selectedaccount = 0;
551 wxTreeItemId selectedChild = treAccounts->GetSelection();
552 wxTreeItemId nextChild;
554 wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
555 int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
557 int SCImg = treAccounts->GetItemImage(selectedChild);
558 int AccountIndex = 0;
560 bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
562 // Process each account.
564 for (int i = 0; i < prefaccounts.GetCount(); i++){
566 if (ActiveItemIcon == 2){
568 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
569 std::multimap<int, int>::iterator AGLiter = AccountGroupList.find(AGTiter->second);
570 int ActiveAccountG = AGLiter->second;
572 if (i == ActiveAccountG){
574 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
575 AccountType.Append(prefaccounts.GetAccountType(i));
580 if (AccountType == wxT("CardDAV")){
581 AccountTypeFinal.Append(wxT("carddav"));
582 } else if (AccountType == wxT("Local")){
583 imgSSLStatus->SetBitmap(*imgOffline);
584 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
585 AccountTypeFinal.Append(wxT("local"));
587 imgSSLStatus->SetBitmap(*imgOffline);
588 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
589 AccountTypeFinal.Append(AccountType.Lower());
600 nextChild = treAccounts->GetFirstChild(next, cookie);
602 nextChild = treAccounts->GetNextSibling(nextChild);
605 AccountName = treAccounts->GetItemText(nextChild);
607 if (nextChild == selectedChild){
609 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
610 AccountType.Append(prefaccounts.GetAccountType(i));
615 if (AccountType == wxT("CardDAV")){
616 AccountTypeFinal.Append(wxT("carddav"));
617 } else if (AccountType == wxT("Local")){
618 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
619 AccountTypeFinal.Append(wxT("local"));
621 AccountTypeFinal.Append(AccountType.Lower());
630 if (selectedaccount >= prefaccounts.GetCount()){
632 // The account selected isn't there so return.
640 // Open the directory and get the list of .vcf files
641 // in that directory.
643 ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
644 ActiveAccountType = AccountType;
646 SetupSSLStatus(AccountIndex);
648 AccountDirFinal.Clear();
649 AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
651 ContactsFileIndex.Clear();
653 wxString vCardFilename;
654 wxString vCardFilenameFull;
655 wxString vCardDataString;
656 wxStringTokenizer vcardfileline;
658 wxString setname, setvalue;
659 std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
660 std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
661 long ContactIndex = 1;
662 long ContactSeekPoint = 0;
664 wxDir vcardaccdir(AccountDirFinal);
666 // Get the wxTreeItemId and image icon and compare it to the list.
668 if (ActiveItemIcon == AccountGrpID){
670 // It's a group so load the file containing the group and
671 // get the members of the group.
676 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
677 std::multimap<int, wxString>::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
679 Group.LoadFile(AGFiter->second);
681 ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
683 for (int i = 0; i < vCardMember.PropCount; i++){
685 vCardMember.PropValues[i].Trim();
686 if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
688 wxString NewPropValue;
689 NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
690 vCardMember.PropValues[i] = NewPropValue;
696 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
700 if (vCardFilename.Right(4) == wxT(".vcf") ||
701 vCardFilename.Right(4) == wxT(".VCF") ||
702 vCardFilename.Right(5) == wxT(".vcard") ||
703 vCardFilename.Right(5) == wxT(".VCARD")){
706 bool FoundMember = FALSE;
708 vCardFilenameFull.Append(AccountDirFinal);
709 vCardFilenameFull.Append(wxT("/"));
710 vCardFilenameFull.Append(vCardFilename);
712 Person.LoadFile(vCardFilenameFull);
714 UIDCode = Person.Get(wxT("UID"));
716 for (int i = 0; i < vCardMember.PropCount; i++){
718 if (vCardMember.PropValues[i] == UIDCode){
726 if (FoundMember == FALSE){
728 vCardFilename.Clear();
729 vCardFilenameFull.Clear();
730 vCardDataString.Clear();
731 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
736 if (Person.MeetBaseSpecification()){
740 // Split the name into sections.
742 vCardDataString = Person.Get(wxT("N"));
744 vCardName NameData = Person.GetName();
746 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
748 } else if (SortMode == 2){
750 // Split the name into sections.
752 vCardName NameData = Person.GetName();
754 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
756 } else if (SortMode == 3){
758 // Check and make sure that the top most nickname is used.
760 vCardDataString = Person.Get(wxT("NICKNAME"));
762 if (vCardDataString.IsEmpty()){
764 vCardDataString = wxT("(no nickname)");
768 } else if (SortMode == 4){
770 vCardDataString = Person.Get(wxT("FN"));
774 if (AscendingMode == TRUE){
775 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
777 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
784 vCardFilename.Clear();
785 vCardFilenameFull.Clear();
786 vCardDataString.Clear();
787 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
793 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
796 if (vCardFilename.Right(4) == wxT(".vcf") ||
797 vCardFilename.Right(4) == wxT(".VCF") ||
798 vCardFilename.Right(5) == wxT(".vcard") ||
799 vCardFilename.Right(5) == wxT(".VCARD")){
803 vCardFilenameFull.Append(AccountDirFinal);
804 vCardFilenameFull.Append(vCardFilename);
806 Person.LoadFile(vCardFilenameFull);
808 if (Person.MeetBaseSpecification()){
812 // Split the name into sections.
814 vCardDataString = Person.Get(wxT("N"));
816 vCardName NameData = Person.GetName();
818 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
820 } else if (SortMode == 2){
822 // Split the name into sections.
824 vCardName NameData = Person.GetName();
826 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
828 } else if (SortMode == 3){
830 // Check and make sure that the top most nickname is used.
832 vCardDataString = Person.Get(wxT("NICKNAME"));
834 if (vCardDataString.IsEmpty()){
836 vCardDataString = wxT("(no nickname)");
840 } else if (SortMode == 4){
842 vCardDataString = Person.Get(wxT("FN"));
846 if (AscendingMode == TRUE){
848 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
852 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
860 vCardFilename.Clear();
861 vCardFilenameFull.Clear();
862 vCardDataString.Clear();
863 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
870 // Insert the data into the control.
872 if (AscendingMode == TRUE){
873 for (std::map<wxString, wxString>::iterator iter = vCardNamesAsc.begin();
874 iter != vCardNamesAsc.end(); ++iter){
876 wxListItem ContactInfo;
878 ContactInfo.SetId(0);
879 ContactInfo.SetText(_("Mooo"));
880 ContactInfo.SetData(ContactSeekPoint);
881 ContactIndex = lstContacts->InsertItem(ContactInfo);
883 lstContacts->SetItem(ContactIndex, 0, iter->first);
885 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
892 for (std::map<wxString, wxString>::iterator iter = vCardNamesDsc.begin();
893 iter != vCardNamesDsc.end(); ++iter){
895 wxListItem ContactInfo;
897 ContactInfo.SetId(0);
898 ContactInfo.SetText(_("Mooo"));
899 ContactInfo.SetData(ContactSeekPoint);
900 ContactIndex = lstContacts->InsertItem(ContactInfo);
902 lstContacts->SetItem(ContactIndex, 0, iter->first);
903 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
912 void frmMain::ShowContactInfo( wxListEvent& event )
915 // Display the contact information.
917 long intSelected = -1;
918 long ContactSeekNum = -1;
920 // Check if several contacts have been selected.
922 int ContactTotal = 0;
926 intSelected = lstContacts->GetNextItem(intSelected,
928 wxLIST_STATE_SELECTED);
930 if (intSelected == -1){
940 if (ContactTotal == 0){
941 htmContactData->SetPage(wxT(""));
945 if (ContactTotal > 1){
947 htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
948 ActiveFilename.Clear();
953 intSelected = lstContacts->GetNextItem(intSelected,
955 wxLIST_STATE_SELECTED);
957 ContactSeekNum = lstContacts->GetItemData(intSelected);
960 wxString wxSContactString;
961 wxString ContactLine;
964 size_t ContactLineLen;
965 bool ExtraLineSeek = FALSE;
966 int QuoteBreakPoint = 0;
968 bool PropertyFind = FALSE;
969 bool QuoteMode = FALSE;
971 wxString wxSPropertyNextLine;
972 wxString wxSProperty;
973 wxString wxSPropertySeg1;
974 wxString wxSPropertySeg2;
976 // Check if we are using wxWidgets version 2.8 or less and
977 // execute the required command accordingly.
979 #if wxABI_VERSION < 20900
980 ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
982 ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
985 if (ContactFile.IsOpened() == FALSE){
991 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
995 std::map<int, wxString> ContactFileLines;
996 std::map<int, wxString>::iterator striter;
998 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
1000 int ContactLineSeek = 0;
1002 while (wSTContactFileLines.HasMoreTokens() == TRUE){
1004 ContactLine = wSTContactFileLines.GetNextToken();
1005 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
1010 if (ContactSeekNum < 0){
1014 for (std::map<int, wxString>::iterator iter = ContactFileLines.begin();
1015 iter != ContactFileLines.end(); ++iter){
1017 // Find the colon which splits the start bit from the data part.
1019 ContactLine = iter->second;
1021 while (ExtraLineSeek == TRUE){
1023 // Check if there is extra data on the next line
1024 // (indicated by space or tab at the start) and add data.
1028 if (iter == ContactFileLines.end()){
1035 wxSPropertyNextLine = iter->second;
1038 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1040 wxSPropertyNextLine.Remove(0, 1);
1041 ContactLine.Append(wxSPropertyNextLine);
1046 ExtraLineSeek = FALSE;
1052 ContactLineLen = ContactLine.Len();
1054 // Make sure we are not in quotation mode.
1055 // Make sure colon does not have \ or \\ before it.
1057 for (int i = 0; i <= ContactLineLen; i++){
1059 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1061 PropertyFind = FALSE;
1063 } else if (PropertyFind == TRUE){
1065 wxSProperty.Append(ContactLine.Mid(i, 1));
1069 if (ContactLine.Mid(i, 1) == wxT("\"")){
1071 if (QuoteMode == TRUE){
1083 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1085 QuoteBreakPoint = i;
1092 // Split that line at the point into two variables (ignore the colon).
1094 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1095 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1097 // Insert both into the vCard data file.
1099 Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
1102 PropertyFind = TRUE;
1103 ExtraLineSeek = TRUE;
1105 QuoteBreakPoint = 0;
1106 ContactLine.Clear();
1107 wxSProperty.Clear();
1111 OldSessionID = SessionID;
1112 SessionID = wxString::Format(wxT("%i"), rand() % 32768);
1113 LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList, ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1114 ActiveFilename = ContactsFileIndex[ContactSeekNum];
1118 void frmMain::ShowContactEditorNew( wxCommandEvent& event )
1121 // Open a contact editor window to write a new contact with.
1123 // Check if there is an account selected and if not
1124 // return immediately.
1126 if (ActiveAccount.IsEmpty()){
1132 // Check if the account type is a valid account type, otherwise
1133 // display an error message.
1135 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1136 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1138 wxMessageBox(_("Cannot add a new contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1143 // Add Pointer to SetupPointers for the ETagDB.
1145 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1146 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1147 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1149 contacticon.CopyFromBitmap(contacticonbmp);
1151 frmContactEditor *ContactEditor = new frmContactEditor( this );
1155 ContactEditor->SetUID(WindowMenuItemID);
1157 WindowData *WData = new WindowData;
1159 WData->DataType = 1;
1160 WData->WindowPointer = (void*)ContactEditor;
1161 WData->WindowID = WindowMenuItemID;
1163 wxCommandEvent addevent(WINDOW_ADD);
1164 addevent.SetClientData(WData);
1165 wxPostEvent(this, addevent);
1167 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1168 ContactEditor->SetupHeaders();
1169 ContactEditor->SetupContact(ActiveAccount);
1170 ContactEditor->SetIcon(contacticon);
1171 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1172 ContactEditor->Show(true);
1176 void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
1179 // Open a contact editor window for editing an existing contact
1182 // Check if there is an account selected and if not
1183 // return immediately.
1185 int DataCheck = event.GetInt();
1187 if (ActiveAccount.IsEmpty() && DataCheck == 0){
1193 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1194 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1195 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1197 contacticon.CopyFromBitmap(contacticonbmp);
1199 // Check if a contact has been selected.
1201 long intSelected = -1;
1202 long intContactSeekNum = -1;
1204 intSelected = lstContacts->GetNextItem(intSelected,
1206 wxLIST_STATE_SELECTED);
1208 if (intSelected == -1){
1214 intContactSeekNum = lstContacts->GetItemData(intSelected);
1216 // Get the filename of the selected contact.
1218 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1219 frmContactEditor *ContactEditor = new frmContactEditor( this );
1223 ContactEditor->SetUID(WindowMenuItemID);
1225 WindowData *WData = new WindowData;
1227 WData->DataType = 1;
1228 WData->WindowPointer = (void*)ContactEditor;
1229 WData->WindowID = WindowMenuItemID;
1231 wxCommandEvent addevent(WINDOW_ADD);
1232 addevent.SetClientData(WData);
1233 wxPostEvent(this, addevent);
1235 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1236 ContactEditor->SetupHeaders();
1238 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1239 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1241 ContactEditor->SetupAccountData(true);
1245 // Check if pointer is NULL (not from the search forms) or not.
1247 if (DataCheck == 0){
1249 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1250 ContactEditor->SetupContact(ActiveAccount);
1254 UCNotif *uc = (UCNotif*)event.GetClientData();
1258 ContactEditor->SetupContact(ActiveAccount);
1259 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1263 ContactEditor->SetupContact(uc->ContactAccount);
1264 ContactEditor->LoadContact(uc->ContactFilename);
1273 ContactEditor->SetIcon(contacticon);
1274 ContactEditor->Show(true);
1278 void frmMain::RefreshAddressBook( wxCommandEvent& event ){
1280 // Refresh the address book data.
1282 // Check if ActiveAccount is empty. If not then check if
1283 // account type is not local otherwise continue.
1285 if (!ActiveAccount.IsEmpty()){
1287 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
1289 // Account type is not local.
1291 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1292 frameActMgr->AddTask(3, wxT(""), ActiveAccount,
1293 wxT(""), wxT(""), wxT(""), wxT(""));
1297 wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported"), wxICON_ERROR);
1305 void frmMain::OpenContactInfoList( wxListEvent& event )
1308 // Open the contact information window.
1310 wxStringTokenizer vcardfileline;
1313 wxString setname, setvalue;
1317 long intSelected = -1;
1318 long intContactSeekNum = -1;
1320 intSelected = lstContacts->GetNextItem(intSelected,
1322 wxLIST_STATE_SELECTED);
1324 intContactSeekNum = lstContacts->GetItemData(intSelected);
1326 if (intContactSeekNum == -1){
1332 Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
1334 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1335 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1336 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1338 contacticon.CopyFromBitmap(contacticonbmp);
1340 frmContact *Contact = new frmContact( this );
1342 // Add to window list.
1346 Contact->SetUID(WindowMenuItemID);
1348 WindowData *WData = new WindowData;
1350 WData->DataType = 0;
1351 WData->WindowPointer = (void*)Contact;
1352 WData->WindowID = WindowMenuItemID;
1354 wxCommandEvent addevent(WINDOW_ADD);
1355 addevent.SetClientData(WData);
1356 wxPostEvent(this, addevent);
1358 Contact->SetupPointers(&MemoryFileList);
1359 Contact->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1360 Contact->SetupContactData(&Person);
1362 Contact->SetIcon(contacticon);
1363 Contact->Show(true);
1367 void frmMain::OpenContactInfoList( wxCommandEvent& event ){
1369 // Open a list of contact information windows.
1372 OpenContactInfoList(pevent);
1376 void frmMain::OpenContactInfo( wxCommandEvent& event )
1379 // Open the contact information window.
1381 UCNotif *uc = (UCNotif*)event.GetClientData();
1383 wxStringTokenizer vcardfileline;
1386 wxString setname, setvalue;
1390 Person.LoadFile(uc->ContactFilename);
1392 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1393 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1394 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1396 contacticon.CopyFromBitmap(contacticonbmp);
1398 frmContact *Contact = new frmContact( this );
1400 // Add to window list.
1404 Contact->SetUID(WindowMenuItemID);
1406 WindowData *WData = new WindowData;
1408 WData->DataType = 0;
1409 WData->WindowPointer = (void*)Contact;
1410 WData->WindowID = WindowMenuItemID;
1412 wxCommandEvent addevent(WINDOW_ADD);
1413 addevent.SetClientData(WData);
1414 wxPostEvent(this, addevent);
1416 Contact->SetupPointers(&MemoryFileList);
1417 Contact->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1418 Contact->SetupContactData(&Person);
1420 Contact->SetIcon(contacticon);
1421 Contact->Show(true);
1426 void frmMain::LoadPreferences( wxActivateEvent& event)
1429 // Load the preferences.
1431 this->LoadPreferences();
1435 void frmMain::LoadPreferences(){
1437 // Load the preferences.
1439 wxString preffilename = GetUserPrefDir();
1441 XABPreferences preferences(preffilename);
1443 // Setup the main window position (if needed).
1445 bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
1446 bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
1447 bool UseBackgroundContactColour = preferences.GetBoolData(wxT("UseBackgroundContactColour"));
1449 if (SaveWindowPos == true){
1451 this->SetSize(preferences.GetMainWindowData());
1455 if (UseBackgroundContactColour == true){
1457 ContactBackgroundColour = preferences.GetBackgroundContactColourData();
1461 ContactBackgroundColour = wxTransparentColour;
1465 treAccounts->DeleteAllItems();
1467 wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
1469 // Stop all account timers and remove the accounts.
1471 for (std::map<wxString, wxAccountSyncTimer*>::iterator iter = AccountSyncTimers.begin();
1472 iter != AccountSyncTimers.end(); iter++){
1474 wxAccountSyncTimer *AccTmrPtr = iter->second;
1482 #if defined(__WIN32__)
1484 for (std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.begin();
1485 CertificateIter != AccountCertificateData.end(); CertificateIter++){
1487 CertFreeCertificateContext(CertificateIter->second);
1491 AccountCertificateData.clear();
1495 AccountSyncTimers.clear();
1498 wxString AccDirFull;
1499 wxString AccDirFullSfx;
1501 wxString AccDirFinal;
1502 AccountAccDirList.clear();
1503 AccountGroupList.clear();
1504 AccountGroupFilename.clear();
1505 AccountGroupTreeId.clear();
1506 wxTreeItemId AccountTreeId;
1507 wxTreeItemId GroupTreeId;
1510 // Relaod the accounts for the ETagProcTimer.
1512 ETagProcTimer.ReloadAccounts();
1514 for (int i = 0; i < preferences.accounts.GetCount(); i++){
1516 if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
1517 preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == true){
1523 if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
1529 AccDir = preferences.accounts.GetAccountDirectory(i);
1530 AccDirFull = preferences.accounts.GetAccountDirectory(i);
1532 AccDirFull.Append(wxT("."));
1533 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
1534 AccDirFullSfx.LowerCase();
1535 AccDirFullSfx.Trim();
1536 AccDirFull.Append(AccDirFullSfx);
1537 AccName = preferences.accounts.GetAccountName(i);
1539 AccountAccDirList.insert(std::make_pair(i, AccDirFull));
1541 if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
1542 preferences.accounts.GetAccountType(i) == wxT("carddav")){
1544 // TODO: Check if the directory exists before doing anything.
1548 // Add a new timer using the existing account details.
1550 wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
1552 ActTmrPtr->SetupData(AccDirFull, AccName);
1553 ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
1554 ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
1555 ActTmrPtr->SetOwner(this);
1556 ActTmrPtr->Notify();
1558 // Add the timer to the list of timers.
1560 AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
1562 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
1564 } else if (preferences.accounts.GetAccountType(i) == wxT("Local") ||
1565 preferences.accounts.GetAccountType(i) == wxT("local")) {
1567 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
1571 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountUnsupportedID, -1);
1575 // Go through the account directory and find contact files with
1576 // 'KIND:group' set and add them to the list of groups for the account.
1578 AccDirFinal = GetAccountDir(AccDirFull, FALSE);
1580 wxDir vcardaccdir(AccDirFinal);
1582 wxString vCardFilename;
1583 wxString vCardDataString;
1584 wxString vCardFilenameFull;
1586 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1590 if (vCardFilename.Right(4) == wxT(".vcf") ||
1591 vCardFilename.Right(4) == wxT(".VCF") ||
1592 vCardFilename.Right(5) == wxT(".vcard") ||
1593 vCardFilename.Right(5) == wxT(".VCARD")){
1597 vCardFilenameFull.Append(AccDirFinal);
1598 vCardFilenameFull.Append(wxT("/"));
1599 vCardFilenameFull.Append(vCardFilename);
1601 Person.LoadFile(vCardFilenameFull);
1603 if (Person.MeetBaseSpecification()){
1605 vCardDataString = Person.Get(wxT("KIND"));
1607 if (vCardDataString == wxT("group")){
1609 // The vCard kind is a group. Add to the account's group list.
1611 GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
1612 treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
1613 AccountGroupList.insert(std::make_pair(intGroupID, i));
1614 AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
1615 AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
1625 vCardFilename.Clear();
1626 vCardFilenameFull.Clear();
1627 vCardDataString.Clear();
1628 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1632 // Clearup for next account.
1636 AccDirFullSfx.clear();
1637 AccDirFinal.clear();
1642 // Load the account settings as they are needed for connecting
1645 prefaccounts = preferences.accounts;
1649 void frmMain::ConflictResolution(wxCommandEvent& event){
1651 // Display the conflict resolution window.
1653 frmConflictResolution *frameCR = new frmConflictResolution ( this );
1654 vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
1655 vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
1656 vCard *ServerDataPtr = vCardConfObj->vCardServerData;
1657 frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList, ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1658 frameCR->ShowModal();
1660 int FinalConflictResult = frameCR->GetResult();
1662 wxCommandEvent event2(ACTMGR_RESUMEPROC);
1663 event2.SetClientData(vCardConfObj->QRNotifData);
1664 event2.SetInt(FinalConflictResult);
1669 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1670 wxPostEvent(frameActMgr, event2);
1674 void frmMain::UpdateContactList(wxCommandEvent& event){
1676 // Update the contact list in the main window.
1678 UCNotif *ucd = (UCNotif*)event.GetClientData();
1680 // Check if the active account is being displayed in the
1681 // main window. If not, skip and delete the data.
1683 long longSelected = -1;
1684 int intSelectedData = 0;
1686 if (ActiveAccount == ucd->ContactAccount){
1688 // Look at the list of contacts and if it matches the
1689 // filename then update the name.
1693 longSelected = lstContacts->GetNextItem(longSelected,
1695 wxLIST_STATE_DONTCARE);
1697 if (longSelected == -1){
1703 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1705 if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
1707 // Work out which sorting mode we are in.
1711 // First Name, Last Name.
1713 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
1715 } else if (SortMode == 2){
1717 // Last Name, First Name.
1719 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
1721 } else if (SortMode == 3){
1725 lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
1727 } else if (SortMode == 4){
1731 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1738 // If the filename is the one loaded into the
1739 // browser control, then update this too.
1741 if (ActiveFilename == ContactsFileIndex[intSelectedData]){
1743 wxListEvent nullevent;
1744 ShowContactInfo(nullevent);
1752 for (std::map<int, void*>::iterator WindowIter = WindowListPointers.begin();
1753 WindowIter != WindowListPointers.end(); WindowIter++){
1755 if (WindowListType[WindowIter->first] != 0){
1761 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
1763 if (frmContactPtr->GetFilename() == ucd->ContactFilename){
1765 vCard UpdatedPerson;
1766 UpdatedPerson.LoadFile(ucd->ContactFilename);
1767 frmContactPtr->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1768 frmContactPtr->SetupContactData(&UpdatedPerson);
1774 // Send message to search window controller subroutine and
1775 // pass that notification onto the search windows.
1777 // Setup the new pointer to use the existing UCNotif without
1780 UCNotif *ucd2 = ucd;
1782 wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
1783 sup.SetClientData(ucd2);
1784 wxPostEvent(this, sup);
1786 // Clear up the unused pointer.
1792 void frmMain::UpdateAccountList(wxCommandEvent& event){
1794 // Update the account list (currently unimplemented).
1798 void frmMain::SetupPointers(void *ActMgrPtrInc){
1800 // Setup the pointers for the main window.
1802 ActMgrPtr = ActMgrPtrInc;
1806 void frmMain::SetupForm(){
1808 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1809 frameActMgr->SetupPointers(&ETagProcTimer, this);
1811 // Setup the contact information icons for later.
1813 wxFileSystem::AddHandler(new wxMemoryFSHandler);
1817 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
1818 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
1819 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1821 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
1822 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
1823 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1825 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
1826 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
1827 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1829 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
1830 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
1831 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1833 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
1834 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
1835 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1837 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
1838 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
1839 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1845 void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
1847 // Update the contact lists in the search windows.
1849 // Go through each of the search windows and
1850 // send the required notification to update the
1851 // contact information.
1853 // Get the event notification data.
1855 UCNotif *ucd = (UCNotif*)event.GetClientData();
1857 // Process each search window giving the new details.
1859 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1860 switer != SearchWindowList.end(); switer++){
1862 // Duplicate the event notification data.
1864 UCNotif *ucd2 = new UCNotif;
1866 ucd2->ContactAccount = ucd->ContactAccount;
1867 ucd2->ContactFilename = ucd->ContactFilename;
1868 ucd2->ContactName = ucd->ContactName;
1869 ucd2->ContactNickname = ucd->ContactNickname;
1870 ucd2->ContactNameArray = ucd->ContactNameArray;
1872 // Pass the data to the search window for processing.
1874 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
1875 wxCommandEvent schupdate(SE_UPDATERESULT);
1876 schupdate.SetClientData(ucd2);
1877 wxPostEvent(frameSCH, schupdate);
1879 // Clear up the pointer prior to variable deletion.
1890 void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
1892 // Open a new search window.
1896 frmSearch *frameSCH = new frmSearch ( this );
1897 frameSCH->SetUID(WindowMenuItemID);
1898 frameSCH->Show(true);
1900 WindowData *WData = new WindowData;
1902 WData->DataType = 2;
1903 WData->WindowPointer = (void*)frameSCH;
1904 WData->WindowID = WindowMenuItemID;
1906 wxCommandEvent addevent(WINDOW_ADD);
1907 addevent.SetClientData(WData);
1908 wxPostEvent(this, addevent);
1910 // Add pointer to the list of open search windows.
1912 SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
1918 void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
1920 // Remove the pointer for a contact window from the
1923 void *frameSCH = (void*)event.GetClientData();
1925 SearchWindowList.erase(frameSCH);
1931 void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
1933 // Remove the pointer for a contact editor window from
1936 void *frameSCH = (void*)event.GetClientData();
1938 SearchWindowList.erase(frameSCH);
1944 void frmMain::RevealContact(wxCommandEvent& event){
1946 // Reveal a contact in the main window.
1948 UCNotif *uc = (UCNotif*)event.GetClientData();
1950 // Switch the account to the one passed.
1952 wxTreeItemIdValue cookie;
1953 wxTreeItemId next = treAccounts->GetRootItem();
1954 wxTreeItemId nextChild;
1956 for (int i = 0; i < prefaccounts.GetCount(); i++){
1959 nextChild = treAccounts->GetFirstChild(next, cookie);
1961 nextChild = treAccounts->GetNextSibling(nextChild);
1964 if (uc->ContactAccount == AccountAccDirList[i]){
1966 treAccounts->SelectItem(nextChild, TRUE);
1967 AccCtrl->SetText(treAccounts->GetItemText(nextChild));
1973 // Switch the contact to the one passed.
1975 long longSelected = -1;
1976 int intSelectedData = 0;
1980 longSelected = lstContacts->GetNextItem(longSelected,
1982 wxLIST_STATE_DONTCARE);
1984 if (longSelected == -1){
1990 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1992 // Compare the filename with the one received.
1993 // If they match then select it.
1995 if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
1999 lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
2000 lstContacts->EnsureVisible(longSelected);
2004 lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
2012 void frmMain::DeleteContact(wxCommandEvent& event){
2014 // Delete a contact from the main window.
2016 // Check if a contact is selected.
2018 long intSelected = -1;
2019 long intContactSeekNum = -1;
2020 wxString wxSContactName;
2022 intSelected = lstContacts->GetNextItem(intSelected,
2024 wxLIST_STATE_SELECTED);
2026 if (intSelected == -1){
2030 // Check if the account type is a valid account type, otherwise
2031 // display an error message.
2033 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
2034 ActiveAccountType != "Local" && ActiveAccountType != "local"){
2036 wxMessageBox(_("Cannot delete contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
2041 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2043 // Get the item data of the contact.
2045 intContactSeekNum = lstContacts->GetItemData(intSelected);
2047 // Get the name of the contact.
2049 wxSContactName = lstContacts->GetItemText(intSelected);
2051 // Display a message confirming if the contact should
2054 int QuestionResponse;
2056 QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
2058 if (QuestionResponse == wxNO){
2060 // Exit the subroutine
2066 // Delete the contact.
2068 if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
2070 wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
2075 // Remove the contact from the list.
2077 lstContacts->DeleteItem(intSelected);
2079 // Update the search windows, removing the deleted
2082 UCNotif *ucd = new UCNotif;
2084 ucd->ContactAccount = ActiveAccount;
2085 ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
2087 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
2088 switer != SearchWindowList.end(); switer++){
2090 // Duplicate the event notification data.
2092 UCNotif *ucd2 = new UCNotif;
2094 ucd2->ContactAccount = ucd->ContactAccount;
2095 ucd2->ContactFilename = ucd->ContactFilename;
2097 // Pass the data to the search window for processing.
2099 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
2100 wxCommandEvent schdelete(SE_DELETERESULT);
2101 schdelete.SetClientData(ucd2);
2102 wxPostEvent(frameSCH, schdelete);
2104 // Clear up the pointer prior to variable deletion.
2111 // Clear the wxHTMLWindow.
2113 wxString EmptyPage = wxT("");
2115 htmContactData->SetPage(EmptyPage);
2117 wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
2119 wxString wxSplitFilename;
2120 wxString wxSDataURL;
2122 while(wSTFilename.HasMoreTokens()){
2124 wxSplitFilename = wSTFilename.GetNextToken();
2128 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
2130 // Update the ETagDB and mark it as deleted.
2132 ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
2134 ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
2136 // Get the Data URL.
2138 wxTreeItemIdValue cookie;
2139 wxTreeItemId next = treAccounts->GetRootItem();
2141 wxTreeItemId selectedChild = treAccounts->GetSelection();
2142 wxTreeItemId nextChild;
2144 for (int i = 0; i < prefaccounts.GetCount(); i++){
2147 nextChild = treAccounts->GetFirstChild(next, cookie);
2149 nextChild = treAccounts->GetNextSibling(nextChild);
2152 if (nextChild == selectedChild){
2154 wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
2161 // Add task to the activity monitor to delete the contact.
2163 frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
2167 // Clear the variable. Don't delete as it will mess things up.
2169 ContactsFileIndex[intContactSeekNum] = wxT("");
2176 void frmMain::EmptyServerDialog(wxCommandEvent& event){
2178 // Display this message when the server information has changed
2181 QRNotif *qrn = (QRNotif *)event.GetClientData();
2183 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);
2185 if (QResponse == wxNO){
2191 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2192 event2.SetInt(*qrn->QResponse);
2193 event2.SetClientData(qrn->PausePtr);
2195 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2197 wxPostEvent(frameActMgr, event2);
2201 void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
2203 // Remove the contact from the window after syncronising.
2205 // Check which account is currently active in the window.
2206 // If it is different from the one passed to this subroutine then
2207 // exit from the subroutine.
2209 if (Account != ActiveAccount){
2213 long longSelected = -1;
2214 int intSelectedData = 0;
2218 longSelected = lstContacts->GetNextItem(longSelected,
2220 wxLIST_STATE_DONTCARE);
2222 if (longSelected == -1){
2228 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2230 // Compare the filename with the one received.
2231 // If they match then select it.
2233 if (ContactsFileIndex[intSelectedData] == Filename){
2235 // Remove the contact from the window.
2237 lstContacts->DeleteItem(intSelectedData);
2239 // Check if contact is the selected contact in the HTML window and
2240 // if it is then clear the window.
2242 if (ActiveFilename == Filename){
2244 wxString EmptyPage = wxT("");
2245 htmContactData->SetPage(EmptyPage);
2259 void frmMain::SortFNLN( wxCommandEvent& event ) {
2261 // Sort first name then last name.
2263 wxTreeEvent NullEvent;
2265 LoadContactList(NullEvent);
2269 void frmMain::SortLNFN( wxCommandEvent& event ) {
2271 // Sort last name then first name.
2273 wxTreeEvent NullEvent;
2275 LoadContactList(NullEvent);
2279 void frmMain::SortNickname( wxCommandEvent& event ) {
2281 // Sort by nickname.
2283 wxTreeEvent NullEvent;
2285 LoadContactList(NullEvent);
2289 void frmMain::SortDisplayAs( wxCommandEvent& event ) {
2291 // Sort by Display As name.
2293 wxTreeEvent NullEvent;
2295 LoadContactList(NullEvent);
2299 void frmMain::SortAscending( wxCommandEvent& event ) {
2303 wxTreeEvent NullEvent;
2304 AscendingMode = TRUE;
2305 LoadContactList(NullEvent);
2309 void frmMain::SortDescending( wxCommandEvent& event ) {
2313 wxTreeEvent NullEvent;
2314 AscendingMode = FALSE;
2315 LoadContactList(NullEvent);
2319 void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
2321 // Toggle the appearance of the status bar.
2323 if (stbBottom->IsShown() == TRUE){
2337 void frmMain::ActivityIconStart( wxCommandEvent& event ){
2339 // Display the activity icon.
2341 imgActivityStatus->SetBitmap(*imgActIcon1);
2342 ActivityIconStatus = 0;
2346 void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
2348 // Shuffle through the activity icons.
2350 switch (ActivityIconStatus){
2353 imgActivityStatus->SetBitmap(*imgActIcon1);
2354 ActivityIconStatus = 1;
2357 imgActivityStatus->SetBitmap(*imgActIcon2);
2358 ActivityIconStatus = 2;
2361 imgActivityStatus->SetBitmap(*imgActIcon3);
2362 ActivityIconStatus = 3;
2365 imgActivityStatus->SetBitmap(*imgActIcon4);
2366 ActivityIconStatus = 0;
2369 ActivityIconStatus = 0;
2375 void frmMain::ActivityIconStop( wxCommandEvent& event ){
2377 // Display the sleep icon.
2379 imgActivityStatus->SetBitmap(*imgActIconSleep);
2383 void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
2385 // Set the placement of the status bar icons.
2387 if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
2395 wxRect rectActivity;
2396 stbBottom->GetFieldRect(1, rectOnline);
2397 stbBottom->GetFieldRect(2, rectSSL);
2398 stbBottom->GetFieldRect(3, rectActivity);
2400 imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
2401 imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
2402 imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
2406 XABViewMode frmMain::GetViewMode(){
2408 // Set the view mode of the contact list.
2412 xvm.SortMode = SortMode;
2413 xvm.AscendingMode = AscendingMode;
2419 void frmMain::WindowAdd( wxCommandEvent &event ){
2421 // Add a window to the window list.
2423 WindowData *WData = (WindowData*)event.GetClientData();
2427 if (WData->DataType == 0){
2431 int intID = mnuContactWindows->GetId();
2433 mnuWindow->FindChildItem(intID, &pos);
2434 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2435 mnuNewItem->SetId(WData->WindowID);
2436 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2437 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2438 WindowListType.insert(std::make_pair(WData->WindowID, 0));
2439 mnuWindow->Insert((pos + 1), mnuNewItem);
2440 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
2442 } else if (WData->DataType == 1){
2444 // Contact Editor Window
2446 int intID = mnuContactEditorWindows->GetId();
2448 mnuWindow->FindChildItem(intID, &pos);
2449 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2450 mnuNewItem->SetId(WData->WindowID);
2451 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2452 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2453 WindowListType.insert(std::make_pair(WData->WindowID, 1));
2454 mnuWindow->Insert((pos + 1), mnuNewItem);
2455 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
2457 } else if (WData->DataType == 2){
2461 int intID = mnuSearchWindows->GetId();
2463 mnuWindow->FindChildItem(intID, &pos);
2464 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2465 mnuNewItem->SetId(WData->WindowID);
2466 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2467 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2468 WindowListType.insert(std::make_pair(WData->WindowID, 2));
2469 mnuWindow->Insert((pos + 1), mnuNewItem);
2470 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
2479 void frmMain::WindowEdit( wxCommandEvent &event ){
2481 // Edit a window in the window list.
2483 WindowData *WData = (WindowData*)event.GetClientData();
2485 if (WData->DataType == 0){
2487 // Get the window title and use that.
2489 frmContact *frmContactPtr = static_cast<frmContact*>(WData->WindowPointer);
2491 wxString WindowTitle = frmContactPtr->GetTitle();
2493 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2495 MenuIter->second->SetItemLabel(WindowTitle);
2497 } else if (WData->DataType == 1){
2499 // Get the window title and use that.
2501 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WData->WindowPointer);
2503 wxString WindowTitle = frmCEPtr->GetTitle();
2505 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2507 if (WindowTitle.IsEmpty()){
2509 MenuIter->second->SetItemLabel(_("Unnamed Contact"));
2513 MenuIter->second->SetItemLabel(WindowTitle);
2524 void frmMain::WindowDelete( wxCommandEvent &event ){
2526 // Delete a window from the window list.
2528 WindowData *WData = (WindowData*)event.GetClientData();
2530 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2532 mnuWindow->Remove(MenuIter->second);
2534 delete MenuIter->second;
2535 MenuIter->second = NULL;
2537 WindowListPointersMenu.erase(WData->WindowID);
2538 WindowListPointers.erase(WData->WindowID);
2539 WindowListType.erase(WData->WindowID);
2546 void frmMain::ShowContactWindow( wxCommandEvent &event ){
2548 // Show a contact window from the window list.
2550 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2552 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
2554 frmContactPtr->Show();
2555 frmContactPtr->Raise();
2559 void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
2561 // Show a contact editor window from the window list.
2563 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2565 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WindowIter->second);
2572 void frmMain::ShowSearchWindow( wxCommandEvent &event ){
2574 // Show a search window from the window list.
2576 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2578 frmSearch *frmSearchPtr = static_cast<frmSearch*>(WindowIter->second);
2580 frmSearchPtr->Show();
2581 frmSearchPtr->Raise();
2585 void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
2587 // Toggle the online/offline connection status.
2589 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2590 wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
2591 wxPostEvent(frameActMgr, toggconn);
2595 void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
2597 // Check the account type before continuing.
2599 wxString SeekAccount;
2600 wxString AccTypeLower;
2604 #if defined(__APPLE__)
2606 std::map<int, SecTrustRef>::iterator SSLTrustIter;
2608 for (int i = 0; i < prefaccounts.GetCount(); i++){
2610 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2611 AccType.Append(prefaccounts.GetAccountType(i));
2612 AccountSSL = prefaccounts.GetAccountSSL(i);
2613 AccTypeLower = AccType.MakeLower();
2614 SeekAccount.Append(wxT("."));
2615 SeekAccount.Append(AccTypeLower);
2617 if (SeekAccount == ActiveAccount){
2619 if (AccTypeLower == wxT("local")){
2625 if (AccountSSL == false){
2631 SSLTrustIter = AccountTrustData.find(i);
2633 // Setup and display the form.
2635 DisplayCertificate(SSLTrustIter->second);
2639 SeekAccount.Clear();
2640 AccTypeLower.Clear();
2645 #elif defined(__WIN32__)
2647 std::map<int, PCCERT_CONTEXT>::iterator SSLCertificateIter;
2649 for (int i = 0; i < prefaccounts.GetCount(); i++){
2651 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2652 AccType.Append(prefaccounts.GetAccountType(i));
2653 AccountSSL = prefaccounts.GetAccountSSL(i);
2654 AccTypeLower = AccType.MakeLower();
2655 SeekAccount.Append(wxT("."));
2656 SeekAccount.Append(AccTypeLower);
2658 if (SeekAccount == ActiveAccount){
2660 if (AccTypeLower == wxT("local")){
2666 if (AccountSSL == false){
2672 SSLCertificateIter = AccountCertificateData.find(i);
2674 // Setup and display the form.
2676 if (SSLCertificateIter->second->pCertInfo == NULL){
2678 wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
2682 BOOL ModifiedCertificateData;
2683 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
2685 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
2686 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
2691 //DisplayCertificate(SSLTrustIter->second);
2695 SeekAccount.Clear();
2696 AccTypeLower.Clear();
2703 std::map<int, SSLCertCollectionString>::iterator SSLColIter;
2705 for (int i = 0; i < prefaccounts.GetCount(); i++){
2707 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2708 AccType.Append(prefaccounts.GetAccountType(i));
2709 AccountSSL = prefaccounts.GetAccountSSL(i);
2710 AccTypeLower = AccType.MakeLower();
2711 SeekAccount.Append(wxT("."));
2712 SeekAccount.Append(AccTypeLower);
2714 if (SeekAccount == ActiveAccount){
2716 if (AccTypeLower == wxT("local")){
2722 if (AccountSSL == false){
2728 SSLColIter = AccountSSLData.find(i);
2730 SSLCertCollectionString SSLCertInfo = SSLColIter->second;
2732 frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
2733 frameSSLCert->StartCertFrom(0);
2734 frameSSLCert->SetupCertsString(SSLCertInfo);
2735 frameSSLCert->ShowModal();
2737 delete frameSSLCert;
2738 frameSSLCert = NULL;
2742 SeekAccount.Clear();
2743 AccTypeLower.Clear();
2752 void frmMain::ShowSSLInfo( wxCommandEvent &event ){
2754 // Check the account type before continuing.
2758 void frmMain::HideSSLInfo( wxCommandEvent &event ){
2760 // Check the account type before continuing.
2764 void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
2766 if (event.GetInt() == 0){
2768 imgConnStatus->SetBitmap(*imgOnline);
2772 imgConnStatus->SetBitmap(*imgOffline);
2778 void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
2780 // Display the form for showing an invalid SSL certificate.
2782 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2783 SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
2784 SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
2785 wxString AccountName = SSLICNObj->AccountName;
2786 frameISC->LoadData(SSLCCData, AccountName);
2787 frameISC->ShowModal();
2789 int FinalConflictResult = frameISC->GetResult();
2791 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2792 event2.SetClientData(SSLICNObj->QRNotifData);
2793 event2.SetInt(FinalConflictResult);
2798 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2799 wxPostEvent(frameActMgr, event2);
2803 void frmMain::InvalidSSLCertificateString( wxCommandEvent &event ){
2805 // Display the form for showing an invalid SSL certificate.
2807 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2808 SSLInvalidCertNotifObjString *SSLICNObj = (SSLInvalidCertNotifObjString*)event.GetClientData();
2809 SSLCertCollectionString SSLCCData = SSLICNObj->CertCollection;
2810 wxString AccountName = SSLICNObj->AccountName;
2811 frameISC->LoadData(SSLCCData, AccountName);
2812 frameISC->ShowModal();
2814 int FinalConflictResult = frameISC->GetResult();
2816 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2817 event2.SetClientData(SSLICNObj->QRNotifData);
2818 event2.SetInt(FinalConflictResult);
2823 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2824 wxPostEvent(frameActMgr, event2);
2828 void frmMain::PauseAllTimers(){
2830 // Pause all the account timers.
2832 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2833 ASTiter != AccountSyncTimers.end(); ASTiter++){
2835 ASTiter->second->Stop();
2841 void frmMain::ResumeAllTimers(){
2843 // Resume all the account timers.
2845 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2846 ASTiter != AccountSyncTimers.end(); ASTiter++){
2848 ASTiter->second->Start();
2854 #if defined(__APPLE__)
2856 #elif defined(__WIN32__)
2858 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
2860 // Delete existing data.
2862 std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.find(AccountID);
2864 if (CertificateIter != AccountCertificateData.end()){
2865 CertFreeCertificateContext(CertificateIter->second);
2868 AccountCertificateData.erase(AccountID);
2869 AccountSSLResult.erase(AccountID);
2873 AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
2874 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2880 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollectionString SSLCertInc){
2882 // Delete existing data.
2884 AccountSSLData.erase(AccountID);
2885 AccountSSLResult.erase(AccountID);
2889 AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
2890 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2896 void frmMain::SetupSSLStatus( int AccountID ){
2898 // Check if account ID given is
2899 // the active account and if not, do nothing.
2902 wxString AccTypeLower;
2904 AccType = prefaccounts.GetAccountType(AccountID);
2905 AccTypeLower = AccType.MakeLower();
2907 wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
2910 if (AccountIDName != ActiveAccount){
2916 // Check the account type is a supported account type.
2918 if (AccType != "CardDAV" && AccType != "carddav" &&
2919 AccType != "Local" && AccType != "local"){
2921 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2922 imgSSLStatus->SetBitmap(*imgNoSSL);
2927 // Check if the account has SSL enabled.
2929 bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
2931 if (SSLInUse == FALSE){
2933 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2934 imgSSLStatus->SetBitmap(*imgNoSSL);
2938 // Get the SSL Collection Data.
2940 std::map<int,int>::iterator SSLResultIter = AccountSSLResult.find(AccountID);
2942 // Check if a result value has been set.
2944 if (SSLResultIter == AccountSSLResult.end()){
2946 imgSSLStatus->SetBitmap(*imgSSLWarning);
2947 SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
2952 if (SSLResultIter->second == 1){
2954 imgSSLStatus->SetBitmap(*imgSSLWarning);
2955 SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
2956 prefaccounts.GetAccountName(AccountID) +
2957 wxT("' (Connection denied by user)\n\nDouble click for more information."));
2959 } else if (SSLResultIter->second == 0){
2961 imgSSLStatus->SetBitmap(*imgSSL);
2962 SSLToolTip->SetTip(wxT("Account '") +
2963 prefaccounts.GetAccountName(AccountID) +
2964 wxT("' secured using SSL\n\nDouble click for more information."));
2972 void frmMain::CheckUpdates( wxCommandEvent& event ){
2974 // Check for updates to Xestia Address Book.
2976 frmUpdate *frameUpdate = new frmUpdate ( this );
2977 frameUpdate->FetchData();
2978 frameUpdate->ShowModal();
2982 void frmMain::OpenImportDialog( wxCommandEvent& event ){
2984 // Run the import contacts function.
2990 void frmMain::OpenExportDialog( wxCommandEvent& event ){
2992 // Check if an account and at least one contact is selected
2993 // before continuing.
2995 wxArrayString ArrData;
2997 if (ActiveAccount.IsEmpty()){
3003 int ContactSelected = 0;
3004 int ContactsCollected = 0;
3005 long longSelected = -1;
3009 longSelected = lstContacts->GetNextItem(longSelected,
3011 wxLIST_STATE_SELECTED);
3013 if (longSelected == -1){
3019 int FileID = (int)lstContacts->GetItemData(longSelected);
3021 ArrData.Insert(ContactsFileIndex[FileID],
3022 ContactsCollected, 1);
3028 if (ContactSelected == 0){
3034 // Run the export contacts system.
3036 ExportRun(this, &ArrData);
3040 void frmMain::GetListControl(wxListCtrl *lstContactsPtr,
3041 wxArrayString *ContactsFileIndexPtr){
3043 // Set the list control pointers.
3045 lstContactsPtr = lstContacts;
3046 ContactsFileIndexPtr = &ContactsFileIndex;
3050 void frmMain::GetSelectedList( wxCommandEvent& event ){
3052 // Get the array of contact filenames.
3054 wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
3056 // Process them into an array of files.
3058 long longSelected = -1;
3059 int ContactsCollected = 0;
3060 wxString ContactFilename;
3064 longSelected = lstContacts->GetNextItem(longSelected,
3066 wxLIST_STATE_SELECTED);
3068 if (longSelected == -1){
3074 // Get the file information and add to the list.
3076 int FileID = (int)lstContacts->GetItemData(longSelected);
3078 ArrData->Insert(ContactsFileIndex[FileID],
3079 ContactsCollected, 1);
3081 ContactsCollected++;
3082 ContactFilename.Clear();
3090 void frmMain::SyncAccount( wxCommandEvent& event ){
3092 // Syncronise the selected account.
3094 wxString AccNameInc = event.GetString();
3096 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
3097 frameActMgr->AddTask(3, wxT(""), AccNameInc,
3098 wxT(""), wxT(""), wxT(""), wxT(""));
3102 void frmMain::ShowHelp( wxCommandEvent& event ){
3104 // Based on the operating system, work out where
3105 // the documentation should be.
3109 #if defined(__HAIKU__)
3111 #elif defined(__WIN32__)
3117 if (wxFileExists("/usr/share/doc/xestiaab/index.html")){
3119 wxLaunchDefaultBrowser(wxT("file:///usr/share/doc/xestiaab/index.html"));
3122 #if XSDAB_RELEASE == 0
3124 } else if (wxFileExists("/usr/local/share/doc/xestiaab/index.html")){
3126 wxLaunchDefaultBrowser(wxT("file:///usr/local/share/doc/xestiaab/index.html"));
3135 #if XSDAB_RELEASE == 0
3137 wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
3141 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!"));
3147 void frmMain::ShowImportResults( wxCommandEvent &event ){
3149 // Show the results of importing contacts.
3151 std::map<int,wxString> *ResultData = (std::map<int,wxString>*)event.GetClientData();
3153 frmImportResults *frmIR = new frmImportResults(this);
3154 frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
3165 void frmMain::ReloadContactList( wxCommandEvent &event ){
3167 // Check if the account name given is the current
3168 // account selected.
3170 if (ActiveAccount == event.GetString()){
3172 wxTreeEvent NullEvent;
3173 LoadContactList(NullEvent);
3179 void frmMain::ShowContactMenu( wxMouseEvent& event ){
3181 // Show the contact menu when a right click occurs
3182 // in the contacts list.
3184 bool EnableRefresh = FALSE;
3186 if (!ActiveAccount.IsEmpty() && (ActiveAccountType == "CardDAV" ||
3187 ActiveAccountType == "carddav" ||
3188 ActiveAccountType == "Local" ||
3189 ActiveAccountType == "local")){
3191 EnableRefresh = TRUE;
3195 ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
3197 this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
3201 void frmMain::ResetContactInfo(){
3203 // Reset the contact information to an empty page.
3205 wxString EmptyPage = wxT("");
3206 htmContactData->SetPage(EmptyPage);
3207 AccCtrl->SetValue("");
3211 bool frmMain::CloseAllWindows()
3213 // Attempt to close all windows.
3215 if (WindowListPointersMenu.size() == 0)
3220 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)
3222 for(std::map<int, void*>::iterator windowIter = WindowListPointers.begin();
3223 windowIter != WindowListPointers.end(); windowIter++)
3225 wxWindow *windowPointer = static_cast<wxWindow*>(windowIter->second);
3226 windowPointer->Close();