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 XABSearchPanel *InitPanel = new XABSearchPanel( tabSearch );
63 InitPanel->EnableButtons(TRUE, FALSE);
64 InitPanel->SetupPointers(this);
65 InitPanel->SetupInteger(ScrollGen);
66 szrSearch->Add(InitPanel, 1, wxEXPAND, 0);
67 szrSearch->Fit(tabSearch);
68 SearchFrames.insert(std::make_pair(ScrollGen, InitPanel));
71 // Get the list of accounts and mark them as true.
73 wxString preffilename = GetUserPrefDir();
75 XABPreferences preferences(preffilename);
79 wxString AccDirFullSfx;
81 for (int i = 0; i < preferences.accounts.GetCount(); i++){
82 AccDir = preferences.accounts.GetAccountDirectory(i);
83 AccDirFull = preferences.accounts.GetAccountDirectory(i);
85 AccDirFull.Append(wxT("."));
86 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
87 AccDirFullSfx.LowerCase();
89 AccDirFull.Append(AccDirFullSfx);
90 SearchAccountsPaths.insert(std::make_pair(AccDir, AccDirFull));
91 SearchAccounts.insert(std::make_pair(AccDir, TRUE));
92 SearchAccountsNames.insert(std::make_pair(AccDir,
93 preferences.accounts.GetAccountName(i)));
95 AccDirFullSfx.clear();
103 item.SetText(_("Name"));
106 lstResults->InsertColumn(0, item);
109 item.SetText(_("Nickname"));
112 lstResults->InsertColumn(1, item);
115 item.SetText(_("Account"));
118 lstResults->InsertColumn(2, item);
122 void frmSearch::SelectAccounts( wxCommandEvent& event )
125 // Create the form and display as modal.
127 frmSearchAccounts *frameSAccount = new frmSearchAccounts ( this );
128 frameSAccount->LoadSearchAccounts(&SearchAccounts, &SearchAccountsNames);
129 frameSAccount->ShowModal();
130 delete frameSAccount;
131 frameSAccount = NULL;
135 void frmSearch::SearchContacts( wxCommandEvent& event )
138 // Check if any accounts has been selected.
140 bool AccountsFound = false;
142 for (std::map<wxString, bool>::iterator saiter = SearchAccounts.begin();
143 saiter != SearchAccounts.end(); saiter++){
145 if (saiter->second == true){
147 AccountsFound = true;
154 if (AccountsFound == false){
156 wxMessageBox(_("No accounts have been selected to search contacts for."),
157 _("No accounts selected"),
163 // Change the button to stop.
165 if (StopMode == FALSE){
167 // Clear the list of search results.
169 lstResults->DeleteAllItems();
170 SearchResultAccount.clear();
171 SearchResultFilename.clear();
173 // Button clicked on as 'Search'.
175 DisableAllSearchSettings(TRUE);
177 btnSearch->SetLabel(_("Stop"));
179 // Spawn a thread so that searching can proceed
180 // without blocking the GUI (and allow the
181 // search to stop when needed).
183 std::thread SearchThread(&frmSearch::SearchContactsThread, this);
184 SearchThread.detach();
188 // Button clicked on as 'Stop'.
191 btnSearch->SetLabel(_("Search"));
192 DisableAllSearchSettings(FALSE);
198 void frmSearch::ResetContacts( wxCommandEvent& event )
201 // Clear all the search settings.
203 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
204 iter != SearchFrames.end(); ++iter){
206 XABSearchPanel *XABSPPtr;
208 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
209 szrSearch->Detach(XABSPPtr);
211 // Remove the frame from the memory and the list.
216 SearchFrames.erase(iter->first);
220 // Clear the list of search results.
222 lstResults->DeleteAllItems();
224 // Clear the account settings.
226 for (std::map<wxString, bool>::iterator iter = SearchAccounts.begin();
227 iter != SearchAccounts.end(); iter++){
233 // Add a search settings with the default things.
237 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
238 NewPanel->EnableButtons(TRUE, FALSE);
239 NewPanel->SetupPointers(this);
240 NewPanel->SetupInteger(ScrollGen);
241 szrSearch->Add(NewPanel, 1, wxEXPAND, 0);
242 szrSearch->Fit(tabSearch);
243 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
248 void frmSearch::AddSearchSetting( wxCommandEvent& event )
251 // Add a search setting frame to the list.
253 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
254 NewPanel->EnableButtons(TRUE, TRUE);
255 NewPanel->SetupPointers(this);
256 NewPanel->SetupInteger(ScrollGen);
257 szrSearch->Add(NewPanel, 1, wxEXPAND|wxGROW, 5);
258 //szrSearch->Fit(tabSearch);
259 szrSearch->FitInside(tabSearch);
261 szrSearch->RecalcSizes();
263 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
266 // Check if number of search settings is SEARCHSETTINGS_MAX (or over).
267 // If it is, disable the option of adding extra settings
268 // for all frames until one is removed.
270 XABSearchPanel *XABSPPtr;
272 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
274 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
275 iter != SearchFrames.end(); ++iter){
277 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
279 XABSPPtr->EnableButtons(FALSE, TRUE);
283 } else if (SearchFrames.size() >= 2){
285 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
286 iter != SearchFrames.end(); ++iter){
288 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
290 XABSPPtr->EnableButtons(TRUE, TRUE);
296 //tabSearch->SetScrollbar(wxVERTICAL, 32768, 25, 32768, false);
298 //tabSearch->ScrollToLine(tabSearch->GetLineCount());
302 void frmSearch::RemoveSearchSetting( wxCommandEvent& event )
305 // Get the integer from the event.
307 std::map<int,void*>::iterator iter;
308 iter = SearchFrames.find(event.GetInt());
310 // Remove a search setting frame from the list.
312 XABSearchPanel *XABSPPtr;
313 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
315 szrSearch->Detach(XABSPPtr);
317 // Remove the frame from the memory and the list.
319 SearchFrames.erase(event.GetInt());
324 //szrSearch->Fit(tabSearch);
326 if (SearchFrames.size() < SEARCHSETTINGS_MAX && SearchFrames.size() > 1){
328 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
329 iter != SearchFrames.end(); ++iter){
331 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
333 XABSPPtr->EnableButtons(TRUE, TRUE);
337 } else if (SearchFrames.size() == 1){
339 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
340 iter != SearchFrames.end(); ++iter){
342 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
344 XABSPPtr->EnableButtons(TRUE, FALSE);
350 szrSearch->FitInside(tabSearch);
352 szrSearch->RecalcSizes();
357 void frmSearch::ReloadAccountList( wxCommandEvent& event ){
359 // Currently unimplemented.
363 void frmSearch::SearchBarUpdate( wxCommandEvent& event ){
365 wxString *SBData = (wxString*)event.GetClientData();
367 stbBottom->SetStatusText(*SBData, 0);
374 void frmSearch::SearchFinished( wxCommandEvent& event ){
377 btnSearch->SetLabel(_("Search"));
378 DisableAllSearchSettings(FALSE);
382 void frmSearch::DisableAllSearchSettings(bool Enable){
384 // Check if there is only one search value. If there is, only enable
385 // the add button if this is the case.
387 if (SearchFrames.size() == 1){
389 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
390 XABSPPtr->EnableButtons(TRUE, FALSE);
395 // Check if there is SEARCHSETTINGS_MAX controls set or more, only
396 // enable the remove button if this is the case.
398 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
400 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
401 siter != SearchFrames.end(); siter++){
403 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
404 XABSPPtr->EnableButtons(FALSE, TRUE);
411 // More than one control, so process them.
413 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
414 siter != SearchFrames.end(); siter++){
416 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(siter->second);
418 if (Enable == FALSE){
420 wxCommandEvent enboxes(XABSP_ENABLECONTROLS);
421 wxPostEvent(XABSPPtr, enboxes);
423 } else if (Enable == TRUE){
425 wxCommandEvent disboxes(XABSP_DISABLECONTROLS);
426 wxPostEvent(XABSPPtr, disboxes);
434 void frmSearch::CloseWindow( wxCloseEvent& event ){
436 // Hide the window so users don't panic
437 // whilst clearing up.
443 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
444 iter != SearchFrames.end(); ++iter){
446 XABSearchPanel *XABSPPtr;
448 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
449 szrSearch->Detach(XABSPPtr);
451 // Remove the frame from the memory and the list.
458 SearchFrames.clear();
462 WindowData *WData = new WindowData;
465 WData->WindowPointer = this;
466 WData->WindowID = SearchUID;
468 wxCommandEvent delevent(WINDOW_CLOSE);
469 delevent.SetClientData(WData);
470 wxPostEvent(GetParent(), delevent);
472 wxCommandEvent rs(CE_REMOVESEARCH);
473 wxPostEvent(this, rs);
481 void frmSearch::CloseWindow( wxCommandEvent& event ){
487 void frmSearch::SetUID(int UID){
493 void frmSearch::SetSearchMode(bool SearchModeIn){
495 SearchMode = SearchModeIn;
497 if (SearchMode == TRUE){
499 mnuContactEdit->Enable(FALSE);
500 mnuContactReveal->Enable(FALSE);
502 wxFileSystem::AddHandler(new wxMemoryFSHandler);
505 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
506 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
507 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
509 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
510 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
511 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
513 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
514 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
515 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
517 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
518 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
519 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
521 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
522 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
523 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
525 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
526 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
527 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
531 mnuContactEdit->Enable(TRUE);
532 mnuContactReveal->Enable(TRUE);