1 // frmMain.cpp - Main window form.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
25 #include <wx/tokenzr.h>
27 #include <wx/mstream.h>
28 #include <wx/fs_mem.h>
30 #include <wx/filesys.h>
32 #include <wx/stdpaths.h>
33 #include <wx/fileconf.h>
34 #include <wx/gdicmn.h>
40 #include "frmPreferences.h"
41 #include "frmNewAccount.h"
42 #include "actmgr/frmActivityMgr.h"
43 #include "frmContact.h"
44 #include "frmConflictResolution.h"
45 #include "frmInvalidSSLCertificate.h"
46 #include "search/frmSearch.h"
47 #include "frmSSLCertificate.h"
48 #include "frmUpdate.h"
49 #include "import/frmImportResults.h"
52 #include "common/preferences.h"
53 #include "common/getcontactinfo.h"
54 #include "common/events.h"
55 #include "common/dirs.h"
56 #include "vcard/vcard.h"
57 #include "carddav/carddav.h"
58 #include "contacteditor/frmContactEditor.h"
59 #include "import/import.h"
60 #include "export/export.h"
61 #include "widgets/XABContactMenu.h"
62 #include "widgets/XABAccountView.h"
66 // Define the event types.
68 DEFINE_EVENT_TYPE(CE_UPDATECONTACTLIST);
69 DEFINE_EVENT_TYPE(CE_UPDATEACCOUNTLIST);
70 DEFINE_EVENT_TYPE(SE_UPDATECONTACTNOTIF);
71 DEFINE_EVENT_TYPE(CE_OPENCONTACT);
72 DEFINE_EVENT_TYPE(CE_OPENCONTACTLIST);
73 DEFINE_EVENT_TYPE(CE_NEWCONTACT);
74 DEFINE_EVENT_TYPE(CE_EDITCONTACT);
75 DEFINE_EVENT_TYPE(CE_DELETECONTACT);
76 DEFINE_EVENT_TYPE(CE_REVEALCONTACT);
77 DEFINE_EVENT_TYPE(CE_REMOVECONTACT);
78 DEFINE_EVENT_TYPE(CE_REMOVESEARCH);
79 DEFINE_EVENT_TYPE(SYNC_EMPTYSERVER);
80 DEFINE_EVENT_TYPE(ACTMGR_START);
81 DEFINE_EVENT_TYPE(ACTMGR_SHUFFLE);
82 DEFINE_EVENT_TYPE(ACTMGR_STOP);
83 DEFINE_EVENT_TYPE(WINDOW_ADD);
84 DEFINE_EVENT_TYPE(WINDOW_EDIT);
85 DEFINE_EVENT_TYPE(WINDOW_CLOSE);
86 DEFINE_EVENT_TYPE(CONNSTAT_UPDATE);
87 DEFINE_EVENT_TYPE(INVALIDSSLCERT);
88 DEFINE_EVENT_TYPE(GETSELECTEDLIST);
89 DEFINE_EVENT_TYPE(SYNCACCOUNT);
90 DEFINE_EVENT_TYPE(IMPORT_RESULTSSHOW);
91 DEFINE_EVENT_TYPE(RELOADCONTACTLIST);
92 DEFINE_EVENT_TYPE(REFRESHADDRESSBOOK);
93 #if defined(__APPLE__)
94 DEFINE_EVENT_TYPE(INVALIDSSLTRUST);
97 // Setup the event table using the event types.
99 BEGIN_EVENT_TABLE(frmMain, wxFrame)
100 EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, frmMain::ConflictResolution)
101 EVT_COMMAND(wxID_ANY, CE_UPDATECONTACTLIST, frmMain::UpdateContactList)
102 EVT_COMMAND(wxID_ANY, CE_UPDATEACCOUNTLIST, frmMain::UpdateAccountList)
103 EVT_COMMAND(wxID_ANY, SE_UPDATECONTACTNOTIF, frmMain::UpdateSearchContactLists)
104 EVT_COMMAND(wxID_ANY, CE_OPENCONTACT, frmMain::OpenContactInfo)
105 EVT_COMMAND(wxID_ANY, CE_OPENCONTACTLIST, frmMain::OpenContactInfoList)
106 EVT_COMMAND(wxID_ANY, CE_NEWCONTACT, frmMain::ShowContactEditorNew)
107 EVT_COMMAND(wxID_ANY, CE_EDITCONTACT, frmMain::ShowContactEditorEdit)
108 EVT_COMMAND(wxID_ANY, CE_DELETECONTACT, frmMain::DeleteContact)
109 EVT_COMMAND(wxID_ANY, CE_REVEALCONTACT, frmMain::RevealContact)
110 EVT_COMMAND(wxID_ANY, CE_REMOVESEARCH, frmMain::RemoveContactsWindowPointer)
111 EVT_COMMAND(wxID_ANY, SYNC_EMPTYSERVER, frmMain::EmptyServerDialog)
112 EVT_COMMAND(wxID_ANY, ACTMGR_START, frmMain::ActivityIconStart)
113 EVT_COMMAND(wxID_ANY, ACTMGR_SHUFFLE, frmMain::ActivityIconShuffle)
114 EVT_COMMAND(wxID_ANY, ACTMGR_STOP, frmMain::ActivityIconStop)
115 EVT_COMMAND(wxID_ANY, WINDOW_ADD, frmMain::WindowAdd)
116 EVT_COMMAND(wxID_ANY, WINDOW_EDIT, frmMain::WindowEdit)
117 EVT_COMMAND(wxID_ANY, WINDOW_CLOSE, frmMain::WindowDelete)
118 EVT_COMMAND(wxID_ANY, CONNSTAT_UPDATE, frmMain::UpdateConnectionStatus)
119 EVT_COMMAND(wxID_ANY, INVALIDSSLCERT, frmMain::InvalidSSLCertificate)
120 EVT_COMMAND(wxID_ANY, GETSELECTEDLIST, frmMain::GetSelectedList)
121 EVT_COMMAND(wxID_ANY, SYNCACCOUNT, frmMain::SyncAccount)
122 EVT_COMMAND(wxID_ANY, IMPORT_RESULTSSHOW, frmMain::ShowImportResults)
123 EVT_COMMAND(wxID_ANY, RELOADCONTACTLIST, frmMain::ReloadContactList)
124 EVT_COMMAND(wxID_ANY, REFRESHADDRESSBOOK, frmMain::RefreshAddressBook)
125 #if defined(__APPLE__)
126 EVT_COMMAND(wxID_ANY, INVALIDSSLTRUST, frmMain::DisplayTrustPanel)
130 frmMain::frmMain( wxWindow* parent )
135 // Setup the account icons.
137 wxMemoryInputStream astream(icons_accinet_png, sizeof(icons_accinet_png));
138 wxMemoryInputStream bstream(icons_acclocal_png, sizeof(icons_acclocal_png));
139 wxMemoryInputStream cstream(icons_accgroup_png, sizeof(icons_accgroup_png));
140 wxMemoryInputStream dstream(icons_accnone_png, sizeof(icons_accnone_png));
141 wxMemoryInputStream estream(icons_accunsupported_png, sizeof(icons_accunsupported_png));
143 wxImage icons_accinet_png(astream, wxBITMAP_TYPE_PNG);
144 wxBitmap AccInet(icons_accinet_png, -1);
146 wxIAccInet.CopyFromBitmap(AccInet);
148 wxImage icons_acclocal_png(bstream, wxBITMAP_TYPE_PNG);
149 wxBitmap AccNIcon(icons_acclocal_png, -1);
151 wxIAccNIcon.CopyFromBitmap(AccNIcon);
153 wxImage icons_accgroup_png(cstream, wxBITMAP_TYPE_PNG);
154 wxBitmap AccGrp(icons_accgroup_png, -1);
156 wxIAccGrp.CopyFromBitmap(AccGrp);
158 wxImage icons_accnone_png(dstream, wxBITMAP_TYPE_PNG);
159 wxBitmap AccNone(icons_accnone_png, -1);
161 wxIAccNone.CopyFromBitmap(AccNone);
163 wxImage icons_accunsupported_png(estream, wxBITMAP_TYPE_PNG);
164 wxBitmap AccUnsupported(icons_accunsupported_png, -1);
165 wxIcon wxIAccUnsupported;
166 wxIAccUnsupported.CopyFromBitmap(AccUnsupported);
168 AccountID = AccImgList->Add(wxIAccNIcon);
169 AccountNetID = AccImgList->Add(wxIAccInet);
170 AccountGrpID = AccImgList->Add(wxIAccGrp);
171 AccountNoneID = AccImgList->Add(wxIAccNone);
172 AccountUnsupportedID = AccImgList->Add(wxIAccUnsupported);
174 bmpIcon->SetIcon(AccImgList->GetIcon(AccountNoneID));
176 // Setup the status bar icons.
180 wxMemoryInputStream sslstream(icons_ssl_png, sizeof(icons_ssl_png));
181 wxMemoryInputStream sslwarningstream(icons_sslwarning_png, sizeof(icons_sslwarning_png));
182 wxMemoryInputStream nosslstream(icons_nossl_png, sizeof(icons_nossl_png));
184 wxImage icons_ssl_png(sslstream, wxBITMAP_TYPE_PNG);
185 imgSSL = new wxBitmap(icons_ssl_png, -1);
187 wxImage icons_sslwarning_png(sslwarningstream, wxBITMAP_TYPE_PNG);
188 imgSSLWarning = new wxBitmap(icons_sslwarning_png, -1);
190 wxImage icons_nossl_png(nosslstream, wxBITMAP_TYPE_PNG);
191 imgNoSSL = new wxBitmap(icons_nossl_png, -1);
195 wxMemoryInputStream act1(icons_act1_png, sizeof(icons_act1_png));
196 wxMemoryInputStream act2(icons_act2_png, sizeof(icons_act2_png));
197 wxMemoryInputStream act3(icons_act3_png, sizeof(icons_act3_png));
198 wxMemoryInputStream act4(icons_act4_png, sizeof(icons_act4_png));
199 wxMemoryInputStream actsleep(icons_actsleep_png, sizeof(icons_actsleep_png));
201 wxImage icons_actsleep_png(actsleep, wxBITMAP_TYPE_PNG);
202 imgActIconSleep = new wxBitmap (icons_actsleep_png, -1);
204 wxImage icons_act1_png(act1, wxBITMAP_TYPE_PNG);
205 imgActIcon1 = new wxBitmap (icons_act1_png, -1);
207 wxIAct1icon.CopyFromBitmap(*imgActIcon1);
209 wxImage icons_act2_png(act2, wxBITMAP_TYPE_PNG);
210 imgActIcon2 = new wxBitmap (icons_act2_png, -1);
212 wxIAct2icon.CopyFromBitmap(*imgActIcon2);
214 wxImage icons_act3_png(act3, wxBITMAP_TYPE_PNG);
215 imgActIcon3 = new wxBitmap (icons_act3_png, -1);
217 wxIAct3icon.CopyFromBitmap(*imgActIcon3);
219 wxImage icons_act4_png(act4, wxBITMAP_TYPE_PNG);
220 imgActIcon4 = new wxBitmap (icons_act4_png, -1);
222 wxIAct4icon.CopyFromBitmap(*imgActIcon4);
224 // Online/Offline icons.
226 wxMemoryInputStream onlinestream(icons_online_png, sizeof(icons_online_png));
227 wxMemoryInputStream offlinestream(icons_offline_png, sizeof(icons_offline_png));
229 wxImage icons_online_png(onlinestream, wxBITMAP_TYPE_PNG);
230 imgOnline = new wxBitmap(icons_online_png, -1);
232 wxImage icons_offline_png(offlinestream, wxBITMAP_TYPE_PNG);
233 imgOffline = new wxBitmap(icons_offline_png, -1);
235 // Setup the account view.
237 AccCtrl->SetPopupControl(treAccounts);
238 AccCtrl->SetPopupMaxHeight(175);
239 AccCtrl->SetPopupMinWidth(250);
240 treAccounts->AssignImageList(AccImgList);
242 wxListItem ColumnData;
244 ColumnData.SetText(wxT("Name0"));
245 ColumnData.SetWidth(320);
246 lstContacts->InsertColumn(0, ColumnData);
248 treAccounts->Connect(wxEVT_LEFT_DCLICK, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
249 treAccounts->Connect(wxEVT_TREE_SEL_CHANGED, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
251 #if defined(__HAIKU__)
253 #elif defined(__WIN32__)
255 int stbBottomData [4] = { -1, 8, 8, 8 };
259 int stbBottomData [4] = { -1, 20, 20, 20 };
263 stbBottom->SetFieldsCount(4, stbBottomData);
264 stbBottom->SetMinHeight(16);
269 stbBottom->GetFieldRect(1, rectOnline);
270 stbBottom->GetFieldRect(2, rectSSL);
271 stbBottom->GetFieldRect(3, rectActivity);
273 SSLToolTip = new wxToolTip(wxT(""));
275 imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectOnline.GetX()),(rectOnline.GetY())), wxDefaultSize, 0 );
276 imgConnStatus->SetBitmap(*imgOnline);
277 imgConnStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ToggleConnectionStatus ), NULL, this );
279 imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()),(rectSSL.GetY())), wxDefaultSize, 0 );
280 imgSSLStatus->SetBitmap(*imgNoSSL);
281 imgSSLStatus->SetToolTip(SSLToolTip);
282 imgSSLStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowSSLCertificates ), NULL, this );
284 imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()),(rectActivity.GetY())), wxDefaultSize, 0);
285 imgActivityStatus->SetBitmap(*imgActIconSleep);
286 imgActivityStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowActivityWindow ), NULL, this );
288 // Setup the window menu.
290 // By default should be:
295 // Contact editor windows:
301 mnuContactWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact windows:") ), wxEmptyString, wxITEM_NORMAL );
302 mnuWindow->Append( mnuContactWindows );
304 mnuWindow->AppendSeparator();
306 mnuContactEditorWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact editor windows:") ), wxEmptyString, wxITEM_NORMAL );
307 mnuWindow->Append( mnuContactEditorWindows );
309 mnuWindow->AppendSeparator();
311 mnuSearchWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( wxT("Search windows:") ), wxEmptyString, wxITEM_NORMAL );
312 mnuWindow->Append( mnuSearchWindows );
314 #if defined(__WIN32__)
319 mnuContactWindows->SetFont(fontstyle);
320 mnuContactEditorWindows->SetFont(fontstyle);
321 mnuSearchWindows->SetFont(fontstyle);
325 mnuContactWindows->Enable(FALSE);
326 mnuContactEditorWindows->Enable(FALSE);
327 mnuSearchWindows->Enable(FALSE);
331 // Hide unimplemented functions.
337 void frmMain::QuitApp( wxCloseEvent& event )
340 // Run the QuitApp function.
346 void frmMain::QuitApp( wxCommandEvent& event )
349 // Run the QuitApp function.
355 void frmMain::QuitApp()
358 // Function to run when quitting.
360 //Go through the windows and close each one (be it search
361 //or contact editor). Abort if user wants to cancel.
363 // Close the contact editor windows.
365 // Close the contact windows.
367 // Close the search windows.
369 // Write out the ETag databases.
371 // Save Preferences: Save the window position if that option is enabled.
373 wxString SetFilename = GetUserPrefDir();
375 #if defined(__HAIKU__)
379 #elif defined(__WIN32__)
381 SetFilename.Append(wxT("settings"));
387 SetFilename.Append(wxT("settings"));
391 wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
393 bool SaveWindowPos = FALSE;
394 wxString SaveWindowInc;
395 cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
397 if (SaveWindowInc == wxT("true")){
399 SaveWindowPos = TRUE;
403 if (SaveWindowPos == TRUE){
405 wxRect frmMainPos = this->GetRect();
407 cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
408 cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
409 cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
410 cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
417 //Everything closed... exit.
425 void frmMain::ShowActivityWindow( wxCommandEvent& event )
428 // Open the activity manager window.
430 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
431 frameActMgr->OpenWindow();
436 void frmMain::ShowAboutWindow( wxCommandEvent& event )
439 // Show the about window.
441 frmAbout *frameAbout = new frmAbout ( this );
442 frameAbout->SetupAboutWindow();
443 frameAbout->ShowModal();
449 void frmMain::OpenPreferences( wxCommandEvent& event)
452 // Open the preferences window.
454 ReloadAccounts = FALSE;
456 frmPreferences *framePreferences = new frmPreferences ( this );
457 framePreferences->SetupPointers(&ReloadAccounts);
458 framePreferences->ShowModal();
459 delete framePreferences;
460 framePreferences = NULL;
462 if (ReloadAccounts == TRUE){
464 // Reload the accounts as a change has been made within
465 // the application and clear the current contact information.
467 this->LoadPreferences();
468 this->ResetContactInfo();
474 void frmMain::OpenNewABDialog( wxCommandEvent& event)
477 // Open the new account dialog.
479 ReloadAccounts = FALSE;
481 frmNewAccount *frameNewAccount = new frmNewAccount ( this );
482 frameNewAccount->SetupPointers(&ReloadAccounts);
483 frameNewAccount->ShowModal();
484 delete frameNewAccount;
485 frameNewAccount = NULL;
487 if (ReloadAccounts == TRUE){
489 // Reload the accounts as a change has been made within
492 this->LoadPreferences();
498 void frmMain::LoadContactList( wxTreeEvent& event )
501 // Load the contact list.
503 // Clear all existing variables.
505 lstContacts->DeleteAllItems();
507 treAccounts->SetAccount();
509 wxTreeItemIdValue cookie;
510 wxTreeItemId next = treAccounts->GetRootItem();
511 wxString AccountName;
512 wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
513 wxString AccountDirCmb;
514 long selectedaccount = 0;
516 wxTreeItemId selectedChild = treAccounts->GetSelection();
517 wxTreeItemId nextChild;
519 wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
520 int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
522 int SCImg = treAccounts->GetItemImage(selectedChild);
523 int AccountIndex = 0;
525 bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
527 // Process each account.
529 for (int i = 0; i < prefaccounts.GetCount(); i++){
531 if (ActiveItemIcon == 2){
533 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
534 std::multimap<int, int>::iterator AGLiter = AccountGroupList.find(AGTiter->second);
535 int ActiveAccountG = AGLiter->second;
537 if (i == ActiveAccountG){
539 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
540 AccountType.Append(prefaccounts.GetAccountType(i));
545 if (AccountType == wxT("CardDAV")){
546 AccountTypeFinal.Append(wxT("carddav"));
547 } else if (AccountType == wxT("Local")){
548 imgSSLStatus->SetBitmap(*imgOffline);
549 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
550 AccountTypeFinal.Append(wxT("local"));
552 imgSSLStatus->SetBitmap(*imgOffline);
553 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
554 AccountTypeFinal.Append(AccountType.Lower());
565 nextChild = treAccounts->GetFirstChild(next, cookie);
567 nextChild = treAccounts->GetNextSibling(nextChild);
570 AccountName = treAccounts->GetItemText(nextChild);
572 if (nextChild == selectedChild){
574 AccountDir.Append(prefaccounts.GetAccountDirectory(i));
575 AccountType.Append(prefaccounts.GetAccountType(i));
580 if (AccountType == wxT("CardDAV")){
581 AccountTypeFinal.Append(wxT("carddav"));
582 } else if (AccountType == wxT("Local")){
583 SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
584 AccountTypeFinal.Append(wxT("local"));
586 AccountTypeFinal.Append(AccountType.Lower());
595 if (selectedaccount >= prefaccounts.GetCount()){
597 // The account selected isn't there so return.
605 // Open the directory and get the list of .vcf files
606 // in that directory.
608 ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
609 ActiveAccountType = AccountType;
611 SetupSSLStatus(AccountIndex);
613 AccountDirFinal.Clear();
614 AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
616 ContactsFileIndex.Clear();
618 wxString vCardFilename;
619 wxString vCardFilenameFull;
620 wxString vCardDataString;
621 wxStringTokenizer vcardfileline;
623 wxString setname, setvalue;
624 std::multimap<wxString, wxString, std::greater<wxString>> vCardNamesAsc;
625 std::multimap<wxString, wxString, std::less<wxString>> vCardNamesDsc;
626 long ContactIndex = 1;
627 long ContactSeekPoint = 0;
629 wxDir vcardaccdir(AccountDirFinal);
631 // Get the wxTreeItemId and image icon and compare it to the list.
633 if (ActiveItemIcon == AccountGrpID){
635 // It's a group so load the file containing the group and
636 // get the members of the group.
641 std::multimap<wxTreeItemId, int>::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
642 std::multimap<int, wxString>::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
644 Group.LoadFile(AGFiter->second);
646 ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
648 for (int i = 0; i < vCardMember.PropCount; i++){
650 vCardMember.PropValues[i].Trim();
651 if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
653 wxString NewPropValue;
654 NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
655 vCardMember.PropValues[i] = NewPropValue;
661 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
665 if (vCardFilename.Right(4) == wxT(".vcf") ||
666 vCardFilename.Right(4) == wxT(".VCF") ||
667 vCardFilename.Right(5) == wxT(".vcard") ||
668 vCardFilename.Right(5) == wxT(".VCARD")){
671 bool FoundMember = FALSE;
673 vCardFilenameFull.Append(AccountDirFinal);
674 vCardFilenameFull.Append(wxT("/"));
675 vCardFilenameFull.Append(vCardFilename);
677 Person.LoadFile(vCardFilenameFull);
679 UIDCode = Person.Get(wxT("UID"));
681 for (int i = 0; i < vCardMember.PropCount; i++){
683 if (vCardMember.PropValues[i] == UIDCode){
691 if (FoundMember == FALSE){
693 vCardFilename.Clear();
694 vCardFilenameFull.Clear();
695 vCardDataString.Clear();
696 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
701 if (Person.MeetBaseSpecification()){
705 // Split the name into sections.
707 vCardDataString = Person.Get(wxT("N"));
709 vCardName NameData = Person.GetName();
711 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
713 } else if (SortMode == 2){
715 // Split the name into sections.
717 vCardName NameData = Person.GetName();
719 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
721 } else if (SortMode == 3){
723 // Check and make sure that the top most nickname is used.
725 vCardDataString = Person.Get(wxT("NICKNAME"));
727 if (vCardDataString.IsEmpty()){
729 vCardDataString = wxT("(no nickname)");
733 } else if (SortMode == 4){
735 vCardDataString = Person.Get(wxT("FN"));
739 if (AscendingMode == TRUE){
740 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
742 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
749 vCardFilename.Clear();
750 vCardFilenameFull.Clear();
751 vCardDataString.Clear();
752 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
758 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
761 if (vCardFilename.Right(4) == wxT(".vcf") ||
762 vCardFilename.Right(4) == wxT(".VCF") ||
763 vCardFilename.Right(5) == wxT(".vcard") ||
764 vCardFilename.Right(5) == wxT(".VCARD")){
768 vCardFilenameFull.Append(AccountDirFinal);
769 vCardFilenameFull.Append(vCardFilename);
771 Person.LoadFile(vCardFilenameFull);
773 if (Person.MeetBaseSpecification()){
777 // Split the name into sections.
779 vCardDataString = Person.Get(wxT("N"));
781 vCardName NameData = Person.GetName();
783 vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
785 } else if (SortMode == 2){
787 // Split the name into sections.
789 vCardName NameData = Person.GetName();
791 vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
793 } else if (SortMode == 3){
795 // Check and make sure that the top most nickname is used.
797 vCardDataString = Person.Get(wxT("NICKNAME"));
799 if (vCardDataString.IsEmpty()){
801 vCardDataString = wxT("(no nickname)");
805 } else if (SortMode == 4){
807 vCardDataString = Person.Get(wxT("FN"));
811 if (AscendingMode == TRUE){
813 vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
817 vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
825 vCardFilename.Clear();
826 vCardFilenameFull.Clear();
827 vCardDataString.Clear();
828 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
835 // Insert the data into the control.
837 if (AscendingMode == TRUE){
838 for (std::map<wxString, wxString>::iterator iter = vCardNamesAsc.begin();
839 iter != vCardNamesAsc.end(); ++iter){
841 wxListItem ContactInfo;
843 ContactInfo.SetId(0);
844 ContactInfo.SetText(_("Mooo"));
845 ContactInfo.SetData(ContactSeekPoint);
846 ContactIndex = lstContacts->InsertItem(ContactInfo);
848 lstContacts->SetItem(ContactIndex, 0, iter->first);
850 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
857 for (std::map<wxString, wxString>::iterator iter = vCardNamesDsc.begin();
858 iter != vCardNamesDsc.end(); ++iter){
860 wxListItem ContactInfo;
862 ContactInfo.SetId(0);
863 ContactInfo.SetText(_("Mooo"));
864 ContactInfo.SetData(ContactSeekPoint);
865 ContactIndex = lstContacts->InsertItem(ContactInfo);
867 lstContacts->SetItem(ContactIndex, 0, iter->first);
868 ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
877 void frmMain::ShowContactInfo( wxListEvent& event )
880 // Display the contact information.
882 long intSelected = -1;
883 long ContactSeekNum = -1;
885 // Check if several contacts have been selected.
887 int ContactTotal = 0;
891 intSelected = lstContacts->GetNextItem(intSelected,
893 wxLIST_STATE_SELECTED);
895 if (intSelected == -1){
905 if (ContactTotal == 0){
906 htmContactData->SetPage(wxT(""));
910 if (ContactTotal > 1){
912 htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
913 ActiveFilename.Clear();
918 intSelected = lstContacts->GetNextItem(intSelected,
920 wxLIST_STATE_SELECTED);
922 ContactSeekNum = lstContacts->GetItemData(intSelected);
925 wxString wxSContactString;
926 wxString ContactLine;
929 size_t ContactLineLen;
930 bool ExtraLineSeek = FALSE;
931 int QuoteBreakPoint = 0;
933 bool PropertyFind = FALSE;
934 bool QuoteMode = FALSE;
936 wxString wxSPropertyNextLine;
937 wxString wxSProperty;
938 wxString wxSPropertySeg1;
939 wxString wxSPropertySeg2;
941 // Check if we are using wxWidgets version 2.8 or less and
942 // execute the required command accordingly.
944 #if wxABI_VERSION < 20900
945 ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
947 ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
950 if (ContactFile.IsOpened() == FALSE){
956 ContactFile.ReadAll(&wxSContactString, wxConvAuto());
960 std::map<int, wxString> ContactFileLines;
961 std::map<int, wxString>::iterator striter;
963 wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
965 int ContactLineSeek = 0;
967 while (wSTContactFileLines.HasMoreTokens() == TRUE){
969 ContactLine = wSTContactFileLines.GetNextToken();
970 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
975 if (ContactSeekNum < 0){
979 for (std::map<int, wxString>::iterator iter = ContactFileLines.begin();
980 iter != ContactFileLines.end(); ++iter){
982 // Find the colon which splits the start bit from the data part.
984 ContactLine = iter->second;
986 while (ExtraLineSeek == TRUE){
988 // Check if there is extra data on the next line
989 // (indicated by space or tab at the start) and add data.
993 if (iter == ContactFileLines.end()){
1000 wxSPropertyNextLine = iter->second;
1003 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1005 wxSPropertyNextLine.Remove(0, 1);
1006 ContactLine.Append(wxSPropertyNextLine);
1011 ExtraLineSeek = FALSE;
1017 ContactLineLen = ContactLine.Len();
1019 // Make sure we are not in quotation mode.
1020 // Make sure colon does not have \ or \\ before it.
1022 for (int i = 0; i <= ContactLineLen; i++){
1024 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1026 PropertyFind = FALSE;
1028 } else if (PropertyFind == TRUE){
1030 wxSProperty.Append(ContactLine.Mid(i, 1));
1034 if (ContactLine.Mid(i, 1) == wxT("\"")){
1036 if (QuoteMode == TRUE){
1048 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1050 QuoteBreakPoint = i;
1057 // Split that line at the point into two variables (ignore the colon).
1059 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1060 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1062 // Insert both into the vCard data file.
1064 Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
1067 PropertyFind = TRUE;
1068 ExtraLineSeek = TRUE;
1070 QuoteBreakPoint = 0;
1071 ContactLine.Clear();
1072 wxSProperty.Clear();
1076 OldSessionID = SessionID;
1077 SessionID = wxString::Format(wxT("%i"), rand() % 32768);
1078 LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList);
1079 ActiveFilename = ContactsFileIndex[ContactSeekNum];
1083 void frmMain::ShowContactEditorNew( wxCommandEvent& event )
1086 // Open a contact editor window to write a new contact with.
1088 // Check if there is an account selected and if not
1089 // return immediately.
1091 if (ActiveAccount.IsEmpty()){
1097 // Check if the account type is a valid account type, otherwise
1098 // display an error message.
1100 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1101 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1103 wxMessageBox(_("Cannot add a new contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1108 // Add Pointer to SetupPointers for the ETagDB.
1110 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1111 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1112 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1114 contacticon.CopyFromBitmap(contacticonbmp);
1116 frmContactEditor *ContactEditor = new frmContactEditor( this );
1120 ContactEditor->SetUID(WindowMenuItemID);
1122 WindowData *WData = new WindowData;
1124 WData->DataType = 1;
1125 WData->WindowPointer = (void*)ContactEditor;
1126 WData->WindowID = WindowMenuItemID;
1128 wxCommandEvent addevent(WINDOW_ADD);
1129 addevent.SetClientData(WData);
1130 wxPostEvent(this, addevent);
1132 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1133 ContactEditor->SetupHeaders();
1134 ContactEditor->SetupContact(ActiveAccount);
1135 ContactEditor->SetIcon(contacticon);
1136 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1137 ContactEditor->Show(true);
1141 void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
1144 // Open a contact editor window for editing an existing contact
1147 // Check if there is an account selected and if not
1148 // return immediately.
1150 int DataCheck = event.GetInt();
1152 if (ActiveAccount.IsEmpty() && DataCheck == 0){
1158 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1159 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1160 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1162 contacticon.CopyFromBitmap(contacticonbmp);
1164 // Check if a contact has been selected.
1166 long intSelected = -1;
1167 long intContactSeekNum = -1;
1169 intSelected = lstContacts->GetNextItem(intSelected,
1171 wxLIST_STATE_SELECTED);
1173 if (intSelected == -1){
1179 intContactSeekNum = lstContacts->GetItemData(intSelected);
1181 // Get the filename of the selected contact.
1183 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1184 frmContactEditor *ContactEditor = new frmContactEditor( this );
1188 ContactEditor->SetUID(WindowMenuItemID);
1190 WindowData *WData = new WindowData;
1192 WData->DataType = 1;
1193 WData->WindowPointer = (void*)ContactEditor;
1194 WData->WindowID = WindowMenuItemID;
1196 wxCommandEvent addevent(WINDOW_ADD);
1197 addevent.SetClientData(WData);
1198 wxPostEvent(this, addevent);
1200 ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
1201 ContactEditor->SetupHeaders();
1203 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1204 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1206 ContactEditor->SetupAccountData(true);
1210 // Check if pointer is NULL (not from the search forms) or not.
1212 if (DataCheck == 0){
1214 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1215 ContactEditor->SetupContact(ActiveAccount);
1219 UCNotif *uc = (UCNotif*)event.GetClientData();
1223 ContactEditor->SetupContact(ActiveAccount);
1224 ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
1228 ContactEditor->SetupContact(uc->ContactAccount);
1229 ContactEditor->LoadContact(uc->ContactFilename);
1238 ContactEditor->SetIcon(contacticon);
1239 ContactEditor->Show(true);
1243 void frmMain::RefreshAddressBook( wxCommandEvent& event ){
1245 // Refresh the address book data.
1247 // Check if ActiveAccount is empty. If not then check if
1248 // account type is not local otherwise continue.
1250 if (!ActiveAccount.IsEmpty()){
1252 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
1254 // Account type is not local.
1256 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1257 frameActMgr->AddTask(3, wxT(""), ActiveAccount,
1258 wxT(""), wxT(""), wxT(""), wxT(""));
1262 wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported"), wxICON_ERROR);
1270 void frmMain::OpenContactInfoList( wxListEvent& event )
1273 // Open the contact information window.
1275 wxStringTokenizer vcardfileline;
1278 wxString setname, setvalue;
1282 long intSelected = -1;
1283 long intContactSeekNum = -1;
1285 intSelected = lstContacts->GetNextItem(intSelected,
1287 wxLIST_STATE_SELECTED);
1289 intContactSeekNum = lstContacts->GetItemData(intSelected);
1291 if (intContactSeekNum == -1){
1297 Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
1299 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1300 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1301 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1303 contacticon.CopyFromBitmap(contacticonbmp);
1305 frmContact *Contact = new frmContact( this );
1307 // Add to window list.
1311 Contact->SetUID(WindowMenuItemID);
1313 WindowData *WData = new WindowData;
1315 WData->DataType = 0;
1316 WData->WindowPointer = (void*)Contact;
1317 WData->WindowID = WindowMenuItemID;
1319 wxCommandEvent addevent(WINDOW_ADD);
1320 addevent.SetClientData(WData);
1321 wxPostEvent(this, addevent);
1323 Contact->SetupPointers(&MemoryFileList);
1324 Contact->SetupContactData(&Person);
1326 Contact->SetIcon(contacticon);
1327 Contact->Show(true);
1331 void frmMain::OpenContactInfoList( wxCommandEvent& event ){
1333 // Open a list of contact information windows.
1336 OpenContactInfoList(pevent);
1340 void frmMain::OpenContactInfo( wxCommandEvent& event )
1343 // Open the contact information window.
1345 UCNotif *uc = (UCNotif*)event.GetClientData();
1347 wxStringTokenizer vcardfileline;
1350 wxString setname, setvalue;
1354 Person.LoadFile(uc->ContactFilename);
1356 wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
1357 wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
1358 wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
1360 contacticon.CopyFromBitmap(contacticonbmp);
1362 frmContact *Contact = new frmContact( this );
1364 // Add to window list.
1368 Contact->SetUID(WindowMenuItemID);
1370 WindowData *WData = new WindowData;
1372 WData->DataType = 0;
1373 WData->WindowPointer = (void*)Contact;
1374 WData->WindowID = WindowMenuItemID;
1376 wxCommandEvent addevent(WINDOW_ADD);
1377 addevent.SetClientData(WData);
1378 wxPostEvent(this, addevent);
1380 Contact->SetupPointers(&MemoryFileList);
1381 Contact->SetupContactData(&Person);
1383 Contact->SetIcon(contacticon);
1384 Contact->Show(true);
1389 void frmMain::LoadPreferences( wxActivateEvent& event)
1392 // Load the preferences.
1394 this->LoadPreferences();
1398 void frmMain::LoadPreferences(){
1400 // Load the preferences.
1402 wxString preffilename = GetUserPrefDir();
1404 XABPreferences preferences(preffilename);
1406 // Setup the main window position (if needed).
1408 bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
1409 bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
1411 if (SaveWindowPos == TRUE){
1413 this->SetSize(preferences.GetMainWindowData());
1417 treAccounts->DeleteAllItems();
1419 wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
1421 // Stop all account timers and remove the accounts.
1423 for (std::map<wxString, wxAccountSyncTimer*>::iterator iter = AccountSyncTimers.begin();
1424 iter != AccountSyncTimers.end(); iter++){
1426 wxAccountSyncTimer *AccTmrPtr = iter->second;
1434 #if defined(__WIN32__)
1436 for (std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.begin();
1437 CertificateIter != AccountCertificateData.end(); CertificateIter++){
1439 CertFreeCertificateContext(CertificateIter->second);
1443 AccountCertificateData.clear();
1447 AccountSyncTimers.clear();
1450 wxString AccDirFull;
1451 wxString AccDirFullSfx;
1453 wxString AccDirFinal;
1454 AccountAccDirList.clear();
1455 AccountGroupList.clear();
1456 AccountGroupFilename.clear();
1457 AccountGroupTreeId.clear();
1458 wxTreeItemId AccountTreeId;
1459 wxTreeItemId GroupTreeId;
1462 // Relaod the accounts for the ETagProcTimer.
1464 ETagProcTimer.ReloadAccounts();
1466 for (int i = 0; i < preferences.accounts.GetCount(); i++){
1468 if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
1469 preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == TRUE){
1475 if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
1481 AccDir = preferences.accounts.GetAccountDirectory(i);
1482 AccDirFull = preferences.accounts.GetAccountDirectory(i);
1484 AccDirFull.Append(wxT("."));
1485 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
1486 AccDirFullSfx.LowerCase();
1487 AccDirFullSfx.Trim();
1488 AccDirFull.Append(AccDirFullSfx);
1489 AccName = preferences.accounts.GetAccountName(i);
1491 AccountAccDirList.insert(std::make_pair(i, AccDirFull));
1493 if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
1494 preferences.accounts.GetAccountType(i) == wxT("carddav")){
1496 // TODO: Check if the directory exists before doing anything.
1500 // Add a new timer using the existing account details.
1502 wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
1504 ActTmrPtr->SetupData(AccDirFull, AccName);
1505 ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
1506 ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
1507 ActTmrPtr->SetOwner(this);
1508 ActTmrPtr->Notify();
1510 // Add the timer to the list of timers.
1512 AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
1514 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
1516 } else if (preferences.accounts.GetAccountType(i) == wxT("Local") ||
1517 preferences.accounts.GetAccountType(i) == wxT("local")) {
1519 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
1523 AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountUnsupportedID, -1);
1527 // Go through the account directory and find contact files with
1528 // 'KIND:group' set and add them to the list of groups for the account.
1530 AccDirFinal = GetAccountDir(AccDirFull, FALSE);
1532 wxDir vcardaccdir(AccDirFinal);
1534 wxString vCardFilename;
1535 wxString vCardDataString;
1536 wxString vCardFilenameFull;
1538 bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
1542 if (vCardFilename.Right(4) == wxT(".vcf") ||
1543 vCardFilename.Right(4) == wxT(".VCF") ||
1544 vCardFilename.Right(5) == wxT(".vcard") ||
1545 vCardFilename.Right(5) == wxT(".VCARD")){
1549 vCardFilenameFull.Append(AccDirFinal);
1550 vCardFilenameFull.Append(wxT("/"));
1551 vCardFilenameFull.Append(vCardFilename);
1553 Person.LoadFile(vCardFilenameFull);
1555 if (Person.MeetBaseSpecification()){
1557 vCardDataString = Person.Get(wxT("KIND"));
1559 if (vCardDataString == wxT("group")){
1561 // The vCard kind is a group. Add to the account's group list.
1563 GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
1564 treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
1565 AccountGroupList.insert(std::make_pair(intGroupID, i));
1566 AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
1567 AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
1577 vCardFilename.Clear();
1578 vCardFilenameFull.Clear();
1579 vCardDataString.Clear();
1580 ProcFiles = vcardaccdir.GetNext(&vCardFilename);
1584 // Clearup for next account.
1588 AccDirFullSfx.clear();
1589 AccDirFinal.clear();
1594 // Load the account settings as they are needed for connecting
1597 prefaccounts = preferences.accounts;
1601 void frmMain::ConflictResolution(wxCommandEvent& event){
1603 // Display the conflict resolution window.
1605 frmConflictResolution *frameCR = new frmConflictResolution ( this );
1606 vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
1607 vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
1608 vCard *ServerDataPtr = vCardConfObj->vCardServerData;
1609 frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList);
1610 frameCR->ShowModal();
1612 int FinalConflictResult = frameCR->GetResult();
1614 wxCommandEvent event2(ACTMGR_RESUMEPROC);
1615 event2.SetClientData(vCardConfObj->QRNotifData);
1616 event2.SetInt(FinalConflictResult);
1621 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1622 wxPostEvent(frameActMgr, event2);
1626 void frmMain::UpdateContactList(wxCommandEvent& event){
1628 // Update the contact list in the main window.
1630 UCNotif *ucd = (UCNotif*)event.GetClientData();
1632 // Check if the active account is being displayed in the
1633 // main window. If not, skip and delete the data.
1635 long longSelected = -1;
1636 int intSelectedData = 0;
1638 if (ActiveAccount == ucd->ContactAccount){
1640 // Look at the list of contacts and if it matches the
1641 // filename then update the name.
1645 longSelected = lstContacts->GetNextItem(longSelected,
1647 wxLIST_STATE_DONTCARE);
1649 if (longSelected == -1){
1655 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1657 if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
1659 // Work out which sorting mode we are in.
1663 // First Name, Last Name.
1665 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
1667 } else if (SortMode == 2){
1669 // Last Name, First Name.
1671 lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
1673 } else if (SortMode == 3){
1677 lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
1679 } else if (SortMode == 4){
1683 lstContacts->SetItem(longSelected, 0, ucd->ContactName);
1690 // If the filename is the one loaded into the
1691 // browser control, then update this too.
1693 if (ActiveFilename == ContactsFileIndex[intSelectedData]){
1695 wxListEvent nullevent;
1696 ShowContactInfo(nullevent);
1704 for (std::map<int, void*>::iterator WindowIter = WindowListPointers.begin();
1705 WindowIter != WindowListPointers.end(); WindowIter++){
1707 if (WindowListType[WindowIter->first] != 0){
1713 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
1715 if (frmContactPtr->GetFilename() == ucd->ContactFilename){
1717 vCard UpdatedPerson;
1718 UpdatedPerson.LoadFile(ucd->ContactFilename);
1719 frmContactPtr->SetupContactData(&UpdatedPerson);
1725 // Send message to search window controller subroutine and
1726 // pass that notification onto the search windows.
1728 // Setup the new pointer to use the existing UCNotif without
1731 UCNotif *ucd2 = ucd;
1733 wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
1734 sup.SetClientData(ucd2);
1735 wxPostEvent(this, sup);
1737 // Clear up the unused pointer.
1743 void frmMain::UpdateAccountList(wxCommandEvent& event){
1745 // Update the account list (currently unimplemented).
1749 void frmMain::SetupPointers(void *ActMgrPtrInc){
1751 // Setup the pointers for the main window.
1753 ActMgrPtr = ActMgrPtrInc;
1757 void frmMain::SetupForm(){
1759 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1760 frameActMgr->SetupPointers(&ETagProcTimer, this);
1762 // Setup the contact information icons for later.
1764 wxFileSystem::AddHandler(new wxMemoryFSHandler);
1768 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
1769 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
1770 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1772 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
1773 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
1774 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1776 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
1777 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
1778 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1780 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
1781 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
1782 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1784 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
1785 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
1786 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1788 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
1789 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
1790 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
1796 void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
1798 // Update the contact lists in the search windows.
1800 // Go through each of the search windows and
1801 // send the required notification to update the
1802 // contact information.
1804 // Get the event notification data.
1806 UCNotif *ucd = (UCNotif*)event.GetClientData();
1808 // Process each search window giving the new details.
1810 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
1811 switer != SearchWindowList.end(); switer++){
1813 // Duplicate the event notification data.
1815 UCNotif *ucd2 = new UCNotif;
1817 ucd2->ContactAccount = ucd->ContactAccount;
1818 ucd2->ContactFilename = ucd->ContactFilename;
1819 ucd2->ContactName = ucd->ContactName;
1820 ucd2->ContactNickname = ucd->ContactNickname;
1821 ucd2->ContactNameArray = ucd->ContactNameArray;
1823 // Pass the data to the search window for processing.
1825 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
1826 wxCommandEvent schupdate(SE_UPDATERESULT);
1827 schupdate.SetClientData(ucd2);
1828 wxPostEvent(frameSCH, schupdate);
1830 // Clear up the pointer prior to variable deletion.
1841 void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
1843 // Open a new search window.
1847 frmSearch *frameSCH = new frmSearch ( this );
1848 frameSCH->SetUID(WindowMenuItemID);
1849 frameSCH->Show(true);
1851 WindowData *WData = new WindowData;
1853 WData->DataType = 2;
1854 WData->WindowPointer = (void*)frameSCH;
1855 WData->WindowID = WindowMenuItemID;
1857 wxCommandEvent addevent(WINDOW_ADD);
1858 addevent.SetClientData(WData);
1859 wxPostEvent(this, addevent);
1861 // Add pointer to the list of open search windows.
1863 SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
1869 void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
1871 // Remove the pointer for a contact window from the
1874 void *frameSCH = (void*)event.GetClientData();
1876 SearchWindowList.erase(frameSCH);
1882 void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
1884 // Remove the pointer for a contact editor window from
1887 void *frameSCH = (void*)event.GetClientData();
1889 SearchWindowList.erase(frameSCH);
1895 void frmMain::RevealContact(wxCommandEvent& event){
1897 // Reveal a contact in the main window.
1899 UCNotif *uc = (UCNotif*)event.GetClientData();
1901 // Switch the account to the one passed.
1903 wxTreeItemIdValue cookie;
1904 wxTreeItemId next = treAccounts->GetRootItem();
1905 wxTreeItemId nextChild;
1907 for (int i = 0; i < prefaccounts.GetCount(); i++){
1910 nextChild = treAccounts->GetFirstChild(next, cookie);
1912 nextChild = treAccounts->GetNextSibling(nextChild);
1915 if (uc->ContactAccount == AccountAccDirList[i]){
1917 treAccounts->SelectItem(nextChild, TRUE);
1918 AccCtrl->SetText(treAccounts->GetItemText(nextChild));
1924 // Switch the contact to the one passed.
1926 long longSelected = -1;
1927 int intSelectedData = 0;
1931 longSelected = lstContacts->GetNextItem(longSelected,
1933 wxLIST_STATE_DONTCARE);
1935 if (longSelected == -1){
1941 intSelectedData = (int)lstContacts->GetItemData(longSelected);
1943 // Compare the filename with the one received.
1944 // If they match then select it.
1946 if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
1950 lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1951 lstContacts->EnsureVisible(longSelected);
1955 lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
1963 void frmMain::DeleteContact(wxCommandEvent& event){
1965 // Delete a contact from the main window.
1967 // Check if a contact is selected.
1969 long intSelected = -1;
1970 long intContactSeekNum = -1;
1971 wxString wxSContactName;
1973 intSelected = lstContacts->GetNextItem(intSelected,
1975 wxLIST_STATE_SELECTED);
1977 if (intSelected == -1){
1981 // Check if the account type is a valid account type, otherwise
1982 // display an error message.
1984 if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
1985 ActiveAccountType != "Local" && ActiveAccountType != "local"){
1987 wxMessageBox(_("Cannot delete contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
1992 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
1994 // Get the item data of the contact.
1996 intContactSeekNum = lstContacts->GetItemData(intSelected);
1998 // Get the name of the contact.
2000 wxSContactName = lstContacts->GetItemText(intSelected);
2002 // Display a message confirming if the contact should
2005 int QuestionResponse;
2007 QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
2009 if (QuestionResponse == wxNO){
2011 // Exit the subroutine
2017 // Delete the contact.
2019 if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
2021 wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
2026 // Remove the contact from the list.
2028 lstContacts->DeleteItem(intSelected);
2030 // Update the search windows, removing the deleted
2033 UCNotif *ucd = new UCNotif;
2035 ucd->ContactAccount = ActiveAccount;
2036 ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
2038 for (std::map<void*,wxString>::iterator switer = SearchWindowList.begin();
2039 switer != SearchWindowList.end(); switer++){
2041 // Duplicate the event notification data.
2043 UCNotif *ucd2 = new UCNotif;
2045 ucd2->ContactAccount = ucd->ContactAccount;
2046 ucd2->ContactFilename = ucd->ContactFilename;
2048 // Pass the data to the search window for processing.
2050 frmSearch *frameSCH = static_cast<frmSearch*>(switer->first);
2051 wxCommandEvent schdelete(SE_DELETERESULT);
2052 schdelete.SetClientData(ucd2);
2053 wxPostEvent(frameSCH, schdelete);
2055 // Clear up the pointer prior to variable deletion.
2062 // Clear the wxHTMLWindow.
2064 wxString EmptyPage = wxT("");
2066 htmContactData->SetPage(EmptyPage);
2068 wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
2070 wxString wxSplitFilename;
2071 wxString wxSDataURL;
2073 while(wSTFilename.HasMoreTokens()){
2075 wxSplitFilename = wSTFilename.GetNextToken();
2079 if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
2081 // Update the ETagDB and mark it as deleted.
2083 ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
2085 ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
2087 // Get the Data URL.
2089 wxTreeItemIdValue cookie;
2090 wxTreeItemId next = treAccounts->GetRootItem();
2092 wxTreeItemId selectedChild = treAccounts->GetSelection();
2093 wxTreeItemId nextChild;
2095 for (int i = 0; i < prefaccounts.GetCount(); i++){
2098 nextChild = treAccounts->GetFirstChild(next, cookie);
2100 nextChild = treAccounts->GetNextSibling(nextChild);
2103 if (nextChild == selectedChild){
2105 wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
2111 // Add task to the activity monitor to delete the contact.
2113 frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
2117 // Clear the variable. Don't delete as it will mess things up.
2119 ContactsFileIndex[intContactSeekNum] = wxT("");
2126 void frmMain::EmptyServerDialog(wxCommandEvent& event){
2128 // Display this message when the server information has changed
2131 QRNotif *qrn = (QRNotif *)event.GetClientData();
2133 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);
2135 if (QResponse == wxNO){
2141 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2142 event2.SetInt(*qrn->QResponse);
2143 event2.SetClientData(qrn->PausePtr);
2145 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2147 wxPostEvent(frameActMgr, event2);
2151 void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
2153 // Remove the contact from the window after syncronising.
2155 // Check which account is currently active in the window.
2156 // If it is different from the one passed to this subroutine then
2157 // exit from the subroutine.
2159 if (Account != ActiveAccount){
2163 long longSelected = -1;
2164 int intSelectedData = 0;
2168 longSelected = lstContacts->GetNextItem(longSelected,
2170 wxLIST_STATE_DONTCARE);
2172 if (longSelected == -1){
2178 intSelectedData = (int)lstContacts->GetItemData(longSelected);
2180 // Compare the filename with the one received.
2181 // If they match then select it.
2183 if (ContactsFileIndex[intSelectedData] == Filename){
2185 // Remove the contact from the window.
2187 lstContacts->DeleteItem(intSelectedData);
2189 // Check if contact is the selected contact in the HTML window and
2190 // if it is then clear the window.
2192 if (ActiveFilename == Filename){
2194 wxString EmptyPage = wxT("");
2195 htmContactData->SetPage(EmptyPage);
2209 void frmMain::SortFNLN( wxCommandEvent& event ) {
2211 // Sort first name then last name.
2213 wxTreeEvent NullEvent;
2215 LoadContactList(NullEvent);
2219 void frmMain::SortLNFN( wxCommandEvent& event ) {
2221 // Sort last name then first name.
2223 wxTreeEvent NullEvent;
2225 LoadContactList(NullEvent);
2229 void frmMain::SortNickname( wxCommandEvent& event ) {
2231 // Sort by nickname.
2233 wxTreeEvent NullEvent;
2235 LoadContactList(NullEvent);
2239 void frmMain::SortDisplayAs( wxCommandEvent& event ) {
2241 // Sort by Display As name.
2243 wxTreeEvent NullEvent;
2245 LoadContactList(NullEvent);
2249 void frmMain::SortAscending( wxCommandEvent& event ) {
2253 wxTreeEvent NullEvent;
2254 AscendingMode = TRUE;
2255 LoadContactList(NullEvent);
2259 void frmMain::SortDescending( wxCommandEvent& event ) {
2263 wxTreeEvent NullEvent;
2264 AscendingMode = FALSE;
2265 LoadContactList(NullEvent);
2269 void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
2271 // Toggle the appearance of the status bar.
2273 if (stbBottom->IsShown() == TRUE){
2287 void frmMain::ActivityIconStart( wxCommandEvent& event ){
2289 // Display the activity icon.
2291 imgActivityStatus->SetBitmap(*imgActIcon1);
2292 ActivityIconStatus = 0;
2296 void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
2298 // Shuffle through the activity icons.
2300 switch (ActivityIconStatus){
2303 imgActivityStatus->SetBitmap(*imgActIcon1);
2304 ActivityIconStatus = 1;
2307 imgActivityStatus->SetBitmap(*imgActIcon2);
2308 ActivityIconStatus = 2;
2311 imgActivityStatus->SetBitmap(*imgActIcon3);
2312 ActivityIconStatus = 3;
2315 imgActivityStatus->SetBitmap(*imgActIcon4);
2316 ActivityIconStatus = 0;
2319 ActivityIconStatus = 0;
2325 void frmMain::ActivityIconStop( wxCommandEvent& event ){
2327 // Display the sleep icon.
2329 imgActivityStatus->SetBitmap(*imgActIconSleep);
2333 void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
2335 // Set the placement of the status bar icons.
2337 if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
2345 wxRect rectActivity;
2346 stbBottom->GetFieldRect(1, rectOnline);
2347 stbBottom->GetFieldRect(2, rectSSL);
2348 stbBottom->GetFieldRect(3, rectActivity);
2350 imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
2351 imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
2352 imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
2356 XABViewMode frmMain::GetViewMode(){
2358 // Set the view mode of the contact list.
2362 xvm.SortMode = SortMode;
2363 xvm.AscendingMode = AscendingMode;
2369 void frmMain::WindowAdd( wxCommandEvent &event ){
2371 // Add a window to the window list.
2373 WindowData *WData = (WindowData*)event.GetClientData();
2377 if (WData->DataType == 0){
2381 int intID = mnuContactWindows->GetId();
2383 mnuWindow->FindChildItem(intID, &pos);
2384 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2385 mnuNewItem->SetId(WData->WindowID);
2386 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2387 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2388 WindowListType.insert(std::make_pair(WData->WindowID, 0));
2389 mnuWindow->Insert((pos + 1), mnuNewItem);
2390 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
2392 } else if (WData->DataType == 1){
2394 // Contact Editor Window
2396 int intID = mnuContactEditorWindows->GetId();
2398 mnuWindow->FindChildItem(intID, &pos);
2399 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2400 mnuNewItem->SetId(WData->WindowID);
2401 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2402 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2403 WindowListType.insert(std::make_pair(WData->WindowID, 1));
2404 mnuWindow->Insert((pos + 1), mnuNewItem);
2405 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
2407 } else if (WData->DataType == 2){
2411 int intID = mnuSearchWindows->GetId();
2413 mnuWindow->FindChildItem(intID, &pos);
2414 wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
2415 mnuNewItem->SetId(WData->WindowID);
2416 WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
2417 WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
2418 WindowListType.insert(std::make_pair(WData->WindowID, 2));
2419 mnuWindow->Insert((pos + 1), mnuNewItem);
2420 this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
2429 void frmMain::WindowEdit( wxCommandEvent &event ){
2431 // Edit a window in the window list.
2433 WindowData *WData = (WindowData*)event.GetClientData();
2435 if (WData->DataType == 0){
2437 // Get the window title and use that.
2439 frmContact *frmContactPtr = static_cast<frmContact*>(WData->WindowPointer);
2441 wxString WindowTitle = frmContactPtr->GetTitle();
2443 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2445 MenuIter->second->SetItemLabel(WindowTitle);
2447 } else if (WData->DataType == 1){
2449 // Get the window title and use that.
2451 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WData->WindowPointer);
2453 wxString WindowTitle = frmCEPtr->GetTitle();
2455 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2457 if (WindowTitle.IsEmpty()){
2459 MenuIter->second->SetItemLabel(_("Unnamed Contact"));
2463 MenuIter->second->SetItemLabel(WindowTitle);
2474 void frmMain::WindowDelete( wxCommandEvent &event ){
2476 // Delete a window from the window list.
2478 WindowData *WData = (WindowData*)event.GetClientData();
2480 std::map<int, wxMenuItem*>::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
2482 mnuWindow->Remove(MenuIter->second);
2484 delete MenuIter->second;
2485 MenuIter->second = NULL;
2487 WindowListPointersMenu.erase(WData->WindowID);
2488 WindowListPointers.erase(WData->WindowID);
2489 WindowListType.erase(WData->WindowID);
2496 void frmMain::ShowContactWindow( wxCommandEvent &event ){
2498 // Show a contact window from the window list.
2500 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2502 frmContact *frmContactPtr = static_cast<frmContact*>(WindowIter->second);
2504 frmContactPtr->Show();
2505 frmContactPtr->Raise();
2509 void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
2511 // Show a contact editor window from the window list.
2513 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2515 frmContactEditor *frmCEPtr = static_cast<frmContactEditor*>(WindowIter->second);
2522 void frmMain::ShowSearchWindow( wxCommandEvent &event ){
2524 // Show a search window from the window list.
2526 std::map<int, void*>::iterator WindowIter = WindowListPointers.find(event.GetId());
2528 frmSearch *frmSearchPtr = static_cast<frmSearch*>(WindowIter->second);
2530 frmSearchPtr->Show();
2531 frmSearchPtr->Raise();
2535 void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
2537 // Toggle the online/offline connection status.
2539 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2540 wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
2541 wxPostEvent(frameActMgr, toggconn);
2545 void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
2547 // Check the account type before continuing.
2549 wxString SeekAccount;
2550 wxString AccTypeLower;
2554 #if defined(__APPLE__)
2556 std::map<int, SecTrustRef>::iterator SSLTrustIter;
2558 for (int i = 0; i < prefaccounts.GetCount(); i++){
2560 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2561 AccType.Append(prefaccounts.GetAccountType(i));
2562 AccountSSL = prefaccounts.GetAccountSSL(i);
2563 AccTypeLower = AccType.MakeLower();
2564 SeekAccount.Append(wxT("."));
2565 SeekAccount.Append(AccTypeLower);
2567 if (SeekAccount == ActiveAccount){
2569 if (AccTypeLower == wxT("local")){
2575 if (AccountSSL == false){
2581 SSLTrustIter = AccountTrustData.find(i);
2583 // Setup and display the form.
2585 DisplayCertificate(SSLTrustIter->second);
2589 SeekAccount.Clear();
2590 AccTypeLower.Clear();
2595 #elif defined(__WIN32__)
2597 std::map<int, PCCERT_CONTEXT>::iterator SSLCertificateIter;
2599 for (int i = 0; i < prefaccounts.GetCount(); i++){
2601 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2602 AccType.Append(prefaccounts.GetAccountType(i));
2603 AccountSSL = prefaccounts.GetAccountSSL(i);
2604 AccTypeLower = AccType.MakeLower();
2605 SeekAccount.Append(wxT("."));
2606 SeekAccount.Append(AccTypeLower);
2608 if (SeekAccount == ActiveAccount){
2610 if (AccTypeLower == wxT("local")){
2616 if (AccountSSL == false){
2622 SSLCertificateIter = AccountCertificateData.find(i);
2624 // Setup and display the form.
2626 if (SSLCertificateIter->second->pCertInfo == NULL){
2628 wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
2632 BOOL ModifiedCertificateData;
2633 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
2635 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
2636 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
2641 //DisplayCertificate(SSLTrustIter->second);
2645 SeekAccount.Clear();
2646 AccTypeLower.Clear();
2653 std::map<int, SSLCertCollection>::iterator SSLColIter;
2655 for (int i = 0; i < prefaccounts.GetCount(); i++){
2657 SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
2658 AccType.Append(prefaccounts.GetAccountType(i));
2659 AccountSSL = prefaccounts.GetAccountSSL(i);
2660 AccTypeLower = AccType.MakeLower();
2661 SeekAccount.Append(wxT("."));
2662 SeekAccount.Append(AccTypeLower);
2664 if (SeekAccount == ActiveAccount){
2666 if (AccTypeLower == wxT("local")){
2672 if (AccountSSL == false){
2678 SSLColIter = AccountSSLData.find(i);
2680 SSLCertCollection SSLCertInfo = SSLColIter->second;
2682 frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
2683 frameSSLCert->StartCertFrom(0);
2684 frameSSLCert->SetupCerts(SSLCertInfo);
2685 frameSSLCert->ShowModal();
2687 delete frameSSLCert;
2688 frameSSLCert = NULL;
2692 SeekAccount.Clear();
2693 AccTypeLower.Clear();
2702 void frmMain::ShowSSLInfo( wxCommandEvent &event ){
2704 // Check the account type before continuing.
2708 void frmMain::HideSSLInfo( wxCommandEvent &event ){
2710 // Check the account type before continuing.
2714 void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
2716 if (event.GetInt() == 0){
2718 imgConnStatus->SetBitmap(*imgOnline);
2722 imgConnStatus->SetBitmap(*imgOffline);
2728 void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
2730 // Display the form for showing an invalid SSL certificate.
2732 frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
2733 SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
2734 SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
2735 wxString AccountName = SSLICNObj->AccountName;
2736 frameISC->LoadData(SSLCCData, AccountName);
2737 frameISC->ShowModal();
2739 int FinalConflictResult = frameISC->GetResult();
2741 wxCommandEvent event2(ACTMGR_RESUMEPROC);
2742 event2.SetClientData(SSLICNObj->QRNotifData);
2743 event2.SetInt(FinalConflictResult);
2748 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
2749 wxPostEvent(frameActMgr, event2);
2753 void frmMain::PauseAllTimers(){
2755 // Pause all the account timers.
2757 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2758 ASTiter != AccountSyncTimers.end(); ASTiter++){
2760 ASTiter->second->Stop();
2766 void frmMain::ResumeAllTimers(){
2768 // Resume all the account timers.
2770 for (std::map<wxString, wxAccountSyncTimer*>::iterator ASTiter = AccountSyncTimers.begin();
2771 ASTiter != AccountSyncTimers.end(); ASTiter++){
2773 ASTiter->second->Start();
2779 #if defined(__APPLE__)
2781 #elif defined(__WIN32__)
2783 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
2785 // Delete existing data.
2787 std::map<int, PCCERT_CONTEXT>::iterator CertificateIter = AccountCertificateData.find(AccountID);
2789 if (CertificateIter != AccountCertificateData.end()){
2790 CertFreeCertificateContext(CertificateIter->second);
2793 AccountCertificateData.erase(AccountID);
2794 AccountSSLResult.erase(AccountID);
2798 AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
2799 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2805 void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollection SSLCertInc){
2807 // Delete existing data.
2809 AccountSSLData.erase(AccountID);
2810 AccountSSLResult.erase(AccountID);
2814 AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
2815 AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
2821 void frmMain::SetupSSLStatus( int AccountID ){
2823 // Check if account ID given is
2824 // the active account and if not, do nothing.
2827 wxString AccTypeLower;
2829 AccType = prefaccounts.GetAccountType(AccountID);
2830 AccTypeLower = AccType.MakeLower();
2832 wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
2835 if (AccountIDName != ActiveAccount){
2841 // Check the account type is a supported account type.
2843 if (AccType != "CardDAV" && AccType != "carddav" &&
2844 AccType != "Local" && AccType != "local"){
2846 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2847 imgSSLStatus->SetBitmap(*imgNoSSL);
2852 // Check if the account has SSL enabled.
2854 bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
2856 if (SSLInUse == FALSE){
2858 SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
2859 imgSSLStatus->SetBitmap(*imgNoSSL);
2863 // Get the SSL Collection Data.
2865 std::map<int,int>::iterator SSLResultIter = AccountSSLResult.find(AccountID);
2867 // Check if a result value has been set.
2869 if (SSLResultIter == AccountSSLResult.end()){
2871 imgSSLStatus->SetBitmap(*imgSSLWarning);
2872 SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
2877 if (SSLResultIter->second == 1){
2879 imgSSLStatus->SetBitmap(*imgSSLWarning);
2880 SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
2881 prefaccounts.GetAccountName(AccountID) +
2882 wxT("' (Connection denied by user)\n\nDouble click for more information."));
2884 } else if (SSLResultIter->second == 0){
2886 imgSSLStatus->SetBitmap(*imgSSL);
2887 SSLToolTip->SetTip(wxT("Account '") +
2888 prefaccounts.GetAccountName(AccountID) +
2889 wxT("' secured using SSL\n\nDouble click for more information."));
2897 void frmMain::CheckUpdates( wxCommandEvent& event ){
2899 // Check for updates to Xestia Address Book.
2901 frmUpdate *frameUpdate = new frmUpdate ( this );
2902 frameUpdate->FetchData();
2903 frameUpdate->ShowModal();
2907 void frmMain::OpenImportDialog( wxCommandEvent& event ){
2909 // Run the import contacts function.
2915 void frmMain::OpenExportDialog( wxCommandEvent& event ){
2917 // Check if an account and at least one contact is selected
2918 // before continuing.
2920 wxArrayString ArrData;
2922 if (ActiveAccount.IsEmpty()){
2928 int ContactSelected = 0;
2929 int ContactsCollected = 0;
2930 long longSelected = -1;
2934 longSelected = lstContacts->GetNextItem(longSelected,
2936 wxLIST_STATE_SELECTED);
2938 if (longSelected == -1){
2944 int FileID = (int)lstContacts->GetItemData(longSelected);
2946 ArrData.Insert(ContactsFileIndex[FileID],
2947 ContactsCollected, 1);
2953 if (ContactSelected == 0){
2959 // Run the export contacts system.
2961 ExportRun(this, &ArrData);
2965 void frmMain::GetListControl(wxListCtrl *lstContactsPtr,
2966 wxArrayString *ContactsFileIndexPtr){
2968 // Set the list control pointers.
2970 lstContactsPtr = lstContacts;
2971 ContactsFileIndexPtr = &ContactsFileIndex;
2975 void frmMain::GetSelectedList( wxCommandEvent& event ){
2977 // Get the array of contact filenames.
2979 wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
2981 // Process them into an array of files.
2983 long longSelected = -1;
2984 int ContactsCollected = 0;
2985 wxString ContactFilename;
2989 longSelected = lstContacts->GetNextItem(longSelected,
2991 wxLIST_STATE_SELECTED);
2993 if (longSelected == -1){
2999 // Get the file information and add to the list.
3001 int FileID = (int)lstContacts->GetItemData(longSelected);
3003 ArrData->Insert(ContactsFileIndex[FileID],
3004 ContactsCollected, 1);
3006 ContactsCollected++;
3007 ContactFilename.Clear();
3015 void frmMain::SyncAccount( wxCommandEvent& event ){
3017 // Syncronise the selected account.
3019 wxString AccNameInc = event.GetString();
3021 frmActivityMgr *frameActMgr = static_cast<frmActivityMgr*>(ActMgrPtr);
3022 frameActMgr->AddTask(3, wxT(""), AccNameInc,
3023 wxT(""), wxT(""), wxT(""), wxT(""));
3027 void frmMain::ShowHelp( wxCommandEvent& event ){
3029 // Based on the operating system, work out where
3030 // the documentation should be.
3034 #if defined(__HAIKU__)
3036 #elif defined(__WIN32__)
3042 if (wxFileExists("/usr/share/doc/xestiaab/index.html")){
3044 wxLaunchDefaultBrowser(wxT("file:///usr/share/doc/xestiaab/index.html"));
3047 #if XSDAB_RELEASE == 0
3049 } else if (wxFileExists("/usr/local/share/doc/xestiaab/index.html")){
3051 wxLaunchDefaultBrowser(wxT("file:///usr/local/share/doc/xestiaab/index.html"));
3060 #if XSDAB_RELEASE == 0
3062 wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
3066 wxMessageBox(_("The help documentation is not available in the usual locations on the system. Please visit http://documentation.xestia.co.uk/xestiaab/ for documentation"), _("Help documentation missing!"));
3072 void frmMain::ShowImportResults( wxCommandEvent &event ){
3074 // Show the results of importing contacts.
3076 std::map<int,wxString> *ResultData = (std::map<int,wxString>*)event.GetClientData();
3078 frmImportResults *frmIR = new frmImportResults(this);
3079 frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
3090 void frmMain::ReloadContactList( wxCommandEvent &event ){
3092 // Check if the account name given is the current
3093 // account selected.
3095 if (ActiveAccount == event.GetString()){
3097 wxTreeEvent NullEvent;
3098 LoadContactList(NullEvent);
3104 void frmMain::ShowContactMenu( wxMouseEvent& event ){
3106 // Show the contact menu when a right click occurs
3107 // in the contacts list.
3109 bool EnableRefresh = FALSE;
3111 if (!ActiveAccount.IsEmpty() && (ActiveAccountType == "CardDAV" || ActiveAccountType == "carddav")){
3113 EnableRefresh = TRUE;
3117 ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
3119 this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
3123 void frmMain::ResetContactInfo(){
3125 // Reset the contact information to an empty page.
3127 wxString EmptyPage = wxT("");
3128 htmContactData->SetPage(EmptyPage);
3129 AccCtrl->SetValue("");