1 // frmMain.cpp - Main window form.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
25 #include <wx/tokenzr.h>
27 #include <wx/mstream.h>
28 #include <wx/fs_mem.h>
30 #include <wx/filesys.h>
32 #include <wx/stdpaths.h>
33 #include <wx/fileconf.h>
34 #include <wx/gdicmn.h>
40 #include "frmPreferences.h"
41 #include "frmNewAccount.h"
42 #include "actmgr/frmActivityMgr.h"
43 #include "frmContact.h"
44 #include "frmConflictResolution.h"
45 #include "frmInvalidSSLCertificate.h"
46 #include "search/frmSearch.h"
47 #include "frmSSLCertificate.h"
48 #include "frmUpdate.h"
49 #include "import/frmImportResults.h"
52 #include "common/preferences.h"
53 #include "common/getcontactinfo.h"
54 #include "common/events.h"
55 #include "common/dirs.h"
56 #include "vcard/vcard.h"
57 #include "contacteditor/frmContactEditor.h"
58 #include "import/import.h"
59 #include "export/export.h"
60 #include "widgets/XABContactMenu.h"
61 #include "widgets/XABAccountView.h"
65 // Define the event types.
67 DEFINE_EVENT_TYPE(CE_UPDATECONTACTLIST);
68 DEFINE_EVENT_TYPE(CE_UPDATEACCOUNTLIST);
69 DEFINE_EVENT_TYPE(SE_UPDATECONTACTNOTIF);
70 DEFINE_EVENT_TYPE(CE_OPENCONTACT);
71 DEFINE_EVENT_TYPE(CE_OPENCONTACTLIST);
72 DEFINE_EVENT_TYPE(CE_NEWCONTACT);
73 DEFINE_EVENT_TYPE(CE_EDITCONTACT);
74 DEFINE_EVENT_TYPE(CE_DELETECONTACT);
75 DEFINE_EVENT_TYPE(CE_REVEALCONTACT);
76 DEFINE_EVENT_TYPE(CE_REMOVECONTACT);
77 DEFINE_EVENT_TYPE(CE_REMOVESEARCH);
78 DEFINE_EVENT_TYPE(SYNC_EMPTYSERVER);
79 DEFINE_EVENT_TYPE(ACTMGR_START);
80 DEFINE_EVENT_TYPE(ACTMGR_SHUFFLE);
81 DEFINE_EVENT_TYPE(ACTMGR_STOP);
82 DEFINE_EVENT_TYPE(WINDOW_ADD);
83 DEFINE_EVENT_TYPE(WINDOW_EDIT);
84 DEFINE_EVENT_TYPE(WINDOW_CLOSE);
85 DEFINE_EVENT_TYPE(CONNSTAT_UPDATE);
86 DEFINE_EVENT_TYPE(INVALIDSSLCERT);
87 DEFINE_EVENT_TYPE(INVALIDSSLCERTSTRING);
88 DEFINE_EVENT_TYPE(GETSELECTEDLIST);
89 DEFINE_EVENT_TYPE(SYNCACCOUNT);
90 DEFINE_EVENT_TYPE(IMPORT_RESULTSSHOW);
91 DEFINE_EVENT_TYPE(RELOADCONTACTLIST);
92 DEFINE_EVENT_TYPE(REFRESHADDRESSBOOK);
93 #if defined(__APPLE__)
94 DEFINE_EVENT_TYPE(INVALIDSSLTRUST);
97 // Setup the event table using the event types.
99 BEGIN_EVENT_TABLE(frmMain, wxFrame)
100 EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, frmMain::ConflictResolution)
101 EVT_COMMAND(wxID_ANY, CE_UPDATECONTACTLIST, frmMain::UpdateContactList)
102 EVT_COMMAND(wxID_ANY, CE_UPDATEACCOUNTLIST, frmMain::UpdateAccountList)
103 EVT_COMMAND(wxID_ANY, SE_UPDATECONTACTNOTIF, frmMain::UpdateSearchContactLists)
104 EVT_COMMAND(wxID_ANY, CE_OPENCONTACT, frmMain::OpenContactInfo)
105 EVT_COMMAND(wxID_ANY, CE_OPENCONTACTLIST, frmMain::OpenContactInfoList)
106 EVT_COMMAND(wxID_ANY, CE_NEWCONTACT, frmMain::ShowContactEditorNew)
107 EVT_COMMAND(wxID_ANY, CE_EDITCONTACT, frmMain::ShowContactEditorEdit)
108 EVT_COMMAND(wxID_ANY, CE_DELETECONTACT, frmMain::DeleteContact)
109 EVT_COMMAND(wxID_ANY, CE_REVEALCONTACT, frmMain::RevealContact)
110 EVT_COMMAND(wxID_ANY, CE_REMOVESEARCH, frmMain::RemoveContactsWindowPointer)
111 EVT_COMMAND(wxID_ANY, SYNC_EMPTYSERVER, frmMain::EmptyServerDialog)
112 EVT_COMMAND(wxID_ANY, ACTMGR_START, frmMain::ActivityIconStart)
113 EVT_COMMAND(wxID_ANY, ACTMGR_SHUFFLE, frmMain::ActivityIconShuffle)
114 EVT_COMMAND(wxID_ANY, ACTMGR_STOP, frmMain::ActivityIconStop)
115 EVT_COMMAND(wxID_ANY, WINDOW_ADD, frmMain::WindowAdd)
116 EVT_COMMAND(wxID_ANY, WINDOW_EDIT, frmMain::WindowEdit)
117 EVT_COMMAND(wxID_ANY, WINDOW_CLOSE, frmMain::WindowDelete)
118 EVT_COMMAND(wxID_ANY, CONNSTAT_UPDATE, frmMain::UpdateConnectionStatus)
119 EVT_COMMAND(wxID_ANY, INVALIDSSLCERT, frmMain::InvalidSSLCertificate)
120 EVT_COMMAND(wxID_ANY, INVALIDSSLCERTSTRING, frmMain::InvalidSSLCertificateString)
121 EVT_COMMAND(wxID_ANY, GETSELECTEDLIST, frmMain::GetSelectedList)
122 EVT_COMMAND(wxID_ANY, SYNCACCOUNT, frmMain::SyncAccount)
123 EVT_COMMAND(wxID_ANY, IMPORT_RESULTSSHOW, frmMain::ShowImportResults)
124 EVT_COMMAND(wxID_ANY, RELOADCONTACTLIST, frmMain::ReloadContactList)
125 EVT_COMMAND(wxID_ANY, REFRESHADDRESSBOOK, frmMain::RefreshAddressBook)
126 #if defined(__APPLE__)
127 EVT_COMMAND(wxID_ANY, INVALIDSSLTRUST, frmMain::DisplayTrustPanel)
131 frmMain::frmMain( wxWindow* parent )
136 // Setup the account icons.
138 wxMemoryInputStream astream(icons_accinet_png, sizeof(icons_accinet_png));
139 wxMemoryInputStream bstream(icons_acclocal_png, sizeof(icons_acclocal_png));
140 wxMemoryInputStream cstream(icons_accgroup_png, sizeof(icons_accgroup_png));
141 wxMemoryInputStream dstream(icons_accnone_png, sizeof(icons_accnone_png));
142 wxMemoryInputStream estream(icons_accunsupported_png, sizeof(icons_accunsupported_png));
144 wxImage icons_accinet_png(astream, wxBITMAP_TYPE_PNG);
145 wxBitmap AccInet(icons_accinet_png, -1);
147 wxIAccInet.CopyFromBitmap(AccInet);
149 wxImage icons_acclocal_png(bstream, wxBITMAP_TYPE_PNG);
150 wxBitmap AccNIcon(icons_acclocal_png, -1);
152 wxIAccNIcon.CopyFromBitmap(AccNIcon);
154 wxImage icons_accgroup_png(cstream, wxBITMAP_TYPE_PNG);
155 wxBitmap AccGrp(icons_accgroup_png, -1);
157 wxIAccGrp.CopyFromBitmap(AccGrp);
159 wxImage icons_accnone_png(dstream, wxBITMAP_TYPE_PNG);
160 wxBitmap AccNone(icons_accnone_png, -1);
162 wxIAccNone.CopyFromBitmap(AccNone);
164 wxImage icons_accunsupported_png(estream, wxBITMAP_TYPE_PNG);
165 wxBitmap AccUnsupported(icons_accunsupported_png, -1);
166 wxIcon wxIAccUnsupported;
167 wxIAccUnsupported.CopyFromBitmap(AccUnsupported);
169 AccountID = AccImgList->Add(wxIAccNIcon);
170 AccountNetID = AccImgList->Add(wxIAccInet);
171 AccountGrpID = AccImgList->Add(wxIAccGrp);
172 AccountNoneID = AccImgList->Add(wxIAccNone);
173 AccountUnsupportedID = AccImgList->Add(wxIAccUnsupported);
175 bmpIcon->SetIcon(AccImgList->GetIcon(AccountNoneID));
177 // Setup the status bar icons.
181 wxMemoryInputStream sslstream(icons_ssl_png, sizeof(icons_ssl_png));
182 wxMemoryInputStream sslwarningstream(icons_sslwarning_png, sizeof(icons_sslwarning_png));
183 wxMemoryInputStream nosslstream(icons_nossl_png, sizeof(icons_nossl_png));
185 wxImage icons_ssl_png(sslstream, wxBITMAP_TYPE_PNG);
186 imgSSL = new wxBitmap(icons_ssl_png, -1);
188 wxImage icons_sslwarning_png(sslwarningstream, wxBITMAP_TYPE_PNG);
189 imgSSLWarning = new wxBitmap(icons_sslwarning_png, -1);
191 wxImage icons_nossl_png(nosslstream, wxBITMAP_TYPE_PNG);
192 imgNoSSL = new wxBitmap(icons_nossl_png, -1);
196 wxMemoryInputStream act1(icons_act1_png, sizeof(icons_act1_png));
197 wxMemoryInputStream act2(icons_act2_png, sizeof(icons_act2_png));
198 wxMemoryInputStream act3(icons_act3_png, sizeof(icons_act3_png));
199 wxMemoryInputStream act4(icons_act4_png, sizeof(icons_act4_png));
200 wxMemoryInputStream actsleep(icons_actsleep_png, sizeof(icons_actsleep_png));
202 wxImage icons_actsleep_png(actsleep, wxBITMAP_TYPE_PNG);
203 imgActIconSleep = new wxBitmap (icons_actsleep_png, -1);
205 wxImage icons_act1_png(act1, wxBITMAP_TYPE_PNG);
206 imgActIcon1 = new wxBitmap (icons_act1_png, -1);
208 wxIAct1icon.CopyFromBitmap(*imgActIcon1);
210 wxImage icons_act2_png(act2, wxBITMAP_TYPE_PNG);
211 imgActIcon2 = new wxBitmap (icons_act2_png, -1);
213 wxIAct2icon.CopyFromBitmap(*imgActIcon2);
215 wxImage icons_act3_png(act3, wxBITMAP_TYPE_PNG);
216 imgActIcon3 = new wxBitmap (icons_act3_png, -1);
218 wxIAct3icon.CopyFromBitmap(*imgActIcon3);
220 wxImage icons_act4_png(act4, wxBITMAP_TYPE_PNG);
221 imgActIcon4 = new wxBitmap (icons_act4_png, -1);
223 wxIAct4icon.CopyFromBitmap(*imgActIcon4);
225 // Online/Offline icons.
227 wxMemoryInputStream onlinestream(icons_online_png, sizeof(icons_online_png));
228 wxMemoryInputStream offlinestream(icons_offline_png, sizeof(icons_offline_png));
230 wxImage icons_online_png(onlinestream, wxBITMAP_TYPE_PNG);
231 imgOnline = new wxBitmap(icons_online_png, -1);
233 wxImage icons_offline_png(offlinestream, wxBITMAP_TYPE_PNG);
234 imgOffline = new wxBitmap(icons_offline_png, -1);
236 // Setup the account view.
238 AccCtrl->SetPopupControl(treAccounts);
239 AccCtrl->SetPopupMaxHeight(175);
240 AccCtrl->SetPopupMinWidth(250);
241 treAccounts->AssignImageList(AccImgList);
243 wxListItem ColumnData;
245 ColumnData.SetText(wxT("Name0"));
246 ColumnData.SetWidth(320);
247 lstContacts->InsertColumn(0, ColumnData);
249 treAccounts->Connect(wxEVT_LEFT_DCLICK, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
250 treAccounts->Connect(wxEVT_TREE_SEL_CHANGED, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
252 #if defined(__HAIKU__)
254 #elif defined(__WIN32__)
256 int stbBottomData [4] = { -1, 8, 8, 8 };
260 int stbBottomData [4] = { -1, 20, 20, 20 };
264 stbBottom->SetFieldsCount(4, stbBottomData);
265 stbBottom->SetMinHeight(16);
270 stbBottom->GetFieldRect(1, rectOnline);
271 stbBottom->GetFieldRect(2, rectSSL);
272 stbBottom->GetFieldRect(3, rectActivity);
274 SSLToolTip = new wxToolTip(wxT(""));
276 imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectOnline.GetX()),(rectOnline.GetY())), wxDefaultSize, 0 );
277 imgConnStatus->SetBitmap(*imgOnline);
278 imgConnStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ToggleConnectionStatus ), NULL, this );
280 imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()),(rectSSL.GetY())), wxDefaultSize, 0 );
281 imgSSLStatus->SetBitmap(*imgNoSSL);
282 imgSSLStatus->SetToolTip(SSLToolTip);
283 imgSSLStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowSSLCertificates ), NULL, this );
285 imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()),(rectActivity.GetY())), wxDefaultSize, 0);
286 imgActivityStatus->SetBitmap(*imgActIconSleep);
287 imgActivityStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowActivityWindow ), NULL, this );
289 // Setup the window menu.
291 // By default should be:
296 // Contact editor windows:
302 mnuContactWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact windows:") ), wxEmptyString, wxITEM_NORMAL );
303 mnuWindow->Append( mnuContactWindows );
305 mnuWindow->AppendSeparator();
307 mnuContactEditorWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact editor windows:") ), wxEmptyString, wxITEM_NORMAL );
308 mnuWindow->Append( mnuContactEditorWindows );
310 mnuWindow->AppendSeparator();
312 mnuSearchWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( wxT("Search windows:") ), wxEmptyString, wxITEM_NORMAL );
313 mnuWindow->Append( mnuSearchWindows );
315 #if defined(__WIN32__)
320 mnuContactWindows->SetFont(fontstyle);
321 mnuContactEditorWindows->SetFont(fontstyle);
322 mnuSearchWindows->SetFont(fontstyle);
326 mnuContactWindows->Enable(FALSE);
327 mnuContactEditorWindows->Enable(FALSE);
328 mnuSearchWindows->Enable(FALSE);
332 // Hide unimplemented functions.
338 void frmMain::QuitApp( wxCloseEvent& event )
341 // Run the QuitApp function.
347 void frmMain::QuitApp( wxCommandEvent& event )
350 // Run the QuitApp function.
356 void frmMain::QuitApp()
359 // Function to run when quitting.
361 //Go through the windows and close each one (be it search
362 //or contact editor). Abort if user wants to cancel.
364 // Close the contact editor windows.
366 // Close the contact windows.
368 // Close the search windows.
370 // Write out the ETag databases.
372 // Save Preferences: Save the window position if that option is enabled.
374 wxString SetFilename = GetUserPrefDir();
376 #if defined(__HAIKU__)
380 #elif defined(__WIN32__)
382 SetFilename.Append(wxT("settings"));
388 SetFilename.Append(wxT("settings"));
392 wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
394 bool SaveWindowPos = FALSE;
395 wxString SaveWindowInc;
396 cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
398 if (SaveWindowInc == wxT("true")){
400 SaveWindowPos = TRUE;
404 if (SaveWindowPos == TRUE){
406 wxRect frmMainPos = this->GetRect();
408 cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
409 cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
410 cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
411 cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
418 //Everything closed... exit.
426 void frmMain::ShowActivityWindow( wxCommandEvent& event )
429 // Open the activity manager window.
431 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
432 frameActMgr->OpenWindow();
437 void frmMain::ShowAboutWindow( wxCommandEvent& event )
440 // Show the about window.
442 frmAbout *frameAbout = new frmAbout ( this );
443 frameAbout->SetupAboutWindow();
444 frameAbout->ShowModal();
450 void frmMain::OpenPreferences( wxCommandEvent& event)
453 // Open the preferences window.
455 ReloadAccounts = FALSE;
457 frmPreferences *framePreferences = new frmPreferences ( this );
458 framePreferences->SetupPointers(&ReloadAccounts);
459 framePreferences->ShowModal();
460 delete framePreferences;
461 framePreferences = NULL;
463 if (ReloadAccounts == TRUE){
465 // Reload the accounts as a change has been made within
466 // the application and clear the current contact information.
468 this->LoadPreferences();
469 this->ResetContactInfo();
475 void frmMain::OpenNewABDialog( wxCommandEvent& event)
478 // Open the new account dialog.
480 ReloadAccounts = FALSE;
482 frmNewAccount *frameNewAccount = new frmNewAccount ( this );
483 frameNewAccount->SetupPointers(&ReloadAccounts);
484 frameNewAccount->ShowModal();
485 delete frameNewAccount;
486 frameNewAccount = NULL;
488 if (ReloadAccounts == TRUE){
490 // Reload the accounts as a change has been made within
493 this->LoadPreferences();
499 void frmMain::LoadContactList( wxTreeEvent& event )
502 // Load the contact list.
504 // Clear all existing variables.
506 lstContacts->DeleteAllItems();
508 treAccounts->SetAccount();
510 wxTreeItemIdValue cookie;
511 wxTreeItemId next = treAccounts->GetRootItem();
512 wxString AccountName;
513 wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
514 wxString AccountDirCmb;
515 long selectedaccount = 0;
517 wxTreeItemId selectedChild = treAccounts->GetSelection();
518 wxTreeItemId nextChild;
520 wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
521 int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
523 int SCImg = treAccounts->GetItemImage(selectedChild);
524 int AccountIndex = 0;
526 bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
528 // Process each account.
530 for (int i = 0; i < prefaccounts.GetCount(); i++){
532 if (ActiveItemIcon == 2){
534 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
535 std::multimap<int, int>::iterator AGLiter = AccountGroupList.find(AGTiter->second);
536 int ActiveAccountG = AGLiter->second;
538 if (i == ActiveAccountG){
540 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
541 AccountType.Append(prefaccounts.GetAccountType(i));
546 if (AccountType == wxT("CardDAV")){
547 AccountTypeFinal.Append(wxT("carddav"));
548 } else if (AccountType == wxT("Local")){
549 imgSSLStatus->SetBitmap(*imgOffline);
550 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
551 AccountTypeFinal.Append(wxT("local"));
553 imgSSLStatus->SetBitmap(*imgOffline);
554 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
555 AccountTypeFinal.Append(AccountType.Lower());
566 nextChild = treAccounts->GetFirstChild(next, cookie);
568 nextChild = treAccounts->GetNextSibling(nextChild);
571 AccountName = treAccounts->GetItemText(nextChild);
573 if (nextChild == selectedChild){
575 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
576 AccountType.Append(prefaccounts.GetAccountType(i));
581 if (AccountType == wxT("CardDAV")){
582 AccountTypeFinal.Append(wxT("carddav"));
583 } else if (AccountType == wxT("Local")){
584 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
585 AccountTypeFinal.Append(wxT("local"));
587 AccountTypeFinal.Append(AccountType.Lower());
596 if (selectedaccount >= prefaccounts.GetCount()){
598 // The account selected isn't there so return.
606 // Open the directory and get the list of .vcf files
607 // in that directory.
609 ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
610 ActiveAccountType = AccountType;
612 SetupSSLStatus(AccountIndex);
614 AccountDirFinal.Clear();
615 AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
617 ContactsFileIndex.Clear();
619 wxString vCardFilename;
620 wxString vCardFilenameFull;
621 wxString vCardDataString;
622 wxStringTokenizer vcardfileline;
624 wxString setname, setvalue;
625 std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
626 std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
627 long ContactIndex = 1;
628 long ContactSeekPoint = 0;
630 wxDir vcardaccdir(AccountDirFinal);
632 // Get the wxTreeItemId and image icon and compare it to the list.
634 if (ActiveItemIcon == AccountGrpID){
636 // It's a group so load the file containing the group and
637 // get the members of the group.
642 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
643 std::multimap<int, wxString>::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
645 Group.LoadFile(AGFiter->second);
647 ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
649 for (int i = 0; i < vCardMember.PropCount; i++){
651 vCardMember.PropValues[i].Trim();
652 if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
654 wxString NewPropValue;
655 NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
656 vCardMember.PropValues[i] = NewPropValue;
662 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
666 if (vCardFilename.Right(4) == wxT(".vcf") ||
667 vCardFilename.Right(4) == wxT(".VCF") ||
668 vCardFilename.Right(5) == wxT(".vcard") ||
669 vCardFilename.Right(5) == wxT(".VCARD")){
672 bool FoundMember = FALSE;
674 vCardFilenameFull.Append(AccountDirFinal);
675 vCardFilenameFull.Append(wxT("/"));
676 vCardFilenameFull.Append(vCardFilename);
678 Person.LoadFile(vCardFilenameFull);
680 UIDCode = Person.Get(wxT("UID"));
682 for (int i = 0; i < vCardMember.PropCount; i++){
684 if (vCardMember.PropValues[i] == UIDCode){
692 if (FoundMember == FALSE){
694 vCardFilename.Clear();
695 vCardFilenameFull.Clear();
696 vCardDataString.Clear();
697 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
702 if (Person.MeetBaseSpecification()){
706 // Split the name into sections.
708 vCardDataString = Person.Get(wxT("N"));
710 vCardName NameData = Person.GetName();
712 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
714 } else if (SortMode == 2){
716 // Split the name into sections.
718 vCardName NameData = Person.GetName();
720 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
722 } else if (SortMode == 3){
724 // Check and make sure that the top most nickname is used.
726 vCardDataString = Person.Get(wxT("NICKNAME"));
728 if (vCardDataString.IsEmpty()){
730 vCardDataString = wxT("(no nickname)");
734 } else if (SortMode == 4){
736 vCardDataString = Person.Get(wxT("FN"));
740 if (AscendingMode == TRUE){
741 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
743 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
750 vCardFilename.Clear();
751 vCardFilenameFull.Clear();
752 vCardDataString.Clear();
753 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
759 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
762 if (vCardFilename.Right(4) == wxT(".vcf") ||
763 vCardFilename.Right(4) == wxT(".VCF") ||
764 vCardFilename.Right(5) == wxT(".vcard") ||
765 vCardFilename.Right(5) == wxT(".VCARD")){
769 vCardFilenameFull.Append(AccountDirFinal);
770 vCardFilenameFull.Append(vCardFilename);
772 Person.LoadFile(vCardFilenameFull);
774 if (Person.MeetBaseSpecification()){
778 // Split the name into sections.
780 vCardDataString = Person.Get(wxT("N"));
782 vCardName NameData = Person.GetName();
784 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
786 } else if (SortMode == 2){
788 // Split the name into sections.
790 vCardName NameData = Person.GetName();
792 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
794 } else if (SortMode == 3){
796 // Check and make sure that the top most nickname is used.
798 vCardDataString = Person.Get(wxT("NICKNAME"));
800 if (vCardDataString.IsEmpty()){
802 vCardDataString = wxT("(no nickname)");
806 } else if (SortMode == 4){
808 vCardDataString = Person.Get(wxT("FN"));
812 if (AscendingMode == TRUE){
814 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
818 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
826 vCardFilename.Clear();
827 vCardFilenameFull.Clear();
828 vCardDataString.Clear();
829 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
836 // Insert the data into the control.
838 if (AscendingMode == TRUE){
839 for (std::map<wxString, wxString>::iterator iter = vCardNamesAsc.begin();
840 iter != vCardNamesAsc.end(); ++iter){
842 wxListItem ContactInfo;
844 ContactInfo.SetId(0);
845 ContactInfo.SetText(_("Mooo"));
846 ContactInfo.SetData(ContactSeekPoint);
847 ContactIndex = lstContacts->InsertItem(ContactInfo);
849 lstContacts->SetItem(ContactIndex, 0, iter->first);
851 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
858 for (std::map<wxString, wxString>::iterator iter = vCardNamesDsc.begin();
859 iter != vCardNamesDsc.end(); ++iter){
861 wxListItem ContactInfo;
863 ContactInfo.SetId(0);
864 ContactInfo.SetText(_("Mooo"));
865 ContactInfo.SetData(ContactSeekPoint);
866 ContactIndex = lstContacts->InsertItem(ContactInfo);
868 lstContacts->SetItem(ContactIndex, 0, iter->first);
869 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
878 void frmMain::ShowContactInfo( wxListEvent& event )
881 // Display the contact information.
883 long intSelected = -1;
884 long ContactSeekNum = -1;
886 // Check if several contacts have been selected.
888 int ContactTotal = 0;
892 intSelected = lstContacts->GetNextItem(intSelected,
894 wxLIST_STATE_SELECTED);
896 if (intSelected == -1){
906 if (ContactTotal == 0){
907 htmContactData->SetPage(wxT(""));
911 if (ContactTotal > 1){
913 htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
914 ActiveFilename.Clear();
919 intSelected = lstContacts->GetNextItem(intSelected,
921 wxLIST_STATE_SELECTED);
923 ContactSeekNum = lstContacts->GetItemData(intSelected);
926 wxString wxSContactString;
927 wxString ContactLine;
930 size_t ContactLineLen;
931 bool ExtraLineSeek = FALSE;
932 int QuoteBreakPoint = 0;
934 bool PropertyFind = FALSE;
935 bool QuoteMode = FALSE;
937 wxString wxSPropertyNextLine;
938 wxString wxSProperty;
939 wxString wxSPropertySeg1;
940 wxString wxSPropertySeg2;
942 // Check if we are using wxWidgets version 2.8 or less and
943 // execute the required command accordingly.
945 #if wxABI_VERSION < 20900
946 ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
948 ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
951 if (ContactFile.IsOpened() == FALSE){
957 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
961 std::map<int, wxString> ContactFileLines;
962 std::map<int, wxString>::iterator striter;
964 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
966 int ContactLineSeek = 0;
968 while (wSTContactFileLines.HasMoreTokens() == TRUE){
970 ContactLine = wSTContactFileLines.GetNextToken();
971 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
976 if (ContactSeekNum < 0){
980 for (std::map<int, wxString>::iterator iter = ContactFileLines.begin();
981 iter != ContactFileLines.end(); ++iter){
983 // Find the colon which splits the start bit from the data part.
985 ContactLine = iter->second;
987 while (ExtraLineSeek == TRUE){
989 // Check if there is extra data on the next line
990 // (indicated by space or tab at the start) and add data.
994 if (iter == ContactFileLines.end()){
1001 wxSPropertyNextLine = iter->second;
1004 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1006 wxSPropertyNextLine.Remove(0, 1);
1007 ContactLine.Append(wxSPropertyNextLine);
1012 ExtraLineSeek = FALSE;
1018 ContactLineLen = ContactLine.Len();
1020 // Make sure we are not in quotation mode.
1021 // Make sure colon does not have \ or \\ before it.
1023 for (int i = 0; i <= ContactLineLen; i++){
1025 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1027 PropertyFind = FALSE;
1029 } else if (PropertyFind == TRUE){
1031 wxSProperty.Append(ContactLine.Mid(i, 1));
1035 if (ContactLine.Mid(i, 1) == wxT("\"")){
1037 if (QuoteMode == TRUE){
1049 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1051 QuoteBreakPoint = i;
1058 // Split that line at the point into two variables (ignore the colon).
1060 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1061 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1063 // Insert both into the vCard data file.
1065 Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
1068 PropertyFind = TRUE;
1069 ExtraLineSeek = TRUE;
1071 QuoteBreakPoint = 0;
1072 ContactLine.Clear();
1073 wxSProperty.Clear();
1077 OldSessionID = SessionID;
1078 SessionID = wxString::Format(wxT("%i"), rand() % 32768);
1079 LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList);
1080 ActiveFilename = ContactsFileIndex[ContactSeekNum];
1084 void frmMain::ShowContactEditorNew( wxCommandEvent& event )
1087 // Open a contact editor window to write a new contact with.
1089 // Check if there is an account selected and if not
1090 // return immediately.
1092 if (ActiveAccount.IsEmpty()){
1098 // Check if the account type is a valid account type, otherwise
1099 // display an error message.
1101 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1102 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1104 wxMessageBox(_("Cannot add a new contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1109 // Add Pointer to SetupPointers for the ETagDB.
1111 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1112 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1113 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1115 contacticon.CopyFromBitmap(contacticonbmp);
1117 frmContactEditor *ContactEditor = new frmContactEditor( this );
1121 ContactEditor->SetUID(WindowMenuItemID);
1123 WindowData *WData = new WindowData;
1125 WData->DataType = 1;
1126 WData->WindowPointer = (void*)ContactEditor;
1127 WData->WindowID = WindowMenuItemID;
1129 wxCommandEvent addevent(WINDOW_ADD);
1130 addevent.SetClientData(WData);
1131 wxPostEvent(this, addevent);
1133 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1134 ContactEditor->SetupHeaders();
1135 ContactEditor->SetupContact(ActiveAccount);
1136 ContactEditor->SetIcon(contacticon);
1137 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1138 ContactEditor->Show(true);
1142 void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
1145 // Open a contact editor window for editing an existing contact
1148 // Check if there is an account selected and if not
1149 // return immediately.
1151 int DataCheck = event.GetInt();
1153 if (ActiveAccount.IsEmpty() && DataCheck == 0){
1159 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1160 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1161 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1163 contacticon.CopyFromBitmap(contacticonbmp);
1165 // Check if a contact has been selected.
1167 long intSelected = -1;
1168 long intContactSeekNum = -1;
1170 intSelected = lstContacts->GetNextItem(intSelected,
1172 wxLIST_STATE_SELECTED);
1174 if (intSelected == -1){
1180 intContactSeekNum = lstContacts->GetItemData(intSelected);
1182 // Get the filename of the selected contact.
1184 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1185 frmContactEditor *ContactEditor = new frmContactEditor( this );
1189 ContactEditor->SetUID(WindowMenuItemID);
1191 WindowData *WData = new WindowData;
1193 WData->DataType = 1;
1194 WData->WindowPointer = (void*)ContactEditor;
1195 WData->WindowID = WindowMenuItemID;
1197 wxCommandEvent addevent(WINDOW_ADD);
1198 addevent.SetClientData(WData);
1199 wxPostEvent(this, addevent);
1201 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1202 ContactEditor->SetupHeaders();
1204 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1205 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1207 ContactEditor->SetupAccountData(true);
1211 // Check if pointer is NULL (not from the search forms) or not.
1213 if (DataCheck == 0){
1215 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1216 ContactEditor->SetupContact(ActiveAccount);
1220 UCNotif *uc = (UCNotif*)event.GetClientData();
1224 ContactEditor->SetupContact(ActiveAccount);
1225 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1229 ContactEditor->SetupContact(uc->ContactAccount);
1230 ContactEditor->LoadContact(uc->ContactFilename);
1239 ContactEditor->SetIcon(contacticon);
1240 ContactEditor->Show(true);
1244 void frmMain::RefreshAddressBook( wxCommandEvent& event ){
1246 // Refresh the address book data.
1248 // Check if ActiveAccount is empty. If not then check if
1249 // account type is not local otherwise continue.
1251 if (!ActiveAccount.IsEmpty()){
1253 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
1255 // Account type is not local.
1257 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1258 frameActMgr->AddTask(3, wxT(""), ActiveAccount,
1259 wxT(""), wxT(""), wxT(""), wxT(""));
1263 wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported"), wxICON_ERROR);
1271 void frmMain::OpenContactInfoList( wxListEvent& event )
1274 // Open the contact information window.
1276 wxStringTokenizer vcardfileline;
1279 wxString setname, setvalue;
1283 long intSelected = -1;
1284 long intContactSeekNum = -1;
1286 intSelected = lstContacts->GetNextItem(intSelected,
1288 wxLIST_STATE_SELECTED);
1290 intContactSeekNum = lstContacts->GetItemData(intSelected);
1292 if (intContactSeekNum == -1){
1298 Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
1300 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1301 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1302 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1304 contacticon.CopyFromBitmap(contacticonbmp);
1306 frmContact *Contact = new frmContact( this );
1308 // Add to window list.
1312 Contact->SetUID(WindowMenuItemID);
1314 WindowData *WData = new WindowData;
1316 WData->DataType = 0;
1317 WData->WindowPointer = (void*)Contact;
1318 WData->WindowID = WindowMenuItemID;
1320 wxCommandEvent addevent(WINDOW_ADD);
1321 addevent.SetClientData(WData);
1322 wxPostEvent(this, addevent);
1324 Contact->SetupPointers(&MemoryFileList);
1325 Contact->SetupContactData(&Person);
1327 Contact->SetIcon(contacticon);
1328 Contact->Show(true);
1332 void frmMain::OpenContactInfoList( wxCommandEvent& event ){
1334 // Open a list of contact information windows.
1337 OpenContactInfoList(pevent);
1341 void frmMain::OpenContactInfo( wxCommandEvent& event )
1344 // Open the contact information window.
1346 UCNotif *uc = (UCNotif*)event.GetClientData();
1348 wxStringTokenizer vcardfileline;
1351 wxString setname, setvalue;
1355 Person.LoadFile(uc->ContactFilename);
1357 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1358 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1359 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1361 contacticon.CopyFromBitmap(contacticonbmp);
1363 frmContact *Contact = new frmContact( this );
1365 // Add to window list.
1369 Contact->SetUID(WindowMenuItemID);
1371 WindowData *WData = new WindowData;
1373 WData->DataType = 0;
1374 WData->WindowPointer = (void*)Contact;
1375 WData->WindowID = WindowMenuItemID;
1377 wxCommandEvent addevent(WINDOW_ADD);
1378 addevent.SetClientData(WData);
1379 wxPostEvent(this, addevent);
1381 Contact->SetupPointers(&MemoryFileList);
1382 Contact->SetupContactData(&Person);
1384 Contact->SetIcon(contacticon);
1385 Contact->Show(true);
1390 void frmMain::LoadPreferences( wxActivateEvent& event)
1393 // Load the preferences.
1395 this->LoadPreferences();
1399 void frmMain::LoadPreferences(){
1401 // Load the preferences.
1403 wxString preffilename = GetUserPrefDir();
1405 XABPreferences preferences(preffilename);
1407 // Setup the main window position (if needed).
1409 bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
1410 bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
1412 if (SaveWindowPos == TRUE){
1414 this->SetSize(preferences.GetMainWindowData());
1418 treAccounts->DeleteAllItems();
1420 wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
1422 // Stop all account timers and remove the accounts.
1424 for (std::map<wxString, wxAccountSyncTimer*>::iterator iter = AccountSyncTimers.begin();
1425 iter != AccountSyncTimers.end(); iter++){
1427 wxAccountSyncTimer *AccTmrPtr = iter->second;
1435 #if defined(__WIN32__)
1437 for (std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.begin();
1438 CertificateIter != AccountCertificateData.end(); CertificateIter++){
1440 CertFreeCertificateContext(CertificateIter->second);
1444 AccountCertificateData.clear();
1448 AccountSyncTimers.clear();
1451 wxString AccDirFull;
1452 wxString AccDirFullSfx;
1454 wxString AccDirFinal;
1455 AccountAccDirList.clear();
1456 AccountGroupList.clear();
1457 AccountGroupFilename.clear();
1458 AccountGroupTreeId.clear();
1459 wxTreeItemId AccountTreeId;
1460 wxTreeItemId GroupTreeId;
1463 // Relaod the accounts for the ETagProcTimer.
1465 ETagProcTimer.ReloadAccounts();
1467 for (int i = 0; i < preferences.accounts.GetCount(); i++){
1469 if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
1470 preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == TRUE){
1476 if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
1482 AccDir = preferences.accounts.GetAccountDirectory(i);
1483 AccDirFull = preferences.accounts.GetAccountDirectory(i);
1485 AccDirFull.Append(wxT("."));
1486 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
1487 AccDirFullSfx.LowerCase();
1488 AccDirFullSfx.Trim();
1489 AccDirFull.Append(AccDirFullSfx);
1490 AccName = preferences.accounts.GetAccountName(i);
1492 AccountAccDirList.insert(std::make_pair(i, AccDirFull));
1494 if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
1495 preferences.accounts.GetAccountType(i) == wxT("carddav")){
1497 // TODO: Check if the directory exists before doing anything.
1501 // Add a new timer using the existing account details.
1503 wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
1505 ActTmrPtr->SetupData(AccDirFull, AccName);
1506 ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
1507 ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
1508 ActTmrPtr->SetOwner(this);
1509 ActTmrPtr->Notify();
1511 // Add the timer to the list of timers.
1513 AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
1515 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
1517 } else if (preferences.accounts.GetAccountType(i) == wxT("Local") ||
1518 preferences.accounts.GetAccountType(i) == wxT("local")) {
1520 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
1524 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountUnsupportedID, -1);
1528 // Go through the account directory and find contact files with
1529 // 'KIND:group' set and add them to the list of groups for the account.
1531 AccDirFinal = GetAccountDir(AccDirFull, FALSE);
1533 wxDir vcardaccdir(AccDirFinal);
1535 wxString vCardFilename;
1536 wxString vCardDataString;
1537 wxString vCardFilenameFull;
1539 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1543 if (vCardFilename.Right(4) == wxT(".vcf") ||
1544 vCardFilename.Right(4) == wxT(".VCF") ||
1545 vCardFilename.Right(5) == wxT(".vcard") ||
1546 vCardFilename.Right(5) == wxT(".VCARD")){
1550 vCardFilenameFull.Append(AccDirFinal);
1551 vCardFilenameFull.Append(wxT("/"));
1552 vCardFilenameFull.Append(vCardFilename);
1554 Person.LoadFile(vCardFilenameFull);
1556 if (Person.MeetBaseSpecification()){
1558 vCardDataString = Person.Get(wxT("KIND"));
1560 if (vCardDataString == wxT("group")){
1562 // The vCard kind is a group. Add to the account's group list.
1564 GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
1565 treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
1566 AccountGroupList.insert(std::make_pair(intGroupID, i));
1567 AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
1568 AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
1578 vCardFilename.Clear();
1579 vCardFilenameFull.Clear();
1580 vCardDataString.Clear();
1581 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1585 // Clearup for next account.
1589 AccDirFullSfx.clear();
1590 AccDirFinal.clear();
1595 // Load the account settings as they are needed for connecting
1598 prefaccounts = preferences.accounts;
1602 void frmMain::ConflictResolution(wxCommandEvent& event){
1604 // Display the conflict resolution window.
1606 frmConflictResolution *frameCR = new frmConflictResolution ( this );
1607 vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
1608 vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
1609 vCard *ServerDataPtr = vCardConfObj->vCardServerData;
1610 frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList);
1611 frameCR->ShowModal();
1613 int FinalConflictResult = frameCR->GetResult();
1615 wxCommandEvent event2(ACTMGR_RESUMEPROC);
1616 event2.SetClientData(vCardConfObj->QRNotifData);
1617 event2.SetInt(FinalConflictResult);
1622 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1623 wxPostEvent(frameActMgr, event2);
1627 void frmMain::UpdateContactList(wxCommandEvent& event){
1629 // Update the contact list in the main window.
1631 UCNotif *ucd = (UCNotif*)event.GetClientData();
1633 // Check if the active account is being displayed in the
1634 // main window. If not, skip and delete the data.
1636 long longSelected = -1;
1637 int intSelectedData = 0;
1639 if (ActiveAccount == ucd->ContactAccount){
1641 // Look at the list of contacts and if it matches the
1642 // filename then update the name.
1646 longSelected = lstContacts->GetNextItem(longSelected,
1648 wxLIST_STATE_DONTCARE);
1650 if (longSelected == -1){
1656 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1658 if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
1660 // Work out which sorting mode we are in.
1664 // First Name, Last Name.
1666 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
1668 } else if (SortMode == 2){
1670 // Last Name, First Name.
1672 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
1674 } else if (SortMode == 3){
1678 lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
1680 } else if (SortMode == 4){
1684 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1691 // If the filename is the one loaded into the
1692 // browser control, then update this too.
1694 if (ActiveFilename == ContactsFileIndex[intSelectedData]){
1696 wxListEvent nullevent;
1697 ShowContactInfo(nullevent);
1705 for (std::map<int, void*>::iterator WindowIter = WindowListPointers.begin();
1706 WindowIter != WindowListPointers.end(); WindowIter++){
1708 if (WindowListType[WindowIter->first] != 0){
1714 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
1716 if (frmContactPtr->GetFilename() == ucd->ContactFilename){
1718 vCard UpdatedPerson;
1719 UpdatedPerson.LoadFile(ucd->ContactFilename);
1720 frmContactPtr->SetupContactData(&UpdatedPerson);
1726 // Send message to search window controller subroutine and
1727 // pass that notification onto the search windows.
1729 // Setup the new pointer to use the existing UCNotif without
1732 UCNotif *ucd2 = ucd;
1734 wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
1735 sup.SetClientData(ucd2);
1736 wxPostEvent(this, sup);
1738 // Clear up the unused pointer.
1744 void frmMain::UpdateAccountList(wxCommandEvent& event){
1746 // Update the account list (currently unimplemented).
1750 void frmMain::SetupPointers(void *ActMgrPtrInc){
1752 // Setup the pointers for the main window.
1754 ActMgrPtr = ActMgrPtrInc;
1758 void frmMain::SetupForm(){
1760 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1761 frameActMgr->SetupPointers(&ETagProcTimer, this);
1763 // Setup the contact information icons for later.
1765 wxFileSystem::AddHandler(new wxMemoryFSHandler);
1769 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
1770 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
1771 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1773 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
1774 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
1775 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1777 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
1778 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
1779 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1781 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
1782 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
1783 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1785 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
1786 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
1787 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1789 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
1790 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
1791 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1797 void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
1799 // Update the contact lists in the search windows.
1801 // Go through each of the search windows and
1802 // send the required notification to update the
1803 // contact information.
1805 // Get the event notification data.
1807 UCNotif *ucd = (UCNotif*)event.GetClientData();
1809 // Process each search window giving the new details.
1811 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1812 switer != SearchWindowList.end(); switer++){
1814 // Duplicate the event notification data.
1816 UCNotif *ucd2 = new UCNotif;
1818 ucd2->ContactAccount = ucd->ContactAccount;
1819 ucd2->ContactFilename = ucd->ContactFilename;
1820 ucd2->ContactName = ucd->ContactName;
1821 ucd2->ContactNickname = ucd->ContactNickname;
1822 ucd2->ContactNameArray = ucd->ContactNameArray;
1824 // Pass the data to the search window for processing.
1826 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
1827 wxCommandEvent schupdate(SE_UPDATERESULT);
1828 schupdate.SetClientData(ucd2);
1829 wxPostEvent(frameSCH, schupdate);
1831 // Clear up the pointer prior to variable deletion.
1842 void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
1844 // Open a new search window.
1848 frmSearch *frameSCH = new frmSearch ( this );
1849 frameSCH->SetUID(WindowMenuItemID);
1850 frameSCH->Show(true);
1852 WindowData *WData = new WindowData;
1854 WData->DataType = 2;
1855 WData->WindowPointer = (void*)frameSCH;
1856 WData->WindowID = WindowMenuItemID;
1858 wxCommandEvent addevent(WINDOW_ADD);
1859 addevent.SetClientData(WData);
1860 wxPostEvent(this, addevent);
1862 // Add pointer to the list of open search windows.
1864 SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
1870 void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
1872 // Remove the pointer for a contact window from the
1875 void *frameSCH = (void*)event.GetClientData();
1877 SearchWindowList.erase(frameSCH);
1883 void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
1885 // Remove the pointer for a contact editor window from
1888 void *frameSCH = (void*)event.GetClientData();
1890 SearchWindowList.erase(frameSCH);
1896 void frmMain::RevealContact(wxCommandEvent& event){
1898 // Reveal a contact in the main window.
1900 UCNotif *uc = (UCNotif*)event.GetClientData();
1902 // Switch the account to the one passed.
1904 wxTreeItemIdValue cookie;
1905 wxTreeItemId next = treAccounts->GetRootItem();
1906 wxTreeItemId nextChild;
1908 for (int i = 0; i < prefaccounts.GetCount(); i++){
1911 nextChild = treAccounts->GetFirstChild(next, cookie);
1913 nextChild = treAccounts->GetNextSibling(nextChild);
1916 if (uc->ContactAccount == AccountAccDirList[i]){
1918 treAccounts->SelectItem(nextChild, TRUE);
1919 AccCtrl->SetText(treAccounts->GetItemText(nextChild));
1925 // Switch the contact to the one passed.
1927 long longSelected = -1;
1928 int intSelectedData = 0;
1932 longSelected = lstContacts->GetNextItem(longSelected,
1934 wxLIST_STATE_DONTCARE);
1936 if (longSelected == -1){
1942 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1944 // Compare the filename with the one received.
1945 // If they match then select it.
1947 if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
1951 lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1952 lstContacts->EnsureVisible(longSelected);
1956 lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
1964 void frmMain::DeleteContact(wxCommandEvent& event){
1966 // Delete a contact from the main window.
1968 // Check if a contact is selected.
1970 long intSelected = -1;
1971 long intContactSeekNum = -1;
1972 wxString wxSContactName;
1974 intSelected = lstContacts->GetNextItem(intSelected,
1976 wxLIST_STATE_SELECTED);
1978 if (intSelected == -1){
1982 // Check if the account type is a valid account type, otherwise
1983 // display an error message.
1985 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1986 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1988 wxMessageBox(_("Cannot delete contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1993 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1995 // Get the item data of the contact.
1997 intContactSeekNum = lstContacts->GetItemData(intSelected);
1999 // Get the name of the contact.
2001 wxSContactName = lstContacts->GetItemText(intSelected);
2003 // Display a message confirming if the contact should
2006 int QuestionResponse;
2008 QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
2010 if (QuestionResponse == wxNO){
2012 // Exit the subroutine
2018 // Delete the contact.
2020 if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
2022 wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
2027 // Remove the contact from the list.
2029 lstContacts->DeleteItem(intSelected);
2031 // Update the search windows, removing the deleted
2034 UCNotif *ucd = new UCNotif;
2036 ucd->ContactAccount = ActiveAccount;
2037 ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
2039 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
2040 switer != SearchWindowList.end(); switer++){
2042 // Duplicate the event notification data.
2044 UCNotif *ucd2 = new UCNotif;
2046 ucd2->ContactAccount = ucd->ContactAccount;
2047 ucd2->ContactFilename = ucd->ContactFilename;
2049 // Pass the data to the search window for processing.
2051 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
2052 wxCommandEvent schdelete(SE_DELETERESULT);
2053 schdelete.SetClientData(ucd2);
2054 wxPostEvent(frameSCH, schdelete);
2056 // Clear up the pointer prior to variable deletion.
2063 // Clear the wxHTMLWindow.
2065 wxString EmptyPage = wxT("");
2067 htmContactData->SetPage(EmptyPage);
2069 wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
2071 wxString wxSplitFilename;
2072 wxString wxSDataURL;
2074 while(wSTFilename.HasMoreTokens()){
2076 wxSplitFilename = wSTFilename.GetNextToken();
2080 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
2082 // Update the ETagDB and mark it as deleted.
2084 ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
2086 ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
2088 // Get the Data URL.
2090 wxTreeItemIdValue cookie;
2091 wxTreeItemId next = treAccounts->GetRootItem();
2093 wxTreeItemId selectedChild = treAccounts->GetSelection();
2094 wxTreeItemId nextChild;
2096 for (int i = 0; i < prefaccounts.GetCount(); i++){
2099 nextChild = treAccounts->GetFirstChild(next, cookie);
2101 nextChild = treAccounts->GetNextSibling(nextChild);
2104 if (nextChild == selectedChild){
2106 wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
2113 // Add task to the activity monitor to delete the contact.
2115 frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
2119 // Clear the variable. Don't delete as it will mess things up.
2121 ContactsFileIndex[intContactSeekNum] = wxT("");
2128 void frmMain::EmptyServerDialog(wxCommandEvent& event){
2130 // Display this message when the server information has changed
2133 QRNotif *qrn = (QRNotif *)event.GetClientData();
2135 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);
2137 if (QResponse == wxNO){
2143 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2144 event2.SetInt(*qrn->QResponse);
2145 event2.SetClientData(qrn->PausePtr);
2147 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2149 wxPostEvent(frameActMgr, event2);
2153 void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
2155 // Remove the contact from the window after syncronising.
2157 // Check which account is currently active in the window.
2158 // If it is different from the one passed to this subroutine then
2159 // exit from the subroutine.
2161 if (Account != ActiveAccount){
2165 long longSelected = -1;
2166 int intSelectedData = 0;
2170 longSelected = lstContacts->GetNextItem(longSelected,
2172 wxLIST_STATE_DONTCARE);
2174 if (longSelected == -1){
2180 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2182 // Compare the filename with the one received.
2183 // If they match then select it.
2185 if (ContactsFileIndex[intSelectedData] == Filename){
2187 // Remove the contact from the window.
2189 lstContacts->DeleteItem(intSelectedData);
2191 // Check if contact is the selected contact in the HTML window and
2192 // if it is then clear the window.
2194 if (ActiveFilename == Filename){
2196 wxString EmptyPage = wxT("");
2197 htmContactData->SetPage(EmptyPage);
2211 void frmMain::SortFNLN( wxCommandEvent& event ) {
2213 // Sort first name then last name.
2215 wxTreeEvent NullEvent;
2217 LoadContactList(NullEvent);
2221 void frmMain::SortLNFN( wxCommandEvent& event ) {
2223 // Sort last name then first name.
2225 wxTreeEvent NullEvent;
2227 LoadContactList(NullEvent);
2231 void frmMain::SortNickname( wxCommandEvent& event ) {
2233 // Sort by nickname.
2235 wxTreeEvent NullEvent;
2237 LoadContactList(NullEvent);
2241 void frmMain::SortDisplayAs( wxCommandEvent& event ) {
2243 // Sort by Display As name.
2245 wxTreeEvent NullEvent;
2247 LoadContactList(NullEvent);
2251 void frmMain::SortAscending( wxCommandEvent& event ) {
2255 wxTreeEvent NullEvent;
2256 AscendingMode = TRUE;
2257 LoadContactList(NullEvent);
2261 void frmMain::SortDescending( wxCommandEvent& event ) {
2265 wxTreeEvent NullEvent;
2266 AscendingMode = FALSE;
2267 LoadContactList(NullEvent);
2271 void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
2273 // Toggle the appearance of the status bar.
2275 if (stbBottom->IsShown() == TRUE){
2289 void frmMain::ActivityIconStart( wxCommandEvent& event ){
2291 // Display the activity icon.
2293 imgActivityStatus->SetBitmap(*imgActIcon1);
2294 ActivityIconStatus = 0;
2298 void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
2300 // Shuffle through the activity icons.
2302 switch (ActivityIconStatus){
2305 imgActivityStatus->SetBitmap(*imgActIcon1);
2306 ActivityIconStatus = 1;
2309 imgActivityStatus->SetBitmap(*imgActIcon2);
2310 ActivityIconStatus = 2;
2313 imgActivityStatus->SetBitmap(*imgActIcon3);
2314 ActivityIconStatus = 3;
2317 imgActivityStatus->SetBitmap(*imgActIcon4);
2318 ActivityIconStatus = 0;
2321 ActivityIconStatus = 0;
2327 void frmMain::ActivityIconStop( wxCommandEvent& event ){
2329 // Display the sleep icon.
2331 imgActivityStatus->SetBitmap(*imgActIconSleep);
2335 void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
2337 // Set the placement of the status bar icons.
2339 if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
2347 wxRect rectActivity;
2348 stbBottom->GetFieldRect(1, rectOnline);
2349 stbBottom->GetFieldRect(2, rectSSL);
2350 stbBottom->GetFieldRect(3, rectActivity);
2352 imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
2353 imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
2354 imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
2358 XABViewMode frmMain::GetViewMode(){
2360 // Set the view mode of the contact list.
2364 xvm.SortMode = SortMode;
2365 xvm.AscendingMode = AscendingMode;
2371 void frmMain::WindowAdd( wxCommandEvent &event ){
2373 // Add a window to the window list.
2375 WindowData *WData = (WindowData*)event.GetClientData();
2379 if (WData->DataType == 0){
2383 int intID = mnuContactWindows->GetId();
2385 mnuWindow->FindChildItem(intID, &pos);
2386 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2387 mnuNewItem->SetId(WData->WindowID);
2388 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2389 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2390 WindowListType.insert(std::make_pair(WData->WindowID, 0));
2391 mnuWindow->Insert((pos + 1), mnuNewItem);
2392 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
2394 } else if (WData->DataType == 1){
2396 // Contact Editor Window
2398 int intID = mnuContactEditorWindows->GetId();
2400 mnuWindow->FindChildItem(intID, &pos);
2401 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2402 mnuNewItem->SetId(WData->WindowID);
2403 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2404 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2405 WindowListType.insert(std::make_pair(WData->WindowID, 1));
2406 mnuWindow->Insert((pos + 1), mnuNewItem);
2407 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
2409 } else if (WData->DataType == 2){
2413 int intID = mnuSearchWindows->GetId();
2415 mnuWindow->FindChildItem(intID, &pos);
2416 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2417 mnuNewItem->SetId(WData->WindowID);
2418 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2419 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2420 WindowListType.insert(std::make_pair(WData->WindowID, 2));
2421 mnuWindow->Insert((pos + 1), mnuNewItem);
2422 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
2431 void frmMain::WindowEdit( wxCommandEvent &event ){
2433 // Edit a window in the window list.
2435 WindowData *WData = (WindowData*)event.GetClientData();
2437 if (WData->DataType == 0){
2439 // Get the window title and use that.
2441 frmContact *frmContactPtr = static_cast<frmContact*>(WData->WindowPointer);
2443 wxString WindowTitle = frmContactPtr->GetTitle();
2445 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2447 MenuIter->second->SetItemLabel(WindowTitle);
2449 } else if (WData->DataType == 1){
2451 // Get the window title and use that.
2453 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WData->WindowPointer);
2455 wxString WindowTitle = frmCEPtr->GetTitle();
2457 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2459 if (WindowTitle.IsEmpty()){
2461 MenuIter->second->SetItemLabel(_("Unnamed Contact"));
2465 MenuIter->second->SetItemLabel(WindowTitle);
2476 void frmMain::WindowDelete( wxCommandEvent &event ){
2478 // Delete a window from the window list.
2480 WindowData *WData = (WindowData*)event.GetClientData();
2482 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2484 mnuWindow->Remove(MenuIter->second);
2486 delete MenuIter->second;
2487 MenuIter->second = NULL;
2489 WindowListPointersMenu.erase(WData->WindowID);
2490 WindowListPointers.erase(WData->WindowID);
2491 WindowListType.erase(WData->WindowID);
2498 void frmMain::ShowContactWindow( wxCommandEvent &event ){
2500 // Show a contact window from the window list.
2502 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2504 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
2506 frmContactPtr->Show();
2507 frmContactPtr->Raise();
2511 void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
2513 // Show a contact editor window from the window list.
2515 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2517 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WindowIter->second);
2524 void frmMain::ShowSearchWindow( wxCommandEvent &event ){
2526 // Show a search window from the window list.
2528 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2530 frmSearch *frmSearchPtr = static_cast<frmSearch*>(WindowIter->second);
2532 frmSearchPtr->Show();
2533 frmSearchPtr->Raise();
2537 void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
2539 // Toggle the online/offline connection status.
2541 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2542 wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
2543 wxPostEvent(frameActMgr, toggconn);
2547 void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
2549 // Check the account type before continuing.
2551 wxString SeekAccount;
2552 wxString AccTypeLower;
2556 #if defined(__APPLE__)
2558 std::map<int, SecTrustRef>::iterator SSLTrustIter;
2560 for (int i = 0; i < prefaccounts.GetCount(); i++){
2562 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2563 AccType.Append(prefaccounts.GetAccountType(i));
2564 AccountSSL = prefaccounts.GetAccountSSL(i);
2565 AccTypeLower = AccType.MakeLower();
2566 SeekAccount.Append(wxT("."));
2567 SeekAccount.Append(AccTypeLower);
2569 if (SeekAccount == ActiveAccount){
2571 if (AccTypeLower == wxT("local")){
2577 if (AccountSSL == false){
2583 SSLTrustIter = AccountTrustData.find(i);
2585 // Setup and display the form.
2587 DisplayCertificate(SSLTrustIter->second);
2591 SeekAccount.Clear();
2592 AccTypeLower.Clear();
2597 #elif defined(__WIN32__)
2599 std::map<int, PCCERT_CONTEXT>::iterator SSLCertificateIter;
2601 for (int i = 0; i < prefaccounts.GetCount(); i++){
2603 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2604 AccType.Append(prefaccounts.GetAccountType(i));
2605 AccountSSL = prefaccounts.GetAccountSSL(i);
2606 AccTypeLower = AccType.MakeLower();
2607 SeekAccount.Append(wxT("."));
2608 SeekAccount.Append(AccTypeLower);
2610 if (SeekAccount == ActiveAccount){
2612 if (AccTypeLower == wxT("local")){
2618 if (AccountSSL == false){
2624 SSLCertificateIter = AccountCertificateData.find(i);
2626 // Setup and display the form.
2628 if (SSLCertificateIter->second->pCertInfo == NULL){
2630 wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
2634 BOOL ModifiedCertificateData;
2635 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
2637 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
2638 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
2643 //DisplayCertificate(SSLTrustIter->second);
2647 SeekAccount.Clear();
2648 AccTypeLower.Clear();
2655 std::map<int, SSLCertCollectionString>::iterator SSLColIter;
2657 for (int i = 0; i < prefaccounts.GetCount(); i++){
2659 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2660 AccType.Append(prefaccounts.GetAccountType(i));
2661 AccountSSL = prefaccounts.GetAccountSSL(i);
2662 AccTypeLower = AccType.MakeLower();
2663 SeekAccount.Append(wxT("."));
2664 SeekAccount.Append(AccTypeLower);
2666 if (SeekAccount == ActiveAccount){
2668 if (AccTypeLower == wxT("local")){
2674 if (AccountSSL == false){
2680 SSLColIter = AccountSSLData.find(i);
2682 SSLCertCollectionString SSLCertInfo = SSLColIter->second;
2684 frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
2685 frameSSLCert->StartCertFrom(0);
2686 frameSSLCert->SetupCertsString(SSLCertInfo);
2687 frameSSLCert->ShowModal();
2689 delete frameSSLCert;
2690 frameSSLCert = NULL;
2694 SeekAccount.Clear();
2695 AccTypeLower.Clear();
2704 void frmMain::ShowSSLInfo( wxCommandEvent &event ){
2706 // Check the account type before continuing.
2710 void frmMain::HideSSLInfo( wxCommandEvent &event ){
2712 // Check the account type before continuing.
2716 void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
2718 if (event.GetInt() == 0){
2720 imgConnStatus->SetBitmap(*imgOnline);
2724 imgConnStatus->SetBitmap(*imgOffline);
2730 void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
2732 // Display the form for showing an invalid SSL certificate.
2734 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2735 SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
2736 SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
2737 wxString AccountName = SSLICNObj->AccountName;
2738 frameISC->LoadData(SSLCCData, AccountName);
2739 frameISC->ShowModal();
2741 int FinalConflictResult = frameISC->GetResult();
2743 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2744 event2.SetClientData(SSLICNObj->QRNotifData);
2745 event2.SetInt(FinalConflictResult);
2750 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2751 wxPostEvent(frameActMgr, event2);
2755 void frmMain::InvalidSSLCertificateString( wxCommandEvent &event ){
2757 // Display the form for showing an invalid SSL certificate.
2759 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2760 SSLInvalidCertNotifObjString *SSLICNObj = (SSLInvalidCertNotifObjString*)event.GetClientData();
2761 SSLCertCollectionString SSLCCData = SSLICNObj->CertCollection;
2762 wxString AccountName = SSLICNObj->AccountName;
2763 frameISC->LoadData(SSLCCData, AccountName);
2764 frameISC->ShowModal();
2766 int FinalConflictResult = frameISC->GetResult();
2768 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2769 event2.SetClientData(SSLICNObj->QRNotifData);
2770 event2.SetInt(FinalConflictResult);
2775 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2776 wxPostEvent(frameActMgr, event2);
2780 void frmMain::PauseAllTimers(){
2782 // Pause all the account timers.
2784 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2785 ASTiter != AccountSyncTimers.end(); ASTiter++){
2787 ASTiter->second->Stop();
2793 void frmMain::ResumeAllTimers(){
2795 // Resume all the account timers.
2797 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2798 ASTiter != AccountSyncTimers.end(); ASTiter++){
2800 ASTiter->second->Start();
2806 #if defined(__APPLE__)
2808 #elif defined(__WIN32__)
2810 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
2812 // Delete existing data.
2814 std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.find(AccountID);
2816 if (CertificateIter != AccountCertificateData.end()){
2817 CertFreeCertificateContext(CertificateIter->second);
2820 AccountCertificateData.erase(AccountID);
2821 AccountSSLResult.erase(AccountID);
2825 AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
2826 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2832 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollectionString SSLCertInc){
2834 // Delete existing data.
2836 AccountSSLData.erase(AccountID);
2837 AccountSSLResult.erase(AccountID);
2841 AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
2842 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2848 void frmMain::SetupSSLStatus( int AccountID ){
2850 // Check if account ID given is
2851 // the active account and if not, do nothing.
2854 wxString AccTypeLower;
2856 AccType = prefaccounts.GetAccountType(AccountID);
2857 AccTypeLower = AccType.MakeLower();
2859 wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
2862 if (AccountIDName != ActiveAccount){
2868 // Check the account type is a supported account type.
2870 if (AccType != "CardDAV" && AccType != "carddav" &&
2871 AccType != "Local" && AccType != "local"){
2873 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2874 imgSSLStatus->SetBitmap(*imgNoSSL);
2879 // Check if the account has SSL enabled.
2881 bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
2883 if (SSLInUse == FALSE){
2885 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2886 imgSSLStatus->SetBitmap(*imgNoSSL);
2890 // Get the SSL Collection Data.
2892 std::map<int,int>::iterator SSLResultIter = AccountSSLResult.find(AccountID);
2894 // Check if a result value has been set.
2896 if (SSLResultIter == AccountSSLResult.end()){
2898 imgSSLStatus->SetBitmap(*imgSSLWarning);
2899 SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
2904 if (SSLResultIter->second == 1){
2906 imgSSLStatus->SetBitmap(*imgSSLWarning);
2907 SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
2908 prefaccounts.GetAccountName(AccountID) +
2909 wxT("' (Connection denied by user)\n\nDouble click for more information."));
2911 } else if (SSLResultIter->second == 0){
2913 imgSSLStatus->SetBitmap(*imgSSL);
2914 SSLToolTip->SetTip(wxT("Account '") +
2915 prefaccounts.GetAccountName(AccountID) +
2916 wxT("' secured using SSL\n\nDouble click for more information."));
2924 void frmMain::CheckUpdates( wxCommandEvent& event ){
2926 // Check for updates to Xestia Address Book.
2928 frmUpdate *frameUpdate = new frmUpdate ( this );
2929 frameUpdate->FetchData();
2930 frameUpdate->ShowModal();
2934 void frmMain::OpenImportDialog( wxCommandEvent& event ){
2936 // Run the import contacts function.
2942 void frmMain::OpenExportDialog( wxCommandEvent& event ){
2944 // Check if an account and at least one contact is selected
2945 // before continuing.
2947 wxArrayString ArrData;
2949 if (ActiveAccount.IsEmpty()){
2955 int ContactSelected = 0;
2956 int ContactsCollected = 0;
2957 long longSelected = -1;
2961 longSelected = lstContacts->GetNextItem(longSelected,
2963 wxLIST_STATE_SELECTED);
2965 if (longSelected == -1){
2971 int FileID = (int)lstContacts->GetItemData(longSelected);
2973 ArrData.Insert(ContactsFileIndex[FileID],
2974 ContactsCollected, 1);
2980 if (ContactSelected == 0){
2986 // Run the export contacts system.
2988 ExportRun(this, &ArrData);
2992 void frmMain::GetListControl(wxListCtrl *lstContactsPtr,
2993 wxArrayString *ContactsFileIndexPtr){
2995 // Set the list control pointers.
2997 lstContactsPtr = lstContacts;
2998 ContactsFileIndexPtr = &ContactsFileIndex;
3002 void frmMain::GetSelectedList( wxCommandEvent& event ){
3004 // Get the array of contact filenames.
3006 wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
3008 // Process them into an array of files.
3010 long longSelected = -1;
3011 int ContactsCollected = 0;
3012 wxString ContactFilename;
3016 longSelected = lstContacts->GetNextItem(longSelected,
3018 wxLIST_STATE_SELECTED);
3020 if (longSelected == -1){
3026 // Get the file information and add to the list.
3028 int FileID = (int)lstContacts->GetItemData(longSelected);
3030 ArrData->Insert(ContactsFileIndex[FileID],
3031 ContactsCollected, 1);
3033 ContactsCollected++;
3034 ContactFilename.Clear();
3042 void frmMain::SyncAccount( wxCommandEvent& event ){
3044 // Syncronise the selected account.
3046 wxString AccNameInc = event.GetString();
3048 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
3049 frameActMgr->AddTask(3, wxT(""), AccNameInc,
3050 wxT(""), wxT(""), wxT(""), wxT(""));
3054 void frmMain::ShowHelp( wxCommandEvent& event ){
3056 // Based on the operating system, work out where
3057 // the documentation should be.
3061 #if defined(__HAIKU__)
3063 #elif defined(__WIN32__)
3069 if (wxFileExists("/usr/share/doc/xestiaab/index.html")){
3071 wxLaunchDefaultBrowser(wxT("file:///usr/share/doc/xestiaab/index.html"));
3074 #if XSDAB_RELEASE == 0
3076 } else if (wxFileExists("/usr/local/share/doc/xestiaab/index.html")){
3078 wxLaunchDefaultBrowser(wxT("file:///usr/local/share/doc/xestiaab/index.html"));
3087 #if XSDAB_RELEASE == 0
3089 wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
3093 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!"));
3099 void frmMain::ShowImportResults( wxCommandEvent &event ){
3101 // Show the results of importing contacts.
3103 std::map<int,wxString> *ResultData = (std::map<int,wxString>*)event.GetClientData();
3105 frmImportResults *frmIR = new frmImportResults(this);
3106 frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
3117 void frmMain::ReloadContactList( wxCommandEvent &event ){
3119 // Check if the account name given is the current
3120 // account selected.
3122 if (ActiveAccount == event.GetString()){
3124 wxTreeEvent NullEvent;
3125 LoadContactList(NullEvent);
3131 void frmMain::ShowContactMenu( wxMouseEvent& event ){
3133 // Show the contact menu when a right click occurs
3134 // in the contacts list.
3136 bool EnableRefresh = FALSE;
3138 if (!ActiveAccount.IsEmpty() && (ActiveAccountType == "CardDAV" || ActiveAccountType == "carddav")){
3140 EnableRefresh = TRUE;
3144 ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
3146 this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
3150 void frmMain::ResetContactInfo(){
3152 // Reset the contact information to an empty page.
3154 wxString EmptyPage = wxT("");
3155 htmContactData->SetPage(EmptyPage);
3156 AccCtrl->SetValue("");