// frmMain.cpp - Main window form.
//
// (c) 2012-2015 Xestia Software Development.
//
// This file is part of Xestia Address Book.
//
// Xestia Address Book is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by the
// Free Software Foundation, version 3 of the license.
//
// Xestia Address Book is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with Xestia Address Book. If not, see
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Include the forms.
#include "frmMain.h"
#include "frmAbout.h"
#include "frmPreferences.h"
#include "frmNewAccount.h"
#include "actmgr/frmActivityMgr.h"
#include "frmContact.h"
#include "frmConflictResolution.h"
#include "frmInvalidSSLCertificate.h"
#include "search/frmSearch.h"
#include "frmSSLCertificate.h"
#include "frmUpdate.h"
#include "import/frmImportResults.h"
#include "bitmaps.h"
#include "common/preferences.h"
#include "common/getcontactinfo.h"
#include "common/events.h"
#include "common/dirs.h"
#include "vcard/vcard.h"
#include "contacteditor/frmContactEditor.h"
#include "import/import.h"
#include "export/export.h"
#include "widgets/XABContactMenu.h"
#include "widgets/XABAccountView.h"
#include "version.h"
// Define the event types.
DEFINE_EVENT_TYPE(CE_UPDATECONTACTLIST);
DEFINE_EVENT_TYPE(CE_UPDATEACCOUNTLIST);
DEFINE_EVENT_TYPE(SE_UPDATECONTACTNOTIF);
DEFINE_EVENT_TYPE(CE_OPENCONTACT);
DEFINE_EVENT_TYPE(CE_OPENCONTACTLIST);
DEFINE_EVENT_TYPE(CE_NEWCONTACT);
DEFINE_EVENT_TYPE(CE_EDITCONTACT);
DEFINE_EVENT_TYPE(CE_DELETECONTACT);
DEFINE_EVENT_TYPE(CE_REVEALCONTACT);
DEFINE_EVENT_TYPE(CE_REMOVECONTACT);
DEFINE_EVENT_TYPE(CE_REMOVESEARCH);
DEFINE_EVENT_TYPE(SYNC_EMPTYSERVER);
DEFINE_EVENT_TYPE(ACTMGR_START);
DEFINE_EVENT_TYPE(ACTMGR_SHUFFLE);
DEFINE_EVENT_TYPE(ACTMGR_STOP);
DEFINE_EVENT_TYPE(WINDOW_ADD);
DEFINE_EVENT_TYPE(WINDOW_EDIT);
DEFINE_EVENT_TYPE(WINDOW_CLOSE);
DEFINE_EVENT_TYPE(CONNSTAT_UPDATE);
DEFINE_EVENT_TYPE(INVALIDSSLCERT);
DEFINE_EVENT_TYPE(INVALIDSSLCERTSTRING);
DEFINE_EVENT_TYPE(GETSELECTEDLIST);
DEFINE_EVENT_TYPE(SYNCACCOUNT);
DEFINE_EVENT_TYPE(IMPORT_RESULTSSHOW);
DEFINE_EVENT_TYPE(RELOADCONTACTLIST);
DEFINE_EVENT_TYPE(REFRESHADDRESSBOOK);
#if defined(__APPLE__)
DEFINE_EVENT_TYPE(INVALIDSSLTRUST);
#endif
// Setup the event table using the event types.
BEGIN_EVENT_TABLE(frmMain, wxFrame)
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, frmMain::ConflictResolution)
EVT_COMMAND(wxID_ANY, CE_UPDATECONTACTLIST, frmMain::UpdateContactList)
EVT_COMMAND(wxID_ANY, CE_UPDATEACCOUNTLIST, frmMain::UpdateAccountList)
EVT_COMMAND(wxID_ANY, SE_UPDATECONTACTNOTIF, frmMain::UpdateSearchContactLists)
EVT_COMMAND(wxID_ANY, CE_OPENCONTACT, frmMain::OpenContactInfo)
EVT_COMMAND(wxID_ANY, CE_OPENCONTACTLIST, frmMain::OpenContactInfoList)
EVT_COMMAND(wxID_ANY, CE_NEWCONTACT, frmMain::ShowContactEditorNew)
EVT_COMMAND(wxID_ANY, CE_EDITCONTACT, frmMain::ShowContactEditorEdit)
EVT_COMMAND(wxID_ANY, CE_DELETECONTACT, frmMain::DeleteContact)
EVT_COMMAND(wxID_ANY, CE_REVEALCONTACT, frmMain::RevealContact)
EVT_COMMAND(wxID_ANY, CE_REMOVESEARCH, frmMain::RemoveContactsWindowPointer)
EVT_COMMAND(wxID_ANY, SYNC_EMPTYSERVER, frmMain::EmptyServerDialog)
EVT_COMMAND(wxID_ANY, ACTMGR_START, frmMain::ActivityIconStart)
EVT_COMMAND(wxID_ANY, ACTMGR_SHUFFLE, frmMain::ActivityIconShuffle)
EVT_COMMAND(wxID_ANY, ACTMGR_STOP, frmMain::ActivityIconStop)
EVT_COMMAND(wxID_ANY, WINDOW_ADD, frmMain::WindowAdd)
EVT_COMMAND(wxID_ANY, WINDOW_EDIT, frmMain::WindowEdit)
EVT_COMMAND(wxID_ANY, WINDOW_CLOSE, frmMain::WindowDelete)
EVT_COMMAND(wxID_ANY, CONNSTAT_UPDATE, frmMain::UpdateConnectionStatus)
EVT_COMMAND(wxID_ANY, INVALIDSSLCERT, frmMain::InvalidSSLCertificate)
EVT_COMMAND(wxID_ANY, INVALIDSSLCERTSTRING, frmMain::InvalidSSLCertificateString)
EVT_COMMAND(wxID_ANY, GETSELECTEDLIST, frmMain::GetSelectedList)
EVT_COMMAND(wxID_ANY, SYNCACCOUNT, frmMain::SyncAccount)
EVT_COMMAND(wxID_ANY, IMPORT_RESULTSSHOW, frmMain::ShowImportResults)
EVT_COMMAND(wxID_ANY, RELOADCONTACTLIST, frmMain::ReloadContactList)
EVT_COMMAND(wxID_ANY, REFRESHADDRESSBOOK, frmMain::RefreshAddressBook)
#if defined(__APPLE__)
EVT_COMMAND(wxID_ANY, INVALIDSSLTRUST, frmMain::DisplayTrustPanel)
#endif
END_EVENT_TABLE()
frmMain::frmMain( wxWindow* parent )
:
frmMainADT( parent )
{
// Setup the account icons.
wxMemoryInputStream astream(icons_accinet_png, sizeof(icons_accinet_png));
wxMemoryInputStream bstream(icons_acclocal_png, sizeof(icons_acclocal_png));
wxMemoryInputStream cstream(icons_accgroup_png, sizeof(icons_accgroup_png));
wxMemoryInputStream dstream(icons_accnone_png, sizeof(icons_accnone_png));
wxMemoryInputStream estream(icons_accunsupported_png, sizeof(icons_accunsupported_png));
wxImage icons_accinet_png(astream, wxBITMAP_TYPE_PNG);
wxBitmap AccInet(icons_accinet_png, -1);
wxIcon wxIAccInet;
wxIAccInet.CopyFromBitmap(AccInet);
wxImage icons_acclocal_png(bstream, wxBITMAP_TYPE_PNG);
wxBitmap AccNIcon(icons_acclocal_png, -1);
wxIcon wxIAccNIcon;
wxIAccNIcon.CopyFromBitmap(AccNIcon);
wxImage icons_accgroup_png(cstream, wxBITMAP_TYPE_PNG);
wxBitmap AccGrp(icons_accgroup_png, -1);
wxIcon wxIAccGrp;
wxIAccGrp.CopyFromBitmap(AccGrp);
wxImage icons_accnone_png(dstream, wxBITMAP_TYPE_PNG);
wxBitmap AccNone(icons_accnone_png, -1);
wxIcon wxIAccNone;
wxIAccNone.CopyFromBitmap(AccNone);
wxImage icons_accunsupported_png(estream, wxBITMAP_TYPE_PNG);
wxBitmap AccUnsupported(icons_accunsupported_png, -1);
wxIcon wxIAccUnsupported;
wxIAccUnsupported.CopyFromBitmap(AccUnsupported);
AccountID = AccImgList->Add(wxIAccNIcon);
AccountNetID = AccImgList->Add(wxIAccInet);
AccountGrpID = AccImgList->Add(wxIAccGrp);
AccountNoneID = AccImgList->Add(wxIAccNone);
AccountUnsupportedID = AccImgList->Add(wxIAccUnsupported);
bmpIcon->SetIcon(AccImgList->GetIcon(AccountNoneID));
// Setup the status bar icons.
// SSL icons.
wxMemoryInputStream sslstream(icons_ssl_png, sizeof(icons_ssl_png));
wxMemoryInputStream sslwarningstream(icons_sslwarning_png, sizeof(icons_sslwarning_png));
wxMemoryInputStream nosslstream(icons_nossl_png, sizeof(icons_nossl_png));
wxImage icons_ssl_png(sslstream, wxBITMAP_TYPE_PNG);
imgSSL = new wxBitmap(icons_ssl_png, -1);
wxImage icons_sslwarning_png(sslwarningstream, wxBITMAP_TYPE_PNG);
imgSSLWarning = new wxBitmap(icons_sslwarning_png, -1);
wxImage icons_nossl_png(nosslstream, wxBITMAP_TYPE_PNG);
imgNoSSL = new wxBitmap(icons_nossl_png, -1);
// Toolbar icons.
wxMemoryInputStream addaddressbook(toolbar_addaddressbook_png, sizeof(toolbar_addaddressbook_png));
wxMemoryInputStream preferences(toolbar_preferences_png, sizeof(toolbar_preferences_png));
wxMemoryInputStream searchcontacts(toolbar_searchcontacts_png, sizeof(toolbar_searchcontacts_png));
wxMemoryInputStream addcontact(toolbar_addcontact_png, sizeof(toolbar_addcontact_png));
wxMemoryInputStream editcontact(toolbar_editcontact_png, sizeof(toolbar_editcontact_png));
wxMemoryInputStream deletecontact(toolbar_deletecontact_png, sizeof(toolbar_deletecontact_png));
wxImage toolbar_addaddressbook_png(addaddressbook, wxBITMAP_TYPE_PNG);
imgAddAddressBook = new wxBitmap (toolbar_addaddressbook_png, -1);
tblMain->SetToolNormalBitmap(tbtNewAccount->GetId(), *imgAddAddressBook);
wxImage toolbar_preferences_png(preferences, wxBITMAP_TYPE_PNG);
imgPreferences = new wxBitmap (toolbar_preferences_png, -1);
tblMain->SetToolNormalBitmap(tbtPreferences->GetId(), *imgPreferences);
wxImage toolbar_searchcontacts_png(searchcontacts, wxBITMAP_TYPE_PNG);
imgSearchContacts = new wxBitmap (toolbar_searchcontacts_png, -1);
tblMain->SetToolNormalBitmap(tbtSearch->GetId(), *imgSearchContacts);
wxImage toolbar_addcontact_png(addcontact, wxBITMAP_TYPE_PNG);
imgAddContact = new wxBitmap (toolbar_addcontact_png, -1);
tblMain->SetToolNormalBitmap(tbtAddContact->GetId(), *imgAddContact);
wxImage toolbar_editcontact_png(editcontact, wxBITMAP_TYPE_PNG);
imgEditContact = new wxBitmap (toolbar_editcontact_png, -1);
tblMain->SetToolNormalBitmap(tbtEditContact->GetId(), *imgEditContact);
wxImage toolbar_deletecontact_png(deletecontact, wxBITMAP_TYPE_PNG);
imgDeleteContact = new wxBitmap (toolbar_deletecontact_png, -1);
tblMain->SetToolNormalBitmap(tbtDeleteContact->GetId(), *imgDeleteContact);
// Activity Icon.
wxMemoryInputStream act1(icons_act1_png, sizeof(icons_act1_png));
wxMemoryInputStream act2(icons_act2_png, sizeof(icons_act2_png));
wxMemoryInputStream act3(icons_act3_png, sizeof(icons_act3_png));
wxMemoryInputStream act4(icons_act4_png, sizeof(icons_act4_png));
wxMemoryInputStream actsleep(icons_actsleep_png, sizeof(icons_actsleep_png));
wxImage icons_actsleep_png(actsleep, wxBITMAP_TYPE_PNG);
imgActIconSleep = new wxBitmap (icons_actsleep_png, -1);
wxImage icons_act1_png(act1, wxBITMAP_TYPE_PNG);
imgActIcon1 = new wxBitmap (icons_act1_png, -1);
wxIcon wxIAct1icon;
wxIAct1icon.CopyFromBitmap(*imgActIcon1);
wxImage icons_act2_png(act2, wxBITMAP_TYPE_PNG);
imgActIcon2 = new wxBitmap (icons_act2_png, -1);
wxIcon wxIAct2icon;
wxIAct2icon.CopyFromBitmap(*imgActIcon2);
wxImage icons_act3_png(act3, wxBITMAP_TYPE_PNG);
imgActIcon3 = new wxBitmap (icons_act3_png, -1);
wxIcon wxIAct3icon;
wxIAct3icon.CopyFromBitmap(*imgActIcon3);
wxImage icons_act4_png(act4, wxBITMAP_TYPE_PNG);
imgActIcon4 = new wxBitmap (icons_act4_png, -1);
wxIcon wxIAct4icon;
wxIAct4icon.CopyFromBitmap(*imgActIcon4);
// Online/Offline icons.
wxMemoryInputStream onlinestream(icons_online_png, sizeof(icons_online_png));
wxMemoryInputStream offlinestream(icons_offline_png, sizeof(icons_offline_png));
wxImage icons_online_png(onlinestream, wxBITMAP_TYPE_PNG);
imgOnline = new wxBitmap(icons_online_png, -1);
wxImage icons_offline_png(offlinestream, wxBITMAP_TYPE_PNG);
imgOffline = new wxBitmap(icons_offline_png, -1);
// Setup the account view.
AccCtrl->SetPopupControl(treAccounts);
AccCtrl->SetPopupMaxHeight(175);
AccCtrl->SetPopupMinWidth(250);
treAccounts->AssignImageList(AccImgList);
wxListItem ColumnData;
ColumnData.SetId(0);
ColumnData.SetText(wxT("Name0"));
ColumnData.SetWidth(320);
lstContacts->InsertColumn(0, ColumnData);
treAccounts->Connect(wxEVT_LEFT_DCLICK, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
treAccounts->Connect(wxEVT_TREE_SEL_CHANGED, wxTreeEventHandler(frmMain::LoadContactList), NULL, this);
#if defined(__HAIKU__)
#elif defined(__WIN32__)
int stbBottomData [4] = { -1, 8, 8, 8 };
#else
int stbBottomData [4] = { -1, 20, 20, 20 };
#endif
stbBottom->SetFieldsCount(4, stbBottomData);
stbBottom->SetMinHeight(16);
wxRect rectOnline;
wxRect rectSSL;
wxRect rectActivity;
stbBottom->GetFieldRect(1, rectOnline);
stbBottom->GetFieldRect(2, rectSSL);
stbBottom->GetFieldRect(3, rectActivity);
SSLToolTip = new wxToolTip(wxT(""));
imgConnStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectOnline.GetX()),(rectOnline.GetY())), wxDefaultSize, 0 );
imgConnStatus->SetBitmap(*imgOnline);
imgConnStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ToggleConnectionStatus ), NULL, this );
imgSSLStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectSSL.GetX()),(rectSSL.GetY())), wxDefaultSize, 0 );
imgSSLStatus->SetBitmap(*imgNoSSL);
imgSSLStatus->SetToolTip(SSLToolTip);
imgSSLStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowSSLCertificates ), NULL, this );
imgActivityStatus = new wxStaticBitmap(stbBottom, wxID_ANY, wxNullBitmap, wxPoint((rectActivity.GetX()),(rectActivity.GetY())), wxDefaultSize, 0);
imgActivityStatus->SetBitmap(*imgActIconSleep);
imgActivityStatus->Connect( wxEVT_LEFT_DCLICK, wxCommandEventHandler( frmMain::ShowActivityWindow ), NULL, this );
// Setup the window menu.
// By default should be:
// Contact windows:
// (none)
// (horizontal line)
// Contact editor windows:
// (none)
// (horizontal line)
// Search windows:
// (none)
mnuContactWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact windows:") ), wxEmptyString, wxITEM_NORMAL );
mnuWindow->Append( mnuContactWindows );
mnuWindow->AppendSeparator();
mnuContactEditorWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( _("Contact editor windows:") ), wxEmptyString, wxITEM_NORMAL );
mnuWindow->Append( mnuContactEditorWindows );
mnuWindow->AppendSeparator();
mnuSearchWindows = new wxMenuItem( mnuManage, wxID_ANY, wxString( wxT("Search windows:") ), wxEmptyString, wxITEM_NORMAL );
mnuWindow->Append( mnuSearchWindows );
#if defined(__WIN32__)
wxFont fontstyle;
fontstyle.Bold();
mnuContactWindows->SetFont(fontstyle);
mnuContactEditorWindows->SetFont(fontstyle);
mnuSearchWindows->SetFont(fontstyle);
#else
mnuContactWindows->Enable(FALSE);
mnuContactEditorWindows->Enable(FALSE);
mnuSearchWindows->Enable(FALSE);
#endif
// Hide unimplemented functions.
mnuMain->Remove(3);
}
void frmMain::QuitApp( wxCloseEvent& event )
{
// Run the QuitApp function.
QuitApp();
}
void frmMain::QuitApp( wxCommandEvent& event )
{
// Run the QuitApp function.
QuitApp();
}
void frmMain::QuitApp()
{
// Function to run when quitting.
// Write out the ETag databases.
ETagProcTimer.Stop();
ETagProcTimer.Notify();
// Save Preferences: Save the window position if that option is enabled.
wxString SetFilename = GetUserPrefDir();
#if defined(__HAIKU__)
#elif defined(__WIN32__)
SetFilename.Append(wxT("settings"));
#else
// *nix OSes
SetFilename.Append(wxT("settings"));
#endif
wxFileConfig *cfgfile = new wxFileConfig("", "", SetFilename);
bool SaveWindowPos = FALSE;
wxString SaveWindowInc;
cfgfile->Read(wxT("SaveWindowPosition"), &SaveWindowInc);
if (SaveWindowInc == wxT("true")){
SaveWindowPos = TRUE;
}
if (SaveWindowPos == TRUE){
wxRect frmMainPos = this->GetRect();
cfgfile->Write(wxT("WindowPositionX"), frmMainPos.GetX());
cfgfile->Write(wxT("WindowPositionY"), frmMainPos.GetY());
cfgfile->Write(wxT("WindowPositionHeight"), frmMainPos.GetHeight());
cfgfile->Write(wxT("WindowPositionWidth"), frmMainPos.GetWidth());
}
delete cfgfile;
cfgfile = NULL;
//Everything closed... exit.
std::exit(0);
Close();
}
void frmMain::ShowActivityWindow( wxCommandEvent& event )
{
// Open the activity manager window.
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
frameActMgr->OpenWindow();
frameActMgr->Show();
}
void frmMain::ShowAboutWindow( wxCommandEvent& event )
{
// Show the about window.
frmAbout *frameAbout = new frmAbout ( this );
frameAbout->SetupAboutWindow();
frameAbout->ShowModal();
delete frameAbout;
frameAbout = NULL;
}
void frmMain::OpenPreferences( wxCommandEvent& event)
{
// Open the preferences window.
ReloadAccounts = FALSE;
frmPreferences *framePreferences = new frmPreferences ( this );
framePreferences->SetupPointers(&ReloadAccounts);
framePreferences->ShowModal();
delete framePreferences;
framePreferences = NULL;
if (ReloadAccounts == TRUE){
// Reload the accounts as a change has been made within
// the application and clear the current contact information.
this->LoadPreferences();
this->ResetContactInfo();
}
}
void frmMain::OpenNewABDialog( wxCommandEvent& event)
{
// Open the new account dialog.
ReloadAccounts = FALSE;
frmNewAccount *frameNewAccount = new frmNewAccount ( this );
frameNewAccount->SetupPointers(&ReloadAccounts);
frameNewAccount->ShowModal();
delete frameNewAccount;
frameNewAccount = NULL;
if (ReloadAccounts == TRUE){
// Reload the accounts as a change has been made within
// the application.
this->LoadPreferences();
}
}
void frmMain::LoadContactList( wxTreeEvent& event )
{
// Load the contact list.
// Clear all existing variables.
lstContacts->DeleteAllItems();
treAccounts->SetAccount();
wxTreeItemIdValue cookie;
wxTreeItemId next = treAccounts->GetRootItem();
wxString AccountName;
wxString AccountDir, AccountType, AccountDirFinal, AccountTypeFinal;
wxString AccountDirCmb;
long selectedaccount = 0;
wxTreeItemId selectedChild = treAccounts->GetSelection();
wxTreeItemId nextChild;
wxTreeItemId ActiveItemId = treAccounts->GetFocusedItem();
int ActiveItemIcon = treAccounts->GetItemImage(ActiveItemId, wxTreeItemIcon_Normal);
int SCImg = treAccounts->GetItemImage(selectedChild);
int AccountIndex = 0;
bmpIcon->SetIcon(AccImgList->GetIcon(SCImg));
// Process each account.
for (int i = 0; i < prefaccounts.GetCount(); i++){
if (ActiveItemIcon == 2){
std::multimap::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
std::multimap::iterator AGLiter = AccountGroupList.find(AGTiter->second);
int ActiveAccountG = AGLiter->second;
if (i == ActiveAccountG){
AccountDir.Append(prefaccounts.GetAccountDirectory(i));
AccountType.Append(prefaccounts.GetAccountType(i));
AccountDir.Trim();
AccountType.Trim();
if (AccountType == wxT("CardDAV")){
AccountTypeFinal.Append(wxT("carddav"));
} else if (AccountType == wxT("Local")){
imgSSLStatus->SetBitmap(*imgOffline);
SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
AccountTypeFinal.Append(wxT("local"));
} else {
imgSSLStatus->SetBitmap(*imgOffline);
SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
AccountTypeFinal.Append(AccountType.Lower());
}
AccountIndex = i;
break;
}
}
if (!nextChild){
nextChild = treAccounts->GetFirstChild(next, cookie);
} else {
nextChild = treAccounts->GetNextSibling(nextChild);
}
AccountName = treAccounts->GetItemText(nextChild);
if (nextChild == selectedChild){
AccountDir.Append(prefaccounts.GetAccountDirectory(i));
AccountType.Append(prefaccounts.GetAccountType(i));
AccountDir.Trim();
AccountType.Trim();
if (AccountType == wxT("CardDAV")){
AccountTypeFinal.Append(wxT("carddav"));
} else if (AccountType == wxT("Local")){
SSLToolTip->SetTip(wxT("SSL status is not applicable for this account"));
AccountTypeFinal.Append(wxT("local"));
} else {
AccountTypeFinal.Append(AccountType.Lower());
}
AccountIndex = i;
}
}
if (selectedaccount >= prefaccounts.GetCount()){
// The account selected isn't there so return.
RevealWait = FALSE;
return;
}
// Open the directory and get the list of .vcf files
// in that directory.
ActiveAccount = AccountDir + wxT(".") + AccountTypeFinal;
ActiveAccountType = AccountType;
SetupSSLStatus(AccountIndex);
AccountDirFinal.Clear();
AccountDirFinal = GetAccountDir(AccountDir + wxT(".") + AccountTypeFinal, FALSE);
ContactsFileIndex.Clear();
wxString vCardFilename;
wxString vCardFilenameFull;
wxString vCardDataString;
wxStringTokenizer vcardfileline;
wxString lwxs;
wxString setname, setvalue;
std::multimap> vCardNamesAsc;
std::multimap> vCardNamesDsc;
long ContactIndex = 1;
long ContactSeekPoint = 0;
wxDir vcardaccdir(AccountDirFinal);
// Get the wxTreeItemId and image icon and compare it to the list.
if (ActiveItemIcon == AccountGrpID){
// It's a group so load the file containing the group and
// get the members of the group.
vCard Group;
wxString UIDCode;
std::multimap::iterator AGTiter = AccountGroupTreeId.find(ActiveItemId);
std::multimap::iterator AGFiter = AccountGroupFilename.find(AGTiter->second);
Group.LoadFile(AGFiter->second);
ArrayvCardOutData vCardMember = Group.GetByPartial(wxT("MEMBER"));
for (int i = 0; i < vCardMember.PropCount; i++){
vCardMember.PropValues[i].Trim();
if (vCardMember.PropValues[i].Left(9) == wxT("urn:uuid:")){
wxString NewPropValue;
NewPropValue = vCardMember.PropValues[i].Mid(9, wxString::npos);
vCardMember.PropValues[i] = NewPropValue;
}
}
bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
while(ProcFiles){
if (vCardFilename.Right(4) == wxT(".vcf") ||
vCardFilename.Right(4) == wxT(".VCF") ||
vCardFilename.Right(5) == wxT(".vcard") ||
vCardFilename.Right(5) == wxT(".VCARD")){
vCard Person;
bool FoundMember = FALSE;
vCardFilenameFull.Append(AccountDirFinal);
vCardFilenameFull.Append(wxT("/"));
vCardFilenameFull.Append(vCardFilename);
Person.LoadFile(vCardFilenameFull);
UIDCode = Person.Get(wxT("UID"));
for (int i = 0; i < vCardMember.PropCount; i++){
if (vCardMember.PropValues[i] == UIDCode){
FoundMember = TRUE;
}
}
if (FoundMember == FALSE){
vCardFilename.Clear();
vCardFilenameFull.Clear();
vCardDataString.Clear();
ProcFiles = vcardaccdir.GetNext(&vCardFilename);
continue;
}
if (Person.MeetBaseSpecification()){
if (SortMode == 1){
// Split the name into sections.
vCardDataString = Person.Get(wxT("N"));
vCardName NameData = Person.GetName();
vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
} else if (SortMode == 2){
// Split the name into sections.
vCardName NameData = Person.GetName();
vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
} else if (SortMode == 3){
// Check and make sure that the top most nickname is used.
vCardDataString = Person.Get(wxT("NICKNAME"));
if (vCardDataString.IsEmpty()){
vCardDataString = wxT("(no nickname)");
}
} else if (SortMode == 4){
vCardDataString = Person.Get(wxT("FN"));
}
if (AscendingMode == TRUE){
vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
} else {
vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
}
}
}
vCardFilename.Clear();
vCardFilenameFull.Clear();
vCardDataString.Clear();
ProcFiles = vcardaccdir.GetNext(&vCardFilename);
}
} else {
bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
while(ProcFiles){
if (vCardFilename.Right(4) == wxT(".vcf") ||
vCardFilename.Right(4) == wxT(".VCF") ||
vCardFilename.Right(5) == wxT(".vcard") ||
vCardFilename.Right(5) == wxT(".VCARD")){
vCard Person;
vCardFilenameFull.Append(AccountDirFinal);
vCardFilenameFull.Append(vCardFilename);
Person.LoadFile(vCardFilenameFull);
if (Person.MeetBaseSpecification()){
if (SortMode == 1){
// Split the name into sections.
vCardDataString = Person.Get(wxT("N"));
vCardName NameData = Person.GetName();
vCardDataString = NameData.Forename + wxT(" ") + NameData.Surname;
} else if (SortMode == 2){
// Split the name into sections.
vCardName NameData = Person.GetName();
vCardDataString = NameData.Surname + wxT(", ") + NameData.Forename;
} else if (SortMode == 3){
// Check and make sure that the top most nickname is used.
vCardDataString = Person.Get(wxT("NICKNAME"));
if (vCardDataString.IsEmpty()){
vCardDataString = wxT("(no nickname)");
}
} else if (SortMode == 4){
vCardDataString = Person.Get(wxT("FN"));
}
if (AscendingMode == TRUE){
vCardNamesAsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
} else {
vCardNamesDsc.insert(std::make_pair(vCardDataString, vCardFilenameFull));
}
}
}
vCardFilename.Clear();
vCardFilenameFull.Clear();
vCardDataString.Clear();
ProcFiles = vcardaccdir.GetNext(&vCardFilename);
}
}
// Sort the data.
// Insert the data into the control.
if (AscendingMode == TRUE){
for (std::map::iterator iter = vCardNamesAsc.begin();
iter != vCardNamesAsc.end(); ++iter){
wxListItem ContactInfo;
ContactInfo.SetId(0);
ContactInfo.SetText(_("Mooo"));
ContactInfo.SetData(ContactSeekPoint);
ContactIndex = lstContacts->InsertItem(ContactInfo);
lstContacts->SetItem(ContactIndex, 0, iter->first);
ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
ContactSeekPoint++;
}
} else {
for (std::map::iterator iter = vCardNamesDsc.begin();
iter != vCardNamesDsc.end(); ++iter){
wxListItem ContactInfo;
ContactInfo.SetId(0);
ContactInfo.SetText(_("Mooo"));
ContactInfo.SetData(ContactSeekPoint);
ContactIndex = lstContacts->InsertItem(ContactInfo);
lstContacts->SetItem(ContactIndex, 0, iter->first);
ContactsFileIndex.Insert(iter->second, ContactSeekPoint);
ContactSeekPoint++;
}
}
}
void frmMain::ShowContactInfo( wxListEvent& event )
{
// Display the contact information.
long intSelected = -1;
long ContactSeekNum = -1;
// Check if several contacts have been selected.
int ContactTotal = 0;
for (;;){
intSelected = lstContacts->GetNextItem(intSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_SELECTED);
if (intSelected == -1){
break;
}
ContactTotal++;
}
if (ContactTotal == 0){
htmContactData->SetPage(wxT(""));
return;
}
if (ContactTotal > 1){
htmContactData->SetPage(wxString::Format(wxT("%i contacts selected."), ContactTotal));
ActiveFilename.Clear();
return;
}
intSelected = lstContacts->GetNextItem(intSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_SELECTED);
ContactSeekNum = lstContacts->GetItemData(intSelected);
wxFFile ContactFile;
wxString wxSContactString;
wxString ContactLine;
vCard Person;
size_t ContactLineLen;
bool ExtraLineSeek = FALSE;
int QuoteBreakPoint = 0;
bool PropertyFind = FALSE;
bool QuoteMode = FALSE;
wxString wxSPropertyNextLine;
wxString wxSProperty;
wxString wxSPropertySeg1;
wxString wxSPropertySeg2;
// Check if we are using wxWidgets version 2.8 or less and
// execute the required command accordingly.
#if wxABI_VERSION < 20900
ContactFile.Open(ContactsFileIndex[ContactSeekNum].c_str(), wxT("r"));
#else
ContactFile.Open(ContactsFileIndex[ContactSeekNum], wxT("r"));
#endif
if (ContactFile.IsOpened() == FALSE){
return;
}
ContactFile.ReadAll(&wxSContactString, wxConvAuto());
// Split the lines.
std::map ContactFileLines;
std::map::iterator striter;
wxStringTokenizer wSTContactFileLines(wxSContactString, wxT("\r\n"));
int ContactLineSeek = 0;
while (wSTContactFileLines.HasMoreTokens() == TRUE){
ContactLine = wSTContactFileLines.GetNextToken();
ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
ContactLineSeek++;
}
if (ContactSeekNum < 0){
return;
}
for (std::map::iterator iter = ContactFileLines.begin();
iter != ContactFileLines.end(); ++iter){
// Find the colon which splits the start bit from the data part.
ContactLine = iter->second;
while (ExtraLineSeek == TRUE){
// Check if there is extra data on the next line
// (indicated by space or tab at the start) and add data.
iter++;
if (iter == ContactFileLines.end()){
iter--;
break;
}
wxSPropertyNextLine = iter->second;
if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
wxSPropertyNextLine.Remove(0, 1);
ContactLine.Append(wxSPropertyNextLine);
} else {
iter--;
ExtraLineSeek = FALSE;
}
}
ContactLineLen = ContactLine.Len();
// Make sure we are not in quotation mode.
// Make sure colon does not have \ or \\ before it.
for (int i = 0; i <= ContactLineLen; i++){
if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
PropertyFind = FALSE;
} else if (PropertyFind == TRUE){
wxSProperty.Append(ContactLine.Mid(i, 1));
}
if (ContactLine.Mid(i, 1) == wxT("\"")){
if (QuoteMode == TRUE){
QuoteMode = FALSE;
} else {
QuoteMode = TRUE;
}
}
if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
QuoteBreakPoint = i;
break;
}
}
// Split that line at the point into two variables (ignore the colon).
wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
// Insert both into the vCard data file.
Person.AddRaw(wxSPropertySeg1, wxSPropertySeg2);
QuoteMode = FALSE;
PropertyFind = TRUE;
ExtraLineSeek = TRUE;
ContactLineLen = 0;
QuoteBreakPoint = 0;
ContactLine.Clear();
wxSProperty.Clear();
}
OldSessionID = SessionID;
SessionID = wxString::Format(wxT("%i"), rand() % 32768);
LoadContactData(&Person, htmContactData, SessionID, OldSessionID, &MemoryFileList, ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
ActiveFilename = ContactsFileIndex[ContactSeekNum];
}
void frmMain::ShowContactEditorNew( wxCommandEvent& event )
{
// Open a contact editor window to write a new contact with.
// Check if there is an account selected and if not
// return immediately.
if (ActiveAccount.IsEmpty()){
return;
}
// Check if the account type is a valid account type, otherwise
// display an error message.
if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
ActiveAccountType != "Local" && ActiveAccountType != "local"){
wxMessageBox(_("Cannot add a new contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
return;
}
// Add Pointer to SetupPointers for the ETagDB.
wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
wxIcon contacticon;
contacticon.CopyFromBitmap(contacticonbmp);
frmContactEditor *ContactEditor = new frmContactEditor( this );
WindowMenuItemID++;
ContactEditor->SetUID(WindowMenuItemID);
WindowData *WData = new WindowData;
WData->DataType = 1;
WData->WindowPointer = (void*)ContactEditor;
WData->WindowID = WindowMenuItemID;
wxCommandEvent addevent(WINDOW_ADD);
addevent.SetClientData(WData);
wxPostEvent(this, addevent);
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
ContactEditor->SetupHeaders();
ContactEditor->SetupContact(ActiveAccount);
ContactEditor->SetIcon(contacticon);
ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
ContactEditor->Show(true);
}
void frmMain::ShowContactEditorEdit( wxCommandEvent& event )
{
// Open a contact editor window for editing an existing contact
// with.
// Check if there is an account selected and if not
// return immediately.
int DataCheck = event.GetInt();
if (ActiveAccount.IsEmpty() && DataCheck == 0){
return;
}
wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
wxIcon contacticon;
contacticon.CopyFromBitmap(contacticonbmp);
// Check if a contact has been selected.
long intSelected = -1;
long intContactSeekNum = -1;
intSelected = lstContacts->GetNextItem(intSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_SELECTED);
if (intSelected == -1){
return;
}
intContactSeekNum = lstContacts->GetItemData(intSelected);
// Get the filename of the selected contact.
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
frmContactEditor *ContactEditor = new frmContactEditor( this );
WindowMenuItemID++;
ContactEditor->SetUID(WindowMenuItemID);
WindowData *WData = new WindowData;
WData->DataType = 1;
WData->WindowPointer = (void*)ContactEditor;
WData->WindowID = WindowMenuItemID;
wxCommandEvent addevent(WINDOW_ADD);
addevent.SetClientData(WData);
wxPostEvent(this, addevent);
ContactEditor->SetupPointers(frameActMgr, &ETagProcTimer, this);
ContactEditor->SetupHeaders();
if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
ActiveAccountType != "Local" && ActiveAccountType != "local"){
ContactEditor->SetupAccountData(true);
}
// Check if pointer is NULL (not from the search forms) or not.
if (DataCheck == 0){
ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
ContactEditor->SetupContact(ActiveAccount);
} else {
UCNotif *uc = (UCNotif*)event.GetClientData();
if (!uc){
ContactEditor->SetupContact(ActiveAccount);
ContactEditor->LoadContact(ContactsFileIndex[intContactSeekNum]);
} else {
ContactEditor->SetupContact(uc->ContactAccount);
ContactEditor->LoadContact(uc->ContactFilename);
delete uc;
uc = NULL;
}
}
ContactEditor->SetIcon(contacticon);
ContactEditor->Show(true);
}
void frmMain::RefreshAddressBook( wxCommandEvent& event ){
// Refresh the address book data.
// Check if ActiveAccount is empty. If not then check if
// account type is not local otherwise continue.
if (!ActiveAccount.IsEmpty()){
if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
// Account type is not local.
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
frameActMgr->AddTask(3, wxT(""), ActiveAccount,
wxT(""), wxT(""), wxT(""), wxT(""));
} else {
wxMessageBox(_("The refresh address book command is not supported with this type of account."), wxT("Not supported"), wxICON_ERROR);
}
}
}
void frmMain::OpenContactInfoList( wxListEvent& event )
{
// Open the contact information window.
wxStringTokenizer vcardfileline;
std::string l;
wxString lwxs;
wxString setname, setvalue;
vCard Person;
wxString nextchar;
long intSelected = -1;
long intContactSeekNum = -1;
intSelected = lstContacts->GetNextItem(intSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_SELECTED);
intContactSeekNum = lstContacts->GetItemData(intSelected);
if (intContactSeekNum == -1){
return;
}
Person.LoadFile(ContactsFileIndex[intContactSeekNum]);
wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
wxIcon contacticon;
contacticon.CopyFromBitmap(contacticonbmp);
frmContact *Contact = new frmContact( this );
// Add to window list.
WindowMenuItemID++;
Contact->SetUID(WindowMenuItemID);
WindowData *WData = new WindowData;
WData->DataType = 0;
WData->WindowPointer = (void*)Contact;
WData->WindowID = WindowMenuItemID;
wxCommandEvent addevent(WINDOW_ADD);
addevent.SetClientData(WData);
wxPostEvent(this, addevent);
Contact->SetupPointers(&MemoryFileList);
Contact->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
Contact->SetupContactData(&Person);
Contact->SetIcon(contacticon);
Contact->Show(true);
}
void frmMain::OpenContactInfoList( wxCommandEvent& event ){
// Open a list of contact information windows.
wxListEvent pevent;
OpenContactInfoList(pevent);
}
void frmMain::OpenContactInfo( wxCommandEvent& event )
{
// Open the contact information window.
UCNotif *uc = (UCNotif*)event.GetClientData();
wxStringTokenizer vcardfileline;
std::string l;
wxString lwxs;
wxString setname, setvalue;
vCard Person;
wxString nextchar;
Person.LoadFile(uc->ContactFilename);
wxMemoryInputStream istream(bigimgs_contactpersonicon48_png, sizeof(bigimgs_contactpersonicon48_png));
wxImage bigimgs_contactpersonicon48i(istream, wxBITMAP_TYPE_PNG);
wxBitmap contacticonbmp(bigimgs_contactpersonicon48i, -1);
wxIcon contacticon;
contacticon.CopyFromBitmap(contacticonbmp);
frmContact *Contact = new frmContact( this );
// Add to window list.
WindowMenuItemID++;
Contact->SetUID(WindowMenuItemID);
WindowData *WData = new WindowData;
WData->DataType = 0;
WData->WindowPointer = (void*)Contact;
WData->WindowID = WindowMenuItemID;
wxCommandEvent addevent(WINDOW_ADD);
addevent.SetClientData(WData);
wxPostEvent(this, addevent);
Contact->SetupPointers(&MemoryFileList);
Contact->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
Contact->SetupContactData(&Person);
Contact->SetIcon(contacticon);
Contact->Show(true);
}
void frmMain::LoadPreferences( wxActivateEvent& event)
{
// Load the preferences.
this->LoadPreferences();
}
void frmMain::LoadPreferences(){
// Load the preferences.
wxString preffilename = GetUserPrefDir();
XABPreferences preferences(preffilename);
// Setup the main window position (if needed).
bool SaveWindowPos = preferences.GetBoolData(wxT("SaveWindowPosition"));
bool HideLocalABs = preferences.GetBoolData(wxT("HideLocalAddressBooks"));
bool UseBackgroundContactColour = preferences.GetBoolData(wxT("UseBackgroundContactColour"));
if (SaveWindowPos == true){
this->SetSize(preferences.GetMainWindowData());
}
if (UseBackgroundContactColour == true){
ContactBackgroundColour = preferences.GetBackgroundContactColourData();
}
treAccounts->DeleteAllItems();
wxTreeItemId RootNode = treAccounts->AddRoot(wxT("Root Item"), AccountNoneID);
// Stop all account timers and remove the accounts.
for (std::map::iterator iter = AccountSyncTimers.begin();
iter != AccountSyncTimers.end(); iter++){
wxAccountSyncTimer *AccTmrPtr = iter->second;
AccTmrPtr->Stop();
delete AccTmrPtr;
AccTmrPtr = NULL;
}
#if defined(__WIN32__)
for (std::map::iterator CertificateIter = AccountCertificateData.begin();
CertificateIter != AccountCertificateData.end(); CertificateIter++){
CertFreeCertificateContext(CertificateIter->second);
}
AccountCertificateData.clear();
#endif
AccountSyncTimers.clear();
wxString AccDir;
wxString AccDirFull;
wxString AccDirFullSfx;
wxString AccName;
wxString AccDirFinal;
AccountAccDirList.clear();
AccountGroupList.clear();
AccountGroupFilename.clear();
AccountGroupTreeId.clear();
wxTreeItemId AccountTreeId;
wxTreeItemId GroupTreeId;
int intGroupID = 0;
// Relaod the accounts for the ETagProcTimer.
ETagProcTimer.ReloadAccounts();
for (int i = 0; i < preferences.accounts.GetCount(); i++){
if ((preferences.accounts.GetAccountType(i) == wxT("Local") ||
preferences.accounts.GetAccountType(i) == wxT("local")) && HideLocalABs == true){
continue;
}
if (preferences.accounts.GetAccountDirectory(i).IsEmpty()){
continue;
}
AccDir = preferences.accounts.GetAccountDirectory(i);
AccDirFull = preferences.accounts.GetAccountDirectory(i);
AccDirFull.Trim();
AccDirFull.Append(wxT("."));
AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
AccDirFullSfx.LowerCase();
AccDirFullSfx.Trim();
AccDirFull.Append(AccDirFullSfx);
AccName = preferences.accounts.GetAccountName(i);
AccName.Trim();
AccountAccDirList.insert(std::make_pair(i, AccDirFull));
if (preferences.accounts.GetAccountType(i) == wxT("CardDAV") ||
preferences.accounts.GetAccountType(i) == wxT("carddav")){
// TODO: Check if the directory exists before doing anything.
// Add a new timer using the existing account details.
wxAccountSyncTimer *ActTmrPtr = new wxAccountSyncTimer;
ActTmrPtr->SetupData(AccDirFull, AccName);
ActTmrPtr->SetupPointers(this, ActMgrPtr, ETagProcTimer.GetPointer(AccDirFull));
ActTmrPtr->Start((int)(preferences.accounts.GetAccountRefresh(i) * 1000));
ActTmrPtr->SetOwner(this);
ActTmrPtr->Notify();
// Add the timer to the list of timers.
AccountSyncTimers.insert(std::make_pair(AccDirFull, ActTmrPtr));
AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountNetID, -1);
} else if (preferences.accounts.GetAccountType(i) == wxT("Local") ||
preferences.accounts.GetAccountType(i) == wxT("local")) {
AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountID, -1);
} else {
AccountTreeId = treAccounts->AppendItem(RootNode, preferences.accounts.GetAccountName(i), AccountUnsupportedID, -1);
}
// Go through the account directory and find contact files with
// 'KIND:group' set and add them to the list of groups for the account.
AccDirFinal = GetAccountDir(AccDirFull, FALSE);
wxDir vcardaccdir(AccDirFinal);
wxString vCardFilename;
wxString vCardDataString;
wxString vCardFilenameFull;
bool ProcFiles = vcardaccdir.GetFirst(&vCardFilename, wxEmptyString, wxDIR_FILES);
while(ProcFiles){
if (vCardFilename.Right(4) == wxT(".vcf") ||
vCardFilename.Right(4) == wxT(".VCF") ||
vCardFilename.Right(5) == wxT(".vcard") ||
vCardFilename.Right(5) == wxT(".VCARD")){
vCard Person;
vCardFilenameFull.Append(AccDirFinal);
vCardFilenameFull.Append(wxT("/"));
vCardFilenameFull.Append(vCardFilename);
Person.LoadFile(vCardFilenameFull);
if (Person.MeetBaseSpecification()){
vCardDataString = Person.Get(wxT("KIND"));
if (vCardDataString == wxT("group")){
// The vCard kind is a group. Add to the account's group list.
GroupTreeId = treAccounts->AppendItem(AccountTreeId, Person.Get(wxT("FN")), AccountGrpID, -1);
treAccounts->SetItemHasChildren(AccountTreeId, TRUE);
AccountGroupList.insert(std::make_pair(intGroupID, i));
AccountGroupFilename.insert(std::make_pair(intGroupID, vCardFilenameFull));
AccountGroupTreeId.insert(std::make_pair(GroupTreeId, intGroupID));
}
intGroupID++;
}
}
vCardFilename.Clear();
vCardFilenameFull.Clear();
vCardDataString.Clear();
ProcFiles = vcardaccdir.GetNext(&vCardFilename);
}
// Clearup for next account.
AccDir.clear();
AccDirFull.clear();
AccDirFullSfx.clear();
AccDirFinal.clear();
AccName.clear();
}
// Load the account settings as they are needed for connecting
// to the servers.
prefaccounts = preferences.accounts;
}
void frmMain::ConflictResolution(wxCommandEvent& event){
// Display the conflict resolution window.
frmConflictResolution *frameCR = new frmConflictResolution ( this );
vCardConflictObj *vCardConfObj = (vCardConflictObj*)event.GetClientData();
vCard *ClientDataPtr = vCardConfObj->vCardLocalData;
vCard *ServerDataPtr = vCardConfObj->vCardServerData;
frameCR->LoadData(ClientDataPtr, ServerDataPtr, &MemoryFileList, ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
frameCR->ShowModal();
int FinalConflictResult = frameCR->GetResult();
wxCommandEvent event2(ACTMGR_RESUMEPROC);
event2.SetClientData(vCardConfObj->QRNotifData);
event2.SetInt(FinalConflictResult);
delete frameCR;
frameCR = NULL;
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
wxPostEvent(frameActMgr, event2);
}
void frmMain::UpdateContactList(wxCommandEvent& event){
// Update the contact list in the main window.
UCNotif *ucd = (UCNotif*)event.GetClientData();
// Check if the active account is being displayed in the
// main window. If not, skip and delete the data.
long longSelected = -1;
int intSelectedData = 0;
if (ActiveAccount == ucd->ContactAccount){
// Look at the list of contacts and if it matches the
// filename then update the name.
for (;;){
longSelected = lstContacts->GetNextItem(longSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_DONTCARE);
if (longSelected == -1){
break;
}
intSelectedData = (int)lstContacts->GetItemData(longSelected);
if (ucd->ContactFilename == ContactsFileIndex[intSelectedData]){
// Work out which sorting mode we are in.
if (SortMode == 1){
// First Name, Last Name.
lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Forename + wxT(" ") + ucd->ContactNameArray.Surname);
} else if (SortMode == 2){
// Last Name, First Name.
lstContacts->SetItem(longSelected, 0, ucd->ContactNameArray.Surname + wxT(", ") + ucd->ContactNameArray.Forename);
} else if (SortMode == 3){
// Nickname.
lstContacts->SetItem(longSelected, 0, ucd->ContactNickname);
} else if (SortMode == 4){
// Display As.
lstContacts->SetItem(longSelected, 0, ucd->ContactName);
}
}
// If the filename is the one loaded into the
// browser control, then update this too.
if (ActiveFilename == ContactsFileIndex[intSelectedData]){
wxListEvent nullevent;
ShowContactInfo(nullevent);
}
}
}
for (std::map::iterator WindowIter = WindowListPointers.begin();
WindowIter != WindowListPointers.end(); WindowIter++){
if (WindowListType[WindowIter->first] != 0){
continue;
}
frmContact *frmContactPtr = static_cast(WindowIter->second);
if (frmContactPtr->GetFilename() == ucd->ContactFilename){
vCard UpdatedPerson;
UpdatedPerson.LoadFile(ucd->ContactFilename);
frmContactPtr->SetBackgroundColour(ContactBackgroundColour.GetAsString(wxC2S_CSS_SYNTAX));
frmContactPtr->SetupContactData(&UpdatedPerson);
}
}
// Send message to search window controller subroutine and
// pass that notification onto the search windows.
// Setup the new pointer to use the existing UCNotif without
// deleting it.
UCNotif *ucd2 = ucd;
wxCommandEvent sup(SE_UPDATECONTACTNOTIF);
sup.SetClientData(ucd2);
wxPostEvent(this, sup);
// Clear up the unused pointer.
ucd = NULL;
}
void frmMain::UpdateAccountList(wxCommandEvent& event){
// Update the account list (currently unimplemented).
}
void frmMain::SetupPointers(void *ActMgrPtrInc){
// Setup the pointers for the main window.
ActMgrPtr = ActMgrPtrInc;
}
void frmMain::SetupForm(){
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
frameActMgr->SetupPointers(&ETagProcTimer, this);
// Setup the contact information icons for later.
wxFileSystem::AddHandler(new wxMemoryFSHandler);
wxImage ciicon_png;
//wxBitmap ciicon;
wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
LoadPreferences();
}
void frmMain::UpdateSearchContactLists(wxCommandEvent& event){
// Update the contact lists in the search windows.
// Go through each of the search windows and
// send the required notification to update the
// contact information.
// Get the event notification data.
UCNotif *ucd = (UCNotif*)event.GetClientData();
// Process each search window giving the new details.
for (std::map::iterator switer = SearchWindowList.begin();
switer != SearchWindowList.end(); switer++){
// Duplicate the event notification data.
UCNotif *ucd2 = new UCNotif;
ucd2->ContactAccount = ucd->ContactAccount;
ucd2->ContactFilename = ucd->ContactFilename;
ucd2->ContactName = ucd->ContactName;
ucd2->ContactNickname = ucd->ContactNickname;
ucd2->ContactNameArray = ucd->ContactNameArray;
// Pass the data to the search window for processing.
frmSearch *frameSCH = static_cast(switer->first);
wxCommandEvent schupdate(SE_UPDATERESULT);
schupdate.SetClientData(ucd2);
wxPostEvent(frameSCH, schupdate);
// Clear up the pointer prior to variable deletion.
frameSCH = NULL;
}
delete ucd;
ucd = NULL;
}
void frmMain::OpenFindContactsWindow(wxCommandEvent& event){
// Open a new search window.
WindowMenuItemID++;
frmSearch *frameSCH = new frmSearch ( this );
frameSCH->SetUID(WindowMenuItemID);
frameSCH->Show(true);
WindowData *WData = new WindowData;
WData->DataType = 2;
WData->WindowPointer = (void*)frameSCH;
WData->WindowID = WindowMenuItemID;
wxCommandEvent addevent(WINDOW_ADD);
addevent.SetClientData(WData);
wxPostEvent(this, addevent);
// Add pointer to the list of open search windows.
SearchWindowList.insert(std::make_pair(frameSCH, wxT("Search")));
WData = NULL;
}
void frmMain::RemoveContactsWindowPointer(wxCommandEvent& event){
// Remove the pointer for a contact window from the
// window list.
void *frameSCH = (void*)event.GetClientData();
SearchWindowList.erase(frameSCH);
frameSCH = NULL;
}
void frmMain::RemoveContactEditorWindowPointer(wxCommandEvent& event){
// Remove the pointer for a contact editor window from
// the window list.
void *frameSCH = (void*)event.GetClientData();
SearchWindowList.erase(frameSCH);
frameSCH = NULL;
}
void frmMain::RevealContact(wxCommandEvent& event){
// Reveal a contact in the main window.
UCNotif *uc = (UCNotif*)event.GetClientData();
// Switch the account to the one passed.
wxTreeItemIdValue cookie;
wxTreeItemId next = treAccounts->GetRootItem();
wxTreeItemId nextChild;
for (int i = 0; i < prefaccounts.GetCount(); i++){
if (!nextChild){
nextChild = treAccounts->GetFirstChild(next, cookie);
} else {
nextChild = treAccounts->GetNextSibling(nextChild);
}
if (uc->ContactAccount == AccountAccDirList[i]){
treAccounts->SelectItem(nextChild, TRUE);
AccCtrl->SetText(treAccounts->GetItemText(nextChild));
}
}
// Switch the contact to the one passed.
long longSelected = -1;
int intSelectedData = 0;
for (;;){
longSelected = lstContacts->GetNextItem(longSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_DONTCARE);
if (longSelected == -1){
break;
}
intSelectedData = (int)lstContacts->GetItemData(longSelected);
// Compare the filename with the one received.
// If they match then select it.
if (ContactsFileIndex[intSelectedData] == uc->ContactFilename){
// Select.
lstContacts->SetItemState(longSelected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
lstContacts->EnsureVisible(longSelected);
} else {
lstContacts->SetItemState(longSelected, 0, wxLIST_STATE_SELECTED);
}
}
}
void frmMain::DeleteContact(wxCommandEvent& event){
// Delete a contact from the main window.
// Check if a contact is selected.
long intSelected = -1;
long intContactSeekNum = -1;
wxString wxSContactName;
intSelected = lstContacts->GetNextItem(intSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_SELECTED);
if (intSelected == -1){
return;
}
// Check if the account type is a valid account type, otherwise
// display an error message.
if (ActiveAccountType != "CardDAV" && ActiveAccountType != "carddav" &&
ActiveAccountType != "Local" && ActiveAccountType != "local"){
wxMessageBox(_("Cannot delete contact as the account type is unsupported."), _("Unsupported account type"), wxICON_ERROR);
return;
}
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
// Get the item data of the contact.
intContactSeekNum = lstContacts->GetItemData(intSelected);
// Get the name of the contact.
wxSContactName = lstContacts->GetItemText(intSelected);
// Display a message confirming if the contact should
// be deleted.
int QuestionResponse;
QuestionResponse = wxMessageBox(_("Are you sure you want to delete this contact?"), _("Delete contact"), wxYES_NO, this);
if (QuestionResponse == wxNO){
// Exit the subroutine
return;
}
// Delete the contact.
if (!wxRemoveFile(ContactsFileIndex[intContactSeekNum])){
wxMessageBox(_("Unable to delete the contact."), _("Cannot delete contact"), wxOK, this);
return;
}
// Remove the contact from the list.
lstContacts->DeleteItem(intSelected);
// Update the search windows, removing the deleted
// contact.
UCNotif *ucd = new UCNotif;
ucd->ContactAccount = ActiveAccount;
ucd->ContactFilename = ContactsFileIndex[intContactSeekNum];
for (std::map::iterator switer = SearchWindowList.begin();
switer != SearchWindowList.end(); switer++){
// Duplicate the event notification data.
UCNotif *ucd2 = new UCNotif;
ucd2->ContactAccount = ucd->ContactAccount;
ucd2->ContactFilename = ucd->ContactFilename;
// Pass the data to the search window for processing.
frmSearch *frameSCH = static_cast(switer->first);
wxCommandEvent schdelete(SE_DELETERESULT);
schdelete.SetClientData(ucd2);
wxPostEvent(frameSCH, schdelete);
// Clear up the pointer prior to variable deletion.
frameSCH = NULL;
ucd2 = NULL;
}
// Clear the wxHTMLWindow.
wxString EmptyPage = wxT("");
htmContactData->SetPage(EmptyPage);
wxStringTokenizer wSTFilename(ContactsFileIndex[intContactSeekNum], wxT("/"));
wxString wxSplitFilename;
wxString wxSDataURL;
while(wSTFilename.HasMoreTokens()){
wxSplitFilename = wSTFilename.GetNextToken();
}
if (ActiveAccountType == wxT("CardDAV") || ActiveAccountType == wxT("carddav")){
// Update the ETagDB and mark it as deleted.
ETagDB *ETagDBPtr = ETagProcTimer.GetPointer(ActiveAccount);
ETagDBPtr->UpdateETag(wxSplitFilename, wxT("DELETED"));
// Get the Data URL.
wxTreeItemIdValue cookie;
wxTreeItemId next = treAccounts->GetRootItem();
wxTreeItemId selectedChild = treAccounts->GetSelection();
wxTreeItemId nextChild;
for (int i = 0; i < prefaccounts.GetCount(); i++){
if (!nextChild){
nextChild = treAccounts->GetFirstChild(next, cookie);
} else {
nextChild = treAccounts->GetNextSibling(nextChild);
}
if (nextChild == selectedChild){
wxSDataURL = prefaccounts.GetAccountDirPrefix(i) + wxT("/") + wxSplitFilename;
break;
}
}
// Add task to the activity monitor to delete the contact.
frameActMgr->AddTask(2, wxSContactName, ActiveAccount, wxSDataURL, wxSplitFilename, ContactsFileIndex[intContactSeekNum], wxT(""));
}
// Clear the variable. Don't delete as it will mess things up.
ContactsFileIndex[intContactSeekNum] = wxT("");
delete ucd;
ucd = NULL;
}
void frmMain::EmptyServerDialog(wxCommandEvent& event){
// Display this message when the server information has changed
// and it is empty.
QRNotif *qrn = (QRNotif *)event.GetClientData();
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);
if (QResponse == wxNO){
return;
}
wxCommandEvent event2(ACTMGR_RESUMEPROC);
event2.SetInt(*qrn->QResponse);
event2.SetClientData(qrn->PausePtr);
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
wxPostEvent(frameActMgr, event2);
}
void frmMain::DeleteContactSync(wxString &Account, wxString &Filename){
// Remove the contact from the window after syncronising.
// Check which account is currently active in the window.
// If it is different from the one passed to this subroutine then
// exit from the subroutine.
if (Account != ActiveAccount){
return;
}
long longSelected = -1;
int intSelectedData = 0;
for (;;){
longSelected = lstContacts->GetNextItem(longSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_DONTCARE);
if (longSelected == -1){
break;
}
intSelectedData = (int)lstContacts->GetItemData(longSelected);
// Compare the filename with the one received.
// If they match then select it.
if (ContactsFileIndex[intSelectedData] == Filename){
// Remove the contact from the window.
lstContacts->DeleteItem(intSelectedData);
// Check if contact is the selected contact in the HTML window and
// if it is then clear the window.
if (ActiveFilename == Filename){
wxString EmptyPage = wxT("");
htmContactData->SetPage(EmptyPage);
}
break;
}
}
}
void frmMain::SortFNLN( wxCommandEvent& event ) {
// Sort first name then last name.
wxTreeEvent NullEvent;
SortMode = 1;
LoadContactList(NullEvent);
}
void frmMain::SortLNFN( wxCommandEvent& event ) {
// Sort last name then first name.
wxTreeEvent NullEvent;
SortMode = 2;
LoadContactList(NullEvent);
}
void frmMain::SortNickname( wxCommandEvent& event ) {
// Sort by nickname.
wxTreeEvent NullEvent;
SortMode = 3;
LoadContactList(NullEvent);
}
void frmMain::SortDisplayAs( wxCommandEvent& event ) {
// Sort by Display As name.
wxTreeEvent NullEvent;
SortMode = 4;
LoadContactList(NullEvent);
}
void frmMain::SortAscending( wxCommandEvent& event ) {
// Sort Ascending.
wxTreeEvent NullEvent;
AscendingMode = TRUE;
LoadContactList(NullEvent);
}
void frmMain::SortDescending( wxCommandEvent& event ) {
// Sort Descending.
wxTreeEvent NullEvent;
AscendingMode = FALSE;
LoadContactList(NullEvent);
}
void frmMain::ToggleStatusBar( wxCommandEvent& event ) {
// Toggle the appearance of the status bar.
if (stbBottom->IsShown() == TRUE){
stbBottom->Hide();
} else {
stbBottom->Show();
}
this->Layout();
}
void frmMain::ActivityIconStart( wxCommandEvent& event ){
// Display the activity icon.
imgActivityStatus->SetBitmap(*imgActIcon1);
ActivityIconStatus = 0;
}
void frmMain::ActivityIconShuffle( wxCommandEvent& event ){
// Shuffle through the activity icons.
switch (ActivityIconStatus){
case 0:
imgActivityStatus->SetBitmap(*imgActIcon1);
ActivityIconStatus = 1;
break;
case 1:
imgActivityStatus->SetBitmap(*imgActIcon2);
ActivityIconStatus = 2;
break;
case 2:
imgActivityStatus->SetBitmap(*imgActIcon3);
ActivityIconStatus = 3;
break;
case 3:
imgActivityStatus->SetBitmap(*imgActIcon4);
ActivityIconStatus = 0;
break;
default:
ActivityIconStatus = 0;
}
}
void frmMain::ActivityIconStop( wxCommandEvent& event ){
// Display the sleep icon.
imgActivityStatus->SetBitmap(*imgActIconSleep);
}
void frmMain::UpdateSBIconPlacement( wxSizeEvent& event ){
// Set the placement of the status bar icons.
if (imgConnStatus == 0 || imgSSLStatus == 0 || imgActivityStatus == 0){
return;
}
wxRect rectOnline;
wxRect rectSSL;
wxRect rectActivity;
stbBottom->GetFieldRect(1, rectOnline);
stbBottom->GetFieldRect(2, rectSSL);
stbBottom->GetFieldRect(3, rectActivity);
imgConnStatus->Move(rectOnline.GetX(),rectOnline.GetY());
imgSSLStatus->Move(rectSSL.GetX(),rectSSL.GetY());
imgActivityStatus->Move(rectActivity.GetX(),rectActivity.GetY());
}
XABViewMode frmMain::GetViewMode(){
// Set the view mode of the contact list.
XABViewMode xvm;
xvm.SortMode = SortMode;
xvm.AscendingMode = AscendingMode;
return xvm;
}
void frmMain::WindowAdd( wxCommandEvent &event ){
// Add a window to the window list.
WindowData *WData = (WindowData*)event.GetClientData();
size_t pos;
if (WData->DataType == 0){
// Contact Window
int intID = mnuContactWindows->GetId();
mnuWindow->FindChildItem(intID, &pos);
wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
mnuNewItem->SetId(WData->WindowID);
WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
WindowListType.insert(std::make_pair(WData->WindowID, 0));
mnuWindow->Insert((pos + 1), mnuNewItem);
this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactWindow));
} else if (WData->DataType == 1){
// Contact Editor Window
int intID = mnuContactEditorWindows->GetId();
mnuWindow->FindChildItem(intID, &pos);
wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Contact Editor Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
mnuNewItem->SetId(WData->WindowID);
WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
WindowListType.insert(std::make_pair(WData->WindowID, 1));
mnuWindow->Insert((pos + 1), mnuNewItem);
this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowContactEditorWindow));
} else if (WData->DataType == 2){
// Search Window
int intID = mnuSearchWindows->GetId();
mnuWindow->FindChildItem(intID, &pos);
wxMenuItem *mnuNewItem = new wxMenuItem(NULL, WData->WindowID, wxT("Search Window #") + wxString::Format(wxT("%i"), WData->WindowID), wxEmptyString, wxITEM_NORMAL, NULL);
mnuNewItem->SetId(WData->WindowID);
WindowListPointersMenu.insert(std::make_pair(WData->WindowID, mnuNewItem));
WindowListPointers.insert(std::make_pair(WData->WindowID, WData->WindowPointer));
WindowListType.insert(std::make_pair(WData->WindowID, 2));
mnuWindow->Insert((pos + 1), mnuNewItem);
this->Connect(mnuNewItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(frmMain::ShowSearchWindow));
}
delete WData;
WData = NULL;
}
void frmMain::WindowEdit( wxCommandEvent &event ){
// Edit a window in the window list.
WindowData *WData = (WindowData*)event.GetClientData();
if (WData->DataType == 0){
// Get the window title and use that.
frmContact *frmContactPtr = static_cast(WData->WindowPointer);
wxString WindowTitle = frmContactPtr->GetTitle();
std::map::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
MenuIter->second->SetItemLabel(WindowTitle);
} else if (WData->DataType == 1){
// Get the window title and use that.
frmContactEditor *frmCEPtr = static_cast(WData->WindowPointer);
wxString WindowTitle = frmCEPtr->GetTitle();
std::map::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
if (WindowTitle.IsEmpty()){
MenuIter->second->SetItemLabel(_("Unnamed Contact"));
} else {
MenuIter->second->SetItemLabel(WindowTitle);
}
}
delete WData;
WData = NULL;
}
void frmMain::WindowDelete( wxCommandEvent &event ){
// Delete a window from the window list.
WindowData *WData = (WindowData*)event.GetClientData();
std::map::iterator MenuIter = WindowListPointersMenu.find(WData->WindowID);
mnuWindow->Remove(MenuIter->second);
delete MenuIter->second;
MenuIter->second = NULL;
WindowListPointersMenu.erase(WData->WindowID);
WindowListPointers.erase(WData->WindowID);
WindowListType.erase(WData->WindowID);
delete WData;
WData = NULL;
}
void frmMain::ShowContactWindow( wxCommandEvent &event ){
// Show a contact window from the window list.
std::map::iterator WindowIter = WindowListPointers.find(event.GetId());
frmContact *frmContactPtr = static_cast(WindowIter->second);
frmContactPtr->Show();
frmContactPtr->Raise();
}
void frmMain::ShowContactEditorWindow( wxCommandEvent &event ){
// Show a contact editor window from the window list.
std::map::iterator WindowIter = WindowListPointers.find(event.GetId());
frmContactEditor *frmCEPtr = static_cast(WindowIter->second);
frmCEPtr->Show();
frmCEPtr->Raise();
}
void frmMain::ShowSearchWindow( wxCommandEvent &event ){
// Show a search window from the window list.
std::map::iterator WindowIter = WindowListPointers.find(event.GetId());
frmSearch *frmSearchPtr = static_cast(WindowIter->second);
frmSearchPtr->Show();
frmSearchPtr->Raise();
}
void frmMain::ToggleConnectionStatus( wxCommandEvent &event ){
// Toggle the online/offline connection status.
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
wxCommandEvent toggconn(ACTMGR_TOGGLECONN);
wxPostEvent(frameActMgr, toggconn);
}
void frmMain::ShowSSLCertificates( wxCommandEvent &event ){
// Check the account type before continuing.
wxString SeekAccount;
wxString AccTypeLower;
wxString AccType;
bool AccountSSL;
#if defined(__APPLE__)
std::map::iterator SSLTrustIter;
for (int i = 0; i < prefaccounts.GetCount(); i++){
SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
AccType.Append(prefaccounts.GetAccountType(i));
AccountSSL = prefaccounts.GetAccountSSL(i);
AccTypeLower = AccType.MakeLower();
SeekAccount.Append(wxT("."));
SeekAccount.Append(AccTypeLower);
if (SeekAccount == ActiveAccount){
if (AccTypeLower == wxT("local")){
return;
}
if (AccountSSL == false){
return;
}
SSLTrustIter = AccountTrustData.find(i);
// Setup and display the form.
DisplayCertificate(SSLTrustIter->second);
}
SeekAccount.Clear();
AccTypeLower.Clear();
AccType.clear();
}
#elif defined(__WIN32__)
std::map::iterator SSLCertificateIter;
for (int i = 0; i < prefaccounts.GetCount(); i++){
SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
AccType.Append(prefaccounts.GetAccountType(i));
AccountSSL = prefaccounts.GetAccountSSL(i);
AccTypeLower = AccType.MakeLower();
SeekAccount.Append(wxT("."));
SeekAccount.Append(AccTypeLower);
if (SeekAccount == ActiveAccount){
if (AccTypeLower == wxT("local")){
return;
}
if (AccountSSL == false){
return;
}
SSLCertificateIter = AccountCertificateData.find(i);
// Setup and display the form.
if (SSLCertificateIter->second->pCertInfo == NULL){
wxMessageBox("No certificate information is available due to invalid connection details, connection being in progress or invalid certificate data received.");
} else {
BOOL ModifiedCertificateData;
CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(SSLCertificateIter->second, (HWND)this->GetHandle());
if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
}
}
//DisplayCertificate(SSLTrustIter->second);
}
SeekAccount.Clear();
AccTypeLower.Clear();
AccType.clear();
}
#else
std::map::iterator SSLColIter;
for (int i = 0; i < prefaccounts.GetCount(); i++){
SeekAccount.Append(prefaccounts.GetAccountDirectory(i));
AccType.Append(prefaccounts.GetAccountType(i));
AccountSSL = prefaccounts.GetAccountSSL(i);
AccTypeLower = AccType.MakeLower();
SeekAccount.Append(wxT("."));
SeekAccount.Append(AccTypeLower);
if (SeekAccount == ActiveAccount){
if (AccTypeLower == wxT("local")){
return;
}
if (AccountSSL == false){
return;
}
SSLColIter = AccountSSLData.find(i);
SSLCertCollectionString SSLCertInfo = SSLColIter->second;
frmSSLCertificate *frameSSLCert = new frmSSLCertificate ( this );
frameSSLCert->StartCertFrom(0);
frameSSLCert->SetupCertsString(SSLCertInfo);
frameSSLCert->ShowModal();
delete frameSSLCert;
frameSSLCert = NULL;
}
SeekAccount.Clear();
AccTypeLower.Clear();
AccType.clear();
}
#endif
}
void frmMain::ShowSSLInfo( wxCommandEvent &event ){
// Check the account type before continuing.
}
void frmMain::HideSSLInfo( wxCommandEvent &event ){
// Check the account type before continuing.
}
void frmMain::UpdateConnectionStatus( wxCommandEvent &event ){
if (event.GetInt() == 0){
imgConnStatus->SetBitmap(*imgOnline);
} else {
imgConnStatus->SetBitmap(*imgOffline);
}
}
void frmMain::InvalidSSLCertificate( wxCommandEvent &event ){
// Display the form for showing an invalid SSL certificate.
frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
SSLInvalidCertNotifObj *SSLICNObj = (SSLInvalidCertNotifObj*)event.GetClientData();
SSLCertCollection SSLCCData = SSLICNObj->CertCollection;
wxString AccountName = SSLICNObj->AccountName;
frameISC->LoadData(SSLCCData, AccountName);
frameISC->ShowModal();
int FinalConflictResult = frameISC->GetResult();
wxCommandEvent event2(ACTMGR_RESUMEPROC);
event2.SetClientData(SSLICNObj->QRNotifData);
event2.SetInt(FinalConflictResult);
delete frameISC;
frameISC = NULL;
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
wxPostEvent(frameActMgr, event2);
}
void frmMain::InvalidSSLCertificateString( wxCommandEvent &event ){
// Display the form for showing an invalid SSL certificate.
frmInvalidSSLCertificate *frameISC = new frmInvalidSSLCertificate ( this );
SSLInvalidCertNotifObjString *SSLICNObj = (SSLInvalidCertNotifObjString*)event.GetClientData();
SSLCertCollectionString SSLCCData = SSLICNObj->CertCollection;
wxString AccountName = SSLICNObj->AccountName;
frameISC->LoadData(SSLCCData, AccountName);
frameISC->ShowModal();
int FinalConflictResult = frameISC->GetResult();
wxCommandEvent event2(ACTMGR_RESUMEPROC);
event2.SetClientData(SSLICNObj->QRNotifData);
event2.SetInt(FinalConflictResult);
delete frameISC;
frameISC = NULL;
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
wxPostEvent(frameActMgr, event2);
}
void frmMain::PauseAllTimers(){
// Pause all the account timers.
for (std::map::iterator ASTiter = AccountSyncTimers.begin();
ASTiter != AccountSyncTimers.end(); ASTiter++){
ASTiter->second->Stop();
}
}
void frmMain::ResumeAllTimers(){
// Resume all the account timers.
for (std::map::iterator ASTiter = AccountSyncTimers.begin();
ASTiter != AccountSyncTimers.end(); ASTiter++){
ASTiter->second->Start();
}
}
#if defined(__APPLE__)
#elif defined(__WIN32__)
void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, PCCERT_CONTEXT CertificateContext){
// Delete existing data.
std::map::iterator CertificateIter = AccountCertificateData.find(AccountID);
if (CertificateIter != AccountCertificateData.end()){
CertFreeCertificateContext(CertificateIter->second);
}
AccountCertificateData.erase(AccountID);
AccountSSLResult.erase(AccountID);
// Insert new data.
AccountCertificateData.insert(std::make_pair(AccountID, CertificateContext));
AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
}
#else
void frmMain::UpdateSSLAccountStatus(int AccountID, int SSLStatus, SSLCertCollectionString SSLCertInc){
// Delete existing data.
AccountSSLData.erase(AccountID);
AccountSSLResult.erase(AccountID);
// Insert new data.
AccountSSLData.insert(std::make_pair(AccountID, SSLCertInc));
AccountSSLResult.insert(std::make_pair(AccountID, SSLStatus));
}
#endif
void frmMain::SetupSSLStatus( int AccountID ){
// Check if account ID given is
// the active account and if not, do nothing.
wxString AccType;
wxString AccTypeLower;
AccType = prefaccounts.GetAccountType(AccountID);
AccTypeLower = AccType.MakeLower();
wxString AccountIDName = prefaccounts.GetAccountDirectory(AccountID) + wxT(".") +
AccTypeLower;
if (AccountIDName != ActiveAccount){
return;
}
// Check the account type is a supported account type.
if (AccType != "CardDAV" && AccType != "carddav" &&
AccType != "Local" && AccType != "local"){
SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
imgSSLStatus->SetBitmap(*imgNoSSL);
return;
}
// Check if the account has SSL enabled.
bool SSLInUse = prefaccounts.GetAccountSSL(AccountID);
if (SSLInUse == FALSE){
SSLToolTip->SetTip(wxT("SSL is not enabled for this account"));
imgSSLStatus->SetBitmap(*imgNoSSL);
} else {
// Get the SSL Collection Data.
std::map::iterator SSLResultIter = AccountSSLResult.find(AccountID);
// Check if a result value has been set.
if (SSLResultIter == AccountSSLResult.end()){
imgSSLStatus->SetBitmap(*imgSSLWarning);
SSLToolTip->SetTip(wxT("Unable to determine SSL information for the '") + prefaccounts.GetAccountName(AccountID) + wxT("' account."));
return;
}
if (SSLResultIter->second == 1){
imgSSLStatus->SetBitmap(*imgSSLWarning);
SSLToolTip->SetTip(wxT("Invalid certificate(s) received for '") +
prefaccounts.GetAccountName(AccountID) +
wxT("' (Connection denied by user)\n\nDouble click for more information."));
} else if (SSLResultIter->second == 0){
imgSSLStatus->SetBitmap(*imgSSL);
SSLToolTip->SetTip(wxT("Account '") +
prefaccounts.GetAccountName(AccountID) +
wxT("' secured using SSL\n\nDouble click for more information."));
}
}
}
void frmMain::CheckUpdates( wxCommandEvent& event ){
// Check for updates to Xestia Address Book.
frmUpdate *frameUpdate = new frmUpdate ( this );
frameUpdate->FetchData();
frameUpdate->ShowModal();
}
void frmMain::OpenImportDialog( wxCommandEvent& event ){
// Run the import contacts function.
ImportRun(this);
}
void frmMain::OpenExportDialog( wxCommandEvent& event ){
// Check if an account and at least one contact is selected
// before continuing.
wxArrayString ArrData;
if (ActiveAccount.IsEmpty()){
return;
}
int ContactSelected = 0;
int ContactsCollected = 0;
long longSelected = -1;
for (;;){
longSelected = lstContacts->GetNextItem(longSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_SELECTED);
if (longSelected == -1){
break;
}
int FileID = (int)lstContacts->GetItemData(longSelected);
ArrData.Insert(ContactsFileIndex[FileID],
ContactsCollected, 1);
ContactSelected++;
}
if (ContactSelected == 0){
return;
}
// Run the export contacts system.
ExportRun(this, &ArrData);
}
void frmMain::GetListControl(wxListCtrl *lstContactsPtr,
wxArrayString *ContactsFileIndexPtr){
// Set the list control pointers.
lstContactsPtr = lstContacts;
ContactsFileIndexPtr = &ContactsFileIndex;
}
void frmMain::GetSelectedList( wxCommandEvent& event ){
// Get the array of contact filenames.
wxArrayString *ArrData = (wxArrayString*)event.GetClientData();
// Process them into an array of files.
long longSelected = -1;
int ContactsCollected = 0;
wxString ContactFilename;
for (;;){
longSelected = lstContacts->GetNextItem(longSelected,
wxLIST_NEXT_ALL,
wxLIST_STATE_SELECTED);
if (longSelected == -1){
break;
}
// Get the file information and add to the list.
int FileID = (int)lstContacts->GetItemData(longSelected);
ArrData->Insert(ContactsFileIndex[FileID],
ContactsCollected, 1);
ContactsCollected++;
ContactFilename.Clear();
}
event.SetInt(1);
}
void frmMain::SyncAccount( wxCommandEvent& event ){
// Syncronise the selected account.
wxString AccNameInc = event.GetString();
frmActivityMgr *frameActMgr = static_cast(ActMgrPtr);
frameActMgr->AddTask(3, wxT(""), AccNameInc,
wxT(""), wxT(""), wxT(""), wxT(""));
}
void frmMain::ShowHelp( wxCommandEvent& event ){
// Based on the operating system, work out where
// the documentation should be.
//#ifdef __APPLE__
#if defined(__HAIKU__)
#elif defined(__WIN32__)
#else
if (wxFileExists("/usr/share/doc/xestiaab/index.html")){
wxLaunchDefaultBrowser(wxT("file:///usr/share/doc/xestiaab/index.html"));
return;
#if XSDAB_RELEASE == 0
} else if (wxFileExists("/usr/local/share/doc/xestiaab/index.html")){
wxLaunchDefaultBrowser(wxT("file:///usr/local/share/doc/xestiaab/index.html"));
return;
#endif
}
#endif
#if XSDAB_RELEASE == 0
wxMessageBox(_("The help documentation is not available.\n\nYou can view the documentation that came with your source package."), _("Help documentation missing!"));
#else
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!"));
#endif
}
void frmMain::ShowImportResults( wxCommandEvent &event ){
// Show the results of importing contacts.
std::map *ResultData = (std::map*)event.GetClientData();
frmImportResults *frmIR = new frmImportResults(this);
frmIR->LoadData(ResultData, event.GetInt(), (int)event.GetExtraLong());
frmIR->ShowModal();
delete frmIR;
frmIR = NULL;
delete ResultData;
ResultData = NULL;
}
void frmMain::ReloadContactList( wxCommandEvent &event ){
// Check if the account name given is the current
// account selected.
if (ActiveAccount == event.GetString()){
wxTreeEvent NullEvent;
LoadContactList(NullEvent);
}
}
void frmMain::ShowContactMenu( wxMouseEvent& event ){
// Show the contact menu when a right click occurs
// in the contacts list.
bool EnableRefresh = FALSE;
if (!ActiveAccount.IsEmpty() && (ActiveAccountType == "CardDAV" || ActiveAccountType == "carddav")){
EnableRefresh = TRUE;
}
ContactMenu->SetupPointers(this, lstContacts, EnableRefresh);
this->PopupMenu(ContactMenu->MenuPointer(), wxDefaultPosition);
}
void frmMain::ResetContactInfo(){
// Reset the contact information to an empty page.
wxString EmptyPage = wxT("");
htmContactData->SetPage(EmptyPage);
AccCtrl->SetValue("");
}