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 //Go through the windows and close each one (be it search
395 //or contact editor). Abort if user wants to cancel.
397 // Close the contact editor windows.
399 // Close the contact windows.
401 // Close the search windows.
403 // Write out the ETag databases.
405 // Save Preferences: Save the window position if that option is enabled.
407 wxString SetFilename = GetUserPrefDir();
409 #if defined(__HAIKU__)
413 #elif defined(__WIN32__)
415 SetFilename.Append(wxT("settings"));
421 SetFilename.Append(wxT("settings"));
425 wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
427 bool SaveWindowPos = FALSE;
428 wxString SaveWindowInc;
429 cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
431 if (SaveWindowInc == wxT("true")){
433 SaveWindowPos = TRUE;
437 if (SaveWindowPos == TRUE){
439 wxRect frmMainPos = this->GetRect();
441 cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
442 cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
443 cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
444 cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
451 //Everything closed... exit.
459 void frmMain::ShowActivityWindow( wxCommandEvent& event )
462 // Open the activity manager window.
464 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
465 frameActMgr->OpenWindow();
470 void frmMain::ShowAboutWindow( wxCommandEvent& event )
473 // Show the about window.
475 frmAbout *frameAbout = new frmAbout ( this );
476 frameAbout->SetupAboutWindow();
477 frameAbout->ShowModal();
483 void frmMain::OpenPreferences( wxCommandEvent& event)
486 // Open the preferences window.
488 ReloadAccounts = FALSE;
490 frmPreferences *framePreferences = new frmPreferences ( this );
491 framePreferences->SetupPointers(&ReloadAccounts);
492 framePreferences->ShowModal();
493 delete framePreferences;
494 framePreferences = NULL;
496 if (ReloadAccounts == TRUE){
498 // Reload the accounts as a change has been made within
499 // the application and clear the current contact information.
501 this->LoadPreferences();
502 this->ResetContactInfo();
508 void frmMain::OpenNewABDialog( wxCommandEvent& event)
511 // Open the new account dialog.
513 ReloadAccounts = FALSE;
515 frmNewAccount *frameNewAccount = new frmNewAccount ( this );
516 frameNewAccount->SetupPointers(&ReloadAccounts);
517 frameNewAccount->ShowModal();
518 delete frameNewAccount;
519 frameNewAccount = NULL;
521 if (ReloadAccounts == TRUE){
523 // Reload the accounts as a change has been made within
526 this->LoadPreferences();
532 void frmMain::LoadContactList( wxTreeEvent& event )
535 // Load the contact list.
537 // Clear all existing variables.
539 lstContacts->DeleteAllItems();
541 treAccounts->SetAccount();
543 wxTreeItemIdValue cookie;
544 wxTreeItemId next = treAccounts->GetRootItem();
545 wxString AccountName;
546 wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
547 wxString AccountDirCmb;
548 long selectedaccount = 0;
550 wxTreeItemId selectedChild = treAccounts->GetSelection();
551 wxTreeItemId nextChild;
553 wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
554 int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
556 int SCImg = treAccounts->GetItemImage(selectedChild);
557 int AccountIndex = 0;
559 bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
561 // Process each account.
563 for (int i = 0; i < prefaccounts.GetCount(); i++){
565 if (ActiveItemIcon == 2){
567 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
568 std::multimap<int, int>::iterator AGLiter = AccountGroupList.find(AGTiter->second);
569 int ActiveAccountG = AGLiter->second;
571 if (i == ActiveAccountG){
573 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
574 AccountType.Append(prefaccounts.GetAccountType(i));
579 if (AccountType == wxT("CardDAV")){
580 AccountTypeFinal.Append(wxT("carddav"));
581 } else if (AccountType == wxT("Local")){
582 imgSSLStatus->SetBitmap(*imgOffline);
583 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
584 AccountTypeFinal.Append(wxT("local"));
586 imgSSLStatus->SetBitmap(*imgOffline);
587 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
588 AccountTypeFinal.Append(AccountType.Lower());
599 nextChild = treAccounts->GetFirstChild(next, cookie);
601 nextChild = treAccounts->GetNextSibling(nextChild);
604 AccountName = treAccounts->GetItemText(nextChild);
606 if (nextChild == selectedChild){
608 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
609 AccountType.Append(prefaccounts.GetAccountType(i));
614 if (AccountType == wxT("CardDAV")){
615 AccountTypeFinal.Append(wxT("carddav"));
616 } else if (AccountType == wxT("Local")){
617 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
618 AccountTypeFinal.Append(wxT("local"));
620 AccountTypeFinal.Append(AccountType.Lower());
629 if (selectedaccount >= prefaccounts.GetCount()){
631 // The account selected isn't there so return.
639 // Open the directory and get the list of .vcf files
640 // in that directory.
642 ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
643 ActiveAccountType = AccountType;
645 SetupSSLStatus(AccountIndex);
647 AccountDirFinal.Clear();
648 AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
650 ContactsFileIndex.Clear();
652 wxString vCardFilename;
653 wxString vCardFilenameFull;
654 wxString vCardDataString;
655 wxStringTokenizer vcardfileline;
657 wxString setname, setvalue;
658 std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
659 std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
660 long ContactIndex = 1;
661 long ContactSeekPoint = 0;
663 wxDir vcardaccdir(AccountDirFinal);
665 // Get the wxTreeItemId and image icon and compare it to the list.
667 if (ActiveItemIcon == AccountGrpID){
669 // It's a group so load the file containing the group and
670 // get the members of the group.
675 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
676 std::multimap<int, wxString>::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
678 Group.LoadFile(AGFiter->second);
680 ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
682 for (int i = 0; i < vCardMember.PropCount; i++){
684 vCardMember.PropValues[i].Trim();
685 if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
687 wxString NewPropValue;
688 NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
689 vCardMember.PropValues[i] = NewPropValue;
695 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
699 if (vCardFilename.Right(4) == wxT(".vcf") ||
700 vCardFilename.Right(4) == wxT(".VCF") ||
701 vCardFilename.Right(5) == wxT(".vcard") ||
702 vCardFilename.Right(5) == wxT(".VCARD")){
705 bool FoundMember = FALSE;
707 vCardFilenameFull.Append(AccountDirFinal);
708 vCardFilenameFull.Append(wxT("/"));
709 vCardFilenameFull.Append(vCardFilename);
711 Person.LoadFile(vCardFilenameFull);
713 UIDCode = Person.Get(wxT("UID"));
715 for (int i = 0; i < vCardMember.PropCount; i++){
717 if (vCardMember.PropValues[i] == UIDCode){
725 if (FoundMember == FALSE){
727 vCardFilename.Clear();
728 vCardFilenameFull.Clear();
729 vCardDataString.Clear();
730 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
735 if (Person.MeetBaseSpecification()){
739 // Split the name into sections.
741 vCardDataString = Person.Get(wxT("N"));
743 vCardName NameData = Person.GetName();
745 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
747 } else if (SortMode == 2){
749 // Split the name into sections.
751 vCardName NameData = Person.GetName();
753 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
755 } else if (SortMode == 3){
757 // Check and make sure that the top most nickname is used.
759 vCardDataString = Person.Get(wxT("NICKNAME"));
761 if (vCardDataString.IsEmpty()){
763 vCardDataString = wxT("(no nickname)");
767 } else if (SortMode == 4){
769 vCardDataString = Person.Get(wxT("FN"));
773 if (AscendingMode == TRUE){
774 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
776 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
783 vCardFilename.Clear();
784 vCardFilenameFull.Clear();
785 vCardDataString.Clear();
786 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
792 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
795 if (vCardFilename.Right(4) == wxT(".vcf") ||
796 vCardFilename.Right(4) == wxT(".VCF") ||
797 vCardFilename.Right(5) == wxT(".vcard") ||
798 vCardFilename.Right(5) == wxT(".VCARD")){
802 vCardFilenameFull.Append(AccountDirFinal);
803 vCardFilenameFull.Append(vCardFilename);
805 Person.LoadFile(vCardFilenameFull);
807 if (Person.MeetBaseSpecification()){
811 // Split the name into sections.
813 vCardDataString = Person.Get(wxT("N"));
815 vCardName NameData = Person.GetName();
817 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
819 } else if (SortMode == 2){
821 // Split the name into sections.
823 vCardName NameData = Person.GetName();
825 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
827 } else if (SortMode == 3){
829 // Check and make sure that the top most nickname is used.
831 vCardDataString = Person.Get(wxT("NICKNAME"));
833 if (vCardDataString.IsEmpty()){
835 vCardDataString = wxT("(no nickname)");
839 } else if (SortMode == 4){
841 vCardDataString = Person.Get(wxT("FN"));
845 if (AscendingMode == TRUE){
847 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
851 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
859 vCardFilename.Clear();
860 vCardFilenameFull.Clear();
861 vCardDataString.Clear();
862 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
869 // Insert the data into the control.
871 if (AscendingMode == TRUE){
872 for (std::map<wxString, wxString>::iterator iter = vCardNamesAsc.begin();
873 iter != vCardNamesAsc.end(); ++iter){
875 wxListItem ContactInfo;
877 ContactInfo.SetId(0);
878 ContactInfo.SetText(_("Mooo"));
879 ContactInfo.SetData(ContactSeekPoint);
880 ContactIndex = lstContacts->InsertItem(ContactInfo);
882 lstContacts->SetItem(ContactIndex, 0, iter->first);
884 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
891 for (std::map<wxString, wxString>::iterator iter = vCardNamesDsc.begin();
892 iter != vCardNamesDsc.end(); ++iter){
894 wxListItem ContactInfo;
896 ContactInfo.SetId(0);
897 ContactInfo.SetText(_("Mooo"));
898 ContactInfo.SetData(ContactSeekPoint);
899 ContactIndex = lstContacts->InsertItem(ContactInfo);
901 lstContacts->SetItem(ContactIndex, 0, iter->first);
902 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
911 void frmMain::ShowContactInfo( wxListEvent& event )
914 // Display the contact information.
916 long intSelected = -1;
917 long ContactSeekNum = -1;
919 // Check if several contacts have been selected.
921 int ContactTotal = 0;
925 intSelected = lstContacts->GetNextItem(intSelected,
927 wxLIST_STATE_SELECTED);
929 if (intSelected == -1){
939 if (ContactTotal == 0){
940 htmContactData->SetPage(wxT(""));
944 if (ContactTotal > 1){
946 htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
947 ActiveFilename.Clear();
952 intSelected = lstContacts->GetNextItem(intSelected,
954 wxLIST_STATE_SELECTED);
956 ContactSeekNum = lstContacts->GetItemData(intSelected);
959 wxString wxSContactString;
960 wxString ContactLine;
963 size_t ContactLineLen;
964 bool ExtraLineSeek = FALSE;
965 int QuoteBreakPoint = 0;
967 bool PropertyFind = FALSE;
968 bool QuoteMode = FALSE;
970 wxString wxSPropertyNextLine;
971 wxString wxSProperty;
972 wxString wxSPropertySeg1;
973 wxString wxSPropertySeg2;
975 // Check if we are using wxWidgets version 2.8 or less and
976 // execute the required command accordingly.
978 #if wxABI_VERSION < 20900
979 ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
981 ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
984 if (ContactFile.IsOpened() == FALSE){
990 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
994 std::map<int, wxString> ContactFileLines;
995 std::map<int, wxString>::iterator striter;
997 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
999 int ContactLineSeek = 0;
1001 while (wSTContactFileLines.HasMoreTokens() == TRUE){
1003 ContactLine = wSTContactFileLines.GetNextToken();
1004 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
1009 if (ContactSeekNum < 0){
1013 for (std::map<int, wxString>::iterator iter = ContactFileLines.begin();
1014 iter != ContactFileLines.end(); ++iter){
1016 // Find the colon which splits the start bit from the data part.
1018 ContactLine = iter->second;
1020 while (ExtraLineSeek == TRUE){
1022 // Check if there is extra data on the next line
1023 // (indicated by space or tab at the start) and add data.
1027 if (iter == ContactFileLines.end()){
1034 wxSPropertyNextLine = iter->second;
1037 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1039 wxSPropertyNextLine.Remove(0, 1);
1040 ContactLine.Append(wxSPropertyNextLine);
1045 ExtraLineSeek = FALSE;
1051 ContactLineLen = ContactLine.Len();
1053 // Make sure we are not in quotation mode.
1054 // Make sure colon does not have \ or \\ before it.
1056 for (int i = 0; i <= ContactLineLen; i++){
1058 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1060 PropertyFind = FALSE;
1062 } else if (PropertyFind == TRUE){
1064 wxSProperty.Append(ContactLine.Mid(i, 1));
1068 if (ContactLine.Mid(i, 1) == wxT("\"")){
1070 if (QuoteMode == TRUE){
1082 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1084 QuoteBreakPoint = i;
1091 // Split that line at the point into two variables (ignore the colon).
1093 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1094 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1096 // Insert both into the vCard data file.
1098 Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
1101 PropertyFind = TRUE;
1102 ExtraLineSeek = TRUE;
1104 QuoteBreakPoint = 0;
1105 ContactLine.Clear();
1106 wxSProperty.Clear();
1110 OldSessionID = SessionID;
1111 SessionID = wxString::Format(wxT("%i"), rand() % 32768);
1112 LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList);
1113 ActiveFilename = ContactsFileIndex[ContactSeekNum];
1117 void frmMain::ShowContactEditorNew( wxCommandEvent& event )
1120 // Open a contact editor window to write a new contact with.
1122 // Check if there is an account selected and if not
1123 // return immediately.
1125 if (ActiveAccount.IsEmpty()){
1131 // Check if the account type is a valid account type, otherwise
1132 // display an error message.
1134 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1135 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1137 wxMessageBox(_("Cannot add a new contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1142 // Add Pointer to SetupPointers for the ETagDB.
1144 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1145 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1146 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1148 contacticon.CopyFromBitmap(contacticonbmp);
1150 frmContactEditor *ContactEditor = new frmContactEditor( this );
1154 ContactEditor->SetUID(WindowMenuItemID);
1156 WindowData *WData = new WindowData;
1158 WData->DataType = 1;
1159 WData->WindowPointer = (void*)ContactEditor;
1160 WData->WindowID = WindowMenuItemID;
1162 wxCommandEvent addevent(WINDOW_ADD);
1163 addevent.SetClientData(WData);
1164 wxPostEvent(this, addevent);
1166 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1167 ContactEditor->SetupHeaders();
1168 ContactEditor->SetupContact(ActiveAccount);
1169 ContactEditor->SetIcon(contacticon);
1170 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1171 ContactEditor->Show(true);
1175 void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
1178 // Open a contact editor window for editing an existing contact
1181 // Check if there is an account selected and if not
1182 // return immediately.
1184 int DataCheck = event.GetInt();
1186 if (ActiveAccount.IsEmpty() && DataCheck == 0){
1192 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1193 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1194 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1196 contacticon.CopyFromBitmap(contacticonbmp);
1198 // Check if a contact has been selected.
1200 long intSelected = -1;
1201 long intContactSeekNum = -1;
1203 intSelected = lstContacts->GetNextItem(intSelected,
1205 wxLIST_STATE_SELECTED);
1207 if (intSelected == -1){
1213 intContactSeekNum = lstContacts->GetItemData(intSelected);
1215 // Get the filename of the selected contact.
1217 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1218 frmContactEditor *ContactEditor = new frmContactEditor( this );
1222 ContactEditor->SetUID(WindowMenuItemID);
1224 WindowData *WData = new WindowData;
1226 WData->DataType = 1;
1227 WData->WindowPointer = (void*)ContactEditor;
1228 WData->WindowID = WindowMenuItemID;
1230 wxCommandEvent addevent(WINDOW_ADD);
1231 addevent.SetClientData(WData);
1232 wxPostEvent(this, addevent);
1234 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1235 ContactEditor->SetupHeaders();
1237 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1238 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1240 ContactEditor->SetupAccountData(true);
1244 // Check if pointer is NULL (not from the search forms) or not.
1246 if (DataCheck == 0){
1248 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1249 ContactEditor->SetupContact(ActiveAccount);
1253 UCNotif *uc = (UCNotif*)event.GetClientData();
1257 ContactEditor->SetupContact(ActiveAccount);
1258 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1262 ContactEditor->SetupContact(uc->ContactAccount);
1263 ContactEditor->LoadContact(uc->ContactFilename);
1272 ContactEditor->SetIcon(contacticon);
1273 ContactEditor->Show(true);
1277 void frmMain::RefreshAddressBook( wxCommandEvent& event ){
1279 // Refresh the address book data.
1281 // Check if ActiveAccount is empty. If not then check if
1282 // account type is not local otherwise continue.
1284 if (!ActiveAccount.IsEmpty()){
1286 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
1288 // Account type is not local.
1290 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1291 frameActMgr->AddTask(3, wxT(""), ActiveAccount,
1292 wxT(""), wxT(""), wxT(""), wxT(""));
1296 wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported"), wxICON_ERROR);
1304 void frmMain::OpenContactInfoList( wxListEvent& event )
1307 // Open the contact information window.
1309 wxStringTokenizer vcardfileline;
1312 wxString setname, setvalue;
1316 long intSelected = -1;
1317 long intContactSeekNum = -1;
1319 intSelected = lstContacts->GetNextItem(intSelected,
1321 wxLIST_STATE_SELECTED);
1323 intContactSeekNum = lstContacts->GetItemData(intSelected);
1325 if (intContactSeekNum == -1){
1331 Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
1333 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1334 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1335 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1337 contacticon.CopyFromBitmap(contacticonbmp);
1339 frmContact *Contact = new frmContact( this );
1341 // Add to window list.
1345 Contact->SetUID(WindowMenuItemID);
1347 WindowData *WData = new WindowData;
1349 WData->DataType = 0;
1350 WData->WindowPointer = (void*)Contact;
1351 WData->WindowID = WindowMenuItemID;
1353 wxCommandEvent addevent(WINDOW_ADD);
1354 addevent.SetClientData(WData);
1355 wxPostEvent(this, addevent);
1357 Contact->SetupPointers(&MemoryFileList);
1358 Contact->SetupContactData(&Person);
1360 Contact->SetIcon(contacticon);
1361 Contact->Show(true);
1365 void frmMain::OpenContactInfoList( wxCommandEvent& event ){
1367 // Open a list of contact information windows.
1370 OpenContactInfoList(pevent);
1374 void frmMain::OpenContactInfo( wxCommandEvent& event )
1377 // Open the contact information window.
1379 UCNotif *uc = (UCNotif*)event.GetClientData();
1381 wxStringTokenizer vcardfileline;
1384 wxString setname, setvalue;
1388 Person.LoadFile(uc->ContactFilename);
1390 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1391 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1392 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1394 contacticon.CopyFromBitmap(contacticonbmp);
1396 frmContact *Contact = new frmContact( this );
1398 // Add to window list.
1402 Contact->SetUID(WindowMenuItemID);
1404 WindowData *WData = new WindowData;
1406 WData->DataType = 0;
1407 WData->WindowPointer = (void*)Contact;
1408 WData->WindowID = WindowMenuItemID;
1410 wxCommandEvent addevent(WINDOW_ADD);
1411 addevent.SetClientData(WData);
1412 wxPostEvent(this, addevent);
1414 Contact->SetupPointers(&MemoryFileList);
1415 Contact->SetupContactData(&Person);
1417 Contact->SetIcon(contacticon);
1418 Contact->Show(true);
1423 void frmMain::LoadPreferences( wxActivateEvent& event)
1426 // Load the preferences.
1428 this->LoadPreferences();
1432 void frmMain::LoadPreferences(){
1434 // Load the preferences.
1436 wxString preffilename = GetUserPrefDir();
1438 XABPreferences preferences(preffilename);
1440 // Setup the main window position (if needed).
1442 bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
1443 bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
1445 if (SaveWindowPos == TRUE){
1447 this->SetSize(preferences.GetMainWindowData());
1451 treAccounts->DeleteAllItems();
1453 wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
1455 // Stop all account timers and remove the accounts.
1457 for (std::map<wxString, wxAccountSyncTimer*>::iterator iter = AccountSyncTimers.begin();
1458 iter != AccountSyncTimers.end(); iter++){
1460 wxAccountSyncTimer *AccTmrPtr = iter->second;
1468 #if defined(__WIN32__)
1470 for (std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.begin();
1471 CertificateIter != AccountCertificateData.end(); CertificateIter++){
1473 CertFreeCertificateContext(CertificateIter->second);
1477 AccountCertificateData.clear();
1481 AccountSyncTimers.clear();
1484 wxString AccDirFull;
1485 wxString AccDirFullSfx;
1487 wxString AccDirFinal;
1488 AccountAccDirList.clear();
1489 AccountGroupList.clear();
1490 AccountGroupFilename.clear();
1491 AccountGroupTreeId.clear();
1492 wxTreeItemId AccountTreeId;
1493 wxTreeItemId GroupTreeId;
1496 // Relaod the accounts for the ETagProcTimer.
1498 ETagProcTimer.ReloadAccounts();
1500 for (int i = 0; i < preferences.accounts.GetCount(); i++){
1502 if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
1503 preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == TRUE){
1509 if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
1515 AccDir = preferences.accounts.GetAccountDirectory(i);
1516 AccDirFull = preferences.accounts.GetAccountDirectory(i);
1518 AccDirFull.Append(wxT("."));
1519 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
1520 AccDirFullSfx.LowerCase();
1521 AccDirFullSfx.Trim();
1522 AccDirFull.Append(AccDirFullSfx);
1523 AccName = preferences.accounts.GetAccountName(i);
1525 AccountAccDirList.insert(std::make_pair(i, AccDirFull));
1527 if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
1528 preferences.accounts.GetAccountType(i) == wxT("carddav")){
1530 // TODO: Check if the directory exists before doing anything.
1534 // Add a new timer using the existing account details.
1536 wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
1538 ActTmrPtr->SetupData(AccDirFull, AccName);
1539 ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
1540 ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
1541 ActTmrPtr->SetOwner(this);
1542 ActTmrPtr->Notify();
1544 // Add the timer to the list of timers.
1546 AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
1548 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
1550 } else if (preferences.accounts.GetAccountType(i) == wxT("Local") ||
1551 preferences.accounts.GetAccountType(i) == wxT("local")) {
1553 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
1557 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountUnsupportedID, -1);
1561 // Go through the account directory and find contact files with
1562 // 'KIND:group' set and add them to the list of groups for the account.
1564 AccDirFinal = GetAccountDir(AccDirFull, FALSE);
1566 wxDir vcardaccdir(AccDirFinal);
1568 wxString vCardFilename;
1569 wxString vCardDataString;
1570 wxString vCardFilenameFull;
1572 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1576 if (vCardFilename.Right(4) == wxT(".vcf") ||
1577 vCardFilename.Right(4) == wxT(".VCF") ||
1578 vCardFilename.Right(5) == wxT(".vcard") ||
1579 vCardFilename.Right(5) == wxT(".VCARD")){
1583 vCardFilenameFull.Append(AccDirFinal);
1584 vCardFilenameFull.Append(wxT("/"));
1585 vCardFilenameFull.Append(vCardFilename);
1587 Person.LoadFile(vCardFilenameFull);
1589 if (Person.MeetBaseSpecification()){
1591 vCardDataString = Person.Get(wxT("KIND"));
1593 if (vCardDataString == wxT("group")){
1595 // The vCard kind is a group. Add to the account's group list.
1597 GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
1598 treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
1599 AccountGroupList.insert(std::make_pair(intGroupID, i));
1600 AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
1601 AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
1611 vCardFilename.Clear();
1612 vCardFilenameFull.Clear();
1613 vCardDataString.Clear();
1614 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1618 // Clearup for next account.
1622 AccDirFullSfx.clear();
1623 AccDirFinal.clear();
1628 // Load the account settings as they are needed for connecting
1631 prefaccounts = preferences.accounts;
1635 void frmMain::ConflictResolution(wxCommandEvent& event){
1637 // Display the conflict resolution window.
1639 frmConflictResolution *frameCR = new frmConflictResolution ( this );
1640 vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
1641 vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
1642 vCard *ServerDataPtr = vCardConfObj->vCardServerData;
1643 frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList);
1644 frameCR->ShowModal();
1646 int FinalConflictResult = frameCR->GetResult();
1648 wxCommandEvent event2(ACTMGR_RESUMEPROC);
1649 event2.SetClientData(vCardConfObj->QRNotifData);
1650 event2.SetInt(FinalConflictResult);
1655 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1656 wxPostEvent(frameActMgr, event2);
1660 void frmMain::UpdateContactList(wxCommandEvent& event){
1662 // Update the contact list in the main window.
1664 UCNotif *ucd = (UCNotif*)event.GetClientData();
1666 // Check if the active account is being displayed in the
1667 // main window. If not, skip and delete the data.
1669 long longSelected = -1;
1670 int intSelectedData = 0;
1672 if (ActiveAccount == ucd->ContactAccount){
1674 // Look at the list of contacts and if it matches the
1675 // filename then update the name.
1679 longSelected = lstContacts->GetNextItem(longSelected,
1681 wxLIST_STATE_DONTCARE);
1683 if (longSelected == -1){
1689 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1691 if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
1693 // Work out which sorting mode we are in.
1697 // First Name, Last Name.
1699 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
1701 } else if (SortMode == 2){
1703 // Last Name, First Name.
1705 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
1707 } else if (SortMode == 3){
1711 lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
1713 } else if (SortMode == 4){
1717 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1724 // If the filename is the one loaded into the
1725 // browser control, then update this too.
1727 if (ActiveFilename == ContactsFileIndex[intSelectedData]){
1729 wxListEvent nullevent;
1730 ShowContactInfo(nullevent);
1738 for (std::map<int, void*>::iterator WindowIter = WindowListPointers.begin();
1739 WindowIter != WindowListPointers.end(); WindowIter++){
1741 if (WindowListType[WindowIter->first] != 0){
1747 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
1749 if (frmContactPtr->GetFilename() == ucd->ContactFilename){
1751 vCard UpdatedPerson;
1752 UpdatedPerson.LoadFile(ucd->ContactFilename);
1753 frmContactPtr->SetupContactData(&UpdatedPerson);
1759 // Send message to search window controller subroutine and
1760 // pass that notification onto the search windows.
1762 // Setup the new pointer to use the existing UCNotif without
1765 UCNotif *ucd2 = ucd;
1767 wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
1768 sup.SetClientData(ucd2);
1769 wxPostEvent(this, sup);
1771 // Clear up the unused pointer.
1777 void frmMain::UpdateAccountList(wxCommandEvent& event){
1779 // Update the account list (currently unimplemented).
1783 void frmMain::SetupPointers(void *ActMgrPtrInc){
1785 // Setup the pointers for the main window.
1787 ActMgrPtr = ActMgrPtrInc;
1791 void frmMain::SetupForm(){
1793 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1794 frameActMgr->SetupPointers(&ETagProcTimer, this);
1796 // Setup the contact information icons for later.
1798 wxFileSystem::AddHandler(new wxMemoryFSHandler);
1802 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
1803 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
1804 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1806 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
1807 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
1808 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1810 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
1811 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
1812 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1814 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
1815 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
1816 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1818 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
1819 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
1820 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1822 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
1823 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
1824 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1830 void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
1832 // Update the contact lists in the search windows.
1834 // Go through each of the search windows and
1835 // send the required notification to update the
1836 // contact information.
1838 // Get the event notification data.
1840 UCNotif *ucd = (UCNotif*)event.GetClientData();
1842 // Process each search window giving the new details.
1844 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1845 switer != SearchWindowList.end(); switer++){
1847 // Duplicate the event notification data.
1849 UCNotif *ucd2 = new UCNotif;
1851 ucd2->ContactAccount = ucd->ContactAccount;
1852 ucd2->ContactFilename = ucd->ContactFilename;
1853 ucd2->ContactName = ucd->ContactName;
1854 ucd2->ContactNickname = ucd->ContactNickname;
1855 ucd2->ContactNameArray = ucd->ContactNameArray;
1857 // Pass the data to the search window for processing.
1859 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
1860 wxCommandEvent schupdate(SE_UPDATERESULT);
1861 schupdate.SetClientData(ucd2);
1862 wxPostEvent(frameSCH, schupdate);
1864 // Clear up the pointer prior to variable deletion.
1875 void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
1877 // Open a new search window.
1881 frmSearch *frameSCH = new frmSearch ( this );
1882 frameSCH->SetUID(WindowMenuItemID);
1883 frameSCH->Show(true);
1885 WindowData *WData = new WindowData;
1887 WData->DataType = 2;
1888 WData->WindowPointer = (void*)frameSCH;
1889 WData->WindowID = WindowMenuItemID;
1891 wxCommandEvent addevent(WINDOW_ADD);
1892 addevent.SetClientData(WData);
1893 wxPostEvent(this, addevent);
1895 // Add pointer to the list of open search windows.
1897 SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
1903 void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
1905 // Remove the pointer for a contact window from the
1908 void *frameSCH = (void*)event.GetClientData();
1910 SearchWindowList.erase(frameSCH);
1916 void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
1918 // Remove the pointer for a contact editor window from
1921 void *frameSCH = (void*)event.GetClientData();
1923 SearchWindowList.erase(frameSCH);
1929 void frmMain::RevealContact(wxCommandEvent& event){
1931 // Reveal a contact in the main window.
1933 UCNotif *uc = (UCNotif*)event.GetClientData();
1935 // Switch the account to the one passed.
1937 wxTreeItemIdValue cookie;
1938 wxTreeItemId next = treAccounts->GetRootItem();
1939 wxTreeItemId nextChild;
1941 for (int i = 0; i < prefaccounts.GetCount(); i++){
1944 nextChild = treAccounts->GetFirstChild(next, cookie);
1946 nextChild = treAccounts->GetNextSibling(nextChild);
1949 if (uc->ContactAccount == AccountAccDirList[i]){
1951 treAccounts->SelectItem(nextChild, TRUE);
1952 AccCtrl->SetText(treAccounts->GetItemText(nextChild));
1958 // Switch the contact to the one passed.
1960 long longSelected = -1;
1961 int intSelectedData = 0;
1965 longSelected = lstContacts->GetNextItem(longSelected,
1967 wxLIST_STATE_DONTCARE);
1969 if (longSelected == -1){
1975 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1977 // Compare the filename with the one received.
1978 // If they match then select it.
1980 if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
1984 lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1985 lstContacts->EnsureVisible(longSelected);
1989 lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
1997 void frmMain::DeleteContact(wxCommandEvent& event){
1999 // Delete a contact from the main window.
2001 // Check if a contact is selected.
2003 long intSelected = -1;
2004 long intContactSeekNum = -1;
2005 wxString wxSContactName;
2007 intSelected = lstContacts->GetNextItem(intSelected,
2009 wxLIST_STATE_SELECTED);
2011 if (intSelected == -1){
2015 // Check if the account type is a valid account type, otherwise
2016 // display an error message.
2018 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
2019 ActiveAccountType != "Local" && ActiveAccountType != "local"){
2021 wxMessageBox(_("Cannot delete contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
2026 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2028 // Get the item data of the contact.
2030 intContactSeekNum = lstContacts->GetItemData(intSelected);
2032 // Get the name of the contact.
2034 wxSContactName = lstContacts->GetItemText(intSelected);
2036 // Display a message confirming if the contact should
2039 int QuestionResponse;
2041 QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
2043 if (QuestionResponse == wxNO){
2045 // Exit the subroutine
2051 // Delete the contact.
2053 if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
2055 wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
2060 // Remove the contact from the list.
2062 lstContacts->DeleteItem(intSelected);
2064 // Update the search windows, removing the deleted
2067 UCNotif *ucd = new UCNotif;
2069 ucd->ContactAccount = ActiveAccount;
2070 ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
2072 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
2073 switer != SearchWindowList.end(); switer++){
2075 // Duplicate the event notification data.
2077 UCNotif *ucd2 = new UCNotif;
2079 ucd2->ContactAccount = ucd->ContactAccount;
2080 ucd2->ContactFilename = ucd->ContactFilename;
2082 // Pass the data to the search window for processing.
2084 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
2085 wxCommandEvent schdelete(SE_DELETERESULT);
2086 schdelete.SetClientData(ucd2);
2087 wxPostEvent(frameSCH, schdelete);
2089 // Clear up the pointer prior to variable deletion.
2096 // Clear the wxHTMLWindow.
2098 wxString EmptyPage = wxT("");
2100 htmContactData->SetPage(EmptyPage);
2102 wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
2104 wxString wxSplitFilename;
2105 wxString wxSDataURL;
2107 while(wSTFilename.HasMoreTokens()){
2109 wxSplitFilename = wSTFilename.GetNextToken();
2113 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
2115 // Update the ETagDB and mark it as deleted.
2117 ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
2119 ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
2121 // Get the Data URL.
2123 wxTreeItemIdValue cookie;
2124 wxTreeItemId next = treAccounts->GetRootItem();
2126 wxTreeItemId selectedChild = treAccounts->GetSelection();
2127 wxTreeItemId nextChild;
2129 for (int i = 0; i < prefaccounts.GetCount(); i++){
2132 nextChild = treAccounts->GetFirstChild(next, cookie);
2134 nextChild = treAccounts->GetNextSibling(nextChild);
2137 if (nextChild == selectedChild){
2139 wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
2146 // Add task to the activity monitor to delete the contact.
2148 frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
2152 // Clear the variable. Don't delete as it will mess things up.
2154 ContactsFileIndex[intContactSeekNum] = wxT("");
2161 void frmMain::EmptyServerDialog(wxCommandEvent& event){
2163 // Display this message when the server information has changed
2166 QRNotif *qrn = (QRNotif *)event.GetClientData();
2168 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);
2170 if (QResponse == wxNO){
2176 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2177 event2.SetInt(*qrn->QResponse);
2178 event2.SetClientData(qrn->PausePtr);
2180 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2182 wxPostEvent(frameActMgr, event2);
2186 void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
2188 // Remove the contact from the window after syncronising.
2190 // Check which account is currently active in the window.
2191 // If it is different from the one passed to this subroutine then
2192 // exit from the subroutine.
2194 if (Account != ActiveAccount){
2198 long longSelected = -1;
2199 int intSelectedData = 0;
2203 longSelected = lstContacts->GetNextItem(longSelected,
2205 wxLIST_STATE_DONTCARE);
2207 if (longSelected == -1){
2213 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2215 // Compare the filename with the one received.
2216 // If they match then select it.
2218 if (ContactsFileIndex[intSelectedData] == Filename){
2220 // Remove the contact from the window.
2222 lstContacts->DeleteItem(intSelectedData);
2224 // Check if contact is the selected contact in the HTML window and
2225 // if it is then clear the window.
2227 if (ActiveFilename == Filename){
2229 wxString EmptyPage = wxT("");
2230 htmContactData->SetPage(EmptyPage);
2244 void frmMain::SortFNLN( wxCommandEvent& event ) {
2246 // Sort first name then last name.
2248 wxTreeEvent NullEvent;
2250 LoadContactList(NullEvent);
2254 void frmMain::SortLNFN( wxCommandEvent& event ) {
2256 // Sort last name then first name.
2258 wxTreeEvent NullEvent;
2260 LoadContactList(NullEvent);
2264 void frmMain::SortNickname( wxCommandEvent& event ) {
2266 // Sort by nickname.
2268 wxTreeEvent NullEvent;
2270 LoadContactList(NullEvent);
2274 void frmMain::SortDisplayAs( wxCommandEvent& event ) {
2276 // Sort by Display As name.
2278 wxTreeEvent NullEvent;
2280 LoadContactList(NullEvent);
2284 void frmMain::SortAscending( wxCommandEvent& event ) {
2288 wxTreeEvent NullEvent;
2289 AscendingMode = TRUE;
2290 LoadContactList(NullEvent);
2294 void frmMain::SortDescending( wxCommandEvent& event ) {
2298 wxTreeEvent NullEvent;
2299 AscendingMode = FALSE;
2300 LoadContactList(NullEvent);
2304 void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
2306 // Toggle the appearance of the status bar.
2308 if (stbBottom->IsShown() == TRUE){
2322 void frmMain::ActivityIconStart( wxCommandEvent& event ){
2324 // Display the activity icon.
2326 imgActivityStatus->SetBitmap(*imgActIcon1);
2327 ActivityIconStatus = 0;
2331 void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
2333 // Shuffle through the activity icons.
2335 switch (ActivityIconStatus){
2338 imgActivityStatus->SetBitmap(*imgActIcon1);
2339 ActivityIconStatus = 1;
2342 imgActivityStatus->SetBitmap(*imgActIcon2);
2343 ActivityIconStatus = 2;
2346 imgActivityStatus->SetBitmap(*imgActIcon3);
2347 ActivityIconStatus = 3;
2350 imgActivityStatus->SetBitmap(*imgActIcon4);
2351 ActivityIconStatus = 0;
2354 ActivityIconStatus = 0;
2360 void frmMain::ActivityIconStop( wxCommandEvent& event ){
2362 // Display the sleep icon.
2364 imgActivityStatus->SetBitmap(*imgActIconSleep);
2368 void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
2370 // Set the placement of the status bar icons.
2372 if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
2380 wxRect rectActivity;
2381 stbBottom->GetFieldRect(1, rectOnline);
2382 stbBottom->GetFieldRect(2, rectSSL);
2383 stbBottom->GetFieldRect(3, rectActivity);
2385 imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
2386 imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
2387 imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
2391 XABViewMode frmMain::GetViewMode(){
2393 // Set the view mode of the contact list.
2397 xvm.SortMode = SortMode;
2398 xvm.AscendingMode = AscendingMode;
2404 void frmMain::WindowAdd( wxCommandEvent &event ){
2406 // Add a window to the window list.
2408 WindowData *WData = (WindowData*)event.GetClientData();
2412 if (WData->DataType == 0){
2416 int intID = mnuContactWindows->GetId();
2418 mnuWindow->FindChildItem(intID, &pos);
2419 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2420 mnuNewItem->SetId(WData->WindowID);
2421 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2422 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2423 WindowListType.insert(std::make_pair(WData->WindowID, 0));
2424 mnuWindow->Insert((pos + 1), mnuNewItem);
2425 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
2427 } else if (WData->DataType == 1){
2429 // Contact Editor Window
2431 int intID = mnuContactEditorWindows->GetId();
2433 mnuWindow->FindChildItem(intID, &pos);
2434 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor 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, 1));
2439 mnuWindow->Insert((pos + 1), mnuNewItem);
2440 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
2442 } else if (WData->DataType == 2){
2446 int intID = mnuSearchWindows->GetId();
2448 mnuWindow->FindChildItem(intID, &pos);
2449 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search 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, 2));
2454 mnuWindow->Insert((pos + 1), mnuNewItem);
2455 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
2464 void frmMain::WindowEdit( wxCommandEvent &event ){
2466 // Edit a window in the window list.
2468 WindowData *WData = (WindowData*)event.GetClientData();
2470 if (WData->DataType == 0){
2472 // Get the window title and use that.
2474 frmContact *frmContactPtr = static_cast<frmContact*>(WData->WindowPointer);
2476 wxString WindowTitle = frmContactPtr->GetTitle();
2478 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2480 MenuIter->second->SetItemLabel(WindowTitle);
2482 } else if (WData->DataType == 1){
2484 // Get the window title and use that.
2486 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WData->WindowPointer);
2488 wxString WindowTitle = frmCEPtr->GetTitle();
2490 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2492 if (WindowTitle.IsEmpty()){
2494 MenuIter->second->SetItemLabel(_("Unnamed Contact"));
2498 MenuIter->second->SetItemLabel(WindowTitle);
2509 void frmMain::WindowDelete( wxCommandEvent &event ){
2511 // Delete a window from the window list.
2513 WindowData *WData = (WindowData*)event.GetClientData();
2515 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2517 mnuWindow->Remove(MenuIter->second);
2519 delete MenuIter->second;
2520 MenuIter->second = NULL;
2522 WindowListPointersMenu.erase(WData->WindowID);
2523 WindowListPointers.erase(WData->WindowID);
2524 WindowListType.erase(WData->WindowID);
2531 void frmMain::ShowContactWindow( wxCommandEvent &event ){
2533 // Show a contact window from the window list.
2535 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2537 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
2539 frmContactPtr->Show();
2540 frmContactPtr->Raise();
2544 void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
2546 // Show a contact editor window from the window list.
2548 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2550 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WindowIter->second);
2557 void frmMain::ShowSearchWindow( wxCommandEvent &event ){
2559 // Show a search window from the window list.
2561 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2563 frmSearch *frmSearchPtr = static_cast<frmSearch*>(WindowIter->second);
2565 frmSearchPtr->Show();
2566 frmSearchPtr->Raise();
2570 void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
2572 // Toggle the online/offline connection status.
2574 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2575 wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
2576 wxPostEvent(frameActMgr, toggconn);
2580 void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
2582 // Check the account type before continuing.
2584 wxString SeekAccount;
2585 wxString AccTypeLower;
2589 #if defined(__APPLE__)
2591 std::map<int, SecTrustRef>::iterator SSLTrustIter;
2593 for (int i = 0; i < prefaccounts.GetCount(); i++){
2595 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2596 AccType.Append(prefaccounts.GetAccountType(i));
2597 AccountSSL = prefaccounts.GetAccountSSL(i);
2598 AccTypeLower = AccType.MakeLower();
2599 SeekAccount.Append(wxT("."));
2600 SeekAccount.Append(AccTypeLower);
2602 if (SeekAccount == ActiveAccount){
2604 if (AccTypeLower == wxT("local")){
2610 if (AccountSSL == false){
2616 SSLTrustIter = AccountTrustData.find(i);
2618 // Setup and display the form.
2620 DisplayCertificate(SSLTrustIter->second);
2624 SeekAccount.Clear();
2625 AccTypeLower.Clear();
2630 #elif defined(__WIN32__)
2632 std::map<int, PCCERT_CONTEXT>::iterator SSLCertificateIter;
2634 for (int i = 0; i < prefaccounts.GetCount(); i++){
2636 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2637 AccType.Append(prefaccounts.GetAccountType(i));
2638 AccountSSL = prefaccounts.GetAccountSSL(i);
2639 AccTypeLower = AccType.MakeLower();
2640 SeekAccount.Append(wxT("."));
2641 SeekAccount.Append(AccTypeLower);
2643 if (SeekAccount == ActiveAccount){
2645 if (AccTypeLower == wxT("local")){
2651 if (AccountSSL == false){
2657 SSLCertificateIter = AccountCertificateData.find(i);
2659 // Setup and display the form.
2661 if (SSLCertificateIter->second->pCertInfo == NULL){
2663 wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
2667 BOOL ModifiedCertificateData;
2668 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
2670 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
2671 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
2676 //DisplayCertificate(SSLTrustIter->second);
2680 SeekAccount.Clear();
2681 AccTypeLower.Clear();
2688 std::map<int, SSLCertCollectionString>::iterator SSLColIter;
2690 for (int i = 0; i < prefaccounts.GetCount(); i++){
2692 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2693 AccType.Append(prefaccounts.GetAccountType(i));
2694 AccountSSL = prefaccounts.GetAccountSSL(i);
2695 AccTypeLower = AccType.MakeLower();
2696 SeekAccount.Append(wxT("."));
2697 SeekAccount.Append(AccTypeLower);
2699 if (SeekAccount == ActiveAccount){
2701 if (AccTypeLower == wxT("local")){
2707 if (AccountSSL == false){
2713 SSLColIter = AccountSSLData.find(i);
2715 SSLCertCollectionString SSLCertInfo = SSLColIter->second;
2717 frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
2718 frameSSLCert->StartCertFrom(0);
2719 frameSSLCert->SetupCertsString(SSLCertInfo);
2720 frameSSLCert->ShowModal();
2722 delete frameSSLCert;
2723 frameSSLCert = NULL;
2727 SeekAccount.Clear();
2728 AccTypeLower.Clear();
2737 void frmMain::ShowSSLInfo( wxCommandEvent &event ){
2739 // Check the account type before continuing.
2743 void frmMain::HideSSLInfo( wxCommandEvent &event ){
2745 // Check the account type before continuing.
2749 void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
2751 if (event.GetInt() == 0){
2753 imgConnStatus->SetBitmap(*imgOnline);
2757 imgConnStatus->SetBitmap(*imgOffline);
2763 void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
2765 // Display the form for showing an invalid SSL certificate.
2767 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2768 SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
2769 SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
2770 wxString AccountName = SSLICNObj->AccountName;
2771 frameISC->LoadData(SSLCCData, AccountName);
2772 frameISC->ShowModal();
2774 int FinalConflictResult = frameISC->GetResult();
2776 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2777 event2.SetClientData(SSLICNObj->QRNotifData);
2778 event2.SetInt(FinalConflictResult);
2783 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2784 wxPostEvent(frameActMgr, event2);
2788 void frmMain::InvalidSSLCertificateString( wxCommandEvent &event ){
2790 // Display the form for showing an invalid SSL certificate.
2792 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2793 SSLInvalidCertNotifObjString *SSLICNObj = (SSLInvalidCertNotifObjString*)event.GetClientData();
2794 SSLCertCollectionString SSLCCData = SSLICNObj->CertCollection;
2795 wxString AccountName = SSLICNObj->AccountName;
2796 frameISC->LoadData(SSLCCData, AccountName);
2797 frameISC->ShowModal();
2799 int FinalConflictResult = frameISC->GetResult();
2801 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2802 event2.SetClientData(SSLICNObj->QRNotifData);
2803 event2.SetInt(FinalConflictResult);
2808 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2809 wxPostEvent(frameActMgr, event2);
2813 void frmMain::PauseAllTimers(){
2815 // Pause all the account timers.
2817 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2818 ASTiter != AccountSyncTimers.end(); ASTiter++){
2820 ASTiter->second->Stop();
2826 void frmMain::ResumeAllTimers(){
2828 // Resume all the account timers.
2830 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2831 ASTiter != AccountSyncTimers.end(); ASTiter++){
2833 ASTiter->second->Start();
2839 #if defined(__APPLE__)
2841 #elif defined(__WIN32__)
2843 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
2845 // Delete existing data.
2847 std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.find(AccountID);
2849 if (CertificateIter != AccountCertificateData.end()){
2850 CertFreeCertificateContext(CertificateIter->second);
2853 AccountCertificateData.erase(AccountID);
2854 AccountSSLResult.erase(AccountID);
2858 AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
2859 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2865 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollectionString SSLCertInc){
2867 // Delete existing data.
2869 AccountSSLData.erase(AccountID);
2870 AccountSSLResult.erase(AccountID);
2874 AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
2875 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2881 void frmMain::SetupSSLStatus( int AccountID ){
2883 // Check if account ID given is
2884 // the active account and if not, do nothing.
2887 wxString AccTypeLower;
2889 AccType = prefaccounts.GetAccountType(AccountID);
2890 AccTypeLower = AccType.MakeLower();
2892 wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
2895 if (AccountIDName != ActiveAccount){
2901 // Check the account type is a supported account type.
2903 if (AccType != "CardDAV" && AccType != "carddav" &&
2904 AccType != "Local" && AccType != "local"){
2906 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2907 imgSSLStatus->SetBitmap(*imgNoSSL);
2912 // Check if the account has SSL enabled.
2914 bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
2916 if (SSLInUse == FALSE){
2918 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2919 imgSSLStatus->SetBitmap(*imgNoSSL);
2923 // Get the SSL Collection Data.
2925 std::map<int,int>::iterator SSLResultIter = AccountSSLResult.find(AccountID);
2927 // Check if a result value has been set.
2929 if (SSLResultIter == AccountSSLResult.end()){
2931 imgSSLStatus->SetBitmap(*imgSSLWarning);
2932 SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
2937 if (SSLResultIter->second == 1){
2939 imgSSLStatus->SetBitmap(*imgSSLWarning);
2940 SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
2941 prefaccounts.GetAccountName(AccountID) +
2942 wxT("' (Connection denied by user)\n\nDouble click for more information."));
2944 } else if (SSLResultIter->second == 0){
2946 imgSSLStatus->SetBitmap(*imgSSL);
2947 SSLToolTip->SetTip(wxT("Account '") +
2948 prefaccounts.GetAccountName(AccountID) +
2949 wxT("' secured using SSL\n\nDouble click for more information."));
2957 void frmMain::CheckUpdates( wxCommandEvent& event ){
2959 // Check for updates to Xestia Address Book.
2961 frmUpdate *frameUpdate = new frmUpdate ( this );
2962 frameUpdate->FetchData();
2963 frameUpdate->ShowModal();
2967 void frmMain::OpenImportDialog( wxCommandEvent& event ){
2969 // Run the import contacts function.
2975 void frmMain::OpenExportDialog( wxCommandEvent& event ){
2977 // Check if an account and at least one contact is selected
2978 // before continuing.
2980 wxArrayString ArrData;
2982 if (ActiveAccount.IsEmpty()){
2988 int ContactSelected = 0;
2989 int ContactsCollected = 0;
2990 long longSelected = -1;
2994 longSelected = lstContacts->GetNextItem(longSelected,
2996 wxLIST_STATE_SELECTED);
2998 if (longSelected == -1){
3004 int FileID = (int)lstContacts->GetItemData(longSelected);
3006 ArrData.Insert(ContactsFileIndex[FileID],
3007 ContactsCollected, 1);
3013 if (ContactSelected == 0){
3019 // Run the export contacts system.
3021 ExportRun(this, &ArrData);
3025 void frmMain::GetListControl(wxListCtrl *lstContactsPtr,
3026 wxArrayString *ContactsFileIndexPtr){
3028 // Set the list control pointers.
3030 lstContactsPtr = lstContacts;
3031 ContactsFileIndexPtr = &ContactsFileIndex;
3035 void frmMain::GetSelectedList( wxCommandEvent& event ){
3037 // Get the array of contact filenames.
3039 wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
3041 // Process them into an array of files.
3043 long longSelected = -1;
3044 int ContactsCollected = 0;
3045 wxString ContactFilename;
3049 longSelected = lstContacts->GetNextItem(longSelected,
3051 wxLIST_STATE_SELECTED);
3053 if (longSelected == -1){
3059 // Get the file information and add to the list.
3061 int FileID = (int)lstContacts->GetItemData(longSelected);
3063 ArrData->Insert(ContactsFileIndex[FileID],
3064 ContactsCollected, 1);
3066 ContactsCollected++;
3067 ContactFilename.Clear();
3075 void frmMain::SyncAccount( wxCommandEvent& event ){
3077 // Syncronise the selected account.
3079 wxString AccNameInc = event.GetString();
3081 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
3082 frameActMgr->AddTask(3, wxT(""), AccNameInc,
3083 wxT(""), wxT(""), wxT(""), wxT(""));
3087 void frmMain::ShowHelp( wxCommandEvent& event ){
3089 // Based on the operating system, work out where
3090 // the documentation should be.
3094 #if defined(__HAIKU__)
3096 #elif defined(__WIN32__)
3102 if (wxFileExists("/usr/share/doc/xestiaab/index.html")){
3104 wxLaunchDefaultBrowser(wxT("file:///usr/share/doc/xestiaab/index.html"));
3107 #if XSDAB_RELEASE == 0
3109 } else if (wxFileExists("/usr/local/share/doc/xestiaab/index.html")){
3111 wxLaunchDefaultBrowser(wxT("file:///usr/local/share/doc/xestiaab/index.html"));
3120 #if XSDAB_RELEASE == 0
3122 wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
3126 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!"));
3132 void frmMain::ShowImportResults( wxCommandEvent &event ){
3134 // Show the results of importing contacts.
3136 std::map<int,wxString> *ResultData = (std::map<int,wxString>*)event.GetClientData();
3138 frmImportResults *frmIR = new frmImportResults(this);
3139 frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
3150 void frmMain::ReloadContactList( wxCommandEvent &event ){
3152 // Check if the account name given is the current
3153 // account selected.
3155 if (ActiveAccount == event.GetString()){
3157 wxTreeEvent NullEvent;
3158 LoadContactList(NullEvent);
3164 void frmMain::ShowContactMenu( wxMouseEvent& event ){
3166 // Show the contact menu when a right click occurs
3167 // in the contacts list.
3169 bool EnableRefresh = FALSE;
3171 if (!ActiveAccount.IsEmpty() && (ActiveAccountType == "CardDAV" || ActiveAccountType == "carddav")){
3173 EnableRefresh = TRUE;
3177 ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
3179 this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
3183 void frmMain::ResetContactInfo(){
3185 // Reset the contact information to an empty page.
3187 wxString EmptyPage = wxT("");
3188 htmContactData->SetPage(EmptyPage);
3189 AccCtrl->SetValue("");