Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Move INSTALL, LICENSE, README, THANKS and TODO into root directory
[xestiaab/.git] / source / frmMain.cpp
1 // frmMain.cpp - Main window form.
2 //
3 // (c) 2012-2015 Xestia Software Development.
4 //
5 // This file is part of Xestia Address Book.
6 //
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.
10 //
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.
15 //
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/>
19 #include <cstdlib>
20 #include <iostream>
21 #include <algorithm>
22 #include <vector>
23 #include <thread>
25 #include <wx/wx.h>
26 #include <wx/tokenzr.h>
27 #include <wx/icon.h>
28 #include <wx/mstream.h>
29 #include <wx/fs_mem.h>
30 #include <wx/ffile.h>
31 #include <wx/filesys.h>
32 #include <wx/dir.h>
33 #include <wx/stdpaths.h>
34 #include <wx/fileconf.h>
35 #include <wx/gdicmn.h>
37 // Include the forms.
39 #include "frmMain.h"
40 #include "frmAbout.h"
41 #include "frmPreferences.h"
42 #include "frmNewAccount.h"
43 #include "actmgr/frmActivityMgr.h"
44 #include "frmContact.h"
45 #include "frmConflictResolution.h"
46 #include "frmInvalidSSLCertificate.h"
47 #include "search/frmSearch.h"
48 #include "frmSSLCertificate.h"
49 #include "frmUpdate.h"
50 #include "import/frmImportResults.h"
51 #include "bitmaps.h"
53 #include "common/preferences.h"
54 #include "common/getcontactinfo.h"
55 #include "common/events.h"
56 #include "common/dirs.h"
57 #include "vcard/vcard.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"
64 #include "version.h"
66 // Define the event types.
68 DEFINE_EVENT_TYPE(CE_UPDATECONTACTLIST);
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);
95 #endif
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, SE_UPDATECONTACTNOTIF, frmMain::UpdateSearchContactLists)
103 EVT_COMMAND(wxID_ANY, CE_OPENCONTACT, frmMain::OpenContactInfo)
104 EVT_COMMAND(wxID_ANY, CE_OPENCONTACTLIST, frmMain::OpenContactInfoList)
105 EVT_COMMAND(wxID_ANY, CE_NEWCONTACT, frmMain::ShowContactEditorNew)
106 EVT_COMMAND(wxID_ANY, CE_EDITCONTACT, frmMain::ShowContactEditorEdit)
107 EVT_COMMAND(wxID_ANY, CE_DELETECONTACT, frmMain::DeleteContact)
108 EVT_COMMAND(wxID_ANY, CE_REVEALCONTACT, frmMain::RevealContact)
109 EVT_COMMAND(wxID_ANY, CE_REMOVESEARCH, frmMain::RemoveContactsWindowPointer)
110 EVT_COMMAND(wxID_ANY, SYNC_EMPTYSERVER, frmMain::EmptyServerDialog)
111 EVT_COMMAND(wxID_ANY, ACTMGR_START, frmMain::ActivityIconStart)
112 EVT_COMMAND(wxID_ANY, ACTMGR_SHUFFLE, frmMain::ActivityIconShuffle)
113 EVT_COMMAND(wxID_ANY, ACTMGR_STOP, frmMain::ActivityIconStop)
114 EVT_COMMAND(wxID_ANY, WINDOW_ADD, frmMain::WindowAdd)
115 EVT_COMMAND(wxID_ANY, WINDOW_EDIT, frmMain::WindowEdit)
116 EVT_COMMAND(wxID_ANY, WINDOW_CLOSE, frmMain::WindowDelete)
117 EVT_COMMAND(wxID_ANY, CONNSTAT_UPDATE, frmMain::UpdateConnectionStatus)
118 EVT_COMMAND(wxID_ANY, INVALIDSSLCERT, frmMain::InvalidSSLCertificate)
119 EVT_COMMAND(wxID_ANY, INVALIDSSLCERTSTRING, frmMain::InvalidSSLCertificateString)
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)
127 #endif
128 END_EVENT_TABLE()
130 frmMain::frmMain( wxWindow* parent )
132 frmMainADT( parent )
134     
135         // Setup the account icons.
136     
137         wxMemoryInputStream astream(icons_accinet_png, sizeof(icons_accinet_png));
138         wxMemoryInputStream bstream(icons_acclocal_png, sizeof(icons_acclocal_png));
139         wxMemoryInputStream cstream(icons_accgroup_png, sizeof(icons_accgroup_png));
140         wxMemoryInputStream dstream(icons_accnone_png, sizeof(icons_accnone_png));
141         wxMemoryInputStream estream(icons_accunsupported_png, sizeof(icons_accunsupported_png));
142     
143         wxImage icons_accinet_png(astream, wxBITMAP_TYPE_PNG);
144         wxBitmap AccInet(icons_accinet_png, -1);
145         wxIcon wxIAccInet;
146         wxIAccInet.CopyFromBitmap(AccInet);
147     
148         wxImage icons_acclocal_png(bstream, wxBITMAP_TYPE_PNG);
149         wxBitmap AccNIcon(icons_acclocal_png, -1);
150         wxIcon wxIAccNIcon;
151         wxIAccNIcon.CopyFromBitmap(AccNIcon);
152     
153         wxImage icons_accgroup_png(cstream, wxBITMAP_TYPE_PNG);
154         wxBitmap AccGrp(icons_accgroup_png, -1);
155         wxIcon wxIAccGrp;
156         wxIAccGrp.CopyFromBitmap(AccGrp);
158         wxImage icons_accnone_png(dstream, wxBITMAP_TYPE_PNG);
159         wxBitmap AccNone(icons_accnone_png, -1);
160         wxIcon wxIAccNone;
161         wxIAccNone.CopyFromBitmap(AccNone);
162         
163         wxImage icons_accunsupported_png(estream, wxBITMAP_TYPE_PNG);
164         wxBitmap AccUnsupported(icons_accunsupported_png, -1);
165         wxIcon wxIAccUnsupported;
166         wxIAccUnsupported.CopyFromBitmap(AccUnsupported);
167     
168         AccountID = AccImgList->Add(wxIAccNIcon);
169         AccountNetID = AccImgList->Add(wxIAccInet);
170         AccountGrpID = AccImgList->Add(wxIAccGrp);
171         AccountNoneID = AccImgList->Add(wxIAccNone);
172         AccountUnsupportedID = AccImgList->Add(wxIAccUnsupported);
173     
174         bmpIcon->SetIcon(AccImgList->GetIcon(AccountNoneID));
175     
176         // Setup the status bar icons.
177     
178         // SSL icons.
179     
180         wxMemoryInputStream sslstream(icons_ssl_png, sizeof(icons_ssl_png));
181         wxMemoryInputStream sslwarningstream(icons_sslwarning_png, sizeof(icons_sslwarning_png));
182         wxMemoryInputStream nosslstream(icons_nossl_png, sizeof(icons_nossl_png));
183     
184         wxImage icons_ssl_png(sslstream, wxBITMAP_TYPE_PNG);
185         imgSSL = new wxBitmap(icons_ssl_png, -1);
186     
187         wxImage icons_sslwarning_png(sslwarningstream, wxBITMAP_TYPE_PNG);
188         imgSSLWarning = new wxBitmap(icons_sslwarning_png, -1);
189     
190         wxImage icons_nossl_png(nosslstream, wxBITMAP_TYPE_PNG);
191         imgNoSSL = new wxBitmap(icons_nossl_png, -1);
192  
193         // Toolbar icons.
195         wxMemoryInputStream addaddressbook(toolbar_addaddressbook_png, sizeof(toolbar_addaddressbook_png));
196         wxMemoryInputStream preferences(toolbar_preferences_png, sizeof(toolbar_preferences_png));
197         wxMemoryInputStream searchcontacts(toolbar_searchcontacts_png, sizeof(toolbar_searchcontacts_png));
198         wxMemoryInputStream addcontact(toolbar_addcontact_png, sizeof(toolbar_addcontact_png));
199         wxMemoryInputStream editcontact(toolbar_editcontact_png, sizeof(toolbar_editcontact_png));
200         wxMemoryInputStream deletecontact(toolbar_deletecontact_png, sizeof(toolbar_deletecontact_png));
202         wxImage toolbar_addaddressbook_png(addaddressbook, wxBITMAP_TYPE_PNG);
203         imgAddAddressBook = new wxBitmap (toolbar_addaddressbook_png, -1);
204         tblMain->SetToolNormalBitmap(tbtNewAccount->GetId(), *imgAddAddressBook);
206         wxImage toolbar_preferences_png(preferences, wxBITMAP_TYPE_PNG);
207         imgPreferences = new wxBitmap (toolbar_preferences_png, -1);
208         tblMain->SetToolNormalBitmap(tbtPreferences->GetId(), *imgPreferences);
210         wxImage toolbar_searchcontacts_png(searchcontacts, wxBITMAP_TYPE_PNG);
211         imgSearchContacts = new wxBitmap (toolbar_searchcontacts_png, -1);
212         tblMain->SetToolNormalBitmap(tbtSearch->GetId(), *imgSearchContacts);
214         wxImage toolbar_addcontact_png(addcontact, wxBITMAP_TYPE_PNG);
215         imgAddContact = new wxBitmap (toolbar_addcontact_png, -1);
216         tblMain->SetToolNormalBitmap(tbtAddContact->GetId(), *imgAddContact);
217         
218         wxImage toolbar_editcontact_png(editcontact, wxBITMAP_TYPE_PNG);
219         imgEditContact = new wxBitmap (toolbar_editcontact_png, -1);
220         tblMain->SetToolNormalBitmap(tbtEditContact->GetId(), *imgEditContact);
221         
222         wxImage toolbar_deletecontact_png(deletecontact, wxBITMAP_TYPE_PNG);
223         imgDeleteContact = new wxBitmap (toolbar_deletecontact_png, -1);
224         tblMain->SetToolNormalBitmap(tbtDeleteContact->GetId(), *imgDeleteContact);
226         // Activity Icon.
227     
228         wxMemoryInputStream act1(icons_act1_png, sizeof(icons_act1_png));
229         wxMemoryInputStream act2(icons_act2_png, sizeof(icons_act2_png));
230         wxMemoryInputStream act3(icons_act3_png, sizeof(icons_act3_png));
231         wxMemoryInputStream act4(icons_act4_png, sizeof(icons_act4_png));
232         wxMemoryInputStream actsleep(icons_actsleep_png, sizeof(icons_actsleep_png));
233     
234         wxImage icons_actsleep_png(actsleep, wxBITMAP_TYPE_PNG);
235         imgActIconSleep = new wxBitmap (icons_actsleep_png, -1);
236     
237         wxImage icons_act1_png(act1, wxBITMAP_TYPE_PNG);
238         imgActIcon1 = new wxBitmap (icons_act1_png, -1);
239         wxIcon wxIAct1icon;
240         wxIAct1icon.CopyFromBitmap(*imgActIcon1);
241     
242         wxImage icons_act2_png(act2, wxBITMAP_TYPE_PNG);
243         imgActIcon2 = new wxBitmap (icons_act2_png, -1);
244         wxIcon wxIAct2icon;
245         wxIAct2icon.CopyFromBitmap(*imgActIcon2);
246     
247         wxImage icons_act3_png(act3, wxBITMAP_TYPE_PNG);
248         imgActIcon3 = new wxBitmap (icons_act3_png, -1);
249         wxIcon wxIAct3icon;
250         wxIAct3icon.CopyFromBitmap(*imgActIcon3);
251     
252         wxImage icons_act4_png(act4, wxBITMAP_TYPE_PNG);
253         imgActIcon4 = new wxBitmap (icons_act4_png, -1);
254         wxIcon wxIAct4icon;
255         wxIAct4icon.CopyFromBitmap(*imgActIcon4);
256     
257         // Online/Offline icons.
258     
259         wxMemoryInputStream onlinestream(icons_online_png, sizeof(icons_online_png));
260         wxMemoryInputStream offlinestream(icons_offline_png, sizeof(icons_offline_png));
261     
262         wxImage icons_online_png(onlinestream, wxBITMAP_TYPE_PNG);
263         imgOnline = new wxBitmap(icons_online_png, -1);
264     
265         wxImage icons_offline_png(offlinestream, wxBITMAP_TYPE_PNG);
266         imgOffline = new wxBitmap(icons_offline_png, -1);
267     
268         // Setup the account view.
269     
270         AccCtrl->SetPopupControl(treAccounts);
271         AccCtrl->SetPopupMaxHeight(175);
272         AccCtrl->SetPopupMinWidth(250);
273         treAccounts->AssignImageList(AccImgList);
274     
275         wxListItem ColumnData;
276         ColumnData.SetId(0);
277         ColumnData.SetText(wxT("Name0"));
278         ColumnData.SetWidth(320);
279         lstContacts->InsertColumn(0, ColumnData);
280     
281         treAccounts->Connect(wxEVT_LEFT_DCLICK, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
282         treAccounts->Connect(wxEVT_TREE_SEL_CHANGED, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
283     
284 #if defined(__HAIKU__)
285     
286 #elif defined(__WIN32__)
287     
288         int stbBottomData [4] = { -1, 8, 8, 8 };
289     
290 #else
291     
292         int stbBottomData [4] = { -1, 20, 20, 20 };
293     
294 #endif
295     
296         stbBottom->SetFieldsCount(4, stbBottomData);
297         stbBottom->SetMinHeight(16);
298     
299         wxRect rectOnline;
300         wxRect rectSSL;
301         wxRect rectActivity;
302         stbBottom->GetFieldRect(1, rectOnline);
303         stbBottom->GetFieldRect(2, rectSSL);
304         stbBottom->GetFieldRect(3, rectActivity);
305     
306         SSLToolTip = new wxToolTip(wxT(""));
307     
308         imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectOnline.GetX()),(rectOnline.GetY())), wxDefaultSize, 0 );
309         imgConnStatus->SetBitmap(*imgOnline);
310         imgConnStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ToggleConnectionStatus ), NULL, this );
311     
312         imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()),(rectSSL.GetY())), wxDefaultSize, 0 );
313         imgSSLStatus->SetBitmap(*imgNoSSL);
314         imgSSLStatus->SetToolTip(SSLToolTip);
315         imgSSLStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowSSLCertificates ), NULL, this );
316     
317         imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()),(rectActivity.GetY())), wxDefaultSize, 0);
318         imgActivityStatus->SetBitmap(*imgActIconSleep);
319         imgActivityStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowActivityWindow ), NULL, this );
320     
321         // Setup the window menu.
322     
323         // By default should be:
324     
325         // Contact windows:
326         // (none)
327         // (horizontal line)
328         // Contact editor windows:
329         // (none)
330         // (horizontal line)
331         // Search windows:
332         // (none)
333     
334         mnuContactWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact windows:") ), wxEmptyString, wxITEM_NORMAL );
335         mnuWindow->Append( mnuContactWindows );
336     
337         mnuWindow->AppendSeparator();
338     
339         mnuContactEditorWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact editor windows:") ), wxEmptyString, wxITEM_NORMAL );
340         mnuWindow->Append( mnuContactEditorWindows );
341     
342         mnuWindow->AppendSeparator();
343     
344         mnuSearchWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( wxT("Search windows:") ), wxEmptyString, wxITEM_NORMAL );
345         mnuWindow->Append( mnuSearchWindows );
346     
347 #if defined(__WIN32__)
348     
349         wxFont fontstyle;
350         fontstyle.Bold();
351     
352         mnuContactWindows->SetFont(fontstyle);
353         mnuContactEditorWindows->SetFont(fontstyle);
354         mnuSearchWindows->SetFont(fontstyle);
355     
356 #else
357     
358         mnuContactWindows->Enable(FALSE);
359         mnuContactEditorWindows->Enable(FALSE);
360         mnuSearchWindows->Enable(FALSE);
361     
362 #endif
363     
364         // Hide unimplemented functions.
365     
366         mnuMain->Remove(3);
367     
370 void frmMain::QuitApp( wxCloseEvent& event )
373         // Run the QuitApp function.
375         QuitApp();
379 void frmMain::QuitApp( wxCommandEvent& event )
381     
382         // Run the QuitApp function.
383     
384         QuitApp();
385     
388 void frmMain::QuitApp()
391         // Function to run when quitting.
392         
393         // Write out the ETag databases.
394         
395         ETagProcTimer.Stop();
396         ETagProcTimer.Notify();
397     
398         // Save Preferences: Save the window position if that option is enabled.
399     
400         wxString SetFilename = GetUserPrefDir();
401     
402 #if defined(__HAIKU__)
403     
404     
405     
406 #elif defined(__WIN32__)
407     
408         SetFilename.Append(wxT("settings"));
409     
410 #elif defined(__APPLE__)
411         
412         TerminateHelpBrowserProcess();
413         
414 #else
415     
416         // *nix OSes
417     
418         SetFilename.Append(wxT("settings"));
419     
420 #endif
421     
422         wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
423     
424         bool SaveWindowPos = FALSE;
425         wxString SaveWindowInc;
426         cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
427     
428         if (SaveWindowInc == wxT("true")){
429         
430                 SaveWindowPos = TRUE;
431         
432         }
433     
434         if (SaveWindowPos == TRUE){
435         
436                 wxRect frmMainPos = GetRect();
437         
438                 cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
439                 cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
440                 cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
441                 cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
442         
443         }
444     
445         delete cfgfile;
446         cfgfile = NULL;
447     
448         // Everything closed... exit.
449     
450         std::exit(0);
451     
452         Close();
453     
456 void frmMain::ShowActivityWindow( wxCommandEvent& event )
458     
459         // Open the activity manager window.
460     
461         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
462         frameActMgr->OpenWindow();
463         frameActMgr->Show();
464     
467 void frmMain::ShowAboutWindow( wxCommandEvent& event )
470         // Show the about window.
471     
472         frmAbout *frameAbout = new frmAbout ( this );
473         frameAbout->SetupAboutWindow();
474         frameAbout->ShowModal();
475         delete frameAbout;
476         frameAbout = NULL;
477     
480 void frmMain::OpenPreferences( wxCommandEvent& event)
483         // Close all windows first.
484         
485         if (CloseAllWindows() == false)
486         {
487                 return;
488         }
490         // Open the preferences window.
491     
492         ReloadAccounts = FALSE;
493     
494         frmPreferences *framePreferences = new frmPreferences ( this );
495         framePreferences->SetupPointers(&ReloadAccounts);
496         framePreferences->ShowModal();
497         delete framePreferences;
498         framePreferences = NULL;
499     
500         if (ReloadAccounts == TRUE){
501         
502                 // Reload the accounts as a change has been made within
503                 // the application and clear the current contact information.
504         
505                 this->LoadPreferences(true);
506                 this->ResetContactInfo();
507         
508         }
509     
512 void frmMain::OpenNewABDialog( wxCommandEvent& event)
515         // Open the new account dialog.
516     
517         ReloadAccounts = FALSE;
518     
519         frmNewAccount *frameNewAccount = new frmNewAccount ( this );
520         frameNewAccount->SetupPointers(&ReloadAccounts);
521         frameNewAccount->ShowModal();
522         delete frameNewAccount;
523         frameNewAccount = NULL;
524         
525         if (ReloadAccounts == TRUE){
526             
527                 // Reload the accounts as a change has been made within
528                 // the application.
529         
530                 this->LoadPreferences(true);
532         }
533     
536 void frmMain::LoadContactList( wxTreeEvent& event )
538     
539         // Load the contact list.
540     
541         // Clear all existing variables.
542     
543         lstContacts->DeleteAllItems();
544     
545         treAccounts->SetAccount();
546     
547         wxTreeItemIdValue cookie;
548         wxTreeItemId next = treAccounts->GetRootItem();
549         wxString AccountName;
550         wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
551         wxString AccountDirCmb;
552         long selectedaccount = 0;
553     
554         wxTreeItemId selectedChild = treAccounts->GetSelection();
555         wxTreeItemId nextChild;
556     
557         wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
558         int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
559     
560         int SCImg = treAccounts->GetItemImage(selectedChild);
561         int AccountIndex = 0;
562     
563         bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
564     
565         // Process each account.
566     
567         for (int i = 0; i < prefaccounts.GetCount(); i++){
568         
569                 if (ActiveItemIcon == 2){
570             
571                         std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
572                         std::multimap<int, int>::iterator AGLiter = AccountGroupList.find(AGTiter->second);
573                         int ActiveAccountG = AGLiter->second;
574             
575                         if (i == ActiveAccountG){
576                 
577                                 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
578                                 AccountType.Append(prefaccounts.GetAccountType(i));
579                 
580                                 AccountDir.Trim();
581                                 AccountType.Trim();
582                 
583                                 if (AccountType == wxT("CardDAV")){
584                                         AccountTypeFinal.Append(wxT("carddav"));
585                                 } else if (AccountType == wxT("Local")){
586                                         imgSSLStatus->SetBitmap(*imgOffline);
587                                         SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
588                                         AccountTypeFinal.Append(wxT("local"));
589                                 } else {
590                                         imgSSLStatus->SetBitmap(*imgOffline);
591                                         SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));                                       
592                                         AccountTypeFinal.Append(AccountType.Lower());
593                                 }
594                 
595                                 AccountIndex = i;
596                                 break;
597                 
598                         }
599             
600                 }
601         
602                 if (!nextChild){
603                         nextChild = treAccounts->GetFirstChild(next, cookie);
604                 } else {
605                         nextChild = treAccounts->GetNextSibling(nextChild);
606                 }
607         
608                 AccountName = treAccounts->GetItemText(nextChild);
609         
610                 if (nextChild == selectedChild){
611                         
612                         AccountDir.Append(prefaccounts.GetAccountDirectory(i));
613                         AccountType.Append(prefaccounts.GetAccountType(i));
614             
615                         AccountDir.Trim();
616                         AccountType.Trim();
617             
618                         if (AccountType == wxT("CardDAV")){
619                                 AccountTypeFinal.Append(wxT("carddav"));
620                         } else if (AccountType == wxT("Local")){
621                                 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
622                                 AccountTypeFinal.Append(wxT("local"));
623                         } else {
624                                 AccountTypeFinal.Append(AccountType.Lower());
625                         }
626             
627                         AccountIndex = i;
628             
629                 }
630         
631         }
632     
633         if (selectedaccount >= prefaccounts.GetCount()){
634         
635                 // The account selected isn't there so return.
636         
637                 RevealWait = FALSE;
638         
639                 return;
640         
641         }
642     
643         // Open the directory and get the list of .vcf files
644         // in that directory.
645     
646         ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
647         ActiveAccountType = AccountType;
648     
649         SetupSSLStatus(AccountIndex);
650     
651         AccountDirFinal.Clear();
652         AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
653     
654         ContactsFileIndex.Clear();
655     
656         wxString vCardFilename;
657         wxString vCardFilenameFull;
658         wxString vCardDataString;
659         wxStringTokenizer vcardfileline;
660         wxString lwxs;
661         wxString setname, setvalue;
662         std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
663         std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
664         long ContactIndex = 1;
665         long ContactSeekPoint = 0;
666     
667         wxDir vcardaccdir(AccountDirFinal);
669         // Get the wxTreeItemId and image icon and compare it to the list.
670     
671         if (ActiveItemIcon == AccountGrpID){
672         
673                 // It's a group so load the file containing the group and
674                 // get the members of the group.
675         
676                 vCard Group;
677                 wxString UIDCode;
678         
679                 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
680                 std::multimap<int, wxString>::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
681        
682                 Group.LoadFile(AGFiter->second);
683         
684                 ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
685         
686                 for (int i = 0; i < vCardMember.PropCount; i++){
687             
688                         vCardMember.PropValues[i].Trim();
689                         if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
690                 
691                                 wxString NewPropValue;
692                                 NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
693                                 vCardMember.PropValues[i] = NewPropValue;
694                 
695                         }
696             
697                 }
698         
699                 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
700         
701                 while(ProcFiles){
702             
703                         if (vCardFilename.Right(4) == wxT(".vcf") ||
704                                 vCardFilename.Right(4) == wxT(".VCF") ||
705                                 vCardFilename.Right(5) == wxT(".vcard") ||
706                                 vCardFilename.Right(5) == wxT(".VCARD")){
707                 
708                                 vCard Person;
709                                 bool FoundMember = FALSE;
710                 
711                                 vCardFilenameFull.Append(AccountDirFinal);
712                                 vCardFilenameFull.Append(wxT("/"));
713                                 vCardFilenameFull.Append(vCardFilename);
714                 
715                                 Person.LoadFile(vCardFilenameFull);
716                 
717                                 UIDCode = Person.Get(wxT("UID"));
718                 
719                                 for (int i = 0; i < vCardMember.PropCount; i++){
720                     
721                                         if (vCardMember.PropValues[i] == UIDCode){
722                         
723                                                 FoundMember = TRUE;
724                         
725                                         }
727                                 }
728                 
729                                 if (FoundMember == FALSE){
730                     
731                                         vCardFilename.Clear();
732                                         vCardFilenameFull.Clear();
733                                         vCardDataString.Clear();
734                                         ProcFiles = vcardaccdir.GetNext(&vCardFilename);
735                                         continue;
736                     
737                                 }
738                 
739                                 if (Person.MeetBaseSpecification()){
740                     
741                                         if (SortMode == 1){
742                         
743                                                 // Split the name into sections.
744                         
745                                                 vCardName NameData = Person.GetName();
746                         
747                                                 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
748                         
749                                         } else if (SortMode == 2){
750                         
751                                                 // Split the name into sections.
752                         
753                                                 vCardName NameData = Person.GetName();
754                         
755                                                 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
756                         
757                                         } else if (SortMode == 3){
758                         
759                                                 // Check and make sure that the top most nickname is used.
760                         
761                                                 vCardDataString = Person.Get(wxT("NICKNAME"));
762                         
763                                                 if (vCardDataString.IsEmpty()){
764                             
765                                                         vCardDataString = wxT("(no nickname)");
766                             
767                                                 }
768                         
769                                         } else if (SortMode == 4){
770                         
771                                                 vCardDataString = Person.Get(wxT("FN"));
772                         
773                                         }
774                     
775                                         if (AscendingMode == TRUE){
776                                                 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
777                                         } else {
778                                                 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
779                                         }
780                     
781                                 }
782                 
783                         }
784             
785                         vCardFilename.Clear();
786                         vCardFilenameFull.Clear();
787                         vCardDataString.Clear();
788                         ProcFiles = vcardaccdir.GetNext(&vCardFilename);
789                         
790                 }
791         
792         } else {
793         
794                 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
795                 while(ProcFiles){
796             
797                         if (vCardFilename.Right(4) == wxT(".vcf") ||
798                                 vCardFilename.Right(4) == wxT(".VCF") ||
799                                 vCardFilename.Right(5) == wxT(".vcard") ||
800                                 vCardFilename.Right(5) == wxT(".VCARD")){
801                 
802                                 vCard Person;
803                 
804                                 vCardFilenameFull.Append(AccountDirFinal);
805                                 vCardFilenameFull.Append(vCardFilename);
806                 
807                                 Person.LoadFile(vCardFilenameFull);
808                 
809                                 if (Person.MeetBaseSpecification()){
810                     
811                                         if (SortMode == 1){
812                         
813                                                 // Split the name into sections.
814                         
815                                                 vCardDataString = Person.Get(wxT("N"));
816                         
817                                                 vCardName NameData = Person.GetName();
818                         
819                                                 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
820                         
821                                         } else if (SortMode == 2){
822                         
823                                                 // Split the name into sections.
824                         
825                                                 vCardName NameData = Person.GetName();
826                         
827                                                 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
828                         
829                                         } else if (SortMode == 3){
830                         
831                                                 // Check and make sure that the top most nickname is used.
832                         
833                                                 vCardDataString = Person.Get(wxT("NICKNAME"));
834                         
835                                                 if (vCardDataString.IsEmpty()){
836                             
837                                                         vCardDataString = wxT("(no nickname)");
838                             
839                                                 }
840                         
841                                         } else if (SortMode == 4){
842                         
843                                                 vCardDataString = Person.Get(wxT("FN"));
844                         
845                                         }
846                     
847                                         if (AscendingMode == TRUE){
848                                         
849                                                 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
850                                                 
851                                         } else {
852                                         
853                                                 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
854                                                 
855                                         }
856                     
857                                 }
858                 
859                         }
860             
861                         vCardFilename.Clear();
862                         vCardFilenameFull.Clear();
863                         vCardDataString.Clear();
864                         ProcFiles = vcardaccdir.GetNext(&vCardFilename);
865                 }
866         
867         }
868     
869         // Sort the data.
870     
871         // Insert the data into the control.
872     
873         if (AscendingMode == TRUE){
874                 for (std::map<wxString, wxString>::iterator iter = vCardNamesAsc.begin();
875                         iter != vCardNamesAsc.end(); ++iter){
876             
877                         wxListItem ContactInfo;
878             
879                         ContactInfo.SetId(0);
880                         ContactInfo.SetText(_("Mooo"));
881                         ContactInfo.SetData(ContactSeekPoint);
882                         ContactIndex = lstContacts->InsertItem(ContactInfo);
883             
884                         lstContacts->SetItem(ContactIndex, 0, iter->first);
885             
886                         ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
887                         ContactSeekPoint++;
888             
889                 }
890         
891         } else {
892         
893                 for (std::map<wxString, wxString>::iterator iter = vCardNamesDsc.begin();
894                      iter != vCardNamesDsc.end(); ++iter){
895             
896                         wxListItem ContactInfo;
897             
898                         ContactInfo.SetId(0);
899                         ContactInfo.SetText(_("Mooo"));
900                         ContactInfo.SetData(ContactSeekPoint);
901                         ContactIndex = lstContacts->InsertItem(ContactInfo);
902             
903                         lstContacts->SetItem(ContactIndex, 0, iter->first);
904                         ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
905                         ContactSeekPoint++;
906             
907                 }
908         
909         }
910     
913 void frmMain::ShowContactInfo( wxListEvent& event )
915     
916         // Display the contact information.
917     
918         long intSelected = -1;
919         long ContactSeekNum = -1;
920     
921         // Check if several contacts have been selected.
922     
923         int ContactTotal = 0;
924     
925         for (;;){
926         
927                 intSelected = lstContacts->GetNextItem(intSelected,
928                         wxLIST_NEXT_ALL,
929                         wxLIST_STATE_SELECTED);
930         
931                 if (intSelected == -1){
932             
933                     break;
934             
935                 }
936         
937                 ContactTotal++;
938         
939         }
940     
941         if (ContactTotal == 0){
942                 htmContactData->SetPage(wxT(""));
943                 return;
944         }
945     
946         if (ContactTotal > 1){
947         
948                 htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
949                 ActiveFilename.Clear();
950                 return;
951         
952         }
953     
954         intSelected = lstContacts->GetNextItem(intSelected,
955                 wxLIST_NEXT_ALL,
956                 wxLIST_STATE_SELECTED);
957     
958         ContactSeekNum = lstContacts->GetItemData(intSelected);
959     
960         wxFFile ContactFile;
961         wxString wxSContactString;
962         wxString ContactLine;
963         vCard Person;
964     
965         size_t ContactLineLen;
966         bool ExtraLineSeek = FALSE;
967         int QuoteBreakPoint = 0;
968     
969         bool PropertyFind = FALSE;
970         bool QuoteMode = FALSE;
971     
972         wxString wxSPropertyNextLine;
973         wxString wxSProperty;
974         wxString wxSPropertySeg1;
975         wxString wxSPropertySeg2;
976     
977         // Check if we are using wxWidgets version 2.8 or less and
978         // execute the required command accordingly.
979     
980 #if wxABI_VERSION < 20900
981         ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
982 #else
983         ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
984 #endif
985     
986         if (ContactFile.IsOpened() == FALSE){
987         
988                 return;
989         
990         }
991     
992         ContactFile.ReadAll(&wxSContactString, wxConvAuto());
993     
994         // Split the lines.
995     
996         std::map<int, wxString> ContactFileLines;
997         std::map<int, wxString>::iterator striter;
998     
999         wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
1000     
1001         int ContactLineSeek = 0;
1002     
1003         while (wSTContactFileLines.HasMoreTokens() == TRUE){
1004         
1005                 ContactLine = wSTContactFileLines.GetNextToken();
1006                 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
1007                 ContactLineSeek++;
1008         
1009         }
1010     
1011         if (ContactSeekNum < 0){
1012                 return;
1013         }
1014     
1015         for (std::map<int, wxString>::iterator iter = ContactFileLines.begin();
1016                 iter != ContactFileLines.end(); ++iter){
1017         
1018                 // Find the colon which splits the start bit from the data part.
1019         
1020                 ContactLine = iter->second;
1021         
1022                 while (ExtraLineSeek == TRUE){
1023             
1024                         // Check if there is extra data on the next line
1025                         // (indicated by space or tab at the start) and add data.
1026             
1027                         iter++;
1028             
1029                         if (iter == ContactFileLines.end()){
1030                 
1031                                 iter--;
1032                                 break;
1033                 
1034                         }
1035             
1036                         wxSPropertyNextLine = iter->second;
1037             
1038             
1039                         if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1040                 
1041                                 wxSPropertyNextLine.Remove(0, 1);
1042                                 ContactLine.Append(wxSPropertyNextLine);
1043                 
1044                         } else {
1045                 
1046                                 iter--;
1047                                 ExtraLineSeek = FALSE;
1048                 
1049                         }
1050             
1051                 }
1052         
1053                 ContactLineLen = ContactLine.Len();
1054         
1055                 // Make sure we are not in quotation mode.
1056                 // Make sure colon does not have \ or \\ before it.
1057         
1058                 for (int i = 0; i <= ContactLineLen; i++){
1059             
1060                         if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1061                 
1062                                 PropertyFind = FALSE;
1063                 
1064                         } else if (PropertyFind == TRUE){
1065                 
1066                                 wxSProperty.Append(ContactLine.Mid(i, 1));
1067                 
1068                         }
1069             
1070                         if (ContactLine.Mid(i, 1) == wxT("\"")){
1071                 
1072                                 if (QuoteMode == TRUE){
1073                     
1074                                         QuoteMode = FALSE;
1075                     
1076                                 } else {
1077                     
1078                                         QuoteMode = TRUE;
1079                     
1080                                 }
1081                 
1082                         }
1083             
1084                         if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1085                 
1086                                 QuoteBreakPoint = i;
1087                                 break;
1088                 
1089                         }
1090             
1091                 }       
1092         
1093                 // Split that line at the point into two variables (ignore the colon).
1094         
1095                 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1096                 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1097         
1098                 // Insert both into the vCard data file.
1099         
1100                 Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
1101         
1102                 QuoteMode = FALSE;
1103                 PropertyFind = TRUE;
1104                 ExtraLineSeek = TRUE;
1105                 ContactLineLen = 0;
1106                 QuoteBreakPoint = 0;
1107                 ContactLine.Clear();
1108                 wxSProperty.Clear();
1109         
1110         }
1111     
1112         OldSessionID = SessionID;
1113         SessionID = wxString::Format(wxT("%i"), rand() % 32768);
1114         LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList, ContactBackgroundColour);
1115         ActiveFilename = ContactsFileIndex[ContactSeekNum];
1116     
1119 void frmMain::ShowContactEditorNew( wxCommandEvent& event )
1121     
1122         // Open a contact editor window to write a new contact with.
1123     
1124         // Check if there is an account selected and if not
1125         // return immediately.
1126     
1127         if (ActiveAccount.IsEmpty()){
1128         
1129                 return;
1130         
1131         }
1132         
1133         // Check if the account type is a valid account type, otherwise
1134         // display an error message.
1135         
1136         if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1137                 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1138                 
1139                 wxMessageBox(_("Cannot add a new contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1140                 return;
1141                         
1142         }
1143     
1144         // Add Pointer to SetupPointers for the ETagDB.
1145     
1146         wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1147         wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1148         wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1149         wxIcon contacticon;
1150         contacticon.CopyFromBitmap(contacticonbmp);
1151     
1152         frmContactEditor *ContactEditor = new frmContactEditor( this );
1153     
1154         WindowMenuItemID++;
1155     
1156         ContactEditor->SetUID(WindowMenuItemID);
1157     
1158         WindowData *WData = new WindowData;
1159     
1160         WData->DataType = 1;
1161         WData->WindowPointer = (void*)ContactEditor;
1162         WData->WindowID = WindowMenuItemID;
1163     
1164         wxCommandEvent addevent(WINDOW_ADD);
1165         addevent.SetClientData(WData);
1166         wxPostEvent(this, addevent);
1167     
1168         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1169         ContactEditor->SetupHeaders();
1170         ContactEditor->SetupContact(ActiveAccount);
1171         ContactEditor->SetIcon(contacticon);
1172         ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1173         ContactEditor->Show(true);
1174     
1177 void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
1179     
1180         // Open a contact editor window for editing an existing contact
1181         // with.
1182     
1183         // Check if there is an account selected and if not
1184         // return immediately.
1185     
1186         int DataCheck = event.GetInt();
1187     
1188         if (ActiveAccount.IsEmpty() && DataCheck == 0){
1189         
1190                 return;
1191         
1192         }
1193         
1194         wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1195         wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1196         wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1197         wxIcon contacticon;
1198         contacticon.CopyFromBitmap(contacticonbmp);
1199     
1200         // Check if a contact has been selected.
1201     
1202         long intSelected = -1;
1203         long intContactSeekNum = -1;
1204         
1205         intSelected = lstContacts->GetNextItem(intSelected,
1206                 wxLIST_NEXT_ALL,
1207                 wxLIST_STATE_SELECTED);
1208     
1209         if (intSelected == -1){
1210         
1211                 return;
1212                 
1213         }
1214     
1215         intContactSeekNum = lstContacts->GetItemData(intSelected);
1216     
1217         // Get the filename of the selected contact.
1218     
1219         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1220         frmContactEditor *ContactEditor = new frmContactEditor( this );
1221     
1222         WindowMenuItemID++;
1223     
1224         ContactEditor->SetUID(WindowMenuItemID);
1225     
1226         WindowData *WData = new WindowData;
1227     
1228         WData->DataType = 1;
1229         WData->WindowPointer = (void*)ContactEditor;
1230         WData->WindowID = WindowMenuItemID;
1231     
1232         wxCommandEvent addevent(WINDOW_ADD);
1233         addevent.SetClientData(WData);
1234         wxPostEvent(this, addevent);
1235     
1236         ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1237         ContactEditor->SetupHeaders();
1239         if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1240                 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1241                         
1242                 ContactEditor->SetupAccountData(true);
1243                         
1244         }
1245     
1246         // Check if pointer is NULL (not from the search forms) or not.
1247     
1248         if (DataCheck == 0){
1249         
1250                 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1251                 ContactEditor->SetupContact(ActiveAccount);
1252         
1253         } else {
1254         
1255                 UCNotif *uc = (UCNotif*)event.GetClientData();
1256         
1257                 if (!uc){
1258             
1259                         ContactEditor->SetupContact(ActiveAccount);
1260                         ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1261             
1262                 } else {
1263             
1264                         ContactEditor->SetupContact(uc->ContactAccount);
1265                         ContactEditor->LoadContact(uc->ContactFilename);
1266             
1267                         delete uc;
1268                         uc = NULL;
1270                 }
1271         
1272         }
1273     
1274         ContactEditor->SetIcon(contacticon);
1275         ContactEditor->Show(true);
1276     
1279 void frmMain::RefreshAddressBook( wxCommandEvent& event ){
1281         // Refresh the address book data.
1282    
1283         // Check if ActiveAccount is empty. If not then check if
1284         // account type is not local otherwise continue.
1285     
1286         if (!ActiveAccount.IsEmpty()){
1287    
1288                 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
1289         
1290                         // Account type is not local.
1291         
1292                         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1293                         frameActMgr->AddTask(3, wxT(""), ActiveAccount,
1294                                      wxT(""), wxT(""), wxT(""), wxT(""));
1295         
1296                 } else {
1297         
1298                         wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported"), wxICON_ERROR);
1299         
1300                 }
1301         
1302         }
1303     
1306 void frmMain::OpenContactInfoList( wxListEvent& event )
1308     
1309         // Open the contact information window.
1310     
1311         wxStringTokenizer vcardfileline;
1312         std::string l;
1313         wxString lwxs;
1314         wxString setname, setvalue;
1315         vCard Person;
1316         wxString nextchar;
1317     
1318         long intSelected = -1;
1319         long intContactSeekNum = -1;
1320     
1321         intSelected = lstContacts->GetNextItem(intSelected,
1322                 wxLIST_NEXT_ALL,
1323                 wxLIST_STATE_SELECTED);
1324     
1325         intContactSeekNum = lstContacts->GetItemData(intSelected);
1326     
1327         if (intContactSeekNum == -1){
1328         
1329                 return;
1330                 
1331         }
1332     
1333         Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
1334     
1335         wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1336         wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1337         wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1338         wxIcon contacticon;
1339         contacticon.CopyFromBitmap(contacticonbmp);
1340     
1341         frmContact *Contact = new frmContact( this );
1342     
1343         // Add to window list.
1344     
1345         WindowMenuItemID++;
1346     
1347         Contact->SetUID(WindowMenuItemID);
1348     
1349         WindowData *WData = new WindowData;
1350     
1351         WData->DataType = 0;
1352         WData->WindowPointer = (void*)Contact;
1353         WData->WindowID = WindowMenuItemID;
1354     
1355         wxCommandEvent addevent(WINDOW_ADD);
1356         addevent.SetClientData(WData);
1357         wxPostEvent(this, addevent);
1358     
1359         Contact->SetupPointers(&MemoryFileList);
1360         Contact->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1361         Contact->SetupContactData(&Person);
1362     
1363         Contact->SetIcon(contacticon);
1364         Contact->Show(true);
1365     
1368 void frmMain::OpenContactInfoList( wxCommandEvent& event ){
1370         // Open a list of contact information windows.
1372         wxListEvent pevent;
1373         OpenContactInfoList(pevent);
1377 void frmMain::OpenContactInfo( wxCommandEvent& event )
1380         // Open the contact information window.
1382         UCNotif *uc = (UCNotif*)event.GetClientData();
1383     
1384         wxStringTokenizer vcardfileline;
1385         std::string l;
1386         wxString lwxs;
1387         wxString setname, setvalue;
1388         vCard Person;
1389         wxString nextchar;
1390     
1391         Person.LoadFile(uc->ContactFilename);
1392     
1393         wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1394         wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1395         wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1396         wxIcon contacticon;
1397         contacticon.CopyFromBitmap(contacticonbmp);
1398     
1399         frmContact *Contact = new frmContact( this );
1400     
1401         // Add to window list.
1402     
1403         WindowMenuItemID++;
1404     
1405         Contact->SetUID(WindowMenuItemID);
1406     
1407         WindowData *WData = new WindowData;
1408     
1409         WData->DataType = 0;
1410         WData->WindowPointer = (void*)Contact;
1411         WData->WindowID = WindowMenuItemID;
1412     
1413         wxCommandEvent addevent(WINDOW_ADD);
1414         addevent.SetClientData(WData);
1415         wxPostEvent(this, addevent);
1416     
1417         Contact->SetupPointers(&MemoryFileList);
1418         Contact->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1419         Contact->SetupContactData(&Person);
1420     
1421         Contact->SetIcon(contacticon);
1422         Contact->Show(true);
1423     
1427 void frmMain::LoadPreferences( wxActivateEvent& event)
1430         // Load the preferences.
1432         this->LoadPreferences(true);
1433         
1436 void frmMain::LoadPreferences(bool skipWindowSizeReload){
1437     
1438         // Load the preferences.
1439     
1440         wxString preffilename = GetUserPrefDir();
1441     
1442         XABPreferences preferences(preffilename);
1443     
1444         // Clear the active account/filename information and account list.
1446         ActiveAccount = "";
1447         ActiveAccountType = "";
1448         ActiveFilename = "";
1449         lstContacts->DeleteAllItems();
1451         // Setup the main window position (if needed).
1452     
1453         bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
1454         bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
1455         bool UseBackgroundContactColour = preferences.GetBoolData(wxT("UseBackgroundContactColour"));
1456     
1457         if (SaveWindowPos == true && skipWindowSizeReload == false){
1458         
1459                 this->SetSize(preferences.GetMainWindowData());
1460         
1461         }
1462     
1463         if (UseBackgroundContactColour == true){
1464                 
1465                 ContactBackgroundColour = preferences.GetBackgroundContactColourData();
1466                 
1467         } else {
1468                 
1469                 ContactBackgroundColour = wxTransparentColour;
1470                 
1471         }
1472         
1473         treAccounts->DeleteAllItems();
1474     
1475         wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
1476     
1477         // Stop all account timers and remove the accounts.
1478     
1479         for (std::map<wxString, wxAccountSyncTimer*>::iterator iter = AccountSyncTimers.begin();
1480                 iter != AccountSyncTimers.end(); iter++){
1481         
1482                 wxAccountSyncTimer *AccTmrPtr = iter->second;
1483                 AccTmrPtr->Stop();
1484         
1485                 delete AccTmrPtr;
1486                 AccTmrPtr = NULL;
1487         
1488         }
1490 #if defined(__WIN32__)
1492         for (std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.begin();
1493                 CertificateIter != AccountCertificateData.end(); CertificateIter++){
1495                 CertFreeCertificateContext(CertificateIter->second);
1497         }
1499         AccountCertificateData.clear();
1501 #endif
1502     
1503         AccountSyncTimers.clear();
1504         
1505         wxString AccDir;
1506         wxString AccDirFull;
1507         wxString AccDirFullSfx;
1508         wxString AccName;
1509         wxString AccDirFinal;
1510         AccountAccDirList.clear();
1511         AccountGroupList.clear();
1512         AccountGroupFilename.clear();
1513         AccountGroupTreeId.clear();
1514         wxTreeItemId AccountTreeId;
1515         wxTreeItemId GroupTreeId;
1516         int intGroupID = 0;
1517         
1518         // Relaod the accounts for the ETagProcTimer.
1519         
1520         ETagProcTimer.ReloadAccounts();
1521     
1522         for (int i = 0; i < preferences.accounts.GetCount(); i++){
1523                 
1524                 if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
1525                         preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == true){
1526             
1527                         continue;
1528             
1529                 }
1530         
1531                 if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
1532             
1533                         continue;
1534             
1535                 }
1536         
1537                 AccDir = preferences.accounts.GetAccountDirectory(i);
1538                 AccDirFull = preferences.accounts.GetAccountDirectory(i);
1539                 AccDirFull.Trim();
1540                 AccDirFull.Append(wxT("."));
1541                 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
1542                 AccDirFullSfx.LowerCase();
1543                 AccDirFullSfx.Trim();
1544                 AccDirFull.Append(AccDirFullSfx);
1545                 AccName = preferences.accounts.GetAccountName(i);
1546                 AccName.Trim();
1547                 AccountAccDirList.insert(std::make_pair(i, AccDirFull));
1548                 
1549                 if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
1550                         preferences.accounts.GetAccountType(i) == wxT("carddav")){
1551             
1552                         // TODO: Check if the directory exists before doing anything.
1553             
1554             
1555             
1556                         // Add a new timer using the existing account details.
1557             
1558                         wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
1559             
1560                         ActTmrPtr->SetupData(AccDirFull, AccName);
1561                         ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
1562                         ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
1563                         ActTmrPtr->SetOwner(this);
1564                         ActTmrPtr->Notify();
1565             
1566                         // Add the timer to the list of timers.
1567             
1568                         AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
1569             
1570                         AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
1571             
1572                 } else if (preferences.accounts.GetAccountType(i) == wxT("Local") ||
1573                         preferences.accounts.GetAccountType(i) == wxT("local")) {
1574             
1575                         AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
1576             
1577                 } else {
1579                         AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountUnsupportedID, -1);
1580                         
1581                 }
1582         
1583                 // Go through the account directory and find contact files with
1584                 // 'KIND:group' set and add them to the list of groups for the account.
1585         
1586                 AccDirFinal = GetAccountDir(AccDirFull, FALSE);
1587         
1588                 wxDir vcardaccdir(AccDirFinal);
1589         
1590                 wxString vCardFilename;
1591                 wxString vCardDataString;
1592                 wxString vCardFilenameFull;
1593                 
1594                 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1595         
1596                 while(ProcFiles){
1597             
1598                         if (vCardFilename.Right(4) == wxT(".vcf") ||
1599                                 vCardFilename.Right(4) == wxT(".VCF") ||
1600                                 vCardFilename.Right(5) == wxT(".vcard") ||
1601                                 vCardFilename.Right(5) == wxT(".VCARD")){
1602                 
1603                                 vCard Person;
1604                 
1605                                 vCardFilenameFull.Append(AccDirFinal);
1606                                 vCardFilenameFull.Append(wxT("/"));
1607                                 vCardFilenameFull.Append(vCardFilename);
1608                 
1609                                 Person.LoadFile(vCardFilenameFull);
1610                 
1611                                 if (Person.MeetBaseSpecification()){
1612                     
1613                                         vCardDataString = Person.Get(wxT("KIND"));
1614                     
1615                                         if (vCardDataString == wxT("group")){
1616                         
1617                                                 // The vCard kind is a group. Add to the account's group list.
1618                         
1619                                                 GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
1620                                                 treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
1621                                                 AccountGroupList.insert(std::make_pair(intGroupID, i));
1622                                                 AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
1623                                                 AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
1624                         
1625                                         }
1626                     
1627                                         intGroupID++;
1628                     
1629                                 }
1630                 
1631                         }
1632             
1633                         vCardFilename.Clear();
1634                         vCardFilenameFull.Clear();
1635                         vCardDataString.Clear();
1636                         ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1637             
1638                 }
1639         
1640                 // Clearup for next account.
1641         
1642                 AccDir.clear();
1643                 AccDirFull.clear();
1644                 AccDirFullSfx.clear();
1645                 AccDirFinal.clear();
1646                 AccName.clear();
1647         
1648         }
1649     
1650         // Load the account settings as they are needed for connecting
1651         // to the servers.
1652     
1653         prefaccounts = preferences.accounts;
1654     
1657 void frmMain::ConflictResolution(wxCommandEvent& event){
1658     
1659         // Display the conflict resolution window.
1660     
1661         frmConflictResolution *frameCR = new frmConflictResolution ( this );
1662         vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
1663         vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
1664         vCard *ServerDataPtr = vCardConfObj->vCardServerData;
1665         frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList, ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1666         frameCR->ShowModal();
1667     
1668         int FinalConflictResult = frameCR->GetResult();
1669     
1670         wxCommandEvent event2(ACTMGR_RESUMEPROC);
1671         event2.SetClientData(vCardConfObj->QRNotifData);
1672         event2.SetInt(FinalConflictResult);
1673     
1674         delete frameCR;
1675         frameCR = NULL;
1676     
1677         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1678         wxPostEvent(frameActMgr, event2);
1679     
1682 void frmMain::UpdateContactList(wxCommandEvent& event){
1683     
1684         // Update the contact list in the main window.
1685     
1686         UCNotif *ucd = (UCNotif*)event.GetClientData();
1687     
1688         // Check if the active account is being displayed in the
1689         // main window. If not, skip and delete the data.
1690     
1691         long longSelected = -1;
1692         int intSelectedData = 0;
1693     
1694         if (ActiveAccount == ucd->ContactAccount){
1695         
1696                 // Look at the list of contacts and if it matches the
1697                 // filename then update the name.
1698         
1699                 for (;;){
1700             
1701                         longSelected = lstContacts->GetNextItem(longSelected,
1702                                 wxLIST_NEXT_ALL,
1703                                 wxLIST_STATE_DONTCARE);
1704             
1705                         if (longSelected == -1){
1706                 
1707                                 break;
1708                 
1709                         }
1710             
1711                         intSelectedData = (int)lstContacts->GetItemData(longSelected);
1712             
1713                         if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
1714                 
1715                                 // Work out which sorting mode we are in.
1716                 
1717                                 if (SortMode == 1){
1718                     
1719                                         // First Name, Last Name.
1720                     
1721                                         if (ucd->ContactNameArray.Forename == wxT("") && ucd->ContactNameArray.Surname == wxT(""))
1722                                         {
1723                                                 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1724                                         }
1725                                         else
1726                                         {
1727                                                 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
1728                                         }
1729                     
1730                                 } else if (SortMode == 2){
1731                     
1732                                         // Last Name, First Name.
1734                                         if (ucd->ContactNameArray.Forename == wxT("") && ucd->ContactNameArray.Surname == wxT(""))
1735                                         {
1736                                                 lstContacts->SetItem(longSelected, 0, wxT(", ") + ucd->ContactName);
1737                                         }
1738                                         else
1739                                         {
1740                                                 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
1741                                         }
1742                     
1743                                 } else if (SortMode == 3){
1744                     
1745                                         // Nickname.
1746                     
1747                                         if (ucd->ContactNickname == wxT(""))
1748                                         {
1749                                                 lstContacts->SetItem(longSelected, 0, _("(no nickname)"));
1750                                         }
1751                                         else
1752                                         {
1753                                                 lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
1754                                         }
1755                     
1756                                 } else if (SortMode == 4){
1757                     
1758                                         // Display As.
1759                     
1760                                         lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1761                     
1762                                 }
1763                 
1764                 
1765                         }
1766             
1767                         // If the filename is the one loaded into the
1768                         // browser control, then update this too.
1769             
1770                         if (ActiveFilename == ContactsFileIndex[intSelectedData]){
1771                 
1772                                 wxListEvent nullevent;
1773                                 ShowContactInfo(nullevent);
1774                 
1775                         }
1776             
1777                 }
1778         
1779         }
1780     
1781         for (std::map<int, void*>::iterator WindowIter = WindowListPointers.begin();
1782                 WindowIter != WindowListPointers.end(); WindowIter++){
1783         
1784                 if (WindowListType[WindowIter->first] != 0){
1785             
1786                         continue;
1787             
1788                 }
1789         
1790                 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
1791         
1792                 if (frmContactPtr->GetFilename() == ucd->ContactFilename){
1793             
1794                         vCard UpdatedPerson;
1795                         UpdatedPerson.LoadFile(ucd->ContactFilename);
1796                         frmContactPtr->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
1797                         frmContactPtr->SetupContactData(&UpdatedPerson);
1798             
1799                 }
1800         
1801         }
1802     
1803         // Send message to search window controller subroutine and
1804         // pass that notification onto the search windows.
1805     
1806         // Setup the new pointer to use the existing UCNotif without
1807         // deleting it.
1808     
1809         UCNotif *ucd2 = ucd;
1810     
1811         wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
1812         sup.SetClientData(ucd2);
1813         wxPostEvent(this, sup);
1814     
1815         // Clear up the unused pointer.
1816     
1817         ucd = NULL;
1818     
1821 void frmMain::SetupPointers(void *ActMgrPtrInc){
1822     
1823         // Setup the pointers for the main window.
1824     
1825         ActMgrPtr = ActMgrPtrInc;
1826     
1829 void frmMain::SetupForm(){
1830     
1831         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1832         frameActMgr->SetupPointers(&ETagProcTimer, this);
1833     
1834         // Setup the contact information icons for later.
1835     
1836         wxFileSystem::AddHandler(new wxMemoryFSHandler);
1837         wxImage ciicon_png;
1838         //wxBitmap ciicon;
1839     
1840         wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
1841         ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
1842         wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1843     
1844         wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
1845         ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
1846         wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1847     
1848         wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
1849         ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
1850         wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1851     
1852         wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
1853         ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
1854         wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1855     
1856         wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
1857         ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
1858         wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1859     
1860         wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
1861         ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
1862         wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1863     
1864         LoadPreferences(false);
1865     
1868 void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
1869     
1870         // Update the contact lists in the search windows.
1871     
1872         // Go through each of the search windows and
1873         // send the required notification to update the
1874         // contact information.
1875     
1876         // Get the event notification data.
1877     
1878         UCNotif *ucd = (UCNotif*)event.GetClientData();
1879     
1880         // Process each search window giving the new details.
1881     
1882         for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1883                 switer != SearchWindowList.end(); switer++){
1884         
1885                 // Duplicate the event notification data.
1886         
1887                 UCNotif *ucd2 = new UCNotif;
1888         
1889                 ucd2->ContactAccount = ucd->ContactAccount;
1890                 ucd2->ContactFilename = ucd->ContactFilename;
1891                 ucd2->ContactName = ucd->ContactName;
1892                 ucd2->ContactNickname = ucd->ContactNickname;
1893                 ucd2->ContactNameArray = ucd->ContactNameArray;
1894         
1895                 // Pass the data to the search window for processing.
1896         
1897                 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
1898                 wxCommandEvent schupdate(SE_UPDATERESULT);
1899                 schupdate.SetClientData(ucd2);
1900                 wxPostEvent(frameSCH, schupdate);
1901         
1902                 // Clear up the pointer prior to variable deletion.
1903         
1904                 frameSCH = NULL;
1905         
1906         }
1907     
1908         delete ucd;
1909         ucd = NULL;
1910     
1913 void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
1914     
1915         // Open a new search window.
1916     
1917         WindowMenuItemID++;
1918     
1919         frmSearch *frameSCH = new frmSearch ( this );
1920         frameSCH->SetUID(WindowMenuItemID);
1921         frameSCH->Show(true);
1922     
1923         WindowData *WData = new WindowData;
1924     
1925         WData->DataType = 2;
1926         WData->WindowPointer = (void*)frameSCH;
1927         WData->WindowID = WindowMenuItemID;
1928     
1929         wxCommandEvent addevent(WINDOW_ADD);
1930         addevent.SetClientData(WData);
1931         wxPostEvent(this, addevent);
1932     
1933         // Add pointer to the list of open search windows.
1934     
1935         SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
1936     
1937         WData = NULL;
1938     
1941 void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
1942     
1943         // Remove the pointer for a contact window from the
1944         // window list.
1945     
1946         void *frameSCH = (void*)event.GetClientData();
1947     
1948         SearchWindowList.erase(frameSCH);
1949     
1950         frameSCH = NULL;
1951     
1954 void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
1955     
1956         // Remove the pointer for a contact editor window from
1957         // the window list.
1958     
1959         void *frameSCH = (void*)event.GetClientData();
1960     
1961         SearchWindowList.erase(frameSCH);
1962     
1963         frameSCH = NULL;
1964     
1967 void frmMain::RevealContact(wxCommandEvent& event){
1968     
1969         // Reveal a contact in the main window.
1970     
1971         UCNotif *uc = (UCNotif*)event.GetClientData();
1972     
1973         // Switch the account to the one passed.
1974     
1975         wxTreeItemIdValue cookie;
1976         wxTreeItemId next = treAccounts->GetRootItem();
1977         wxTreeItemId nextChild;
1978     
1979         for (int i = 0; i < prefaccounts.GetCount(); i++){
1980         
1981                 if (!nextChild){
1982                         nextChild = treAccounts->GetFirstChild(next, cookie);
1983                 } else {
1984                         nextChild = treAccounts->GetNextSibling(nextChild);
1985                 }
1986                
1987                 if (uc->ContactAccount == AccountAccDirList[i]){
1988             
1989                         treAccounts->SelectItem(nextChild, TRUE);
1990                         AccCtrl->SetText(treAccounts->GetItemText(nextChild));
1991             
1992                 }
1993         
1994         }
1995     
1996         // Switch the contact to the one passed.
1997     
1998         long longSelected = -1;
1999         int intSelectedData = 0;
2000     
2001         for (;;){
2002         
2003                 longSelected = lstContacts->GetNextItem(longSelected,
2004                         wxLIST_NEXT_ALL,
2005                         wxLIST_STATE_DONTCARE);
2006         
2007                 if (longSelected == -1){
2008             
2009                         break;
2010             
2011                 }
2012         
2013                 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2014         
2015                 // Compare the filename with the one received.
2016                 // If they match then select it.
2017         
2018                 if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
2019             
2020                         // Select.
2021             
2022                         lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
2023                         lstContacts->EnsureVisible(longSelected);
2024             
2025                 } else {
2026         
2027                         lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
2028         
2029                 }
2030         
2031         }
2032     
2035 void frmMain::DeleteContact(wxCommandEvent& event){
2036     
2037         // Delete a contact from the main window.
2038         
2039         // Check if a contact is selected.
2040     
2041         long intSelected = -1;
2042         long intContactSeekNum = -1;
2043         wxString wxSContactName;
2044     
2045         intSelected = lstContacts->GetNextItem(intSelected,
2046                 wxLIST_NEXT_ALL,
2047                 wxLIST_STATE_SELECTED);
2048     
2049         if (intSelected == -1){
2050                 return;
2051         }
2052         
2053         // Check if the account type is a valid account type, otherwise
2054         // display an error message.
2055         
2056         if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
2057                 ActiveAccountType != "Local" && ActiveAccountType != "local"){
2058                 
2059                 wxMessageBox(_("Cannot delete contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
2060                 return;
2061                         
2062         }
2063     
2064         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2065     
2066         // Get the item data of the contact.
2067     
2068         intContactSeekNum = lstContacts->GetItemData(intSelected);
2069     
2070         // Get the name of the contact.
2071     
2072         wxSContactName = lstContacts->GetItemText(intSelected);
2073     
2074         // Display a message confirming if the contact should
2075         // be deleted.
2076     
2077         int QuestionResponse;
2078     
2079         QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
2080     
2081         if (QuestionResponse == wxNO){
2082         
2083                 // Exit the subroutine
2084         
2085                 return;
2086         
2087         }
2088     
2089         // Delete the contact.
2090     
2091         if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
2092         
2093                 wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
2094                 return;
2095         
2096         }
2097     
2098         // Remove the contact from the list.
2099     
2100         lstContacts->DeleteItem(intSelected);
2101     
2102         // Update the search windows, removing the deleted
2103         // contact.
2104     
2105         UCNotif *ucd = new UCNotif;
2106     
2107         ucd->ContactAccount = ActiveAccount;
2108         ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
2109     
2110         for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
2111                 switer != SearchWindowList.end(); switer++){
2112         
2113                 // Duplicate the event notification data.
2114         
2115                 UCNotif *ucd2 = new UCNotif;
2116         
2117                 ucd2->ContactAccount = ucd->ContactAccount;
2118                 ucd2->ContactFilename = ucd->ContactFilename;
2119         
2120                 // Pass the data to the search window for processing.
2121         
2122                 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
2123                 wxCommandEvent schdelete(SE_DELETERESULT);
2124                 schdelete.SetClientData(ucd2);
2125                 wxPostEvent(frameSCH, schdelete);
2126         
2127                 // Clear up the pointer prior to variable deletion.
2128         
2129                 frameSCH = NULL;
2130                 ucd2 = NULL;
2131         
2132         }
2133     
2134         // Clear the wxHTMLWindow.
2135     
2136         wxString EmptyPage = wxT("");
2137     
2138         htmContactData->SetPage(EmptyPage);
2139     
2140         wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
2141     
2142         wxString wxSplitFilename;
2143         wxString wxSDataURL;
2144     
2145         while(wSTFilename.HasMoreTokens()){
2146         
2147                 wxSplitFilename = wSTFilename.GetNextToken();
2148         
2149         }
2150     
2151         if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
2152         
2153                 // Update the ETagDB and mark it as deleted.
2154         
2155                 ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
2156         
2157                 ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
2158         
2159                 // Get the Data URL.
2160         
2161                 wxTreeItemIdValue cookie;
2162                 wxTreeItemId next = treAccounts->GetRootItem();
2163         
2164                 wxTreeItemId selectedChild = treAccounts->GetSelection();
2165                 wxTreeItemId nextChild;
2166         
2167                 for (int i = 0; i < prefaccounts.GetCount(); i++){
2168             
2169                         if (!nextChild){
2170                                 nextChild = treAccounts->GetFirstChild(next, cookie);
2171                         } else {
2172                                 nextChild = treAccounts->GetNextSibling(nextChild);
2173                         }
2174             
2175                         if (nextChild == selectedChild){
2176                         
2177                                 wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
2178                                 break;
2180                         }
2181             
2182                 }
2183         
2184                 // Add task to the activity monitor to delete the contact.
2185                 
2186                 frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
2187         
2188         }
2189     
2190         // Clear the variable. Don't delete as it will mess things up.
2191     
2192         ContactsFileIndex[intContactSeekNum] = wxT("");
2193     
2194         delete ucd;
2195         ucd = NULL;
2199 void frmMain::EmptyServerDialog(wxCommandEvent& event){
2200     
2201         // Display this message when the server information has changed
2202         // and it is empty.
2204         QRNotif *qrn = (QRNotif *)event.GetClientData();
2205     
2206         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);
2207     
2208         if (QResponse == wxNO){
2209         
2210                 return;
2211     
2212         }
2213     
2214         wxCommandEvent event2(ACTMGR_RESUMEPROC);
2215         event2.SetInt(*qrn->QResponse);
2216         event2.SetClientData(qrn->PausePtr);
2217     
2218         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2219     
2220         wxPostEvent(frameActMgr, event2);
2221     
2224 void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
2225     
2226         // Remove the contact from the window after syncronising.
2227     
2228         // Check which account is currently active in the window.
2229         // If it is different from the one passed to this subroutine then
2230         // exit from the subroutine.
2231     
2232         if (Account != ActiveAccount){
2233                 return;
2234         }
2235     
2236         long longSelected = -1;
2237         int intSelectedData = 0;
2238     
2239         for (;;){
2240         
2241                 longSelected = lstContacts->GetNextItem(longSelected,
2242                         wxLIST_NEXT_ALL,
2243                         wxLIST_STATE_DONTCARE);
2244         
2245                 if (longSelected == -1){
2246             
2247                         break;
2248             
2249                 }
2250         
2251                 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2252         
2253                 // Compare the filename with the one received.
2254                 // If they match then select it.
2255         
2256                 if (ContactsFileIndex[intSelectedData] == Filename){
2257             
2258                         // Remove the contact from the window.
2259             
2260                         lstContacts->DeleteItem(intSelectedData);
2261             
2262                         // Check if contact is the selected contact in the HTML window and
2263                         // if it is then clear the window.
2264             
2265                         if (ActiveFilename == Filename){
2266                 
2267                                 wxString EmptyPage = wxT("");
2268                                 htmContactData->SetPage(EmptyPage);
2269                 
2270                         }
2271             
2272                         break;
2273             
2274                 }
2275         
2276         }
2277     
2282 void frmMain::SortFNLN( wxCommandEvent& event ) {
2283     
2284         // Sort first name then last name.
2285     
2286         wxTreeEvent NullEvent;
2287         SortMode = 1;
2288         LoadContactList(NullEvent);
2289     
2292 void frmMain::SortLNFN( wxCommandEvent& event ) {
2293     
2294         // Sort last name then first name.
2295     
2296         wxTreeEvent NullEvent;
2297         SortMode = 2;
2298         LoadContactList(NullEvent);
2299     
2302 void frmMain::SortNickname( wxCommandEvent& event ) {
2303     
2304         // Sort by nickname.
2305     
2306         wxTreeEvent NullEvent;
2307         SortMode = 3;
2308         LoadContactList(NullEvent);
2309     
2312 void frmMain::SortDisplayAs( wxCommandEvent& event ) {
2313     
2314         // Sort by Display As name.
2315     
2316         wxTreeEvent NullEvent;
2317         SortMode = 4;
2318         LoadContactList(NullEvent);
2319     
2322 void frmMain::SortAscending( wxCommandEvent& event ) {
2323     
2324         // Sort Ascending.
2325     
2326         wxTreeEvent NullEvent;
2327         AscendingMode = TRUE;
2328         LoadContactList(NullEvent);
2329     
2332 void frmMain::SortDescending( wxCommandEvent& event ) {
2333     
2334         // Sort Descending.
2335     
2336         wxTreeEvent NullEvent;
2337         AscendingMode = FALSE;
2338         LoadContactList(NullEvent);
2339     
2342 void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
2343     
2344         // Toggle the appearance of the status bar.
2345     
2346         if (stbBottom->IsShown() == TRUE){
2347         
2348                 stbBottom->Hide();
2349         
2350         } else {
2351         
2352                 stbBottom->Show();
2353         
2354         }
2355     
2356         this->Layout();
2357     
2360 void frmMain::ActivityIconStart( wxCommandEvent& event ){
2361     
2362         // Display the activity icon.
2363     
2364         imgActivityStatus->SetBitmap(*imgActIcon1);
2365         ActivityIconStatus = 0;
2366     
2369 void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
2371         // Shuffle through the activity icons.
2372     
2373         switch (ActivityIconStatus){
2374             
2375                 case 0:
2376                         imgActivityStatus->SetBitmap(*imgActIcon1);
2377                         ActivityIconStatus = 1;
2378                         break;
2379                 case 1:
2380                         imgActivityStatus->SetBitmap(*imgActIcon2);
2381                         ActivityIconStatus = 2;
2382                         break;
2383                 case 2:
2384                         imgActivityStatus->SetBitmap(*imgActIcon3);
2385                         ActivityIconStatus = 3;
2386                         break;
2387                 case 3:
2388                         imgActivityStatus->SetBitmap(*imgActIcon4);
2389                         ActivityIconStatus = 0;
2390                         break;
2391                 default:
2392                         ActivityIconStatus = 0;
2393                             
2394         }
2395     
2398 void frmMain::ActivityIconStop( wxCommandEvent& event ){
2399     
2400         // Display the sleep icon.
2401     
2402         imgActivityStatus->SetBitmap(*imgActIconSleep);
2403     
2406 void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
2407     
2408         // Set the placement of the status bar icons.
2409     
2410         if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
2411         
2412                 return;
2413         
2414         }
2415     
2416         wxRect rectOnline;
2417         wxRect rectSSL;
2418         wxRect rectActivity;
2419         stbBottom->GetFieldRect(1, rectOnline);
2420         stbBottom->GetFieldRect(2, rectSSL);
2421         stbBottom->GetFieldRect(3, rectActivity);
2422     
2423         imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
2424         imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
2425         imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
2426     
2429 XABViewMode frmMain::GetViewMode(){
2430     
2431         // Set the view mode of the contact list.
2432     
2433         XABViewMode xvm;
2434     
2435         xvm.SortMode = SortMode;
2436         xvm.AscendingMode = AscendingMode;
2437     
2438         return xvm;
2439     
2442 void frmMain::WindowAdd( wxCommandEvent &event ){
2443     
2444         // Add a window to the window list.
2445     
2446         WindowData *WData = (WindowData*)event.GetClientData();
2447     
2448         size_t pos;
2449     
2450         if (WData->DataType == 0){
2451         
2452                 // Contact Window
2453         
2454                 int intID = mnuContactWindows->GetId();
2455         
2456                 mnuWindow->FindChildItem(intID, &pos);
2457                 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2458                 mnuNewItem->SetId(WData->WindowID);
2459                 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2460                 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2461                 WindowListType.insert(std::make_pair(WData->WindowID, 0));
2462                 mnuWindow->Insert((pos + 1), mnuNewItem);
2463                 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
2464         
2465         } else if (WData->DataType == 1){
2466         
2467                 // Contact Editor Window
2468         
2469                 int intID = mnuContactEditorWindows->GetId();
2470         
2471                 mnuWindow->FindChildItem(intID, &pos);
2472                 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2473                 mnuNewItem->SetId(WData->WindowID);
2474                 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2475                 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2476                 WindowListType.insert(std::make_pair(WData->WindowID, 1));
2477                 mnuWindow->Insert((pos + 1), mnuNewItem);
2478                 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
2479         
2480         } else if (WData->DataType == 2){
2481         
2482                 // Search Window
2483         
2484                 int intID = mnuSearchWindows->GetId();
2485                 
2486                 mnuWindow->FindChildItem(intID, &pos);
2487                 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2488                 mnuNewItem->SetId(WData->WindowID);
2489                 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2490                 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2491                 WindowListType.insert(std::make_pair(WData->WindowID, 2));
2492                 mnuWindow->Insert((pos + 1), mnuNewItem);
2493                 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
2494         
2495         }
2496     
2497         delete WData;
2498         WData = NULL;
2499     
2502 void frmMain::WindowEdit( wxCommandEvent &event ){
2504         // Edit a window in the window list.
2505     
2506         WindowData *WData = (WindowData*)event.GetClientData();
2507     
2508         if (WData->DataType == 0){
2509         
2510                 // Get the window title and use that.
2511         
2512                 frmContact *frmContactPtr = static_cast<frmContact*>(WData->WindowPointer);
2513         
2514                 wxString WindowTitle = frmContactPtr->GetTitle();
2515         
2516                 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2517         
2518                 MenuIter->second->SetItemLabel(WindowTitle);
2519                 
2520         } else if (WData->DataType == 1){
2521         
2522                 // Get the window title and use that.
2523         
2524                 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WData->WindowPointer);
2525         
2526                 wxString WindowTitle = frmCEPtr->GetTitle();
2527         
2528                 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2529         
2530                 if (WindowTitle.IsEmpty()){
2531             
2532                         MenuIter->second->SetItemLabel(_("Unnamed Contact"));
2533             
2534                 } else {
2535             
2536                         MenuIter->second->SetItemLabel(WindowTitle);
2537             
2538                 }
2539         
2540         }
2541     
2542         delete WData;
2543         WData = NULL;
2544     
2547 void frmMain::WindowDelete( wxCommandEvent &event ){
2548     
2549         // Delete a window from the window list.
2550     
2551         WindowData *WData = (WindowData*)event.GetClientData();
2552     
2553         std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2554     
2555         mnuWindow->Remove(MenuIter->second);
2556     
2557         delete MenuIter->second;
2558         MenuIter->second = NULL;
2559     
2560         WindowListPointersMenu.erase(WData->WindowID);
2561         WindowListPointers.erase(WData->WindowID);
2562         WindowListType.erase(WData->WindowID);
2563     
2564         delete WData;
2565         WData = NULL;
2566     
2569 void frmMain::ShowContactWindow( wxCommandEvent &event ){
2570     
2571         // Show a contact window from the window list.
2572     
2573         std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2574     
2575         frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
2576     
2577         frmContactPtr->Show();
2578         frmContactPtr->Raise();
2579     
2582 void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
2583     
2584         // Show a contact editor window from the window list.
2585     
2586         std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2587     
2588         frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WindowIter->second);
2589     
2590         frmCEPtr->Show();
2591         frmCEPtr->Raise();
2592     
2595 void frmMain::ShowSearchWindow( wxCommandEvent &event ){
2596     
2597         // Show a search window from the window list.   
2598             
2599         std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2600     
2601         frmSearch *frmSearchPtr = static_cast<frmSearch*>(WindowIter->second);
2602     
2603         frmSearchPtr->Show();
2604         frmSearchPtr->Raise();
2605     
2608 void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
2609     
2610         // Toggle the online/offline connection status.
2611     
2612         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2613         wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
2614         wxPostEvent(frameActMgr, toggconn);
2615     
2618 void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
2619     
2620         // Check the account type before continuing.
2621     
2622         wxString SeekAccount;
2623         wxString AccTypeLower;
2624         wxString AccType;
2625         bool AccountSSL;
2626     
2627 #if defined(__APPLE__)
2629         std::map<int, SecTrustRef>::iterator SSLTrustIter;
2630         
2631         for (int i = 0; i < prefaccounts.GetCount(); i++){
2632                 
2633                 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2634                 AccType.Append(prefaccounts.GetAccountType(i));
2635                 AccountSSL = prefaccounts.GetAccountSSL(i);
2636                 AccTypeLower = AccType.MakeLower();
2637                 SeekAccount.Append(wxT("."));
2638                 SeekAccount.Append(AccTypeLower);
2639                 
2640                 if (SeekAccount == ActiveAccount){
2641                         
2642                         if (AccTypeLower == wxT("local")){
2643                                 
2644                                 return;
2645                                 
2646                         }
2647                         
2648                         if (AccountSSL == false){
2649                                 
2650                                 return;
2651                                 
2652                         }
2653                         
2654                         SSLTrustIter = AccountTrustData.find(i);
2655                         
2656                         // Setup and display the form.
2657                         
2658                         DisplayCertificate(SSLTrustIter->second);
2659                         
2660                 }
2661                 
2662                 SeekAccount.Clear();
2663                 AccTypeLower.Clear();
2664                 AccType.clear();
2665                 
2666         }
2667    
2668 #elif defined(__WIN32__)
2670         std::map<int, PCCERT_CONTEXT>::iterator SSLCertificateIter;
2672         for (int i = 0; i < prefaccounts.GetCount(); i++){
2674                 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2675                 AccType.Append(prefaccounts.GetAccountType(i));
2676                 AccountSSL = prefaccounts.GetAccountSSL(i);
2677                 AccTypeLower = AccType.MakeLower();
2678                 SeekAccount.Append(wxT("."));
2679                 SeekAccount.Append(AccTypeLower);
2681                 if (SeekAccount == ActiveAccount){
2683                         if (AccTypeLower == wxT("local")){
2685                                 return;
2687                         }
2689                         if (AccountSSL == false){
2691                                 return;
2693                         }
2695                         SSLCertificateIter = AccountCertificateData.find(i);
2697                         // Setup and display the form.
2699                         if (SSLCertificateIter->second->pCertInfo == NULL){
2701                                 wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
2703                         } else {
2705                                 BOOL ModifiedCertificateData;
2706                                 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
2708                                 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
2709                                         wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
2710                                 }
2712                         }
2714                         //DisplayCertificate(SSLTrustIter->second);
2716                 }
2718                 SeekAccount.Clear();
2719                 AccTypeLower.Clear();
2720                 AccType.clear();
2722         }
2724 #else
2725     
2726         std::map<int, SSLCertCollectionString>::iterator SSLColIter;
2727         
2728         for (int i = 0; i < prefaccounts.GetCount(); i++){
2729         
2730                 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2731                 AccType.Append(prefaccounts.GetAccountType(i));
2732                 AccountSSL = prefaccounts.GetAccountSSL(i);
2733                 AccTypeLower = AccType.MakeLower();
2734                 SeekAccount.Append(wxT("."));
2735                 SeekAccount.Append(AccTypeLower);
2736         
2737                 if (SeekAccount == ActiveAccount){
2738             
2739                         if (AccTypeLower == wxT("local")){
2740                 
2741                                 return;
2742                 
2743                         }
2744             
2745                         if (AccountSSL == false){
2746                 
2747                                 return;
2748                 
2749                         }
2750             
2751                         SSLColIter = AccountSSLData.find(i);
2752             
2753                         SSLCertCollectionString SSLCertInfo = SSLColIter->second;
2754                         
2755                         frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
2756                         frameSSLCert->StartCertFrom(0);
2757                         frameSSLCert->SetupCertsString(SSLCertInfo);
2758                         frameSSLCert->ShowModal();
2759             
2760                         delete frameSSLCert;
2761                         frameSSLCert = NULL;
2762             
2763                 }
2764         
2765                 SeekAccount.Clear();
2766                 AccTypeLower.Clear();
2767                 AccType.clear();
2768         
2769         }
2771 #endif
2772     
2775 void frmMain::ShowSSLInfo( wxCommandEvent &event ){
2776     
2777         // Check the account type before continuing.
2778     
2781 void frmMain::HideSSLInfo( wxCommandEvent &event ){
2782     
2783         // Check the account type before continuing.
2784     
2787 void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
2788     
2789         if (event.GetInt() == 0){
2790         
2791                 imgConnStatus->SetBitmap(*imgOnline);
2792         
2793         } else {
2794         
2795                 imgConnStatus->SetBitmap(*imgOffline);
2796         
2797         }       
2798     
2801 void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
2802     
2803         // Display the form for showing an invalid SSL certificate.
2804     
2805         frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2806         SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
2807         SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
2808         wxString AccountName = SSLICNObj->AccountName;
2809         frameISC->LoadData(SSLCCData, AccountName);
2810         frameISC->ShowModal();
2811     
2812         int FinalConflictResult = frameISC->GetResult();
2813     
2814         wxCommandEvent event2(ACTMGR_RESUMEPROC);
2815         event2.SetClientData(SSLICNObj->QRNotifData);
2816         event2.SetInt(FinalConflictResult);
2817     
2818         delete frameISC;
2819         frameISC = NULL;
2820     
2821         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);  
2822         wxPostEvent(frameActMgr, event2);
2823         
2826 void frmMain::InvalidSSLCertificateString( wxCommandEvent &event ){
2827     
2828         // Display the form for showing an invalid SSL certificate.
2829     
2830         frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2831         SSLInvalidCertNotifObjString *SSLICNObj = (SSLInvalidCertNotifObjString*)event.GetClientData();
2832         SSLCertCollectionString SSLCCData = SSLICNObj->CertCollection;
2833         wxString AccountName = SSLICNObj->AccountName;
2834         frameISC->LoadData(SSLCCData, AccountName);
2835         frameISC->ShowModal();
2836     
2837         int FinalConflictResult = frameISC->GetResult();
2838     
2839         wxCommandEvent event2(ACTMGR_RESUMEPROC);
2840         event2.SetClientData(SSLICNObj->QRNotifData);
2841         event2.SetInt(FinalConflictResult);
2842     
2843         delete frameISC;
2844         frameISC = NULL;
2845     
2846         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);  
2847         wxPostEvent(frameActMgr, event2);
2848         
2851 void frmMain::PauseAllTimers(){
2852     
2853         // Pause all the account timers.
2854     
2855         for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin(); 
2856                 ASTiter != AccountSyncTimers.end(); ASTiter++){
2857         
2858                 ASTiter->second->Stop();
2859         
2860         }
2861     
2864 void frmMain::ResumeAllTimers(){
2865     
2866         // Resume all the account timers.
2867     
2868         for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin(); 
2869                 ASTiter != AccountSyncTimers.end(); ASTiter++){
2870         
2871                 ASTiter->second->Start();
2872         
2873         }
2874     
2877 #if defined(__APPLE__)
2879 #elif defined(__WIN32__)
2881 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
2883         // Delete existing data.
2885         std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.find(AccountID);
2887         if (CertificateIter != AccountCertificateData.end()){
2888                 CertFreeCertificateContext(CertificateIter->second);
2889         }
2891         AccountCertificateData.erase(AccountID);
2892         AccountSSLResult.erase(AccountID);
2894         // Insert new data.
2896         AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
2897         AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2901 #else
2903 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollectionString SSLCertInc){
2904     
2905         // Delete existing data.
2906     
2907         AccountSSLData.erase(AccountID);
2908         AccountSSLResult.erase(AccountID);
2909     
2910         // Insert new data.
2911     
2912         AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
2913         AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2914     
2917 #endif
2919 void frmMain::SetupSSLStatus( int AccountID ){
2920         
2921         // Check if account ID given is
2922         // the active account and if not, do nothing.
2923         
2924         wxString AccType;
2925         wxString AccTypeLower;
2926         
2927         AccType = prefaccounts.GetAccountType(AccountID);
2928         AccTypeLower = AccType.MakeLower();
2929         
2930         wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
2931         AccTypeLower;
2932         
2933         if (AccountIDName != ActiveAccount){
2934                 
2935                 return;
2936                 
2937         }
2938         
2939         // Check the account type is a supported account type.
2940         
2941         if (AccType != "CardDAV" && AccType != "carddav" &&
2942                 AccType != "Local" && AccType != "local"){
2943         
2944                 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2945                 imgSSLStatus->SetBitmap(*imgNoSSL);
2946                 return;
2947                         
2948         }
2949         
2950         // Check if the account has SSL enabled.
2951         
2952         bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
2953         
2954         if (SSLInUse == FALSE){
2955                 
2956                 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2957                 imgSSLStatus->SetBitmap(*imgNoSSL);
2958                 
2959         } else {
2960                 
2961                 // Get the SSL Collection Data.
2962                 
2963                 std::map<int,int>::iterator SSLResultIter = AccountSSLResult.find(AccountID);
2964                 
2965                 // Check if a result value has been set.
2967                 if (SSLResultIter == AccountSSLResult.end()){
2969                         imgSSLStatus->SetBitmap(*imgSSLWarning);
2970                         SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
2971                         return;
2973                 }
2975                 if (SSLResultIter->second == 1){
2976                         
2977                         imgSSLStatus->SetBitmap(*imgSSLWarning);
2978                         SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
2979                                            prefaccounts.GetAccountName(AccountID) +
2980                                            wxT("' (Connection denied by user)\n\nDouble click for more information."));
2981                         
2982                 } else if (SSLResultIter->second == 0){
2983                         
2984                         imgSSLStatus->SetBitmap(*imgSSL);
2985                         SSLToolTip->SetTip(wxT("Account '") +
2986                                            prefaccounts.GetAccountName(AccountID) +
2987                                            wxT("' secured using SSL\n\nDouble click for more information."));
2988                         
2989                 }
2990                 
2991         }
2992         
2995 void frmMain::CheckUpdates( wxCommandEvent& event ){
2996     
2997         // Check for updates to Xestia Address Book.
2998     
2999         frmUpdate *frameUpdate = new frmUpdate ( this );
3000         frameUpdate->FetchData();
3001         frameUpdate->ShowModal();
3002     
3005 void frmMain::OpenImportDialog( wxCommandEvent& event ){
3006     
3007         // Run the import contacts function.
3008     
3009         ImportRun(this);
3010     
3013 void frmMain::OpenExportDialog( wxCommandEvent& event ){
3014     
3015         // Check if an account and at least one contact is selected
3016         // before continuing.
3017     
3018         wxArrayString ArrData;
3019     
3020         if (ActiveAccount.IsEmpty()){
3021         
3022                 return;
3023         
3024         }
3025     
3026         int ContactSelected = 0;
3027         int ContactsCollected = 0;
3028         long longSelected = -1;
3029     
3030         for (;;){
3031         
3032                 longSelected = lstContacts->GetNextItem(longSelected, 
3033                         wxLIST_NEXT_ALL,
3034                         wxLIST_STATE_SELECTED);
3035         
3036                 if (longSelected == -1){
3037             
3038                         break;
3039         
3040                 }
3041         
3042                 int FileID = (int)lstContacts->GetItemData(longSelected);
3043         
3044                 ArrData.Insert(ContactsFileIndex[FileID],
3045                        ContactsCollected, 1);
3046         
3047                 ContactSelected++;
3048         
3049         }
3050     
3051         if (ContactSelected == 0){
3052         
3053                 return;
3054         
3055         }
3056     
3057         // Run the export contacts system.
3058     
3059         ExportRun(this, &ArrData);
3060     
3063 void frmMain::GetListControl(wxListCtrl *lstContactsPtr, 
3064                              wxArrayString *ContactsFileIndexPtr){
3065     
3066         // Set the list control pointers.
3067     
3068         lstContactsPtr = lstContacts;
3069         ContactsFileIndexPtr = &ContactsFileIndex;
3070     
3073 void frmMain::GetSelectedList( wxCommandEvent& event ){
3074     
3075         // Get the array of contact filenames. 
3076     
3077         wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
3078     
3079         // Process them into an array of files. 
3080     
3081         long longSelected = -1;
3082         int ContactsCollected = 0;
3083         wxString ContactFilename;
3084     
3085         for (;;){
3086         
3087                 longSelected = lstContacts->GetNextItem(longSelected, 
3088                         wxLIST_NEXT_ALL,
3089                         wxLIST_STATE_SELECTED);
3090         
3091                 if (longSelected == -1){
3092             
3093                         break;
3094             
3095                 }
3096         
3097                 // Get the file information and add to the list.
3098         
3099                 int FileID = (int)lstContacts->GetItemData(longSelected);
3100         
3101                 ArrData->Insert(ContactsFileIndex[FileID],
3102                         ContactsCollected, 1);
3103         
3104                 ContactsCollected++;
3105                 ContactFilename.Clear();        
3106         
3107         }
3108     
3109         event.SetInt(1);
3110     
3113 void frmMain::SyncAccount( wxCommandEvent& event ){
3114     
3115         // Syncronise the selected account.
3116     
3117         wxString AccNameInc = event.GetString();
3118     
3119         frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
3120         frameActMgr->AddTask(3, wxT(""), AccNameInc, 
3121                 wxT(""), wxT(""), wxT(""), wxT(""));
3122     
3125 void frmMain::ShowHelp( wxCommandEvent& event ){
3126     
3127         // Based on the operating system, work out where 
3128         // the documentation should be.
3129         
3130     
3131 #if defined(__HAIKU__)
3133 #elif defined(__WIN32__)    
3135 #elif defined(__APPLE__)
3136         DisplayHelpBrowser();
3137         return;
3138 #else
3139     
3140         // Get the LANG environment variable
3141         
3142         char *languageEnvironmentVariableChar = getenv("LANG");
3143         std::string languageEnvironmentVariable(languageEnvironmentVariableChar);
3144         
3145         int executeResult = 0;
3146         
3147         wxString documentPath = wxString::Format("/usr/local/share/doc/xestiaab/%s.fodt", 
3148                 wxString(languageEnvironmentVariable).BeforeFirst('.', nullptr));
3149         std::string commandToExecute = "odthelpbrowser -d " + documentPath.ToStdString();
3150         
3151         if (wxFileExists(documentPath))
3152                 executeResult = system(commandToExecute.c_str());
3153        
3154         if (executeResult == 0)
3155                 return;
3156         
3157 #if XSDAB_RELEASE == 0
3158         documentPath = wxString::Format("/usr/share/doc/xestiaab/%s.fodt", 
3159                 wxString(languageEnvironmentVariable).BeforeFirst('.', nullptr));       
3160         commandToExecute = "odthelpbrowser -d " + documentPath.ToStdString();
3161         
3162         if (wxFileExists(documentPath))
3163                 executeResult = system(commandToExecute.c_str());
3164         
3165         if (executeResult == 0)
3166                 return;
3167 #endif 
3168     
3169         // Attempt to launch using the "default" language.
3170         
3171         if (wxFileExists("/usr/share/doc/xestiaab/en_GB.fodt") && executeResult > 0)
3172         {
3173                 commandToExecute = "odthelpbrowser -d " + documentPath.ToStdString();
3174                 executeResult = system(commandToExecute.c_str());
3175         }
3176         else if (wxFileExists("/usr/local/share/doc/xestiaab/en_GB.fodt") && executeResult > 0)
3177         {
3178                 commandToExecute = "odthelpbrowser -d " + documentPath.ToStdString();
3179                 executeResult = system(commandToExecute.c_str());
3180         }
3181     
3182         if (executeResult == 0)
3183                 return;
3184     
3185 #endif
3187 #if XSDAB_RELEASE == 0
3188         wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
3189         return;
3190 #else
3191         wxMessageBox(_("The help documentation is not available in the usual locations on the system. Please visit https://xestia.co.uk/addressbook for documentation"), _("Help documentation missing!"));
3192         return;
3193 #endif
3194     
3197 void frmMain::ShowImportResults( wxCommandEvent &event ){
3199         // Show the results of importing contacts.
3201         std::map<int,wxString> *ResultData = (std::map<int,wxString>*)event.GetClientData();
3203         frmImportResults *frmIR = new frmImportResults(this);
3204         frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
3205         frmIR->ShowModal();
3206                 
3207         delete frmIR;
3208         frmIR = NULL;
3209         
3210         delete ResultData;
3211         ResultData = NULL;
3215 void frmMain::ReloadContactList( wxCommandEvent &event ){
3217         // Check if the account name given is the current
3218         // account selected.
3220         if (ActiveAccount == event.GetString()){
3221         
3222                 wxTreeEvent NullEvent;
3223                 LoadContactList(NullEvent);
3224         
3225         }
3229 void frmMain::ShowContactMenu( wxMouseEvent& event ){
3231         // Show the contact menu when a right click occurs
3232         // in the contacts list.
3234         bool EnableRefresh = FALSE;
3236         if (!ActiveAccount.IsEmpty() && (ActiveAccountType == "CardDAV" ||
3237                 ActiveAccountType == "carddav" ||
3238                 ActiveAccountType == "Local" ||
3239                 ActiveAccountType == "local")){
3241                 EnableRefresh = TRUE;
3242         
3243         }
3245         ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
3247         this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
3251 void frmMain::ResetContactInfo(){
3253         // Reset the contact information to an empty page.
3254         
3255         wxString EmptyPage = wxT("");
3256         htmContactData->SetPage(EmptyPage);
3257         AccCtrl->SetValue("");
3258         
3261 bool frmMain::CloseAllWindows()
3263         // Attempt to close all windows.
3264         
3265         if (WindowListPointersMenu.size() == 0)
3266         {
3267                 return true;
3268         }
3269         
3270         if (wxMessageBox(_("Before preforming the action, all windows that are open will need to close. Do you wish to continue?"), _("Close All Windowss"), wxYES_NO) == wxYES)
3271         {
3272                 for(std::map<int, void*>::iterator windowIter = WindowListPointers.begin();
3273                         windowIter != WindowListPointers.end(); windowIter++)
3274                 {
3275                         wxWindow *windowPointer = static_cast<wxWindow*>(windowIter->second);
3276                         windowPointer->Close();
3277                 }
3278                 return true;
3279         }
3280         else
3281         {
3282                 return false;
3283         }
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy