1 // frmMain.cpp - Main window form.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
25 #include <wx/tokenzr.h>
27 #include <wx/mstream.h>
28 #include <wx/fs_mem.h>
30 #include <wx/filesys.h>
32 #include <wx/stdpaths.h>
33 #include <wx/fileconf.h>
34 #include <wx/gdicmn.h>
40 #include "frmPreferences.h"
41 #include "frmNewAccount.h"
42 #include "actmgr/frmActivityMgr.h"
43 #include "frmContact.h"
44 #include "frmConflictResolution.h"
45 #include "frmInvalidSSLCertificate.h"
46 #include "search/frmSearch.h"
47 #include "frmSSLCertificate.h"
48 #include "frmUpdate.h"
49 #include "import/frmImportResults.h"
52 #include "common/preferences.h"
53 #include "common/getcontactinfo.h"
54 #include "common/events.h"
55 #include "common/dirs.h"
56 #include "vcard/vcard.h"
57 #include "carddav/carddav.h"
58 #include "contacteditor/frmContactEditor.h"
59 #include "import/import.h"
60 #include "export/export.h"
61 #include "widgets/XABContactMenu.h"
62 #include "widgets/XABAccountView.h"
66 // Define the event types.
68 DEFINE_EVENT_TYPE(CE_UPDATECONTACTLIST);
69 DEFINE_EVENT_TYPE(CE_UPDATEACCOUNTLIST);
70 DEFINE_EVENT_TYPE(SE_UPDATECONTACTNOTIF);
71 DEFINE_EVENT_TYPE(CE_OPENCONTACT);
72 DEFINE_EVENT_TYPE(CE_OPENCONTACTLIST);
73 DEFINE_EVENT_TYPE(CE_NEWCONTACT);
74 DEFINE_EVENT_TYPE(CE_EDITCONTACT);
75 DEFINE_EVENT_TYPE(CE_DELETECONTACT);
76 DEFINE_EVENT_TYPE(CE_REVEALCONTACT);
77 DEFINE_EVENT_TYPE(CE_REMOVECONTACT);
78 DEFINE_EVENT_TYPE(CE_REMOVESEARCH);
79 DEFINE_EVENT_TYPE(SYNC_EMPTYSERVER);
80 DEFINE_EVENT_TYPE(ACTMGR_START);
81 DEFINE_EVENT_TYPE(ACTMGR_SHUFFLE);
82 DEFINE_EVENT_TYPE(ACTMGR_STOP);
83 DEFINE_EVENT_TYPE(WINDOW_ADD);
84 DEFINE_EVENT_TYPE(WINDOW_EDIT);
85 DEFINE_EVENT_TYPE(WINDOW_CLOSE);
86 DEFINE_EVENT_TYPE(CONNSTAT_UPDATE);
87 DEFINE_EVENT_TYPE(INVALIDSSLCERT);
88 DEFINE_EVENT_TYPE(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, GETSELECTEDLIST, frmMain::GetSelectedList)
121 EVT_COMMAND(wxID_ANY, SYNCACCOUNT, frmMain::SyncAccount)
122 EVT_COMMAND(wxID_ANY, IMPORT_RESULTSSHOW, frmMain::ShowImportResults)
123 EVT_COMMAND(wxID_ANY, RELOADCONTACTLIST, frmMain::ReloadContactList)
124 EVT_COMMAND(wxID_ANY, REFRESHADDRESSBOOK, frmMain::RefreshAddressBook)
125 #if defined(__APPLE__)
126 EVT_COMMAND(wxID_ANY, INVALIDSSLTRUST, frmMain::DisplayTrustPanel)
130 frmMain::frmMain( wxWindow* parent )
135 // Setup the account icons.
137 wxMemoryInputStream astream(icons_accinet_png, sizeof(icons_accinet_png));
138 wxMemoryInputStream bstream(icons_acclocal_png, sizeof(icons_acclocal_png));
139 wxMemoryInputStream cstream(icons_accgroup_png, sizeof(icons_accgroup_png));
140 wxMemoryInputStream dstream(icons_accnone_png, sizeof(icons_accnone_png));
141 wxMemoryInputStream estream(icons_accunsupported_png, sizeof(icons_accunsupported_png));
143 wxImage icons_accinet_png(astream, wxBITMAP_TYPE_PNG);
144 wxBitmap AccInet(icons_accinet_png, -1);
146 wxIAccInet.CopyFromBitmap(AccInet);
148 wxImage icons_acclocal_png(bstream, wxBITMAP_TYPE_PNG);
149 wxBitmap AccNIcon(icons_acclocal_png, -1);
151 wxIAccNIcon.CopyFromBitmap(AccNIcon);
153 wxImage icons_accgroup_png(cstream, wxBITMAP_TYPE_PNG);
154 wxBitmap AccGrp(icons_accgroup_png, -1);
156 wxIAccGrp.CopyFromBitmap(AccGrp);
158 wxImage icons_accnone_png(dstream, wxBITMAP_TYPE_PNG);
159 wxBitmap AccNone(icons_accnone_png, -1);
161 wxIAccNone.CopyFromBitmap(AccNone);
163 wxImage icons_accunsupported_png(estream, wxBITMAP_TYPE_PNG);
164 wxBitmap AccUnsupported(icons_accunsupported_png, -1);
165 wxIcon wxIAccUnsupported;
166 wxIAccUnsupported.CopyFromBitmap(AccUnsupported);
168 AccountID = AccImgList->Add(wxIAccNIcon);
169 AccountNetID = AccImgList->Add(wxIAccInet);
170 AccountGrpID = AccImgList->Add(wxIAccGrp);
171 AccountNoneID = AccImgList->Add(wxIAccNone);
172 AccountUnsupportedID = AccImgList->Add(wxIAccUnsupported);
174 bmpIcon->SetIcon(AccImgList->GetIcon(AccountNoneID));
176 // Setup the status bar icons.
180 wxMemoryInputStream sslstream(icons_ssl_png, sizeof(icons_ssl_png));
181 wxMemoryInputStream sslwarningstream(icons_sslwarning_png, sizeof(icons_sslwarning_png));
182 wxMemoryInputStream nosslstream(icons_nossl_png, sizeof(icons_nossl_png));
184 wxImage icons_ssl_png(sslstream, wxBITMAP_TYPE_PNG);
185 imgSSL = new wxBitmap(icons_ssl_png, -1);
187 wxImage icons_sslwarning_png(sslwarningstream, wxBITMAP_TYPE_PNG);
188 imgSSLWarning = new wxBitmap(icons_sslwarning_png, -1);
190 wxImage icons_nossl_png(nosslstream, wxBITMAP_TYPE_PNG);
191 imgNoSSL = new wxBitmap(icons_nossl_png, -1);
195 wxMemoryInputStream act1(icons_act1_png, sizeof(icons_act1_png));
196 wxMemoryInputStream act2(icons_act2_png, sizeof(icons_act2_png));
197 wxMemoryInputStream act3(icons_act3_png, sizeof(icons_act3_png));
198 wxMemoryInputStream act4(icons_act4_png, sizeof(icons_act4_png));
199 wxMemoryInputStream actsleep(icons_actsleep_png, sizeof(icons_actsleep_png));
201 wxImage icons_actsleep_png(actsleep, wxBITMAP_TYPE_PNG);
202 imgActIconSleep = new wxBitmap (icons_actsleep_png, -1);
204 wxImage icons_act1_png(act1, wxBITMAP_TYPE_PNG);
205 imgActIcon1 = new wxBitmap (icons_act1_png, -1);
207 wxIAct1icon.CopyFromBitmap(*imgActIcon1);
209 wxImage icons_act2_png(act2, wxBITMAP_TYPE_PNG);
210 imgActIcon2 = new wxBitmap (icons_act2_png, -1);
212 wxIAct2icon.CopyFromBitmap(*imgActIcon2);
214 wxImage icons_act3_png(act3, wxBITMAP_TYPE_PNG);
215 imgActIcon3 = new wxBitmap (icons_act3_png, -1);
217 wxIAct3icon.CopyFromBitmap(*imgActIcon3);
219 wxImage icons_act4_png(act4, wxBITMAP_TYPE_PNG);
220 imgActIcon4 = new wxBitmap (icons_act4_png, -1);
222 wxIAct4icon.CopyFromBitmap(*imgActIcon4);
224 // Online/Offline icons.
226 wxMemoryInputStream onlinestream(icons_online_png, sizeof(icons_online_png));
227 wxMemoryInputStream offlinestream(icons_offline_png, sizeof(icons_offline_png));
229 wxImage icons_online_png(onlinestream, wxBITMAP_TYPE_PNG);
230 imgOnline = new wxBitmap(icons_online_png, -1);
232 wxImage icons_offline_png(offlinestream, wxBITMAP_TYPE_PNG);
233 imgOffline = new wxBitmap(icons_offline_png, -1);
235 // Setup the account view.
237 AccCtrl->SetPopupControl(treAccounts);
238 AccCtrl->SetPopupMaxHeight(175);
239 AccCtrl->SetPopupMinWidth(250);
240 treAccounts->AssignImageList(AccImgList);
242 wxListItem ColumnData;
244 ColumnData.SetText(wxT("Name0"));
245 ColumnData.SetWidth(320);
246 lstContacts->InsertColumn(0, ColumnData);
248 treAccounts->Connect(wxEVT_LEFT_DCLICK, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
249 treAccounts->Connect(wxEVT_TREE_SEL_CHANGED, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
251 #if defined(__HAIKU__)
253 #elif defined(__WIN32__)
255 int stbBottomData [4] = { -1, 16, 16, 16 };
259 int stbBottomData [4] = { -1, 20, 20, 20 };
263 stbBottom->SetFieldsCount(4, stbBottomData);
264 stbBottom->SetMinHeight(16);
269 stbBottom->GetFieldRect(1, rectOnline);
270 stbBottom->GetFieldRect(2, rectSSL);
271 stbBottom->GetFieldRect(3, rectActivity);
273 SSLToolTip = new wxToolTip(wxT(""));
275 #if defined(__WIN32__)
277 imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint(rectOnline.GetX(),rectOnline.GetY()), wxDefaultSize, 0 );
278 imgConnStatus->SetBitmap(*imgOnline);
279 imgConnStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ToggleConnectionStatus ), NULL, this );
281 imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()),(rectSSL.GetY())), wxDefaultSize, 0 );
282 imgSSLStatus->SetBitmap(*imgNoSSL);
283 imgSSLStatus->SetToolTip(SSLToolTip);
284 imgSSLStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowSSLCertificates ), NULL, this );
286 imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()),(rectActivity.GetY())), wxDefaultSize, 0);
287 imgActivityStatus->SetBitmap(*imgActIconSleep);
288 imgActivityStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowActivityWindow ), NULL, this );
292 imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectOnline.GetX()), (rectOnline.GetY())), wxDefaultSize, 0);
293 imgConnStatus->SetBitmap(*imgOnline);
294 imgConnStatus->Connect(wxEVT_LEFT_DCLICK, wxCommandEventHandler(frmMain::ToggleConnectionStatus), NULL, this);
296 imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()), (rectSSL.GetY())), wxDefaultSize, 0);
297 imgSSLStatus->SetBitmap(*imgNoSSL);
298 imgSSLStatus->SetToolTip(SSLToolTip);
299 imgSSLStatus->Connect(wxEVT_LEFT_DCLICK, wxCommandEventHandler(frmMain::ShowSSLCertificates), NULL, this);
301 imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()), (rectActivity.GetY())), wxDefaultSize, 0);
302 imgActivityStatus->SetBitmap(*imgActIconSleep);
303 imgActivityStatus->Connect(wxEVT_LEFT_DCLICK, wxCommandEventHandler(frmMain::ShowActivityWindow), NULL, this);
307 // Setup the window menu.
309 // By default should be:
314 // Contact editor windows:
320 mnuContactWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact windows:") ), wxEmptyString, wxITEM_NORMAL );
321 mnuWindow->Append( mnuContactWindows );
323 mnuWindow->AppendSeparator();
325 mnuContactEditorWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact editor windows:") ), wxEmptyString, wxITEM_NORMAL );
326 mnuWindow->Append( mnuContactEditorWindows );
328 mnuWindow->AppendSeparator();
330 mnuSearchWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( wxT("Search windows:") ), wxEmptyString, wxITEM_NORMAL );
331 mnuWindow->Append( mnuSearchWindows );
333 #if defined(__WIN32__)
338 mnuContactWindows->SetFont(fontstyle);
339 mnuContactEditorWindows->SetFont(fontstyle);
340 mnuSearchWindows->SetFont(fontstyle);
344 mnuContactWindows->Enable(FALSE);
345 mnuContactEditorWindows->Enable(FALSE);
346 mnuSearchWindows->Enable(FALSE);
350 // Hide unimplemented functions.
356 void frmMain::QuitApp( wxCloseEvent& event )
359 // Run the QuitApp function.
365 void frmMain::QuitApp( wxCommandEvent& event )
368 // Run the QuitApp function.
374 void frmMain::QuitApp()
377 // Function to run when quitting.
379 //Go through the windows and close each one (be it search
380 //or contact editor). Abort if user wants to cancel.
382 // Close the contact editor windows.
384 // Close the contact windows.
386 // Close the search windows.
388 // Write out the ETag databases.
390 // Save Preferences: Save the window position if that option is enabled.
392 wxString SetFilename = GetUserPrefDir();
394 #if defined(__HAIKU__)
398 #elif defined(__WIN32__)
400 SetFilename.Append(wxT("settings"));
406 SetFilename.Append(wxT("settings"));
410 wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
412 bool SaveWindowPos = FALSE;
413 wxString SaveWindowInc;
414 cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
416 if (SaveWindowInc == wxT("true")){
418 SaveWindowPos = TRUE;
422 if (SaveWindowPos == TRUE){
424 wxRect frmMainPos = this->GetRect();
426 cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
427 cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
428 cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
429 cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
436 //Everything closed... exit.
444 void frmMain::ShowActivityWindow( wxCommandEvent& event )
447 // Open the activity manager window.
449 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
450 frameActMgr->OpenWindow();
455 void frmMain::ShowAboutWindow( wxCommandEvent& event )
458 // Show the about window.
460 frmAbout *frameAbout = new frmAbout ( this );
461 frameAbout->SetupAboutWindow();
462 frameAbout->ShowModal();
468 void frmMain::OpenPreferences( wxCommandEvent& event)
471 // Open the preferences window.
473 ReloadAccounts = FALSE;
475 frmPreferences *framePreferences = new frmPreferences ( this );
476 framePreferences->SetupPointers(&ReloadAccounts);
477 framePreferences->ShowModal();
478 delete framePreferences;
479 framePreferences = NULL;
481 if (ReloadAccounts == TRUE){
483 // Reload the accounts as a change has been made within
484 // the application and clear the current contact information.
486 this->LoadPreferences();
487 this->ResetContactInfo();
493 void frmMain::OpenNewABDialog( wxCommandEvent& event)
496 // Open the new account dialog.
498 ReloadAccounts = FALSE;
500 frmNewAccount *frameNewAccount = new frmNewAccount ( this );
501 frameNewAccount->SetupPointers(&ReloadAccounts);
502 frameNewAccount->ShowModal();
503 delete frameNewAccount;
504 frameNewAccount = NULL;
506 if (ReloadAccounts == TRUE){
508 // Reload the accounts as a change has been made within
511 this->LoadPreferences();
517 void frmMain::LoadContactList( wxTreeEvent& event )
520 // Load the contact list.
522 // Clear all existing variables.
524 lstContacts->DeleteAllItems();
526 treAccounts->SetAccount();
528 wxTreeItemIdValue cookie;
529 wxTreeItemId next = treAccounts->GetRootItem();
530 wxString AccountName;
531 wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
532 wxString AccountDirCmb;
533 long selectedaccount = 0;
535 wxTreeItemId selectedChild = treAccounts->GetSelection();
536 wxTreeItemId nextChild;
538 wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
539 int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
541 int SCImg = treAccounts->GetItemImage(selectedChild);
542 int AccountIndex = 0;
544 bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
546 // Process each account.
548 for (int i = 0; i < prefaccounts.GetCount(); i++){
550 if (ActiveItemIcon == 2){
552 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
553 std::multimap<int, int>::iterator AGLiter = AccountGroupList.find(AGTiter->second);
554 int ActiveAccountG = AGLiter->second;
556 if (i == ActiveAccountG){
558 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
559 AccountType.Append(prefaccounts.GetAccountType(i));
564 if (AccountType == wxT("CardDAV")){
565 AccountTypeFinal.Append(wxT("carddav"));
566 } else if (AccountType == wxT("Local")){
567 imgSSLStatus->SetBitmap(*imgOffline);
568 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
569 AccountTypeFinal.Append(wxT("local"));
571 imgSSLStatus->SetBitmap(*imgOffline);
572 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
573 AccountTypeFinal.Append(AccountType.Lower());
584 nextChild = treAccounts->GetFirstChild(next, cookie);
586 nextChild = treAccounts->GetNextSibling(nextChild);
589 AccountName = treAccounts->GetItemText(nextChild);
591 if (nextChild == selectedChild){
593 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
594 AccountType.Append(prefaccounts.GetAccountType(i));
599 if (AccountType == wxT("CardDAV")){
600 AccountTypeFinal.Append(wxT("carddav"));
601 } else if (AccountType == wxT("Local")){
602 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
603 AccountTypeFinal.Append(wxT("local"));
605 AccountTypeFinal.Append(AccountType.Lower());
614 if (selectedaccount >= prefaccounts.GetCount()){
616 // The account selected isn't there so return.
624 // Open the directory and get the list of .vcf files
625 // in that directory.
627 ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
628 ActiveAccountType = AccountType;
630 SetupSSLStatus(AccountIndex);
632 AccountDirFinal.Clear();
633 AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
635 ContactsFileIndex.Clear();
637 wxString vCardFilename;
638 wxString vCardFilenameFull;
639 wxString vCardDataString;
640 wxStringTokenizer vcardfileline;
642 wxString setname, setvalue;
643 std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
644 std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
645 long ContactIndex = 1;
646 long ContactSeekPoint = 0;
648 wxDir vcardaccdir(AccountDirFinal);
650 // Get the wxTreeItemId and image icon and compare it to the list.
652 if (ActiveItemIcon == AccountGrpID){
654 // It's a group so load the file containing the group and
655 // get the members of the group.
660 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
661 std::multimap<int, wxString>::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
663 Group.LoadFile(AGFiter->second);
665 ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
667 for (int i = 0; i < vCardMember.PropCount; i++){
669 vCardMember.PropValues[i].Trim();
670 if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
672 wxString NewPropValue;
673 NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
674 vCardMember.PropValues[i] = NewPropValue;
680 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
684 if (vCardFilename.Right(4) == wxT(".vcf") ||
685 vCardFilename.Right(4) == wxT(".VCF") ||
686 vCardFilename.Right(5) == wxT(".vcard") ||
687 vCardFilename.Right(5) == wxT(".VCARD")){
690 bool FoundMember = FALSE;
692 vCardFilenameFull.Append(AccountDirFinal);
693 vCardFilenameFull.Append(wxT("/"));
694 vCardFilenameFull.Append(vCardFilename);
696 Person.LoadFile(vCardFilenameFull);
698 UIDCode = Person.Get(wxT("UID"));
700 for (int i = 0; i < vCardMember.PropCount; i++){
702 if (vCardMember.PropValues[i] == UIDCode){
710 if (FoundMember == FALSE){
712 vCardFilename.Clear();
713 vCardFilenameFull.Clear();
714 vCardDataString.Clear();
715 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
720 if (Person.MeetBaseSpecification()){
724 // Split the name into sections.
726 vCardDataString = Person.Get(wxT("N"));
728 vCardName NameData = Person.GetName();
730 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
732 } else if (SortMode == 2){
734 // Split the name into sections.
736 vCardName NameData = Person.GetName();
738 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
740 } else if (SortMode == 3){
742 // Check and make sure that the top most nickname is used.
744 vCardDataString = Person.Get(wxT("NICKNAME"));
746 if (vCardDataString.IsEmpty()){
748 vCardDataString = wxT("(no nickname)");
752 } else if (SortMode == 4){
754 vCardDataString = Person.Get(wxT("FN"));
758 if (AscendingMode == TRUE){
759 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
761 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
768 vCardFilename.Clear();
769 vCardFilenameFull.Clear();
770 vCardDataString.Clear();
771 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
777 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
780 if (vCardFilename.Right(4) == wxT(".vcf") ||
781 vCardFilename.Right(4) == wxT(".VCF") ||
782 vCardFilename.Right(5) == wxT(".vcard") ||
783 vCardFilename.Right(5) == wxT(".VCARD")){
787 vCardFilenameFull.Append(AccountDirFinal);
788 vCardFilenameFull.Append(vCardFilename);
790 Person.LoadFile(vCardFilenameFull);
792 if (Person.MeetBaseSpecification()){
796 // Split the name into sections.
798 vCardDataString = Person.Get(wxT("N"));
800 vCardName NameData = Person.GetName();
802 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
804 } else if (SortMode == 2){
806 // Split the name into sections.
808 vCardName NameData = Person.GetName();
810 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
812 } else if (SortMode == 3){
814 // Check and make sure that the top most nickname is used.
816 vCardDataString = Person.Get(wxT("NICKNAME"));
818 if (vCardDataString.IsEmpty()){
820 vCardDataString = wxT("(no nickname)");
824 } else if (SortMode == 4){
826 vCardDataString = Person.Get(wxT("FN"));
830 if (AscendingMode == TRUE){
832 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
836 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
844 vCardFilename.Clear();
845 vCardFilenameFull.Clear();
846 vCardDataString.Clear();
847 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
854 // Insert the data into the control.
856 if (AscendingMode == TRUE){
857 for (std::map<wxString, wxString>::iterator iter = vCardNamesAsc.begin();
858 iter != vCardNamesAsc.end(); ++iter){
860 wxListItem ContactInfo;
862 ContactInfo.SetId(0);
863 ContactInfo.SetText(_("Mooo"));
864 ContactInfo.SetData(ContactSeekPoint);
865 ContactIndex = lstContacts->InsertItem(ContactInfo);
867 lstContacts->SetItem(ContactIndex, 0, iter->first);
869 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
876 for (std::map<wxString, wxString>::iterator iter = vCardNamesDsc.begin();
877 iter != vCardNamesDsc.end(); ++iter){
879 wxListItem ContactInfo;
881 ContactInfo.SetId(0);
882 ContactInfo.SetText(_("Mooo"));
883 ContactInfo.SetData(ContactSeekPoint);
884 ContactIndex = lstContacts->InsertItem(ContactInfo);
886 lstContacts->SetItem(ContactIndex, 0, iter->first);
887 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
896 void frmMain::ShowContactInfo( wxListEvent& event )
899 // Display the contact information.
901 long intSelected = -1;
902 long ContactSeekNum = -1;
904 // Check if several contacts have been selected.
906 int ContactTotal = 0;
910 intSelected = lstContacts->GetNextItem(intSelected,
912 wxLIST_STATE_SELECTED);
914 if (intSelected == -1){
924 if (ContactTotal == 0){
925 htmContactData->SetPage(wxT(""));
929 if (ContactTotal > 1){
931 htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
932 ActiveFilename.Clear();
937 intSelected = lstContacts->GetNextItem(intSelected,
939 wxLIST_STATE_SELECTED);
941 ContactSeekNum = lstContacts->GetItemData(intSelected);
944 wxString wxSContactString;
945 wxString ContactLine;
948 size_t ContactLineLen;
949 bool ExtraLineSeek = FALSE;
950 int QuoteBreakPoint = 0;
952 bool PropertyFind = FALSE;
953 bool QuoteMode = FALSE;
955 wxString wxSPropertyNextLine;
956 wxString wxSProperty;
957 wxString wxSPropertySeg1;
958 wxString wxSPropertySeg2;
960 // Check if we are using wxWidgets version 2.8 or less and
961 // execute the required command accordingly.
963 #if wxABI_VERSION < 20900
964 ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
966 ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
969 if (ContactFile.IsOpened() == FALSE){
975 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
979 std::map<int, wxString> ContactFileLines;
980 std::map<int, wxString>::iterator striter;
982 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
984 int ContactLineSeek = 0;
986 while (wSTContactFileLines.HasMoreTokens() == TRUE){
988 ContactLine = wSTContactFileLines.GetNextToken();
989 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
994 if (ContactSeekNum < 0){
998 for (std::map<int, wxString>::iterator iter = ContactFileLines.begin();
999 iter != ContactFileLines.end(); ++iter){
1001 // Find the colon which splits the start bit from the data part.
1003 ContactLine = iter->second;
1005 while (ExtraLineSeek == TRUE){
1007 // Check if there is extra data on the next line
1008 // (indicated by space or tab at the start) and add data.
1012 if (iter == ContactFileLines.end()){
1019 wxSPropertyNextLine = iter->second;
1022 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1024 wxSPropertyNextLine.Remove(0, 1);
1025 ContactLine.Append(wxSPropertyNextLine);
1030 ExtraLineSeek = FALSE;
1036 ContactLineLen = ContactLine.Len();
1038 // Make sure we are not in quotation mode.
1039 // Make sure colon does not have \ or \\ before it.
1041 for (int i = 0; i <= ContactLineLen; i++){
1043 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1045 PropertyFind = FALSE;
1047 } else if (PropertyFind == TRUE){
1049 wxSProperty.Append(ContactLine.Mid(i, 1));
1053 if (ContactLine.Mid(i, 1) == wxT("\"")){
1055 if (QuoteMode == TRUE){
1067 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1069 QuoteBreakPoint = i;
1076 // Split that line at the point into two variables (ignore the colon).
1078 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1079 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1081 // Insert both into the vCard data file.
1083 Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
1086 PropertyFind = TRUE;
1087 ExtraLineSeek = TRUE;
1089 QuoteBreakPoint = 0;
1090 ContactLine.Clear();
1091 wxSProperty.Clear();
1095 OldSessionID = SessionID;
1096 SessionID = wxString::Format(wxT("%i"), rand() % 32768);
1097 LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList);
1098 ActiveFilename = ContactsFileIndex[ContactSeekNum];
1102 void frmMain::ShowContactEditorNew( wxCommandEvent& event )
1105 // Open a contact editor window to write a new contact with.
1107 // Check if there is an account selected and if not
1108 // return immediately.
1110 if (ActiveAccount.IsEmpty()){
1116 // Check if the account type is a valid account type, otherwise
1117 // display an error message.
1119 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1120 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1122 wxMessageBox(_("Cannot add a new contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1127 // Add Pointer to SetupPointers for the ETagDB.
1129 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1130 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1131 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1133 contacticon.CopyFromBitmap(contacticonbmp);
1135 frmContactEditor *ContactEditor = new frmContactEditor( this );
1139 ContactEditor->SetUID(WindowMenuItemID);
1141 WindowData *WData = new WindowData;
1143 WData->DataType = 1;
1144 WData->WindowPointer = (void*)ContactEditor;
1145 WData->WindowID = WindowMenuItemID;
1147 wxCommandEvent addevent(WINDOW_ADD);
1148 addevent.SetClientData(WData);
1149 wxPostEvent(this, addevent);
1151 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1152 ContactEditor->SetupHeaders();
1153 ContactEditor->SetupContact(ActiveAccount);
1154 ContactEditor->SetIcon(contacticon);
1155 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1156 ContactEditor->Show(true);
1160 void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
1163 // Open a contact editor window for editing an existing contact
1166 // Check if there is an account selected and if not
1167 // return immediately.
1169 int DataCheck = event.GetInt();
1171 if (ActiveAccount.IsEmpty() && DataCheck == 0){
1177 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1178 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1179 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1181 contacticon.CopyFromBitmap(contacticonbmp);
1183 // Check if a contact has been selected.
1185 long intSelected = -1;
1186 long intContactSeekNum = -1;
1188 intSelected = lstContacts->GetNextItem(intSelected,
1190 wxLIST_STATE_SELECTED);
1192 if (intSelected == -1){
1198 intContactSeekNum = lstContacts->GetItemData(intSelected);
1200 // Get the filename of the selected contact.
1202 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1203 frmContactEditor *ContactEditor = new frmContactEditor( this );
1207 ContactEditor->SetUID(WindowMenuItemID);
1209 WindowData *WData = new WindowData;
1211 WData->DataType = 1;
1212 WData->WindowPointer = (void*)ContactEditor;
1213 WData->WindowID = WindowMenuItemID;
1215 wxCommandEvent addevent(WINDOW_ADD);
1216 addevent.SetClientData(WData);
1217 wxPostEvent(this, addevent);
1219 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1220 ContactEditor->SetupHeaders();
1222 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1223 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1225 ContactEditor->SetupAccountData(true);
1229 // Check if pointer is NULL (not from the search forms) or not.
1231 if (DataCheck == 0){
1233 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1234 ContactEditor->SetupContact(ActiveAccount);
1238 UCNotif *uc = (UCNotif*)event.GetClientData();
1242 ContactEditor->SetupContact(ActiveAccount);
1243 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1247 ContactEditor->SetupContact(uc->ContactAccount);
1248 ContactEditor->LoadContact(uc->ContactFilename);
1257 ContactEditor->SetIcon(contacticon);
1258 ContactEditor->Show(true);
1262 void frmMain::RefreshAddressBook( wxCommandEvent& event ){
1264 // Refresh the address book data.
1266 // Check if ActiveAccount is empty. If not then check if
1267 // account type is not local otherwise continue.
1269 if (!ActiveAccount.IsEmpty()){
1271 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
1273 // Account type is not local.
1275 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1276 frameActMgr->AddTask(3, wxT(""), ActiveAccount,
1277 wxT(""), wxT(""), wxT(""), wxT(""));
1281 wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported"), wxICON_ERROR);
1289 void frmMain::OpenContactInfoList( wxListEvent& event )
1292 // Open the contact information window.
1294 wxStringTokenizer vcardfileline;
1297 wxString setname, setvalue;
1301 long intSelected = -1;
1302 long intContactSeekNum = -1;
1304 intSelected = lstContacts->GetNextItem(intSelected,
1306 wxLIST_STATE_SELECTED);
1308 intContactSeekNum = lstContacts->GetItemData(intSelected);
1310 if (intContactSeekNum == -1){
1316 Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
1318 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1319 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1320 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1322 contacticon.CopyFromBitmap(contacticonbmp);
1324 frmContact *Contact = new frmContact( this );
1326 // Add to window list.
1330 Contact->SetUID(WindowMenuItemID);
1332 WindowData *WData = new WindowData;
1334 WData->DataType = 0;
1335 WData->WindowPointer = (void*)Contact;
1336 WData->WindowID = WindowMenuItemID;
1338 wxCommandEvent addevent(WINDOW_ADD);
1339 addevent.SetClientData(WData);
1340 wxPostEvent(this, addevent);
1342 Contact->SetupPointers(&MemoryFileList);
1343 Contact->SetupContactData(&Person);
1345 Contact->SetIcon(contacticon);
1346 Contact->Show(true);
1350 void frmMain::OpenContactInfoList( wxCommandEvent& event ){
1352 // Open a list of contact information windows.
1355 OpenContactInfoList(pevent);
1359 void frmMain::OpenContactInfo( wxCommandEvent& event )
1362 // Open the contact information window.
1364 UCNotif *uc = (UCNotif*)event.GetClientData();
1366 wxStringTokenizer vcardfileline;
1369 wxString setname, setvalue;
1373 Person.LoadFile(uc->ContactFilename);
1375 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1376 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1377 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1379 contacticon.CopyFromBitmap(contacticonbmp);
1381 frmContact *Contact = new frmContact( this );
1383 // Add to window list.
1387 Contact->SetUID(WindowMenuItemID);
1389 WindowData *WData = new WindowData;
1391 WData->DataType = 0;
1392 WData->WindowPointer = (void*)Contact;
1393 WData->WindowID = WindowMenuItemID;
1395 wxCommandEvent addevent(WINDOW_ADD);
1396 addevent.SetClientData(WData);
1397 wxPostEvent(this, addevent);
1399 Contact->SetupPointers(&MemoryFileList);
1400 Contact->SetupContactData(&Person);
1402 Contact->SetIcon(contacticon);
1403 Contact->Show(true);
1408 void frmMain::LoadPreferences( wxActivateEvent& event)
1411 // Load the preferences.
1413 this->LoadPreferences();
1417 void frmMain::LoadPreferences(){
1419 // Load the preferences.
1421 wxString preffilename = GetUserPrefDir();
1423 XABPreferences preferences(preffilename);
1425 // Setup the main window position (if needed).
1427 bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
1428 bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
1430 if (SaveWindowPos == TRUE){
1432 this->SetSize(preferences.GetMainWindowData());
1436 treAccounts->DeleteAllItems();
1438 wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
1440 // Stop all account timers and remove the accounts.
1442 for (std::map<wxString, wxAccountSyncTimer*>::iterator iter = AccountSyncTimers.begin();
1443 iter != AccountSyncTimers.end(); iter++){
1445 wxAccountSyncTimer *AccTmrPtr = iter->second;
1453 #if defined(__WIN32__)
1455 for (std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.begin();
1456 CertificateIter != AccountCertificateData.end(); CertificateIter++){
1458 CertFreeCertificateContext(CertificateIter->second);
1462 AccountCertificateData.clear();
1466 AccountSyncTimers.clear();
1469 wxString AccDirFull;
1470 wxString AccDirFullSfx;
1472 wxString AccDirFinal;
1473 AccountAccDirList.clear();
1474 AccountGroupList.clear();
1475 AccountGroupFilename.clear();
1476 AccountGroupTreeId.clear();
1477 wxTreeItemId AccountTreeId;
1478 wxTreeItemId GroupTreeId;
1481 // Relaod the accounts for the ETagProcTimer.
1483 ETagProcTimer.ReloadAccounts();
1485 for (int i = 0; i < preferences.accounts.GetCount(); i++){
1487 if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
1488 preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == TRUE){
1494 if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
1500 AccDir = preferences.accounts.GetAccountDirectory(i);
1501 AccDirFull = preferences.accounts.GetAccountDirectory(i);
1503 AccDirFull.Append(wxT("."));
1504 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
1505 AccDirFullSfx.LowerCase();
1506 AccDirFullSfx.Trim();
1507 AccDirFull.Append(AccDirFullSfx);
1508 AccName = preferences.accounts.GetAccountName(i);
1510 AccountAccDirList.insert(std::make_pair(i, AccDirFull));
1512 if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
1513 preferences.accounts.GetAccountType(i) == wxT("carddav")){
1515 // TODO: Check if the directory exists before doing anything.
1519 // Add a new timer using the existing account details.
1521 wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
1523 ActTmrPtr->SetupData(AccDirFull, AccName);
1524 ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
1525 ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
1526 ActTmrPtr->SetOwner(this);
1527 ActTmrPtr->Notify();
1529 // Add the timer to the list of timers.
1531 AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
1533 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
1535 } else if (preferences.accounts.GetAccountType(i) == wxT("Local") ||
1536 preferences.accounts.GetAccountType(i) == wxT("local")) {
1538 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
1542 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountUnsupportedID, -1);
1546 // Go through the account directory and find contact files with
1547 // 'KIND:group' set and add them to the list of groups for the account.
1549 AccDirFinal = GetAccountDir(AccDirFull, FALSE);
1551 wxDir vcardaccdir(AccDirFinal);
1553 wxString vCardFilename;
1554 wxString vCardDataString;
1555 wxString vCardFilenameFull;
1557 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1561 if (vCardFilename.Right(4) == wxT(".vcf") ||
1562 vCardFilename.Right(4) == wxT(".VCF") ||
1563 vCardFilename.Right(5) == wxT(".vcard") ||
1564 vCardFilename.Right(5) == wxT(".VCARD")){
1568 vCardFilenameFull.Append(AccDirFinal);
1569 vCardFilenameFull.Append(wxT("/"));
1570 vCardFilenameFull.Append(vCardFilename);
1572 Person.LoadFile(vCardFilenameFull);
1574 if (Person.MeetBaseSpecification()){
1576 vCardDataString = Person.Get(wxT("KIND"));
1578 if (vCardDataString == wxT("group")){
1580 // The vCard kind is a group. Add to the account's group list.
1582 GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
1583 treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
1584 AccountGroupList.insert(std::make_pair(intGroupID, i));
1585 AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
1586 AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
1596 vCardFilename.Clear();
1597 vCardFilenameFull.Clear();
1598 vCardDataString.Clear();
1599 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1603 // Clearup for next account.
1607 AccDirFullSfx.clear();
1608 AccDirFinal.clear();
1613 // Load the account settings as they are needed for connecting
1616 prefaccounts = preferences.accounts;
1620 void frmMain::ConflictResolution(wxCommandEvent& event){
1622 // Display the conflict resolution window.
1624 frmConflictResolution *frameCR = new frmConflictResolution ( this );
1625 vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
1626 vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
1627 vCard *ServerDataPtr = vCardConfObj->vCardServerData;
1628 frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList);
1629 frameCR->ShowModal();
1631 int FinalConflictResult = frameCR->GetResult();
1633 wxCommandEvent event2(ACTMGR_RESUMEPROC);
1634 event2.SetClientData(vCardConfObj->QRNotifData);
1635 event2.SetInt(FinalConflictResult);
1640 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1641 wxPostEvent(frameActMgr, event2);
1645 void frmMain::UpdateContactList(wxCommandEvent& event){
1647 // Update the contact list in the main window.
1649 UCNotif *ucd = (UCNotif*)event.GetClientData();
1651 // Check if the active account is being displayed in the
1652 // main window. If not, skip and delete the data.
1654 long longSelected = -1;
1655 int intSelectedData = 0;
1657 if (ActiveAccount == ucd->ContactAccount){
1659 // Look at the list of contacts and if it matches the
1660 // filename then update the name.
1664 longSelected = lstContacts->GetNextItem(longSelected,
1666 wxLIST_STATE_DONTCARE);
1668 if (longSelected == -1){
1674 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1676 if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
1678 // Work out which sorting mode we are in.
1682 // First Name, Last Name.
1684 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
1686 } else if (SortMode == 2){
1688 // Last Name, First Name.
1690 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
1692 } else if (SortMode == 3){
1696 lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
1698 } else if (SortMode == 4){
1702 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1709 // If the filename is the one loaded into the
1710 // browser control, then update this too.
1712 if (ActiveFilename == ContactsFileIndex[intSelectedData]){
1714 wxListEvent nullevent;
1715 ShowContactInfo(nullevent);
1723 for (std::map<int, void*>::iterator WindowIter = WindowListPointers.begin();
1724 WindowIter != WindowListPointers.end(); WindowIter++){
1726 if (WindowListType[WindowIter->first] != 0){
1732 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
1734 if (frmContactPtr->GetFilename() == ucd->ContactFilename){
1736 vCard UpdatedPerson;
1737 UpdatedPerson.LoadFile(ucd->ContactFilename);
1738 frmContactPtr->SetupContactData(&UpdatedPerson);
1744 // Send message to search window controller subroutine and
1745 // pass that notification onto the search windows.
1747 // Setup the new pointer to use the existing UCNotif without
1750 UCNotif *ucd2 = ucd;
1752 wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
1753 sup.SetClientData(ucd2);
1754 wxPostEvent(this, sup);
1756 // Clear up the unused pointer.
1762 void frmMain::UpdateAccountList(wxCommandEvent& event){
1764 // Update the account list (currently unimplemented).
1768 void frmMain::SetupPointers(void *ActMgrPtrInc){
1770 // Setup the pointers for the main window.
1772 ActMgrPtr = ActMgrPtrInc;
1776 void frmMain::SetupForm(){
1778 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1779 frameActMgr->SetupPointers(&ETagProcTimer, this);
1781 // Setup the contact information icons for later.
1783 wxFileSystem::AddHandler(new wxMemoryFSHandler);
1787 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
1788 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
1789 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1791 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
1792 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
1793 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1795 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
1796 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
1797 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1799 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
1800 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
1801 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1803 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
1804 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
1805 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1807 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
1808 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
1809 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1815 void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
1817 // Update the contact lists in the search windows.
1819 // Go through each of the search windows and
1820 // send the required notification to update the
1821 // contact information.
1823 // Get the event notification data.
1825 UCNotif *ucd = (UCNotif*)event.GetClientData();
1827 // Process each search window giving the new details.
1829 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1830 switer != SearchWindowList.end(); switer++){
1832 // Duplicate the event notification data.
1834 UCNotif *ucd2 = new UCNotif;
1836 ucd2->ContactAccount = ucd->ContactAccount;
1837 ucd2->ContactFilename = ucd->ContactFilename;
1838 ucd2->ContactName = ucd->ContactName;
1839 ucd2->ContactNickname = ucd->ContactNickname;
1840 ucd2->ContactNameArray = ucd->ContactNameArray;
1842 // Pass the data to the search window for processing.
1844 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
1845 wxCommandEvent schupdate(SE_UPDATERESULT);
1846 schupdate.SetClientData(ucd2);
1847 wxPostEvent(frameSCH, schupdate);
1849 // Clear up the pointer prior to variable deletion.
1860 void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
1862 // Open a new search window.
1866 frmSearch *frameSCH = new frmSearch ( this );
1867 frameSCH->SetUID(WindowMenuItemID);
1868 frameSCH->Show(true);
1870 WindowData *WData = new WindowData;
1872 WData->DataType = 2;
1873 WData->WindowPointer = (void*)frameSCH;
1874 WData->WindowID = WindowMenuItemID;
1876 wxCommandEvent addevent(WINDOW_ADD);
1877 addevent.SetClientData(WData);
1878 wxPostEvent(this, addevent);
1880 // Add pointer to the list of open search windows.
1882 SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
1888 void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
1890 // Remove the pointer for a contact window from the
1893 void *frameSCH = (void*)event.GetClientData();
1895 SearchWindowList.erase(frameSCH);
1901 void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
1903 // Remove the pointer for a contact editor window from
1906 void *frameSCH = (void*)event.GetClientData();
1908 SearchWindowList.erase(frameSCH);
1914 void frmMain::RevealContact(wxCommandEvent& event){
1916 // Reveal a contact in the main window.
1918 UCNotif *uc = (UCNotif*)event.GetClientData();
1920 // Switch the account to the one passed.
1922 wxTreeItemIdValue cookie;
1923 wxTreeItemId next = treAccounts->GetRootItem();
1924 wxTreeItemId nextChild;
1926 for (int i = 0; i < prefaccounts.GetCount(); i++){
1929 nextChild = treAccounts->GetFirstChild(next, cookie);
1931 nextChild = treAccounts->GetNextSibling(nextChild);
1934 if (uc->ContactAccount == AccountAccDirList[i]){
1936 treAccounts->SelectItem(nextChild, TRUE);
1937 AccCtrl->SetText(treAccounts->GetItemText(nextChild));
1943 // Switch the contact to the one passed.
1945 long longSelected = -1;
1946 int intSelectedData = 0;
1950 longSelected = lstContacts->GetNextItem(longSelected,
1952 wxLIST_STATE_DONTCARE);
1954 if (longSelected == -1){
1960 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1962 // Compare the filename with the one received.
1963 // If they match then select it.
1965 if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
1969 lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1970 lstContacts->EnsureVisible(longSelected);
1974 lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
1982 void frmMain::DeleteContact(wxCommandEvent& event){
1984 // Delete a contact from the main window.
1986 // Check if a contact is selected.
1988 long intSelected = -1;
1989 long intContactSeekNum = -1;
1990 wxString wxSContactName;
1992 intSelected = lstContacts->GetNextItem(intSelected,
1994 wxLIST_STATE_SELECTED);
1996 if (intSelected == -1){
2000 // Check if the account type is a valid account type, otherwise
2001 // display an error message.
2003 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
2004 ActiveAccountType != "Local" && ActiveAccountType != "local"){
2006 wxMessageBox(_("Cannot delete contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
2011 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2013 // Get the item data of the contact.
2015 intContactSeekNum = lstContacts->GetItemData(intSelected);
2017 // Get the name of the contact.
2019 wxSContactName = lstContacts->GetItemText(intSelected);
2021 // Display a message confirming if the contact should
2024 int QuestionResponse;
2026 QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
2028 if (QuestionResponse == wxNO){
2030 // Exit the subroutine
2036 // Delete the contact.
2038 if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
2040 wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
2045 // Remove the contact from the list.
2047 lstContacts->DeleteItem(intSelected);
2049 // Update the search windows, removing the deleted
2052 UCNotif *ucd = new UCNotif;
2054 ucd->ContactAccount = ActiveAccount;
2055 ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
2057 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
2058 switer != SearchWindowList.end(); switer++){
2060 // Duplicate the event notification data.
2062 UCNotif *ucd2 = new UCNotif;
2064 ucd2->ContactAccount = ucd->ContactAccount;
2065 ucd2->ContactFilename = ucd->ContactFilename;
2067 // Pass the data to the search window for processing.
2069 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
2070 wxCommandEvent schdelete(SE_DELETERESULT);
2071 schdelete.SetClientData(ucd2);
2072 wxPostEvent(frameSCH, schdelete);
2074 // Clear up the pointer prior to variable deletion.
2081 // Clear the wxHTMLWindow.
2083 wxString EmptyPage = wxT("");
2085 htmContactData->SetPage(EmptyPage);
2087 wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
2089 wxString wxSplitFilename;
2090 wxString wxSDataURL;
2092 while(wSTFilename.HasMoreTokens()){
2094 wxSplitFilename = wSTFilename.GetNextToken();
2098 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
2100 // Update the ETagDB and mark it as deleted.
2102 ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
2104 ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
2106 // Get the Data URL.
2108 wxTreeItemIdValue cookie;
2109 wxTreeItemId next = treAccounts->GetRootItem();
2111 wxTreeItemId selectedChild = treAccounts->GetSelection();
2112 wxTreeItemId nextChild;
2114 for (int i = 0; i < prefaccounts.GetCount(); i++){
2117 nextChild = treAccounts->GetFirstChild(next, cookie);
2119 nextChild = treAccounts->GetNextSibling(nextChild);
2122 if (nextChild == selectedChild){
2124 wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
2130 // Add task to the activity monitor to delete the contact.
2132 frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
2136 // Clear the variable. Don't delete as it will mess things up.
2138 ContactsFileIndex[intContactSeekNum] = wxT("");
2145 void frmMain::EmptyServerDialog(wxCommandEvent& event){
2147 // Display this message when the server information has changed
2150 QRNotif *qrn = (QRNotif *)event.GetClientData();
2152 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);
2154 if (QResponse == wxNO){
2160 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2161 event2.SetInt(*qrn->QResponse);
2162 event2.SetClientData(qrn->PausePtr);
2164 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2166 wxPostEvent(frameActMgr, event2);
2170 void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
2172 // Remove the contact from the window after syncronising.
2174 // Check which account is currently active in the window.
2175 // If it is different from the one passed to this subroutine then
2176 // exit from the subroutine.
2178 if (Account != ActiveAccount){
2182 long longSelected = -1;
2183 int intSelectedData = 0;
2187 longSelected = lstContacts->GetNextItem(longSelected,
2189 wxLIST_STATE_DONTCARE);
2191 if (longSelected == -1){
2197 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2199 // Compare the filename with the one received.
2200 // If they match then select it.
2202 if (ContactsFileIndex[intSelectedData] == Filename){
2204 // Remove the contact from the window.
2206 lstContacts->DeleteItem(intSelectedData);
2208 // Check if contact is the selected contact in the HTML window and
2209 // if it is then clear the window.
2211 if (ActiveFilename == Filename){
2213 wxString EmptyPage = wxT("");
2214 htmContactData->SetPage(EmptyPage);
2228 void frmMain::SortFNLN( wxCommandEvent& event ) {
2230 // Sort first name then last name.
2232 wxTreeEvent NullEvent;
2234 LoadContactList(NullEvent);
2238 void frmMain::SortLNFN( wxCommandEvent& event ) {
2240 // Sort last name then first name.
2242 wxTreeEvent NullEvent;
2244 LoadContactList(NullEvent);
2248 void frmMain::SortNickname( wxCommandEvent& event ) {
2250 // Sort by nickname.
2252 wxTreeEvent NullEvent;
2254 LoadContactList(NullEvent);
2258 void frmMain::SortDisplayAs( wxCommandEvent& event ) {
2260 // Sort by Display As name.
2262 wxTreeEvent NullEvent;
2264 LoadContactList(NullEvent);
2268 void frmMain::SortAscending( wxCommandEvent& event ) {
2272 wxTreeEvent NullEvent;
2273 AscendingMode = TRUE;
2274 LoadContactList(NullEvent);
2278 void frmMain::SortDescending( wxCommandEvent& event ) {
2282 wxTreeEvent NullEvent;
2283 AscendingMode = FALSE;
2284 LoadContactList(NullEvent);
2288 void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
2290 // Toggle the appearance of the status bar.
2292 if (stbBottom->IsShown() == TRUE){
2306 void frmMain::ActivityIconStart( wxCommandEvent& event ){
2308 // Display the activity icon.
2310 imgActivityStatus->SetBitmap(*imgActIcon1);
2311 ActivityIconStatus = 0;
2315 void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
2317 // Shuffle through the activity icons.
2319 switch (ActivityIconStatus){
2322 imgActivityStatus->SetBitmap(*imgActIcon1);
2323 ActivityIconStatus = 1;
2326 imgActivityStatus->SetBitmap(*imgActIcon2);
2327 ActivityIconStatus = 2;
2330 imgActivityStatus->SetBitmap(*imgActIcon3);
2331 ActivityIconStatus = 3;
2334 imgActivityStatus->SetBitmap(*imgActIcon4);
2335 ActivityIconStatus = 0;
2338 ActivityIconStatus = 0;
2344 void frmMain::ActivityIconStop( wxCommandEvent& event ){
2346 // Display the sleep icon.
2348 imgActivityStatus->SetBitmap(*imgActIconSleep);
2352 void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
2354 // Set the placement of the status bar icons.
2356 if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
2364 wxRect rectActivity;
2365 stbBottom->GetFieldRect(1, rectOnline);
2366 stbBottom->GetFieldRect(2, rectSSL);
2367 stbBottom->GetFieldRect(3, rectActivity);
2369 imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
2370 imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
2371 imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
2375 XABViewMode frmMain::GetViewMode(){
2377 // Set the view mode of the contact list.
2381 xvm.SortMode = SortMode;
2382 xvm.AscendingMode = AscendingMode;
2388 void frmMain::WindowAdd( wxCommandEvent &event ){
2390 // Add a window to the window list.
2392 WindowData *WData = (WindowData*)event.GetClientData();
2396 if (WData->DataType == 0){
2400 int intID = mnuContactWindows->GetId();
2402 mnuWindow->FindChildItem(intID, &pos);
2403 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2404 mnuNewItem->SetId(WData->WindowID);
2405 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2406 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2407 WindowListType.insert(std::make_pair(WData->WindowID, 0));
2408 mnuWindow->Insert((pos + 1), mnuNewItem);
2409 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
2411 } else if (WData->DataType == 1){
2413 // Contact Editor Window
2415 int intID = mnuContactEditorWindows->GetId();
2417 mnuWindow->FindChildItem(intID, &pos);
2418 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2419 mnuNewItem->SetId(WData->WindowID);
2420 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2421 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2422 WindowListType.insert(std::make_pair(WData->WindowID, 1));
2423 mnuWindow->Insert((pos + 1), mnuNewItem);
2424 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
2426 } else if (WData->DataType == 2){
2430 int intID = mnuSearchWindows->GetId();
2432 mnuWindow->FindChildItem(intID, &pos);
2433 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2434 mnuNewItem->SetId(WData->WindowID);
2435 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2436 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2437 WindowListType.insert(std::make_pair(WData->WindowID, 2));
2438 mnuWindow->Insert((pos + 1), mnuNewItem);
2439 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
2448 void frmMain::WindowEdit( wxCommandEvent &event ){
2450 // Edit a window in the window list.
2452 WindowData *WData = (WindowData*)event.GetClientData();
2454 if (WData->DataType == 0){
2456 // Get the window title and use that.
2458 frmContact *frmContactPtr = static_cast<frmContact*>(WData->WindowPointer);
2460 wxString WindowTitle = frmContactPtr->GetTitle();
2462 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2464 MenuIter->second->SetItemLabel(WindowTitle);
2466 } else if (WData->DataType == 1){
2468 // Get the window title and use that.
2470 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WData->WindowPointer);
2472 wxString WindowTitle = frmCEPtr->GetTitle();
2474 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2476 if (WindowTitle.IsEmpty()){
2478 MenuIter->second->SetItemLabel(_("Unnamed Contact"));
2482 MenuIter->second->SetItemLabel(WindowTitle);
2493 void frmMain::WindowDelete( wxCommandEvent &event ){
2495 // Delete a window from the window list.
2497 WindowData *WData = (WindowData*)event.GetClientData();
2499 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2501 mnuWindow->Remove(MenuIter->second);
2503 delete MenuIter->second;
2504 MenuIter->second = NULL;
2506 WindowListPointersMenu.erase(WData->WindowID);
2507 WindowListPointers.erase(WData->WindowID);
2508 WindowListType.erase(WData->WindowID);
2515 void frmMain::ShowContactWindow( wxCommandEvent &event ){
2517 // Show a contact window from the window list.
2519 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2521 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
2523 frmContactPtr->Show();
2524 frmContactPtr->Raise();
2528 void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
2530 // Show a contact editor window from the window list.
2532 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2534 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WindowIter->second);
2541 void frmMain::ShowSearchWindow( wxCommandEvent &event ){
2543 // Show a search window from the window list.
2545 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2547 frmSearch *frmSearchPtr = static_cast<frmSearch*>(WindowIter->second);
2549 frmSearchPtr->Show();
2550 frmSearchPtr->Raise();
2554 void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
2556 // Toggle the online/offline connection status.
2558 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2559 wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
2560 wxPostEvent(frameActMgr, toggconn);
2564 void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
2566 // Check the account type before continuing.
2568 wxString SeekAccount;
2569 wxString AccTypeLower;
2573 #if defined(__APPLE__)
2575 std::map<int, SecTrustRef>::iterator SSLTrustIter;
2577 for (int i = 0; i < prefaccounts.GetCount(); i++){
2579 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2580 AccType.Append(prefaccounts.GetAccountType(i));
2581 AccountSSL = prefaccounts.GetAccountSSL(i);
2582 AccTypeLower = AccType.MakeLower();
2583 SeekAccount.Append(wxT("."));
2584 SeekAccount.Append(AccTypeLower);
2586 if (SeekAccount == ActiveAccount){
2588 if (AccTypeLower == wxT("local")){
2594 if (AccountSSL == false){
2600 SSLTrustIter = AccountTrustData.find(i);
2602 // Setup and display the form.
2604 DisplayCertificate(SSLTrustIter->second);
2608 SeekAccount.Clear();
2609 AccTypeLower.Clear();
2614 #elif defined(__WIN32__)
2616 std::map<int, PCCERT_CONTEXT>::iterator SSLCertificateIter;
2618 for (int i = 0; i < prefaccounts.GetCount(); i++){
2620 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2621 AccType.Append(prefaccounts.GetAccountType(i));
2622 AccountSSL = prefaccounts.GetAccountSSL(i);
2623 AccTypeLower = AccType.MakeLower();
2624 SeekAccount.Append(wxT("."));
2625 SeekAccount.Append(AccTypeLower);
2627 if (SeekAccount == ActiveAccount){
2629 if (AccTypeLower == wxT("local")){
2635 if (AccountSSL == false){
2641 SSLCertificateIter = AccountCertificateData.find(i);
2643 // Setup and display the form.
2645 if (SSLCertificateIter == AccountCertificateData.end() || SSLCertificateIter->second->pCertInfo == NULL){
2647 wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
2651 BOOL ModifiedCertificateData;
2652 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
2654 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
2655 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
2660 //DisplayCertificate(SSLTrustIter->second);
2664 SeekAccount.Clear();
2665 AccTypeLower.Clear();
2672 std::map<int, SSLCertCollection>::iterator SSLColIter;
2674 for (int i = 0; i < prefaccounts.GetCount(); i++){
2676 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2677 AccType.Append(prefaccounts.GetAccountType(i));
2678 AccountSSL = prefaccounts.GetAccountSSL(i);
2679 AccTypeLower = AccType.MakeLower();
2680 SeekAccount.Append(wxT("."));
2681 SeekAccount.Append(AccTypeLower);
2683 if (SeekAccount == ActiveAccount){
2685 if (AccTypeLower == wxT("local")){
2691 if (AccountSSL == false){
2697 SSLColIter = AccountSSLData.find(i);
2699 SSLCertCollection SSLCertInfo = SSLColIter->second;
2701 frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
2702 frameSSLCert->StartCertFrom(0);
2703 frameSSLCert->SetupCerts(SSLCertInfo);
2704 frameSSLCert->ShowModal();
2706 delete frameSSLCert;
2707 frameSSLCert = NULL;
2711 SeekAccount.Clear();
2712 AccTypeLower.Clear();
2721 void frmMain::ShowSSLInfo( wxCommandEvent &event ){
2723 // Check the account type before continuing.
2727 void frmMain::HideSSLInfo( wxCommandEvent &event ){
2729 // Check the account type before continuing.
2733 void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
2735 if (event.GetInt() == 0){
2737 imgConnStatus->SetBitmap(*imgOnline);
2741 imgConnStatus->SetBitmap(*imgOffline);
2747 void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
2749 // Display the form for showing an invalid SSL certificate.
2751 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2752 SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
2753 SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
2754 wxString AccountName = SSLICNObj->AccountName;
2755 frameISC->LoadData(SSLCCData, AccountName);
2756 frameISC->ShowModal();
2758 int FinalConflictResult = frameISC->GetResult();
2760 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2761 event2.SetClientData(SSLICNObj->QRNotifData);
2762 event2.SetInt(FinalConflictResult);
2767 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2768 wxPostEvent(frameActMgr, event2);
2772 void frmMain::PauseAllTimers(){
2774 // Pause all the account timers.
2776 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2777 ASTiter != AccountSyncTimers.end(); ASTiter++){
2779 ASTiter->second->Stop();
2785 void frmMain::ResumeAllTimers(){
2787 // Resume all the account timers.
2789 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2790 ASTiter != AccountSyncTimers.end(); ASTiter++){
2792 ASTiter->second->Start();
2798 #if defined(__APPLE__)
2800 #elif defined(__WIN32__)
2802 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
2804 // Delete existing data.
2806 std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.find(AccountID);
2808 if (CertificateIter != AccountCertificateData.end()){
2809 CertFreeCertificateContext(CertificateIter->second);
2812 AccountCertificateData.erase(AccountID);
2813 AccountSSLResult.erase(AccountID);
2817 AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
2818 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2824 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollection SSLCertInc){
2826 // Delete existing data.
2828 AccountSSLData.erase(AccountID);
2829 AccountSSLResult.erase(AccountID);
2833 AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
2834 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2840 void frmMain::SetupSSLStatus( int AccountID ){
2842 // Check if account ID given is
2843 // the active account and if not, do nothing.
2846 wxString AccTypeLower;
2848 AccType = prefaccounts.GetAccountType(AccountID);
2849 AccTypeLower = AccType.MakeLower();
2851 wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
2854 if (AccountIDName != ActiveAccount){
2860 // Check the account type is a supported account type.
2862 if (AccType != "CardDAV" && AccType != "carddav" &&
2863 AccType != "Local" && AccType != "local"){
2865 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2866 imgSSLStatus->SetBitmap(*imgNoSSL);
2871 // Check if the account has SSL enabled.
2873 bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
2875 if (SSLInUse == FALSE){
2877 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2878 imgSSLStatus->SetBitmap(*imgNoSSL);
2882 // Get the SSL Collection Data.
2884 std::map<int,int>::iterator SSLResultIter = AccountSSLResult.find(AccountID);
2886 // Check if a result value has been set.
2888 if (SSLResultIter == AccountSSLResult.end()){
2890 imgSSLStatus->SetBitmap(*imgSSLWarning);
2891 SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
2896 if (SSLResultIter->second == 1){
2898 imgSSLStatus->SetBitmap(*imgSSLWarning);
2899 SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
2900 prefaccounts.GetAccountName(AccountID) +
2901 wxT("' (Connection denied by user)\n\nDouble click for more information."));
2903 } else if (SSLResultIter->second == 0){
2905 imgSSLStatus->SetBitmap(*imgSSL);
2906 SSLToolTip->SetTip(wxT("Account '") +
2907 prefaccounts.GetAccountName(AccountID) +
2908 wxT("' secured using SSL\n\nDouble click for more information."));
2916 void frmMain::CheckUpdates( wxCommandEvent& event ){
2918 // Check for updates to Xestia Address Book.
2920 frmUpdate *frameUpdate = new frmUpdate ( this );
2921 frameUpdate->FetchData();
2922 frameUpdate->ShowModal();
2926 void frmMain::OpenImportDialog( wxCommandEvent& event ){
2928 // Run the import contacts function.
2934 void frmMain::OpenExportDialog( wxCommandEvent& event ){
2936 // Check if an account and at least one contact is selected
2937 // before continuing.
2939 wxArrayString ArrData;
2941 if (ActiveAccount.IsEmpty()){
2947 int ContactSelected = 0;
2948 int ContactsCollected = 0;
2949 long longSelected = -1;
2953 longSelected = lstContacts->GetNextItem(longSelected,
2955 wxLIST_STATE_SELECTED);
2957 if (longSelected == -1){
2963 int FileID = (int)lstContacts->GetItemData(longSelected);
2965 ArrData.Insert(ContactsFileIndex[FileID],
2966 ContactsCollected, 1);
2972 if (ContactSelected == 0){
2978 // Run the export contacts system.
2980 ExportRun(this, &ArrData);
2984 void frmMain::GetListControl(wxListCtrl *lstContactsPtr,
2985 wxArrayString *ContactsFileIndexPtr){
2987 // Set the list control pointers.
2989 lstContactsPtr = lstContacts;
2990 ContactsFileIndexPtr = &ContactsFileIndex;
2994 void frmMain::GetSelectedList( wxCommandEvent& event ){
2996 // Get the array of contact filenames.
2998 wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
3000 // Process them into an array of files.
3002 long longSelected = -1;
3003 int ContactsCollected = 0;
3004 wxString ContactFilename;
3008 longSelected = lstContacts->GetNextItem(longSelected,
3010 wxLIST_STATE_SELECTED);
3012 if (longSelected == -1){
3018 // Get the file information and add to the list.
3020 int FileID = (int)lstContacts->GetItemData(longSelected);
3022 ArrData->Insert(ContactsFileIndex[FileID],
3023 ContactsCollected, 1);
3025 ContactsCollected++;
3026 ContactFilename.Clear();
3034 void frmMain::SyncAccount( wxCommandEvent& event ){
3036 // Syncronise the selected account.
3038 wxString AccNameInc = event.GetString();
3040 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
3041 frameActMgr->AddTask(3, wxT(""), AccNameInc,
3042 wxT(""), wxT(""), wxT(""), wxT(""));
3046 void frmMain::ShowHelp( wxCommandEvent& event ){
3048 // Based on the operating system, work out where
3049 // the documentation should be.
3053 #if defined(__HAIKU__)
3055 #elif defined(__WIN32__)
3061 if (wxFileExists("/usr/share/doc/xestiaab/index.html")){
3063 wxLaunchDefaultBrowser(wxT("file:///usr/share/doc/xestiaab/index.html"));
3066 #if XSDAB_RELEASE == 0
3068 } else if (wxFileExists("/usr/local/share/doc/xestiaab/index.html")){
3070 wxLaunchDefaultBrowser(wxT("file:///usr/local/share/doc/xestiaab/index.html"));
3079 #if XSDAB_RELEASE == 0
3081 wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
3085 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!"));
3091 void frmMain::ShowImportResults( wxCommandEvent &event ){
3093 // Show the results of importing contacts.
3095 std::map<int,wxString> *ResultData = (std::map<int,wxString>*)event.GetClientData();
3097 frmImportResults *frmIR = new frmImportResults(this);
3098 frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
3109 void frmMain::ReloadContactList( wxCommandEvent &event ){
3111 // Check if the account name given is the current
3112 // account selected.
3114 if (ActiveAccount == event.GetString()){
3116 wxTreeEvent NullEvent;
3117 LoadContactList(NullEvent);
3123 void frmMain::ShowContactMenu( wxMouseEvent& event ){
3125 // Show the contact menu when a right click occurs
3126 // in the contacts list.
3128 bool EnableRefresh = FALSE;
3130 if (!ActiveAccount.IsEmpty() && (ActiveAccountType == "CardDAV" || ActiveAccountType == "carddav")){
3132 EnableRefresh = TRUE;
3136 ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
3138 this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
3142 void frmMain::ResetContactInfo(){
3144 // Reset the contact information to an empty page.
3146 wxString EmptyPage = wxT("");
3147 htmContactData->SetPage(EmptyPage);
3148 AccCtrl->SetValue("");