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));
142 wxImage icons_accinet_png(astream, wxBITMAP_TYPE_PNG);
143 wxBitmap AccInet(icons_accinet_png, -1);
145 wxIAccInet.CopyFromBitmap(AccInet);
147 wxImage icons_acclocal_png(bstream, wxBITMAP_TYPE_PNG);
148 wxBitmap AccNIcon(icons_acclocal_png, -1);
150 wxIAccNIcon.CopyFromBitmap(AccNIcon);
152 wxImage icons_accgroup_png(cstream, wxBITMAP_TYPE_PNG);
153 wxBitmap AccGrp(icons_accgroup_png, -1);
155 wxIAccGrp.CopyFromBitmap(AccGrp);
157 wxImage icons_accnone_png(dstream, wxBITMAP_TYPE_PNG);
158 wxBitmap AccNone(icons_accnone_png, -1);
160 wxIAccNone.CopyFromBitmap(AccNone);
162 AccountID = AccImgList->Add(wxIAccNIcon);
163 AccountNetID = AccImgList->Add(wxIAccInet);
164 AccountGrpID = AccImgList->Add(wxIAccGrp);
165 AccountNoneID = AccImgList->Add(wxIAccNone);
167 bmpIcon->SetIcon(AccImgList->GetIcon(AccountNoneID));
169 // Setup the status bar icons.
173 wxMemoryInputStream sslstream(icons_ssl_png, sizeof(icons_ssl_png));
174 wxMemoryInputStream sslwarningstream(icons_sslwarning_png, sizeof(icons_sslwarning_png));
175 wxMemoryInputStream nosslstream(icons_nossl_png, sizeof(icons_nossl_png));
177 wxImage icons_ssl_png(sslstream, wxBITMAP_TYPE_PNG);
178 imgSSL = new wxBitmap(icons_ssl_png, -1);
180 wxImage icons_sslwarning_png(sslwarningstream, wxBITMAP_TYPE_PNG);
181 imgSSLWarning = new wxBitmap(icons_sslwarning_png, -1);
183 wxImage icons_nossl_png(nosslstream, wxBITMAP_TYPE_PNG);
184 imgNoSSL = new wxBitmap(icons_nossl_png, -1);
188 wxMemoryInputStream act1(icons_act1_png, sizeof(icons_act1_png));
189 wxMemoryInputStream act2(icons_act2_png, sizeof(icons_act2_png));
190 wxMemoryInputStream act3(icons_act3_png, sizeof(icons_act3_png));
191 wxMemoryInputStream act4(icons_act4_png, sizeof(icons_act4_png));
192 wxMemoryInputStream actsleep(icons_actsleep_png, sizeof(icons_actsleep_png));
194 wxImage icons_actsleep_png(actsleep, wxBITMAP_TYPE_PNG);
195 imgActIconSleep = new wxBitmap (icons_actsleep_png, -1);
197 wxImage icons_act1_png(act1, wxBITMAP_TYPE_PNG);
198 imgActIcon1 = new wxBitmap (icons_act1_png, -1);
200 wxIAct1icon.CopyFromBitmap(*imgActIcon1);
202 wxImage icons_act2_png(act2, wxBITMAP_TYPE_PNG);
203 imgActIcon2 = new wxBitmap (icons_act2_png, -1);
205 wxIAct2icon.CopyFromBitmap(*imgActIcon2);
207 wxImage icons_act3_png(act3, wxBITMAP_TYPE_PNG);
208 imgActIcon3 = new wxBitmap (icons_act3_png, -1);
210 wxIAct3icon.CopyFromBitmap(*imgActIcon3);
212 wxImage icons_act4_png(act4, wxBITMAP_TYPE_PNG);
213 imgActIcon4 = new wxBitmap (icons_act4_png, -1);
215 wxIAct4icon.CopyFromBitmap(*imgActIcon4);
217 // Online/Offline icons.
219 wxMemoryInputStream onlinestream(icons_online_png, sizeof(icons_online_png));
220 wxMemoryInputStream offlinestream(icons_offline_png, sizeof(icons_offline_png));
222 wxImage icons_online_png(onlinestream, wxBITMAP_TYPE_PNG);
223 imgOnline = new wxBitmap(icons_online_png, -1);
225 wxImage icons_offline_png(offlinestream, wxBITMAP_TYPE_PNG);
226 imgOffline = new wxBitmap(icons_offline_png, -1);
228 // Setup the account view.
230 AccCtrl->SetPopupControl(treAccounts);
231 AccCtrl->SetPopupMaxHeight(175);
232 AccCtrl->SetPopupMinWidth(250);
233 treAccounts->AssignImageList(AccImgList);
235 wxListItem ColumnData;
237 ColumnData.SetText(wxT("Name0"));
238 ColumnData.SetWidth(320);
239 lstContacts->InsertColumn(0, ColumnData);
241 treAccounts->Connect(wxEVT_LEFT_DCLICK, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
242 treAccounts->Connect(wxEVT_TREE_SEL_CHANGED, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
244 #if defined(__HAIKU__)
246 #elif defined(__WIN32__)
248 int stbBottomData [4] = { -1, 8, 8, 8 };
252 int stbBottomData [4] = { -1, 20, 20, 20 };
256 stbBottom->SetFieldsCount(4, stbBottomData);
257 stbBottom->SetMinHeight(16);
262 stbBottom->GetFieldRect(1, rectOnline);
263 stbBottom->GetFieldRect(2, rectSSL);
264 stbBottom->GetFieldRect(3, rectActivity);
266 SSLToolTip = new wxToolTip(wxT(""));
268 imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectOnline.GetX()),(rectOnline.GetY())), wxDefaultSize, 0 );
269 imgConnStatus->SetBitmap(*imgOnline);
270 imgConnStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ToggleConnectionStatus ), NULL, this );
272 imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()),(rectSSL.GetY())), wxDefaultSize, 0 );
273 imgSSLStatus->SetBitmap(*imgNoSSL);
274 imgSSLStatus->SetToolTip(SSLToolTip);
275 imgSSLStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowSSLCertificates ), NULL, this );
277 imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()),(rectActivity.GetY())), wxDefaultSize, 0);
278 imgActivityStatus->SetBitmap(*imgActIconSleep);
279 imgActivityStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowActivityWindow ), NULL, this );
281 // Setup the window menu.
283 // By default should be:
288 // Contact editor windows:
294 mnuContactWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact windows:") ), wxEmptyString, wxITEM_NORMAL );
295 mnuWindow->Append( mnuContactWindows );
297 mnuWindow->AppendSeparator();
299 mnuContactEditorWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact editor windows:") ), wxEmptyString, wxITEM_NORMAL );
300 mnuWindow->Append( mnuContactEditorWindows );
302 mnuWindow->AppendSeparator();
304 mnuSearchWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( wxT("Search windows:") ), wxEmptyString, wxITEM_NORMAL );
305 mnuWindow->Append( mnuSearchWindows );
307 #if defined(__WIN32__)
312 mnuContactWindows->SetFont(fontstyle);
313 mnuContactEditorWindows->SetFont(fontstyle);
314 mnuSearchWindows->SetFont(fontstyle);
318 mnuContactWindows->Enable(FALSE);
319 mnuContactEditorWindows->Enable(FALSE);
320 mnuSearchWindows->Enable(FALSE);
324 // Hide unimplemented functions.
330 void frmMain::QuitApp( wxCloseEvent& event )
333 // Run the QuitApp function.
339 void frmMain::QuitApp( wxCommandEvent& event )
342 // Run the QuitApp function.
348 void frmMain::QuitApp()
351 // Function to run when quitting.
353 //Go through the windows and close each one (be it search
354 //or contact editor). Abort if user wants to cancel.
356 // Close the contact editor windows.
358 // Close the contact windows.
360 // Close the search windows.
362 // Write out the ETag databases.
364 // Save Preferences: Save the window position if that option is enabled.
366 wxString SetFilename = GetUserPrefDir();
368 #if defined(__HAIKU__)
372 #elif defined(__WIN32__)
374 SetFilename.Append(wxT("settings"));
380 SetFilename.Append(wxT("settings"));
384 wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
386 bool SaveWindowPos = FALSE;
387 wxString SaveWindowInc;
388 cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
390 if (SaveWindowInc == wxT("true")){
392 SaveWindowPos = TRUE;
396 if (SaveWindowPos == TRUE){
398 wxRect frmMainPos = this->GetRect();
400 cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
401 cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
402 cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
403 cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
410 //Everything closed... exit.
418 void frmMain::ShowActivityWindow( wxCommandEvent& event )
421 // Open the activity manager window.
423 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
424 frameActMgr->OpenWindow();
429 void frmMain::ShowAboutWindow( wxCommandEvent& event )
432 // Show the about window.
434 frmAbout *frameAbout = new frmAbout ( this );
435 frameAbout->SetupAboutWindow();
436 frameAbout->ShowModal();
442 void frmMain::OpenPreferences( wxCommandEvent& event)
445 // Open the preferences window.
447 ReloadAccounts = FALSE;
449 frmPreferences *framePreferences = new frmPreferences ( this );
450 framePreferences->SetupPointers(&ReloadAccounts);
451 framePreferences->ShowModal();
452 delete framePreferences;
453 framePreferences = NULL;
455 if (ReloadAccounts == TRUE){
457 // Reload the accounts as a change has been made within
458 // the application and clear the current contact information.
460 this->LoadPreferences();
461 this->ResetContactInfo();
467 void frmMain::OpenNewABDialog( wxCommandEvent& event)
470 // Open the new account dialog.
472 ReloadAccounts = FALSE;
474 frmNewAccount *frameNewAccount = new frmNewAccount ( this );
475 frameNewAccount->SetupPointers(&ReloadAccounts);
476 frameNewAccount->ShowModal();
477 delete frameNewAccount;
478 frameNewAccount = NULL;
480 if (ReloadAccounts == TRUE){
482 // Reload the accounts as a change has been made within
485 this->LoadPreferences();
491 void frmMain::LoadContactList( wxTreeEvent& event )
494 // Load the contact list.
496 // Clear all existing variables.
498 lstContacts->DeleteAllItems();
500 treAccounts->SetAccount();
502 wxTreeItemIdValue cookie;
503 wxTreeItemId next = treAccounts->GetRootItem();
504 wxString AccountName;
505 wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
506 wxString AccountDirCmb;
507 long selectedaccount = 0;
509 wxTreeItemId selectedChild = treAccounts->GetSelection();
510 wxTreeItemId nextChild;
512 wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
513 int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
515 int SCImg = treAccounts->GetItemImage(selectedChild);
516 int AccountIndex = 0;
518 bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
520 // Process each account.
522 for (int i = 0; i < prefaccounts.GetCount(); i++){
524 if (ActiveItemIcon == 2){
526 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
527 std::multimap<int, int>::iterator AGLiter = AccountGroupList.find(AGTiter->second);
528 int ActiveAccountG = AGLiter->second;
530 if (i == ActiveAccountG){
532 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
533 AccountType.Append(prefaccounts.GetAccountType(i));
538 if (AccountType == wxT("CardDAV")){
539 AccountTypeFinal.Append(wxT("carddav"));
540 } else if (AccountType == wxT("Local")){
541 imgSSLStatus->SetBitmap(*imgOffline);
542 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
543 AccountTypeFinal.Append(wxT("local"));
554 nextChild = treAccounts->GetFirstChild(next, cookie);
556 nextChild = treAccounts->GetNextSibling(nextChild);
559 AccountName = treAccounts->GetItemText(nextChild);
561 if (nextChild == selectedChild){
563 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
564 AccountType.Append(prefaccounts.GetAccountType(i));
569 if (AccountType == wxT("CardDAV")){
570 AccountTypeFinal.Append(wxT("carddav"));
571 } else if (AccountType == wxT("Local")){
572 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
573 AccountTypeFinal.Append(wxT("local"));
582 if (selectedaccount >= prefaccounts.GetCount()){
584 // The account selected isn't there so return.
592 // Open the directory and get the list of .vcf files
593 // in that directory.
595 ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
596 ActiveAccountType = AccountType;
598 SetupSSLStatus(AccountIndex);
600 AccountDirFinal.Clear();
601 AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
603 ContactsFileIndex.Clear();
605 wxString vCardFilename;
606 wxString vCardFilenameFull;
607 wxString vCardDataString;
608 wxStringTokenizer vcardfileline;
610 wxString setname, setvalue;
611 std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
612 std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
613 long ContactIndex = 1;
614 long ContactSeekPoint = 0;
616 wxDir vcardaccdir(AccountDirFinal);
618 // Get the wxTreeItemId and image icon and compare it to the list.
620 if (ActiveItemIcon == AccountGrpID){
622 // It's a group so load the file containing the group and
623 // get the members of the group.
628 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
629 std::multimap<int, wxString>::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
631 Group.LoadFile(AGFiter->second);
633 ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
635 for (int i = 0; i < vCardMember.PropCount; i++){
637 vCardMember.PropValues[i].Trim();
638 if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
640 wxString NewPropValue;
641 NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
642 vCardMember.PropValues[i] = NewPropValue;
648 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
652 if (vCardFilename.Right(4) == wxT(".vcf") ||
653 vCardFilename.Right(4) == wxT(".VCF") ||
654 vCardFilename.Right(5) == wxT(".vcard") ||
655 vCardFilename.Right(5) == wxT(".VCARD")){
658 bool FoundMember = FALSE;
660 vCardFilenameFull.Append(AccountDirFinal);
661 vCardFilenameFull.Append(wxT("/"));
662 vCardFilenameFull.Append(vCardFilename);
664 Person.LoadFile(vCardFilenameFull);
666 UIDCode = Person.Get(wxT("UID"));
668 for (int i = 0; i < vCardMember.PropCount; i++){
670 if (vCardMember.PropValues[i] == UIDCode){
678 if (FoundMember == FALSE){
680 vCardFilename.Clear();
681 vCardFilenameFull.Clear();
682 vCardDataString.Clear();
683 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
688 if (Person.MeetBaseSpecification()){
692 // Split the name into sections.
694 vCardDataString = Person.Get(wxT("N"));
696 vCardName NameData = Person.GetName();
698 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
700 } else if (SortMode == 2){
702 // Split the name into sections.
704 vCardName NameData = Person.GetName();
706 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
708 } else if (SortMode == 3){
710 // Check and make sure that the top most nickname is used.
712 vCardDataString = Person.Get(wxT("NICKNAME"));
714 if (vCardDataString.IsEmpty()){
716 vCardDataString = wxT("(no nickname)");
720 } else if (SortMode == 4){
722 vCardDataString = Person.Get(wxT("FN"));
726 if (AscendingMode == TRUE){
727 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
729 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
736 vCardFilename.Clear();
737 vCardFilenameFull.Clear();
738 vCardDataString.Clear();
739 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
745 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
748 if (vCardFilename.Right(4) == wxT(".vcf") ||
749 vCardFilename.Right(4) == wxT(".VCF") ||
750 vCardFilename.Right(5) == wxT(".vcard") ||
751 vCardFilename.Right(5) == wxT(".VCARD")){
755 vCardFilenameFull.Append(AccountDirFinal);
756 vCardFilenameFull.Append(vCardFilename);
758 Person.LoadFile(vCardFilenameFull);
760 if (Person.MeetBaseSpecification()){
764 // Split the name into sections.
766 vCardDataString = Person.Get(wxT("N"));
768 vCardName NameData = Person.GetName();
770 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
772 } else if (SortMode == 2){
774 // Split the name into sections.
776 vCardName NameData = Person.GetName();
778 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
780 } else if (SortMode == 3){
782 // Check and make sure that the top most nickname is used.
784 vCardDataString = Person.Get(wxT("NICKNAME"));
786 if (vCardDataString.IsEmpty()){
788 vCardDataString = wxT("(no nickname)");
792 } else if (SortMode == 4){
794 vCardDataString = Person.Get(wxT("FN"));
798 if (AscendingMode == TRUE){
800 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
804 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
812 vCardFilename.Clear();
813 vCardFilenameFull.Clear();
814 vCardDataString.Clear();
815 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
822 // Insert the data into the control.
824 if (AscendingMode == TRUE){
825 for (std::map<wxString, wxString>::iterator iter = vCardNamesAsc.begin();
826 iter != vCardNamesAsc.end(); ++iter){
828 wxListItem ContactInfo;
830 ContactInfo.SetId(0);
831 ContactInfo.SetText(_("Mooo"));
832 ContactInfo.SetData(ContactSeekPoint);
833 ContactIndex = lstContacts->InsertItem(ContactInfo);
835 lstContacts->SetItem(ContactIndex, 0, iter->first);
837 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
844 for (std::map<wxString, wxString>::iterator iter = vCardNamesDsc.begin();
845 iter != vCardNamesDsc.end(); ++iter){
847 wxListItem ContactInfo;
849 ContactInfo.SetId(0);
850 ContactInfo.SetText(_("Mooo"));
851 ContactInfo.SetData(ContactSeekPoint);
852 ContactIndex = lstContacts->InsertItem(ContactInfo);
854 lstContacts->SetItem(ContactIndex, 0, iter->first);
855 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
864 void frmMain::ShowContactInfo( wxListEvent& event )
867 // Display the contact information.
869 long intSelected = -1;
870 long ContactSeekNum = -1;
872 // Check if several contacts have been selected.
874 int ContactTotal = 0;
878 intSelected = lstContacts->GetNextItem(intSelected,
880 wxLIST_STATE_SELECTED);
882 if (intSelected == -1){
892 if (ContactTotal == 0){
893 htmContactData->SetPage(wxT(""));
897 if (ContactTotal > 1){
899 htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
900 ActiveFilename.Clear();
905 intSelected = lstContacts->GetNextItem(intSelected,
907 wxLIST_STATE_SELECTED);
909 ContactSeekNum = lstContacts->GetItemData(intSelected);
912 wxString wxSContactString;
913 wxString ContactLine;
916 size_t ContactLineLen;
917 bool ExtraLineSeek = FALSE;
918 int QuoteBreakPoint = 0;
920 bool PropertyFind = FALSE;
921 bool QuoteMode = FALSE;
923 wxString wxSPropertyNextLine;
924 wxString wxSProperty;
925 wxString wxSPropertySeg1;
926 wxString wxSPropertySeg2;
928 // Check if we are using wxWidgets version 2.8 or less and
929 // execute the required command accordingly.
931 #if wxABI_VERSION < 20900
932 ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
934 ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
937 if (ContactFile.IsOpened() == FALSE){
943 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
947 std::map<int, wxString> ContactFileLines;
948 std::map<int, wxString>::iterator striter;
950 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
952 int ContactLineSeek = 0;
954 while (wSTContactFileLines.HasMoreTokens() == TRUE){
956 ContactLine = wSTContactFileLines.GetNextToken();
957 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
962 if (ContactSeekNum < 0){
966 for (std::map<int, wxString>::iterator iter = ContactFileLines.begin();
967 iter != ContactFileLines.end(); ++iter){
969 // Find the colon which splits the start bit from the data part.
971 ContactLine = iter->second;
973 while (ExtraLineSeek == TRUE){
975 // Check if there is extra data on the next line
976 // (indicated by space or tab at the start) and add data.
980 if (iter == ContactFileLines.end()){
987 wxSPropertyNextLine = iter->second;
990 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
992 wxSPropertyNextLine.Remove(0, 1);
993 ContactLine.Append(wxSPropertyNextLine);
998 ExtraLineSeek = FALSE;
1004 ContactLineLen = ContactLine.Len();
1006 // Make sure we are not in quotation mode.
1007 // Make sure colon does not have \ or \\ before it.
1009 for (int i = 0; i <= ContactLineLen; i++){
1011 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1013 PropertyFind = FALSE;
1015 } else if (PropertyFind == TRUE){
1017 wxSProperty.Append(ContactLine.Mid(i, 1));
1021 if (ContactLine.Mid(i, 1) == wxT("\"")){
1023 if (QuoteMode == TRUE){
1035 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1037 QuoteBreakPoint = i;
1044 // Split that line at the point into two variables (ignore the colon).
1046 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1047 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1049 // Insert both into the vCard data file.
1051 Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
1054 PropertyFind = TRUE;
1055 ExtraLineSeek = TRUE;
1057 QuoteBreakPoint = 0;
1058 ContactLine.Clear();
1059 wxSProperty.Clear();
1063 OldSessionID = SessionID;
1064 SessionID = wxString::Format(wxT("%i"), rand() % 32768);
1065 LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList);
1066 ActiveFilename = ContactsFileIndex[ContactSeekNum];
1070 void frmMain::ShowContactEditorNew( wxCommandEvent& event )
1073 // Open a contact editor window to write a new contact with.
1075 // Check if there is an account selected and if not
1076 // return immediately.
1078 if (ActiveAccount.IsEmpty()){
1084 // Add Pointer to SetupPointers for the ETagDB.
1086 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1087 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1088 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1090 contacticon.CopyFromBitmap(contacticonbmp);
1092 frmContactEditor *ContactEditor = new frmContactEditor( this );
1096 ContactEditor->SetUID(WindowMenuItemID);
1098 WindowData *WData = new WindowData;
1100 WData->DataType = 1;
1101 WData->WindowPointer = (void*)ContactEditor;
1102 WData->WindowID = WindowMenuItemID;
1104 wxCommandEvent addevent(WINDOW_ADD);
1105 addevent.SetClientData(WData);
1106 wxPostEvent(this, addevent);
1108 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1109 ContactEditor->SetupHeaders();
1110 ContactEditor->SetupContact(ActiveAccount);
1111 ContactEditor->SetIcon(contacticon);
1112 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1113 ContactEditor->Show(true);
1117 void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
1120 // Open a contact editor window for editing an existing contact
1123 // Check if there is an account selected and if not
1124 // return immediately.
1126 int DataCheck = event.GetInt();
1128 if (ActiveAccount.IsEmpty() && DataCheck == 0){
1134 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1135 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1136 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1138 contacticon.CopyFromBitmap(contacticonbmp);
1140 // Check if a contact has been selected.
1142 long intSelected = -1;
1143 long intContactSeekNum = -1;
1145 intSelected = lstContacts->GetNextItem(intSelected,
1147 wxLIST_STATE_SELECTED);
1149 if (intSelected == -1){
1155 intContactSeekNum = lstContacts->GetItemData(intSelected);
1157 // Get the filename of the selected contact.
1159 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1160 frmContactEditor *ContactEditor = new frmContactEditor( this );
1164 ContactEditor->SetUID(WindowMenuItemID);
1166 WindowData *WData = new WindowData;
1168 WData->DataType = 1;
1169 WData->WindowPointer = (void*)ContactEditor;
1170 WData->WindowID = WindowMenuItemID;
1172 wxCommandEvent addevent(WINDOW_ADD);
1173 addevent.SetClientData(WData);
1174 wxPostEvent(this, addevent);
1176 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1177 ContactEditor->SetupHeaders();
1179 // Check if pointer is NULL (not from the search forms) or not.
1181 if (DataCheck == 0){
1183 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1184 ContactEditor->SetupContact(ActiveAccount);
1188 UCNotif *uc = (UCNotif*)event.GetClientData();
1192 ContactEditor->SetupContact(ActiveAccount);
1193 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1197 ContactEditor->SetupContact(uc->ContactAccount);
1198 ContactEditor->LoadContact(uc->ContactFilename);
1207 ContactEditor->SetIcon(contacticon);
1208 ContactEditor->Show(true);
1212 void frmMain::RefreshAddressBook( wxCommandEvent& event ){
1214 // Refresh the address book data.
1216 // Check if ActiveAccount is empty. If not then check if
1217 // account type is not local otherwise continue.
1219 if (!ActiveAccount.IsEmpty()){
1221 if (ActiveAccountType != wxT("Local")){
1223 // Account type is not local.
1225 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1226 frameActMgr->AddTask(3, wxT(""), ActiveAccount,
1227 wxT(""), wxT(""), wxT(""), wxT(""));
1231 wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported for this type of account"));
1239 void frmMain::OpenContactInfoList( wxListEvent& event )
1242 // Open the contact information window.
1244 wxStringTokenizer vcardfileline;
1247 wxString setname, setvalue;
1251 long intSelected = -1;
1252 long intContactSeekNum = -1;
1254 intSelected = lstContacts->GetNextItem(intSelected,
1256 wxLIST_STATE_SELECTED);
1258 intContactSeekNum = lstContacts->GetItemData(intSelected);
1260 if (intContactSeekNum == -1){
1266 Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
1268 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1269 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1270 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1272 contacticon.CopyFromBitmap(contacticonbmp);
1274 frmContact *Contact = new frmContact( this );
1276 // Add to window list.
1280 Contact->SetUID(WindowMenuItemID);
1282 WindowData *WData = new WindowData;
1284 WData->DataType = 0;
1285 WData->WindowPointer = (void*)Contact;
1286 WData->WindowID = WindowMenuItemID;
1288 wxCommandEvent addevent(WINDOW_ADD);
1289 addevent.SetClientData(WData);
1290 wxPostEvent(this, addevent);
1292 Contact->SetupPointers(&MemoryFileList);
1293 Contact->SetupContactData(&Person);
1295 Contact->SetIcon(contacticon);
1296 Contact->Show(true);
1300 void frmMain::OpenContactInfoList( wxCommandEvent& event ){
1302 // Open a list of contact information windows.
1305 OpenContactInfoList(pevent);
1309 void frmMain::OpenContactInfo( wxCommandEvent& event )
1312 // Open the contact information window.
1314 UCNotif *uc = (UCNotif*)event.GetClientData();
1316 wxStringTokenizer vcardfileline;
1319 wxString setname, setvalue;
1323 Person.LoadFile(uc->ContactFilename);
1325 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1326 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1327 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1329 contacticon.CopyFromBitmap(contacticonbmp);
1331 frmContact *Contact = new frmContact( this );
1333 // Add to window list.
1337 Contact->SetUID(WindowMenuItemID);
1339 WindowData *WData = new WindowData;
1341 WData->DataType = 0;
1342 WData->WindowPointer = (void*)Contact;
1343 WData->WindowID = WindowMenuItemID;
1345 wxCommandEvent addevent(WINDOW_ADD);
1346 addevent.SetClientData(WData);
1347 wxPostEvent(this, addevent);
1349 Contact->SetupPointers(&MemoryFileList);
1350 Contact->SetupContactData(&Person);
1352 Contact->SetIcon(contacticon);
1353 Contact->Show(true);
1358 void frmMain::LoadPreferences( wxActivateEvent& event)
1361 // Load the preferences.
1363 this->LoadPreferences();
1367 void frmMain::LoadPreferences(){
1369 // Load the preferences.
1371 wxString preffilename = GetUserPrefDir();
1373 XABPreferences preferences(preffilename);
1375 // Setup the main window position (if needed).
1377 bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
1378 bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
1380 if (SaveWindowPos == TRUE){
1382 this->SetSize(preferences.GetMainWindowData());
1386 treAccounts->DeleteAllItems();
1388 wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
1390 // Stop all account timers and remove the accounts.
1392 for (std::map<wxString, wxAccountSyncTimer*>::iterator iter = AccountSyncTimers.begin();
1393 iter != AccountSyncTimers.end(); iter++){
1395 wxAccountSyncTimer *AccTmrPtr = iter->second;
1403 #if defined(__WIN32__)
1405 for (std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.begin();
1406 CertificateIter != AccountCertificateData.end(); CertificateIter++){
1408 CertFreeCertificateContext(CertificateIter->second);
1412 AccountCertificateData.clear();
1416 AccountSyncTimers.clear();
1419 wxString AccDirFull;
1420 wxString AccDirFullSfx;
1422 wxString AccDirFinal;
1423 AccountAccDirList.clear();
1424 AccountGroupList.clear();
1425 AccountGroupFilename.clear();
1426 AccountGroupTreeId.clear();
1427 wxTreeItemId AccountTreeId;
1428 wxTreeItemId GroupTreeId;
1431 // Relaod the accounts for the ETagProcTimer.
1433 ETagProcTimer.ReloadAccounts();
1435 for (int i = 0; i < preferences.accounts.GetCount(); i++){
1437 if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
1438 preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == TRUE){
1444 if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
1450 AccDir = preferences.accounts.GetAccountDirectory(i);
1451 AccDirFull = preferences.accounts.GetAccountDirectory(i);
1453 AccDirFull.Append(wxT("."));
1454 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
1455 AccDirFullSfx.LowerCase();
1456 AccDirFullSfx.Trim();
1457 AccDirFull.Append(AccDirFullSfx);
1458 AccName = preferences.accounts.GetAccountName(i);
1460 AccountAccDirList.insert(std::make_pair(i, AccDirFull));
1462 if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
1463 preferences.accounts.GetAccountType(i) == wxT("carddav")){
1465 // TODO: Check if the directory exists before doing anything.
1469 // Add a new timer using the existing account details.
1471 wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
1473 ActTmrPtr->SetupData(AccDirFull, AccName);
1474 ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
1475 ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
1476 ActTmrPtr->SetOwner(this);
1477 ActTmrPtr->Notify();
1479 // Add the timer to the list of timers.
1481 AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
1483 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
1487 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
1491 // Go through the account directory and find contact files with
1492 // 'KIND:group' set and add them to the list of groups for the account.
1494 AccDirFinal = GetAccountDir(AccDirFull, FALSE);
1496 wxDir vcardaccdir(AccDirFinal);
1498 wxString vCardFilename;
1499 wxString vCardDataString;
1500 wxString vCardFilenameFull;
1502 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1506 if (vCardFilename.Right(4) == wxT(".vcf") ||
1507 vCardFilename.Right(4) == wxT(".VCF") ||
1508 vCardFilename.Right(5) == wxT(".vcard") ||
1509 vCardFilename.Right(5) == wxT(".VCARD")){
1513 vCardFilenameFull.Append(AccDirFinal);
1514 vCardFilenameFull.Append(wxT("/"));
1515 vCardFilenameFull.Append(vCardFilename);
1517 Person.LoadFile(vCardFilenameFull);
1519 if (Person.MeetBaseSpecification()){
1521 vCardDataString = Person.Get(wxT("KIND"));
1523 if (vCardDataString == wxT("group")){
1525 // The vCard kind is a group. Add to the account's group list.
1527 GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
1528 treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
1529 AccountGroupList.insert(std::make_pair(intGroupID, i));
1530 AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
1531 AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
1541 vCardFilename.Clear();
1542 vCardFilenameFull.Clear();
1543 vCardDataString.Clear();
1544 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1548 // Clearup for next account.
1552 AccDirFullSfx.clear();
1553 AccDirFinal.clear();
1558 // Load the account settings as they are needed for connecting
1561 prefaccounts = preferences.accounts;
1565 void frmMain::ConflictResolution(wxCommandEvent& event){
1567 // Display the conflict resolution window.
1569 frmConflictResolution *frameCR = new frmConflictResolution ( this );
1570 vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
1571 vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
1572 vCard *ServerDataPtr = vCardConfObj->vCardServerData;
1573 frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList);
1574 frameCR->ShowModal();
1576 int FinalConflictResult = frameCR->GetResult();
1578 wxCommandEvent event2(ACTMGR_RESUMEPROC);
1579 event2.SetClientData(vCardConfObj->QRNotifData);
1580 event2.SetInt(FinalConflictResult);
1585 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1586 wxPostEvent(frameActMgr, event2);
1590 void frmMain::UpdateContactList(wxCommandEvent& event){
1592 // Update the contact list in the main window.
1594 UCNotif *ucd = (UCNotif*)event.GetClientData();
1596 // Check if the active account is being displayed in the
1597 // main window. If not, skip and delete the data.
1599 long longSelected = -1;
1600 int intSelectedData = 0;
1602 if (ActiveAccount == ucd->ContactAccount){
1604 // Look at the list of contacts and if it matches the
1605 // filename then update the name.
1609 longSelected = lstContacts->GetNextItem(longSelected,
1611 wxLIST_STATE_DONTCARE);
1613 if (longSelected == -1){
1619 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1621 if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
1623 // Work out which sorting mode we are in.
1627 // First Name, Last Name.
1629 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
1631 } else if (SortMode == 2){
1633 // Last Name, First Name.
1635 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
1637 } else if (SortMode == 3){
1641 lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
1643 } else if (SortMode == 4){
1647 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1654 // If the filename is the one loaded into the
1655 // browser control, then update this too.
1657 if (ActiveFilename == ContactsFileIndex[intSelectedData]){
1659 wxListEvent nullevent;
1660 ShowContactInfo(nullevent);
1668 for (std::map<int, void*>::iterator WindowIter = WindowListPointers.begin();
1669 WindowIter != WindowListPointers.end(); WindowIter++){
1671 if (WindowListType[WindowIter->first] != 0){
1677 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
1679 if (frmContactPtr->GetFilename() == ucd->ContactFilename){
1681 vCard UpdatedPerson;
1682 UpdatedPerson.LoadFile(ucd->ContactFilename);
1683 frmContactPtr->SetupContactData(&UpdatedPerson);
1689 // Send message to search window controller subroutine and
1690 // pass that notification onto the search windows.
1692 // Setup the new pointer to use the existing UCNotif without
1695 UCNotif *ucd2 = ucd;
1697 wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
1698 sup.SetClientData(ucd2);
1699 wxPostEvent(this, sup);
1701 // Clear up the unused pointer.
1707 void frmMain::UpdateAccountList(wxCommandEvent& event){
1709 // Update the account list (currently unimplemented).
1713 void frmMain::SetupPointers(void *ActMgrPtrInc){
1715 // Setup the pointers for the main window.
1717 ActMgrPtr = ActMgrPtrInc;
1721 void frmMain::SetupForm(){
1723 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1724 frameActMgr->SetupPointers(&ETagProcTimer, this);
1726 // Setup the contact information icons for later.
1728 wxFileSystem::AddHandler(new wxMemoryFSHandler);
1732 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
1733 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
1734 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1736 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
1737 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
1738 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1740 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
1741 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
1742 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1744 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
1745 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
1746 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1748 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
1749 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
1750 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1752 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
1753 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
1754 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1760 void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
1762 // Update the contact lists in the search windows.
1764 // Go through each of the search windows and
1765 // send the required notification to update the
1766 // contact information.
1768 // Get the event notification data.
1770 UCNotif *ucd = (UCNotif*)event.GetClientData();
1772 // Process each search window giving the new details.
1774 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1775 switer != SearchWindowList.end(); switer++){
1777 // Duplicate the event notification data.
1779 UCNotif *ucd2 = new UCNotif;
1781 ucd2->ContactAccount = ucd->ContactAccount;
1782 ucd2->ContactFilename = ucd->ContactFilename;
1783 ucd2->ContactName = ucd->ContactName;
1784 ucd2->ContactNickname = ucd->ContactNickname;
1785 ucd2->ContactNameArray = ucd->ContactNameArray;
1787 // Pass the data to the search window for processing.
1789 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
1790 wxCommandEvent schupdate(SE_UPDATERESULT);
1791 schupdate.SetClientData(ucd2);
1792 wxPostEvent(frameSCH, schupdate);
1794 // Clear up the pointer prior to variable deletion.
1805 void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
1807 // Open a new search window.
1811 frmSearch *frameSCH = new frmSearch ( this );
1812 frameSCH->SetUID(WindowMenuItemID);
1813 frameSCH->Show(true);
1815 WindowData *WData = new WindowData;
1817 WData->DataType = 2;
1818 WData->WindowPointer = (void*)frameSCH;
1819 WData->WindowID = WindowMenuItemID;
1821 wxCommandEvent addevent(WINDOW_ADD);
1822 addevent.SetClientData(WData);
1823 wxPostEvent(this, addevent);
1825 // Add pointer to the list of open search windows.
1827 SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
1833 void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
1835 // Remove the pointer for a contact window from the
1838 void *frameSCH = (void*)event.GetClientData();
1840 SearchWindowList.erase(frameSCH);
1846 void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
1848 // Remove the pointer for a contact editor window from
1851 void *frameSCH = (void*)event.GetClientData();
1853 SearchWindowList.erase(frameSCH);
1859 void frmMain::RevealContact(wxCommandEvent& event){
1861 // Reveal a contact in the main window.
1863 UCNotif *uc = (UCNotif*)event.GetClientData();
1865 // Switch the account to the one passed.
1867 wxTreeItemIdValue cookie;
1868 wxTreeItemId next = treAccounts->GetRootItem();
1869 wxTreeItemId nextChild;
1871 for (int i = 0; i < prefaccounts.GetCount(); i++){
1874 nextChild = treAccounts->GetFirstChild(next, cookie);
1876 nextChild = treAccounts->GetNextSibling(nextChild);
1879 if (uc->ContactAccount == AccountAccDirList[i]){
1881 treAccounts->SelectItem(nextChild, TRUE);
1882 AccCtrl->SetText(treAccounts->GetItemText(nextChild));
1888 // Switch the contact to the one passed.
1890 long longSelected = -1;
1891 int intSelectedData = 0;
1895 longSelected = lstContacts->GetNextItem(longSelected,
1897 wxLIST_STATE_DONTCARE);
1899 if (longSelected == -1){
1905 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1907 // Compare the filename with the one received.
1908 // If they match then select it.
1910 if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
1914 lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1915 lstContacts->EnsureVisible(longSelected);
1919 lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
1927 void frmMain::DeleteContact(wxCommandEvent& event){
1929 // Delete a contact from the main window.
1931 // Check if a contact is selected.
1933 long intSelected = -1;
1934 long intContactSeekNum = -1;
1935 wxString wxSContactName;
1937 intSelected = lstContacts->GetNextItem(intSelected,
1939 wxLIST_STATE_SELECTED);
1941 if (intSelected == -1){
1945 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1947 // Get the item data of the contact.
1949 intContactSeekNum = lstContacts->GetItemData(intSelected);
1951 // Get the name of the contact.
1953 wxSContactName = lstContacts->GetItemText(intSelected);
1955 // Display a message confirming if the contact should
1958 int QuestionResponse;
1960 QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
1962 if (QuestionResponse == wxNO){
1964 // Exit the subroutine
1970 // Delete the contact.
1972 if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
1974 wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
1979 // Remove the contact from the list.
1981 lstContacts->DeleteItem(intSelected);
1983 // Update the search windows, removing the deleted
1986 UCNotif *ucd = new UCNotif;
1988 ucd->ContactAccount = ActiveAccount;
1989 ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
1991 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1992 switer != SearchWindowList.end(); switer++){
1994 // Duplicate the event notification data.
1996 UCNotif *ucd2 = new UCNotif;
1998 ucd2->ContactAccount = ucd->ContactAccount;
1999 ucd2->ContactFilename = ucd->ContactFilename;
2001 // Pass the data to the search window for processing.
2003 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
2004 wxCommandEvent schdelete(SE_DELETERESULT);
2005 schdelete.SetClientData(ucd2);
2006 wxPostEvent(frameSCH, schdelete);
2008 // Clear up the pointer prior to variable deletion.
2015 // Clear the wxHTMLWindow.
2017 wxString EmptyPage = wxT("");
2019 htmContactData->SetPage(EmptyPage);
2021 wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
2023 wxString wxSplitFilename;
2024 wxString wxSDataURL;
2026 while(wSTFilename.HasMoreTokens()){
2028 wxSplitFilename = wSTFilename.GetNextToken();
2032 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
2034 // Update the ETagDB and mark it as deleted.
2036 ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
2038 ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
2040 // Get the Data URL.
2042 wxTreeItemIdValue cookie;
2043 wxTreeItemId next = treAccounts->GetRootItem();
2045 wxTreeItemId selectedChild = treAccounts->GetSelection();
2046 wxTreeItemId nextChild;
2048 for (int i = 0; i < prefaccounts.GetCount(); i++){
2051 nextChild = treAccounts->GetFirstChild(next, cookie);
2053 nextChild = treAccounts->GetNextSibling(nextChild);
2056 if (nextChild == selectedChild){
2058 wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
2064 // Add task to the activity monitor to delete the contact.
2066 frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
2070 // Clear the variable. Don't delete as it will mess things up.
2072 ContactsFileIndex[intContactSeekNum] = wxT("");
2079 void frmMain::EmptyServerDialog(wxCommandEvent& event){
2081 // Display this message when the server information has changed
2084 QRNotif *qrn = (QRNotif *)event.GetClientData();
2086 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);
2088 if (QResponse == wxNO){
2094 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2095 event2.SetInt(*qrn->QResponse);
2096 event2.SetClientData(qrn->PausePtr);
2098 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2100 wxPostEvent(frameActMgr, event2);
2104 void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
2106 // Remove the contact from the window after syncronising.
2108 // Check which account is currently active in the window.
2109 // If it is different from the one passed to this subroutine then
2110 // exit from the subroutine.
2112 if (Account != ActiveAccount){
2116 long longSelected = -1;
2117 int intSelectedData = 0;
2121 longSelected = lstContacts->GetNextItem(longSelected,
2123 wxLIST_STATE_DONTCARE);
2125 if (longSelected == -1){
2131 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2133 // Compare the filename with the one received.
2134 // If they match then select it.
2136 if (ContactsFileIndex[intSelectedData] == Filename){
2138 // Remove the contact from the window.
2140 lstContacts->DeleteItem(intSelectedData);
2142 // Check if contact is the selected contact in the HTML window and
2143 // if it is then clear the window.
2145 if (ActiveFilename == Filename){
2147 wxString EmptyPage = wxT("");
2148 htmContactData->SetPage(EmptyPage);
2162 void frmMain::SortFNLN( wxCommandEvent& event ) {
2164 // Sort first name then last name.
2166 wxTreeEvent NullEvent;
2168 LoadContactList(NullEvent);
2172 void frmMain::SortLNFN( wxCommandEvent& event ) {
2174 // Sort last name then first name.
2176 wxTreeEvent NullEvent;
2178 LoadContactList(NullEvent);
2182 void frmMain::SortNickname( wxCommandEvent& event ) {
2184 // Sort by nickname.
2186 wxTreeEvent NullEvent;
2188 LoadContactList(NullEvent);
2192 void frmMain::SortDisplayAs( wxCommandEvent& event ) {
2194 // Sort by Display As name.
2196 wxTreeEvent NullEvent;
2198 LoadContactList(NullEvent);
2202 void frmMain::SortAscending( wxCommandEvent& event ) {
2206 wxTreeEvent NullEvent;
2207 AscendingMode = TRUE;
2208 LoadContactList(NullEvent);
2212 void frmMain::SortDescending( wxCommandEvent& event ) {
2216 wxTreeEvent NullEvent;
2217 AscendingMode = FALSE;
2218 LoadContactList(NullEvent);
2222 void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
2224 // Toggle the appearance of the status bar.
2226 if (stbBottom->IsShown() == TRUE){
2240 void frmMain::ActivityIconStart( wxCommandEvent& event ){
2242 // Display the activity icon.
2244 imgActivityStatus->SetBitmap(*imgActIcon1);
2245 ActivityIconStatus = 0;
2249 void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
2251 // Shuffle through the activity icons.
2253 switch (ActivityIconStatus){
2256 imgActivityStatus->SetBitmap(*imgActIcon1);
2257 ActivityIconStatus = 1;
2260 imgActivityStatus->SetBitmap(*imgActIcon2);
2261 ActivityIconStatus = 2;
2264 imgActivityStatus->SetBitmap(*imgActIcon3);
2265 ActivityIconStatus = 3;
2268 imgActivityStatus->SetBitmap(*imgActIcon4);
2269 ActivityIconStatus = 0;
2272 ActivityIconStatus = 0;
2278 void frmMain::ActivityIconStop( wxCommandEvent& event ){
2280 // Display the sleep icon.
2282 imgActivityStatus->SetBitmap(*imgActIconSleep);
2286 void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
2288 // Set the placement of the status bar icons.
2290 if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
2298 wxRect rectActivity;
2299 stbBottom->GetFieldRect(1, rectOnline);
2300 stbBottom->GetFieldRect(2, rectSSL);
2301 stbBottom->GetFieldRect(3, rectActivity);
2303 imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
2304 imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
2305 imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
2309 XABViewMode frmMain::GetViewMode(){
2311 // Set the view mode of the contact list.
2315 xvm.SortMode = SortMode;
2316 xvm.AscendingMode = AscendingMode;
2322 void frmMain::WindowAdd( wxCommandEvent &event ){
2324 // Add a window to the window list.
2326 WindowData *WData = (WindowData*)event.GetClientData();
2330 if (WData->DataType == 0){
2334 int intID = mnuContactWindows->GetId();
2336 mnuWindow->FindChildItem(intID, &pos);
2337 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2338 mnuNewItem->SetId(WData->WindowID);
2339 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2340 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2341 WindowListType.insert(std::make_pair(WData->WindowID, 0));
2342 mnuWindow->Insert((pos + 1), mnuNewItem);
2343 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
2345 } else if (WData->DataType == 1){
2347 // Contact Editor Window
2349 int intID = mnuContactEditorWindows->GetId();
2351 mnuWindow->FindChildItem(intID, &pos);
2352 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2353 mnuNewItem->SetId(WData->WindowID);
2354 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2355 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2356 WindowListType.insert(std::make_pair(WData->WindowID, 1));
2357 mnuWindow->Insert((pos + 1), mnuNewItem);
2358 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
2360 } else if (WData->DataType == 2){
2364 int intID = mnuSearchWindows->GetId();
2366 mnuWindow->FindChildItem(intID, &pos);
2367 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2368 mnuNewItem->SetId(WData->WindowID);
2369 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2370 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2371 WindowListType.insert(std::make_pair(WData->WindowID, 2));
2372 mnuWindow->Insert((pos + 1), mnuNewItem);
2373 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
2382 void frmMain::WindowEdit( wxCommandEvent &event ){
2384 // Edit a window in the window list.
2386 WindowData *WData = (WindowData*)event.GetClientData();
2388 if (WData->DataType == 0){
2390 // Get the window title and use that.
2392 frmContact *frmContactPtr = static_cast<frmContact*>(WData->WindowPointer);
2394 wxString WindowTitle = frmContactPtr->GetTitle();
2396 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2398 MenuIter->second->SetItemLabel(WindowTitle);
2400 } else if (WData->DataType == 1){
2402 // Get the window title and use that.
2404 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WData->WindowPointer);
2406 wxString WindowTitle = frmCEPtr->GetTitle();
2408 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2410 if (WindowTitle.IsEmpty()){
2412 MenuIter->second->SetItemLabel(_("Unnamed Contact"));
2416 MenuIter->second->SetItemLabel(WindowTitle);
2427 void frmMain::WindowDelete( wxCommandEvent &event ){
2429 // Delete a window from the window list.
2431 WindowData *WData = (WindowData*)event.GetClientData();
2433 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2435 mnuWindow->Remove(MenuIter->second);
2437 delete MenuIter->second;
2438 MenuIter->second = NULL;
2440 WindowListPointersMenu.erase(WData->WindowID);
2441 WindowListPointers.erase(WData->WindowID);
2442 WindowListType.erase(WData->WindowID);
2449 void frmMain::ShowContactWindow( wxCommandEvent &event ){
2451 // Show a contact window from the window list.
2453 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2455 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
2457 frmContactPtr->Show();
2458 frmContactPtr->Raise();
2462 void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
2464 // Show a contact editor window from the window list.
2466 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2468 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WindowIter->second);
2475 void frmMain::ShowSearchWindow( wxCommandEvent &event ){
2477 // Show a search window from the window list.
2479 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2481 frmSearch *frmSearchPtr = static_cast<frmSearch*>(WindowIter->second);
2483 frmSearchPtr->Show();
2484 frmSearchPtr->Raise();
2488 void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
2490 // Toggle the online/offline connection status.
2492 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2493 wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
2494 wxPostEvent(frameActMgr, toggconn);
2498 void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
2500 // Check the account type before continuing.
2502 wxString SeekAccount;
2503 wxString AccTypeLower;
2507 #if defined(__APPLE__)
2509 std::map<int, SecTrustRef>::iterator SSLTrustIter;
2511 for (int i = 0; i < prefaccounts.GetCount(); i++){
2513 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2514 AccType.Append(prefaccounts.GetAccountType(i));
2515 AccountSSL = prefaccounts.GetAccountSSL(i);
2516 AccTypeLower = AccType.MakeLower();
2517 SeekAccount.Append(wxT("."));
2518 SeekAccount.Append(AccTypeLower);
2520 if (SeekAccount == ActiveAccount){
2522 if (AccTypeLower == wxT("local")){
2528 if (AccountSSL == false){
2534 SSLTrustIter = AccountTrustData.find(i);
2536 // Setup and display the form.
2538 DisplayCertificate(SSLTrustIter->second);
2542 SeekAccount.Clear();
2543 AccTypeLower.Clear();
2548 #elif defined(__WIN32__)
2550 std::map<int, PCCERT_CONTEXT>::iterator SSLCertificateIter;
2552 for (int i = 0; i < prefaccounts.GetCount(); i++){
2554 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2555 AccType.Append(prefaccounts.GetAccountType(i));
2556 AccountSSL = prefaccounts.GetAccountSSL(i);
2557 AccTypeLower = AccType.MakeLower();
2558 SeekAccount.Append(wxT("."));
2559 SeekAccount.Append(AccTypeLower);
2561 if (SeekAccount == ActiveAccount){
2563 if (AccTypeLower == wxT("local")){
2569 if (AccountSSL == false){
2575 SSLCertificateIter = AccountCertificateData.find(i);
2577 // Setup and display the form.
2579 if (SSLCertificateIter->second->pCertInfo == NULL){
2581 wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
2585 BOOL ModifiedCertificateData;
2586 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
2588 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
2589 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
2594 //DisplayCertificate(SSLTrustIter->second);
2598 SeekAccount.Clear();
2599 AccTypeLower.Clear();
2606 std::map<int, SSLCertCollection>::iterator SSLColIter;
2608 for (int i = 0; i < prefaccounts.GetCount(); i++){
2610 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2611 AccType.Append(prefaccounts.GetAccountType(i));
2612 AccountSSL = prefaccounts.GetAccountSSL(i);
2613 AccTypeLower = AccType.MakeLower();
2614 SeekAccount.Append(wxT("."));
2615 SeekAccount.Append(AccTypeLower);
2617 if (SeekAccount == ActiveAccount){
2619 if (AccTypeLower == wxT("local")){
2625 if (AccountSSL == false){
2631 SSLColIter = AccountSSLData.find(i);
2633 SSLCertCollection SSLCertInfo = SSLColIter->second;
2635 frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
2636 frameSSLCert->StartCertFrom(0);
2637 frameSSLCert->SetupCerts(SSLCertInfo);
2638 frameSSLCert->ShowModal();
2640 delete frameSSLCert;
2641 frameSSLCert = NULL;
2645 SeekAccount.Clear();
2646 AccTypeLower.Clear();
2655 void frmMain::ShowSSLInfo( wxCommandEvent &event ){
2657 // Check the account type before continuing.
2661 void frmMain::HideSSLInfo( wxCommandEvent &event ){
2663 // Check the account type before continuing.
2667 void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
2669 if (event.GetInt() == 0){
2671 imgConnStatus->SetBitmap(*imgOnline);
2675 imgConnStatus->SetBitmap(*imgOffline);
2681 void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
2683 // Display the form for showing an invalid SSL certificate.
2685 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2686 SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
2687 SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
2688 wxString AccountName = SSLICNObj->AccountName;
2689 frameISC->LoadData(SSLCCData, AccountName);
2690 frameISC->ShowModal();
2692 int FinalConflictResult = frameISC->GetResult();
2694 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2695 event2.SetClientData(SSLICNObj->QRNotifData);
2696 event2.SetInt(FinalConflictResult);
2701 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2702 wxPostEvent(frameActMgr, event2);
2706 void frmMain::PauseAllTimers(){
2708 // Pause all the account timers.
2710 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2711 ASTiter != AccountSyncTimers.end(); ASTiter++){
2713 ASTiter->second->Stop();
2719 void frmMain::ResumeAllTimers(){
2721 // Resume all the account timers.
2723 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2724 ASTiter != AccountSyncTimers.end(); ASTiter++){
2726 ASTiter->second->Start();
2732 #if defined(__APPLE__)
2734 #elif defined(__WIN32__)
2736 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
2738 // Delete existing data.
2740 std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.find(AccountID);
2742 if (CertificateIter != AccountCertificateData.end()){
2743 CertFreeCertificateContext(CertificateIter->second);
2746 AccountCertificateData.erase(AccountID);
2747 AccountSSLResult.erase(AccountID);
2751 AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
2752 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2758 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollection SSLCertInc){
2760 // Delete existing data.
2762 AccountSSLData.erase(AccountID);
2763 AccountSSLResult.erase(AccountID);
2767 AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
2768 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2774 void frmMain::SetupSSLStatus( int AccountID ){
2776 // Check if account ID given is
2777 // the active account and if not, do nothing.
2780 wxString AccTypeLower;
2782 AccType = prefaccounts.GetAccountType(AccountID);
2783 AccTypeLower = AccType.MakeLower();
2785 wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
2788 if (AccountIDName != ActiveAccount){
2794 // Check if the account has SSL enabled.
2796 bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
2798 if (SSLInUse == FALSE){
2800 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2801 imgSSLStatus->SetBitmap(*imgNoSSL);
2805 // Get the SSL Collection Data.
2807 std::map<int,int>::iterator SSLResultIter = AccountSSLResult.find(AccountID);
2809 // Check if a result value has been set.
2811 if (SSLResultIter == AccountSSLResult.end()){
2813 imgSSLStatus->SetBitmap(*imgSSLWarning);
2814 SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
2819 if (SSLResultIter->second == 1){
2821 imgSSLStatus->SetBitmap(*imgSSLWarning);
2822 SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
2823 prefaccounts.GetAccountName(AccountID) +
2824 wxT("' (Connection denied by user)\n\nDouble click for more information."));
2826 } else if (SSLResultIter->second == 0){
2828 imgSSLStatus->SetBitmap(*imgSSL);
2829 SSLToolTip->SetTip(wxT("Account '") +
2830 prefaccounts.GetAccountName(AccountID) +
2831 wxT("' secured using SSL\n\nDouble click for more information."));
2839 void frmMain::CheckUpdates( wxCommandEvent& event ){
2841 // Check for updates to Xestia Address Book.
2843 frmUpdate *frameUpdate = new frmUpdate ( this );
2844 frameUpdate->FetchData();
2845 frameUpdate->ShowModal();
2849 void frmMain::OpenImportDialog( wxCommandEvent& event ){
2851 // Run the import contacts function.
2857 void frmMain::OpenExportDialog( wxCommandEvent& event ){
2859 // Check if an account and at least one contact is selected
2860 // before continuing.
2862 wxArrayString ArrData;
2864 if (ActiveAccount.IsEmpty()){
2870 int ContactSelected = 0;
2871 int ContactsCollected = 0;
2872 long longSelected = -1;
2876 longSelected = lstContacts->GetNextItem(longSelected,
2878 wxLIST_STATE_SELECTED);
2880 if (longSelected == -1){
2886 int FileID = (int)lstContacts->GetItemData(longSelected);
2888 ArrData.Insert(ContactsFileIndex[FileID],
2889 ContactsCollected, 1);
2895 if (ContactSelected == 0){
2901 // Run the export contacts system.
2903 ExportRun(this, &ArrData);
2907 void frmMain::GetListControl(wxListCtrl *lstContactsPtr,
2908 wxArrayString *ContactsFileIndexPtr){
2910 // Set the list control pointers.
2912 lstContactsPtr = lstContacts;
2913 ContactsFileIndexPtr = &ContactsFileIndex;
2917 void frmMain::GetSelectedList( wxCommandEvent& event ){
2919 // Get the array of contact filenames.
2921 wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
2923 // Process them into an array of files.
2925 long longSelected = -1;
2926 int ContactsCollected = 0;
2927 wxString ContactFilename;
2931 longSelected = lstContacts->GetNextItem(longSelected,
2933 wxLIST_STATE_SELECTED);
2935 if (longSelected == -1){
2941 // Get the file information and add to the list.
2943 int FileID = (int)lstContacts->GetItemData(longSelected);
2945 ArrData->Insert(ContactsFileIndex[FileID],
2946 ContactsCollected, 1);
2948 ContactsCollected++;
2949 ContactFilename.Clear();
2957 void frmMain::SyncAccount( wxCommandEvent& event ){
2959 // Syncronise the selected account.
2961 wxString AccNameInc = event.GetString();
2963 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2964 frameActMgr->AddTask(3, wxT(""), AccNameInc,
2965 wxT(""), wxT(""), wxT(""), wxT(""));
2969 void frmMain::ShowHelp( wxCommandEvent& event ){
2971 // Based on the operating system, work out where
2972 // the documentation should be.
2976 #if defined(__HAIKU__)
2978 #elif defined(__WIN32__)
2984 if (wxFileExists("/usr/share/doc/xestiaab/index.html")){
2986 wxLaunchDefaultBrowser(wxT("file:///usr/share/doc/xestiaab/index.html"));
2989 #if XSDAB_RELEASE == 0
2991 } else if (wxFileExists("/usr/local/share/doc/xestiaab/index.html")){
2993 wxLaunchDefaultBrowser(wxT("file:///usr/local/share/doc/xestiaab/index.html"));
3002 #if XSDAB_RELEASE == 0
3004 wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
3008 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!"));
3014 void frmMain::ShowImportResults( wxCommandEvent &event ){
3016 // Show the results of importing contacts.
3018 std::map<int,wxString> *ResultData = (std::map<int,wxString>*)event.GetClientData();
3020 frmImportResults *frmIR = new frmImportResults(this);
3021 frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
3032 void frmMain::ReloadContactList( wxCommandEvent &event ){
3034 // Check if the account name given is the current
3035 // account selected.
3037 if (ActiveAccount == event.GetString()){
3039 wxTreeEvent NullEvent;
3040 LoadContactList(NullEvent);
3046 void frmMain::ShowContactMenu( wxMouseEvent& event ){
3048 // Show the contact menu when a right click occurs
3049 // in the contacts list.
3051 bool EnableRefresh = FALSE;
3053 if (!ActiveAccount.IsEmpty()){
3055 EnableRefresh = TRUE;
3059 ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
3061 this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
3065 void frmMain::ResetContactInfo(){
3067 // Reset the contact information to an empty page.
3069 wxString EmptyPage = wxT("");
3070 htmContactData->SetPage(EmptyPage);
3071 AccCtrl->SetValue("");