// frmSearch.cpp - Search form. // // (c) 2012-2017 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 "frmSearch.h" #define SEARCHSETTINGS_MAX 15 DEFINE_EVENT_TYPE(SE_ADDSEARCHSETTING); DEFINE_EVENT_TYPE(SE_REMOVESEARCHSETTING); DEFINE_EVENT_TYPE(SE_RELOADACCOUNTS); DEFINE_EVENT_TYPE(SE_ADDRESULT); DEFINE_EVENT_TYPE(SE_SBUPDATE); DEFINE_EVENT_TYPE(SE_SEARCHFINISHED); DEFINE_EVENT_TYPE(SE_UPDATERESULT); DEFINE_EVENT_TYPE(SE_DELETERESULT); DEFINE_EVENT_TYPE(SE_OPENCONTACT); DEFINE_EVENT_TYPE(SE_EDITCONTACT); DEFINE_EVENT_TYPE(SE_REVEALCONTACT); BEGIN_EVENT_TABLE(frmSearch, wxFrame) EVT_COMMAND(wxID_ANY, SE_ADDSEARCHSETTING, frmSearch::AddSearchSetting) EVT_COMMAND(wxID_ANY, SE_REMOVESEARCHSETTING, frmSearch::RemoveSearchSetting) EVT_COMMAND(wxID_ANY, SE_RELOADACCOUNTS, frmSearch::ReloadAccountList) EVT_COMMAND(wxID_ANY, SE_ADDRESULT, frmSearch::AddResult) EVT_COMMAND(wxID_ANY, SE_SBUPDATE, frmSearch::SearchBarUpdate) EVT_COMMAND(wxID_ANY, SE_SEARCHFINISHED, frmSearch::SearchFinished) EVT_COMMAND(wxID_ANY, SE_UPDATERESULT, frmSearch::UpdateResult) EVT_COMMAND(wxID_ANY, SE_DELETERESULT, frmSearch::DeleteResult) EVT_COMMAND(wxID_ANY, SE_OPENCONTACT, frmSearch::OpenContact) EVT_COMMAND(wxID_ANY, SE_EDITCONTACT, frmSearch::EditContact) EVT_COMMAND(wxID_ANY, SE_REVEALCONTACT, frmSearch::RevealContact) END_EVENT_TABLE() frmSearch::frmSearch( wxWindow* parent ) : frmSearchADT( parent ) { // Setup the application icon. wxMemoryInputStream istream(bigimgs_searchicon_png, sizeof(bigimgs_searchicon_png)); wxImage bigimgs_searchiconi(istream, wxBITMAP_TYPE_PNG); wxBitmap searchiconbmp(bigimgs_searchiconi, -1); wxIcon searchicon; searchicon.CopyFromBitmap(searchiconbmp); this->SetIcon(searchicon); // Setup the search window. XABSearchPanel *InitPanel = new XABSearchPanel( tabSearch ); InitPanel->EnableButtons(TRUE, FALSE); InitPanel->SetupPointers(this); InitPanel->SetupInteger(ScrollGen); szrSearch->Add(InitPanel, 1, wxEXPAND, 0); szrSearch->Fit(tabSearch); SearchFrames.insert(std::make_pair(ScrollGen, InitPanel)); ScrollGen++; // Get the list of accounts and mark them as true. wxString preffilename = GetUserPrefDir(); XABPreferences preferences(preffilename); wxString AccDir; wxString AccDirFull; wxString AccDirFullSfx; for (int i = 0; i < preferences.accounts.GetCount(); i++){ 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); SearchAccountsPaths.insert(std::make_pair(AccDir, AccDirFull)); SearchAccounts.insert(std::make_pair(AccDir, TRUE)); SearchAccountsNames.insert(std::make_pair(AccDir, preferences.accounts.GetAccountName(i))); AccDirFull.clear(); AccDirFullSfx.clear(); AccDir.clear(); } // Setup the columns. wxListItem item; item.SetId(0); item.SetText(_("Name")); item.SetWidth(228); lstResults->InsertColumn(0, item); item.SetId(1); item.SetText(_("Nickname")); item.SetWidth(128); lstResults->InsertColumn(1, item); item.SetId(2); item.SetText(_("Account")); item.SetWidth(128); lstResults->InsertColumn(2, item); } void frmSearch::SelectAccounts( wxCommandEvent& event ) { // Create the form and display as modal. frmSearchAccounts *frameSAccount = new frmSearchAccounts ( this ); frameSAccount->LoadSearchAccounts(&SearchAccounts, &SearchAccountsNames); frameSAccount->ShowModal(); delete frameSAccount; frameSAccount = NULL; } void frmSearch::SearchContacts( wxCommandEvent& event ) { // Check if any accounts has been selected. bool AccountsFound = false; for (std::map::iterator saiter = SearchAccounts.begin(); saiter != SearchAccounts.end(); saiter++){ if (saiter->second == true){ AccountsFound = true; break; } } if (AccountsFound == false){ wxMessageBox(_("No accounts have been selected to search contacts for."), _("No accounts selected"), wxOK|wxICON_ERROR); return; } // Change the button to stop. if (StopMode == FALSE){ // Clear the list of search results. lstResults->DeleteAllItems(); SearchResultAccount.clear(); SearchResultFilename.clear(); // Button clicked on as 'Search'. DisableAllSearchSettings(TRUE); StopMode = TRUE; btnSearch->SetLabel(_("Stop")); // Spawn a thread so that searching can proceed // without blocking the GUI (and allow the // search to stop when needed). std::thread SearchThread(&frmSearch::SearchContactsThread, this); SearchThread.detach(); } else { // Button clicked on as 'Stop'. StopMode = FALSE; btnSearch->SetLabel(_("Search")); DisableAllSearchSettings(FALSE); } } void frmSearch::ResetContacts( wxCommandEvent& event ) { // Clear all the search settings. for (std::map::iterator iter = SearchFrames.begin(); iter != SearchFrames.end(); ++iter){ XABSearchPanel *XABSPPtr; XABSPPtr = static_cast(iter->second); szrSearch->Detach(XABSPPtr); // Remove the frame from the memory and the list. delete XABSPPtr; XABSPPtr = NULL; SearchFrames.erase(iter->first); } // Clear the list of search results. lstResults->DeleteAllItems(); // Clear the account settings. for (std::map::iterator iter = SearchAccounts.begin(); iter != SearchAccounts.end(); iter++){ iter->second = TRUE; } // Clear the status bar. wxCommandEvent statusResetEvent (SE_SBUPDATE); wxString *statusReset = new wxString(wxT("")); statusResetEvent.SetClientData(statusReset); wxPostEvent(this, statusResetEvent); // Add a search settings with the default things. ScrollGen = 0; XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch ); NewPanel->EnableButtons(TRUE, FALSE); NewPanel->SetupPointers(this); NewPanel->SetupInteger(ScrollGen); szrSearch->Add(NewPanel, 1, wxEXPAND, 0); szrSearch->Fit(tabSearch); SearchFrames.insert(std::make_pair(ScrollGen, NewPanel)); ScrollGen++; } void frmSearch::AddSearchSetting( wxCommandEvent& event ) { // Add a search setting frame to the list. XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch ); NewPanel->EnableButtons(TRUE, TRUE); NewPanel->SetupPointers(this); NewPanel->SetupInteger(ScrollGen); szrSearch->Add(NewPanel, 1, wxEXPAND|wxGROW, 5); szrSearch->FitInside(tabSearch); szrSearch->Layout(); szrSearch->RecalcSizes(); tabSearch->Layout(); SearchFrames.insert(std::make_pair(ScrollGen, NewPanel)); ScrollGen++; // Check if number of search settings is SEARCHSETTINGS_MAX (or over). // If it is, disable the option of adding extra settings // for all frames until one is removed. XABSearchPanel *XABSPPtr; if (SearchFrames.size() >= SEARCHSETTINGS_MAX){ for (std::map::iterator iter = SearchFrames.begin(); iter != SearchFrames.end(); ++iter){ XABSPPtr = static_cast(iter->second); XABSPPtr->EnableButtons(FALSE, TRUE); } } else if (SearchFrames.size() >= 2){ for (std::map::iterator iter = SearchFrames.begin(); iter != SearchFrames.end(); ++iter){ XABSPPtr = static_cast(iter->second); XABSPPtr->EnableButtons(TRUE, TRUE); } } //tabSearch->SetScrollbar(wxVERTICAL, 32768, 25, 32768, false); tabSearch->Update(); //tabSearch->ScrollToLine(tabSearch->GetLineCount()); } void frmSearch::RemoveSearchSetting( wxCommandEvent& event ) { // Remove a search setting frame from the list. // Get the integer from the event. std::map::iterator iter; iter = SearchFrames.find(event.GetInt()); XABSearchPanel *XABSPPtr; XABSPPtr = static_cast(iter->second); szrSearch->Detach(XABSPPtr); // Remove the frame from the memory and the list. SearchFrames.erase(event.GetInt()); delete XABSPPtr; XABSPPtr = NULL; if (SearchFrames.size() < SEARCHSETTINGS_MAX && SearchFrames.size() > 1){ for (std::map::iterator iter = SearchFrames.begin(); iter != SearchFrames.end(); ++iter){ XABSPPtr = static_cast(iter->second); XABSPPtr->EnableButtons(TRUE, TRUE); } } else if (SearchFrames.size() == 1){ for (std::map::iterator iter = SearchFrames.begin(); iter != SearchFrames.end(); ++iter){ XABSPPtr = static_cast(iter->second); XABSPPtr->EnableButtons(TRUE, FALSE); } } szrSearch->FitInside(tabSearch); szrSearch->Layout(); szrSearch->RecalcSizes(); tabSearch->Layout(); } void frmSearch::ReloadAccountList( wxCommandEvent& event ){ // Currently unimplemented. } void frmSearch::SearchBarUpdate( wxCommandEvent& event ){ // Update the status bar. wxString *SBData = (wxString*)event.GetClientData(); stbBottom->SetStatusText(*SBData, 0); delete SBData; SBData = NULL; } void frmSearch::SearchFinished( wxCommandEvent& event ){ // Reset the search button and unlock the search // panel buttons. StopMode = FALSE; btnSearch->SetLabel(_("Search")); DisableAllSearchSettings(FALSE); } void frmSearch::DisableAllSearchSettings(bool Enable){ // Check if there is only one search value. If there is, only enable // the add button if this is the case. if (SearchFrames.size() == 1){ XABSearchPanel *XABSPPtr = static_cast(SearchFrames.begin()->second); XABSPPtr->EnableButtons(TRUE, FALSE); return; } // Check if there is SEARCHSETTINGS_MAX controls set or more, only // enable the remove button if this is the case. if (SearchFrames.size() >= SEARCHSETTINGS_MAX){ for (std::map::iterator siter = SearchFrames.begin(); siter != SearchFrames.end(); siter++){ XABSearchPanel *XABSPPtr = static_cast(SearchFrames.begin()->second); XABSPPtr->EnableButtons(FALSE, TRUE); } return; } // More than one control, so process them. for (std::map::iterator siter = SearchFrames.begin(); siter != SearchFrames.end(); siter++){ XABSearchPanel *XABSPPtr = static_cast(siter->second); if (Enable == FALSE){ wxCommandEvent enboxes(XABSP_ENABLECONTROLS); wxPostEvent(XABSPPtr, enboxes); } else if (Enable == TRUE){ wxCommandEvent disboxes(XABSP_DISABLECONTROLS); wxPostEvent(XABSPPtr, disboxes); } } } void frmSearch::CloseWindow( wxCloseEvent& event ){ // Hide the window so users don't panic // whilst clearing up. this->Hide(); // Clear up. for (std::map::iterator iter = SearchFrames.begin(); iter != SearchFrames.end(); ++iter){ XABSearchPanel *XABSPPtr; XABSPPtr = static_cast(iter->second); szrSearch->Detach(XABSPPtr); // Remove the frame from the memory and the list. delete XABSPPtr; XABSPPtr = NULL; } SearchFrames.clear(); // Close window. if (SearchMode == false){ WindowData *WData = new WindowData; WData->DataType = 2; WData->WindowPointer = this; WData->WindowID = SearchUID; wxCommandEvent delevent(WINDOW_CLOSE); delevent.SetClientData(WData); wxPostEvent(GetParent(), delevent); wxCommandEvent rs(CE_REMOVESEARCH); wxPostEvent(this, rs); WData = NULL; } this->Destroy(); } void frmSearch::CloseWindow( wxCommandEvent& event ){ // Close this window. this->Close(); } void frmSearch::SetUID(int UID){ // Set the UID of the search window. SearchUID = UID; } void frmSearch::SetSearchMode(bool SearchModeIn){ // Set the search mode of the window. SearchMode = SearchModeIn; if (SearchMode == TRUE){ mnuContactEdit->Enable(FALSE); mnuContactReveal->Enable(FALSE); wxFileSystem::AddHandler(new wxMemoryFSHandler); wxImage ciicon_png; 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); } else { mnuContactEdit->Enable(TRUE); mnuContactReveal->Enable(TRUE); } }