1 // frmSearch.cpp - Search 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/>
19 #include "frmSearch.h"
20 #include "../frmMain.h"
21 #include "../frmContact.h"
22 #include "frmSearchAccounts.h"
23 #include "../common/preferences.h"
24 #include "../common/dirs.h"
25 #include "../vcard/vcard.h"
29 #define SEARCHSETTINGS_MAX 15
31 DEFINE_EVENT_TYPE(SE_ADDSEARCHSETTING);
32 DEFINE_EVENT_TYPE(SE_REMOVESEARCHSETTING);
33 DEFINE_EVENT_TYPE(SE_RELOADACCOUNTS);
34 DEFINE_EVENT_TYPE(SE_ADDRESULT);
35 DEFINE_EVENT_TYPE(SE_SBUPDATE);
36 DEFINE_EVENT_TYPE(SE_SEARCHFINISHED);
37 DEFINE_EVENT_TYPE(SE_UPDATERESULT);
38 DEFINE_EVENT_TYPE(SE_DELETERESULT);
39 DEFINE_EVENT_TYPE(SE_OPENCONTACT);
40 DEFINE_EVENT_TYPE(SE_EDITCONTACT);
41 DEFINE_EVENT_TYPE(SE_REVEALCONTACT);
43 BEGIN_EVENT_TABLE(frmSearch, wxFrame)
44 EVT_COMMAND(wxID_ANY, SE_ADDSEARCHSETTING, frmSearch::AddSearchSetting)
45 EVT_COMMAND(wxID_ANY, SE_REMOVESEARCHSETTING, frmSearch::RemoveSearchSetting)
46 EVT_COMMAND(wxID_ANY, SE_RELOADACCOUNTS, frmSearch::ReloadAccountList)
47 EVT_COMMAND(wxID_ANY, SE_ADDRESULT, frmSearch::AddResult)
48 EVT_COMMAND(wxID_ANY, SE_SBUPDATE, frmSearch::SearchBarUpdate)
49 EVT_COMMAND(wxID_ANY, SE_SEARCHFINISHED, frmSearch::SearchFinished)
50 EVT_COMMAND(wxID_ANY, SE_UPDATERESULT, frmSearch::UpdateResult)
51 EVT_COMMAND(wxID_ANY, SE_DELETERESULT, frmSearch::DeleteResult)
52 EVT_COMMAND(wxID_ANY, SE_OPENCONTACT, frmSearch::OpenContact)
53 EVT_COMMAND(wxID_ANY, SE_EDITCONTACT, frmSearch::EditContact)
54 EVT_COMMAND(wxID_ANY, SE_REVEALCONTACT, frmSearch::RevealContact)
57 frmSearch::frmSearch( wxWindow* parent )
59 frmSearchADT( parent )
62 // Setup the search window.
64 XABSearchPanel *InitPanel = new XABSearchPanel( tabSearch );
65 InitPanel->EnableButtons(TRUE, FALSE);
66 InitPanel->SetupPointers(this);
67 InitPanel->SetupInteger(ScrollGen);
68 szrSearch->Add(InitPanel, 1, wxEXPAND, 0);
69 szrSearch->Fit(tabSearch);
70 SearchFrames.insert(std::make_pair(ScrollGen, InitPanel));
73 // Get the list of accounts and mark them as true.
75 wxString preffilename = GetUserPrefDir();
77 XABPreferences preferences(preffilename);
81 wxString AccDirFullSfx;
83 for (int i = 0; i < preferences.accounts.GetCount(); i++){
84 AccDir = preferences.accounts.GetAccountDirectory(i);
85 AccDirFull = preferences.accounts.GetAccountDirectory(i);
87 AccDirFull.Append(wxT("."));
88 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
89 AccDirFullSfx.LowerCase();
91 AccDirFull.Append(AccDirFullSfx);
92 SearchAccountsPaths.insert(std::make_pair(AccDir, AccDirFull));
93 SearchAccounts.insert(std::make_pair(AccDir, TRUE));
94 SearchAccountsNames.insert(std::make_pair(AccDir,
95 preferences.accounts.GetAccountName(i)));
97 AccDirFullSfx.clear();
101 // Setup the columns.
105 item.SetText(_("Name"));
108 lstResults->InsertColumn(0, item);
111 item.SetText(_("Nickname"));
114 lstResults->InsertColumn(1, item);
117 item.SetText(_("Account"));
120 lstResults->InsertColumn(2, item);
124 void frmSearch::SelectAccounts( wxCommandEvent& event )
127 // Create the form and display as modal.
129 frmSearchAccounts *frameSAccount = new frmSearchAccounts ( this );
130 frameSAccount->LoadSearchAccounts(&SearchAccounts, &SearchAccountsNames);
131 frameSAccount->ShowModal();
132 delete frameSAccount;
133 frameSAccount = NULL;
137 void frmSearch::SearchContacts( wxCommandEvent& event )
140 // Check if any accounts has been selected.
142 bool AccountsFound = false;
144 for (std::map<wxString, bool>::iterator saiter = SearchAccounts.begin();
145 saiter != SearchAccounts.end(); saiter++){
147 if (saiter->second == true){
149 AccountsFound = true;
156 if (AccountsFound == false){
158 wxMessageBox(_("No accounts have been selected to search contacts for."),
159 _("No accounts selected"),
165 // Change the button to stop.
167 if (StopMode == FALSE){
169 // Clear the list of search results.
171 lstResults->DeleteAllItems();
172 SearchResultAccount.clear();
173 SearchResultFilename.clear();
175 // Button clicked on as 'Search'.
177 DisableAllSearchSettings(TRUE);
179 btnSearch->SetLabel(_("Stop"));
181 // Spawn a thread so that searching can proceed
182 // without blocking the GUI (and allow the
183 // search to stop when needed).
185 std::thread SearchThread(&frmSearch::SearchContactsThread, this);
186 SearchThread.detach();
190 // Button clicked on as 'Stop'.
193 btnSearch->SetLabel(_("Search"));
194 DisableAllSearchSettings(FALSE);
200 void frmSearch::ResetContacts( wxCommandEvent& event )
203 // Clear all the search settings.
205 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
206 iter != SearchFrames.end(); ++iter){
208 XABSearchPanel *XABSPPtr;
210 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
211 szrSearch->Detach(XABSPPtr);
213 // Remove the frame from the memory and the list.
218 SearchFrames.erase(iter->first);
222 // Clear the list of search results.
224 lstResults->DeleteAllItems();
226 // Clear the account settings.
228 for (std::map<wxString, bool>::iterator iter = SearchAccounts.begin();
229 iter != SearchAccounts.end(); iter++){
235 // Add a search settings with the default things.
239 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
240 NewPanel->EnableButtons(TRUE, FALSE);
241 NewPanel->SetupPointers(this);
242 NewPanel->SetupInteger(ScrollGen);
243 szrSearch->Add(NewPanel, 1, wxEXPAND, 0);
244 szrSearch->Fit(tabSearch);
245 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
250 void frmSearch::AddSearchSetting( wxCommandEvent& event )
253 // Add a search setting frame to the list.
255 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
256 NewPanel->EnableButtons(TRUE, TRUE);
257 NewPanel->SetupPointers(this);
258 NewPanel->SetupInteger(ScrollGen);
259 szrSearch->Add(NewPanel, 1, wxEXPAND|wxGROW, 5);
260 //szrSearch->Fit(tabSearch);
261 szrSearch->FitInside(tabSearch);
263 szrSearch->RecalcSizes();
265 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
268 // Check if number of search settings is SEARCHSETTINGS_MAX (or over).
269 // If it is, disable the option of adding extra settings
270 // for all frames until one is removed.
272 XABSearchPanel *XABSPPtr;
274 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
276 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
277 iter != SearchFrames.end(); ++iter){
279 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
281 XABSPPtr->EnableButtons(FALSE, TRUE);
285 } else if (SearchFrames.size() >= 2){
287 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
288 iter != SearchFrames.end(); ++iter){
290 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
292 XABSPPtr->EnableButtons(TRUE, TRUE);
298 //tabSearch->SetScrollbar(wxVERTICAL, 32768, 25, 32768, false);
300 //tabSearch->ScrollToLine(tabSearch->GetLineCount());
304 void frmSearch::RemoveSearchSetting( wxCommandEvent& event )
307 // Remove a search setting frame from the list.
309 // Get the integer from the event.
311 std::map<int,void*>::iterator iter;
312 iter = SearchFrames.find(event.GetInt());
314 XABSearchPanel *XABSPPtr;
315 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
317 szrSearch->Detach(XABSPPtr);
319 // Remove the frame from the memory and the list.
321 SearchFrames.erase(event.GetInt());
326 //szrSearch->Fit(tabSearch);
328 if (SearchFrames.size() < SEARCHSETTINGS_MAX && SearchFrames.size() > 1){
330 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
331 iter != SearchFrames.end(); ++iter){
333 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
335 XABSPPtr->EnableButtons(TRUE, TRUE);
339 } else if (SearchFrames.size() == 1){
341 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
342 iter != SearchFrames.end(); ++iter){
344 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
346 XABSPPtr->EnableButtons(TRUE, FALSE);
352 szrSearch->FitInside(tabSearch);
354 szrSearch->RecalcSizes();
359 void frmSearch::ReloadAccountList( wxCommandEvent& event ){
361 // Currently unimplemented.
365 void frmSearch::SearchBarUpdate( wxCommandEvent& event ){
367 // Update the status bar.
369 wxString *SBData = (wxString*)event.GetClientData();
371 stbBottom->SetStatusText(*SBData, 0);
378 void frmSearch::SearchFinished( wxCommandEvent& event ){
380 // Reset the search button and unlock the search
384 btnSearch->SetLabel(_("Search"));
385 DisableAllSearchSettings(FALSE);
389 void frmSearch::DisableAllSearchSettings(bool Enable){
391 // Check if there is only one search value. If there is, only enable
392 // the add button if this is the case.
394 if (SearchFrames.size() == 1){
396 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
397 XABSPPtr->EnableButtons(TRUE, FALSE);
402 // Check if there is SEARCHSETTINGS_MAX controls set or more, only
403 // enable the remove button if this is the case.
405 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
407 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
408 siter != SearchFrames.end(); siter++){
410 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
411 XABSPPtr->EnableButtons(FALSE, TRUE);
418 // More than one control, so process them.
420 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
421 siter != SearchFrames.end(); siter++){
423 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(siter->second);
425 if (Enable == FALSE){
427 wxCommandEvent enboxes(XABSP_ENABLECONTROLS);
428 wxPostEvent(XABSPPtr, enboxes);
430 } else if (Enable == TRUE){
432 wxCommandEvent disboxes(XABSP_DISABLECONTROLS);
433 wxPostEvent(XABSPPtr, disboxes);
441 void frmSearch::CloseWindow( wxCloseEvent& event ){
443 // Hide the window so users don't panic
444 // whilst clearing up.
450 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
451 iter != SearchFrames.end(); ++iter){
453 XABSearchPanel *XABSPPtr;
455 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
456 szrSearch->Detach(XABSPPtr);
458 // Remove the frame from the memory and the list.
465 SearchFrames.clear();
469 WindowData *WData = new WindowData;
472 WData->WindowPointer = this;
473 WData->WindowID = SearchUID;
475 wxCommandEvent delevent(WINDOW_CLOSE);
476 delevent.SetClientData(WData);
477 wxPostEvent(GetParent(), delevent);
479 wxCommandEvent rs(CE_REMOVESEARCH);
480 wxPostEvent(this, rs);
488 void frmSearch::CloseWindow( wxCommandEvent& event ){
490 // Close this window.
496 void frmSearch::SetUID(int UID){
498 // Set the UID of the search window.
504 void frmSearch::SetSearchMode(bool SearchModeIn){
506 // Set the search mode of the window.
508 SearchMode = SearchModeIn;
510 if (SearchMode == TRUE){
512 mnuContactEdit->Enable(FALSE);
513 mnuContactReveal->Enable(FALSE);
515 wxFileSystem::AddHandler(new wxMemoryFSHandler);
518 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
519 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
520 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
522 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
523 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
524 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
526 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
527 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
528 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
530 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
531 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
532 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
534 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
535 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
536 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
538 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
539 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
540 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
544 mnuContactEdit->Enable(TRUE);
545 mnuContactReveal->Enable(TRUE);