1 // frmSearch.cpp - Search form.
3 // (c) 2012-2017 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 application icon.
64 wxMemoryInputStream istream(bigimgs_searchicon_png, sizeof(bigimgs_searchicon_png));
65 wxImage bigimgs_searchiconi(istream, wxBITMAP_TYPE_PNG);
66 wxBitmap searchiconbmp(bigimgs_searchiconi, -1);
68 searchicon.CopyFromBitmap(searchiconbmp);
69 this->SetIcon(searchicon);
71 // Setup the search window.
73 XABSearchPanel *InitPanel = new XABSearchPanel( tabSearch );
74 InitPanel->EnableButtons(TRUE, FALSE);
75 InitPanel->SetupPointers(this);
76 InitPanel->SetupInteger(ScrollGen);
77 szrSearch->Add(InitPanel, 1, wxEXPAND, 0);
78 szrSearch->Fit(tabSearch);
79 SearchFrames.insert(std::make_pair(ScrollGen, InitPanel));
82 // Get the list of accounts and mark them as true.
84 wxString preffilename = GetUserPrefDir();
86 XABPreferences preferences(preffilename);
90 wxString AccDirFullSfx;
92 for (int i = 0; i < preferences.accounts.GetCount(); i++){
93 AccDir = preferences.accounts.GetAccountDirectory(i);
94 AccDirFull = preferences.accounts.GetAccountDirectory(i);
96 AccDirFull.Append(wxT("."));
97 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
98 AccDirFullSfx.LowerCase();
100 AccDirFull.Append(AccDirFullSfx);
101 SearchAccountsPaths.insert(std::make_pair(AccDir, AccDirFull));
102 SearchAccounts.insert(std::make_pair(AccDir, TRUE));
103 SearchAccountsNames.insert(std::make_pair(AccDir,
104 preferences.accounts.GetAccountName(i)));
106 AccDirFullSfx.clear();
110 // Setup the columns.
114 item.SetText(_("Name"));
117 lstResults->InsertColumn(0, item);
120 item.SetText(_("Nickname"));
123 lstResults->InsertColumn(1, item);
126 item.SetText(_("Account"));
129 lstResults->InsertColumn(2, item);
133 void frmSearch::SelectAccounts( wxCommandEvent& event )
136 // Create the form and display as modal.
138 frmSearchAccounts *frameSAccount = new frmSearchAccounts ( this );
139 frameSAccount->LoadSearchAccounts(&SearchAccounts, &SearchAccountsNames);
140 frameSAccount->ShowModal();
141 delete frameSAccount;
142 frameSAccount = NULL;
146 void frmSearch::SearchContacts( wxCommandEvent& event )
149 // Check if any accounts has been selected.
151 bool AccountsFound = false;
153 for (std::map<wxString, bool>::iterator saiter = SearchAccounts.begin();
154 saiter != SearchAccounts.end(); saiter++){
156 if (saiter->second == true){
158 AccountsFound = true;
165 if (AccountsFound == false){
167 wxMessageBox(_("No accounts have been selected to search contacts for."),
168 _("No accounts selected"),
174 // Change the button to stop.
176 if (StopMode == FALSE){
178 // Clear the list of search results.
180 lstResults->DeleteAllItems();
181 SearchResultAccount.clear();
182 SearchResultFilename.clear();
184 // Button clicked on as 'Search'.
186 DisableAllSearchSettings(TRUE);
188 btnSearch->SetLabel(_("Stop"));
190 // Spawn a thread so that searching can proceed
191 // without blocking the GUI (and allow the
192 // search to stop when needed).
194 std::thread SearchThread(&frmSearch::SearchContactsThread, this);
195 SearchThread.detach();
199 // Button clicked on as 'Stop'.
202 btnSearch->SetLabel(_("Search"));
203 DisableAllSearchSettings(FALSE);
209 void frmSearch::ResetContacts( wxCommandEvent& event )
212 // Clear all the search settings.
214 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
215 iter != SearchFrames.end(); ++iter){
217 XABSearchPanel *XABSPPtr;
219 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
220 szrSearch->Detach(XABSPPtr);
222 // Remove the frame from the memory and the list.
227 SearchFrames.erase(iter->first);
231 // Clear the list of search results.
233 lstResults->DeleteAllItems();
235 // Clear the account settings.
237 for (std::map<wxString, bool>::iterator iter = SearchAccounts.begin();
238 iter != SearchAccounts.end(); iter++){
244 // Clear the status bar.
246 wxCommandEvent statusResetEvent (SE_SBUPDATE);
248 wxString *statusReset = new wxString(wxT(""));
250 statusResetEvent.SetClientData(statusReset);
251 wxPostEvent(this, statusResetEvent);
253 // Add a search settings with the default things.
257 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
258 NewPanel->EnableButtons(TRUE, FALSE);
259 NewPanel->SetupPointers(this);
260 NewPanel->SetupInteger(ScrollGen);
261 szrSearch->Add(NewPanel, 1, wxEXPAND, 0);
262 szrSearch->Fit(tabSearch);
263 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
268 void frmSearch::AddSearchSetting( wxCommandEvent& event )
271 // Add a search setting frame to the list.
273 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
274 NewPanel->EnableButtons(TRUE, TRUE);
275 NewPanel->SetupPointers(this);
276 NewPanel->SetupInteger(ScrollGen);
277 szrSearch->Add(NewPanel, 1, wxEXPAND|wxGROW, 5);
278 szrSearch->FitInside(tabSearch);
280 szrSearch->RecalcSizes();
282 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
285 // Check if number of search settings is SEARCHSETTINGS_MAX (or over).
286 // If it is, disable the option of adding extra settings
287 // for all frames until one is removed.
289 XABSearchPanel *XABSPPtr;
291 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
293 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
294 iter != SearchFrames.end(); ++iter){
296 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
298 XABSPPtr->EnableButtons(FALSE, TRUE);
302 } else if (SearchFrames.size() >= 2){
304 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
305 iter != SearchFrames.end(); ++iter){
307 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
309 XABSPPtr->EnableButtons(TRUE, TRUE);
315 //tabSearch->SetScrollbar(wxVERTICAL, 32768, 25, 32768, false);
317 //tabSearch->ScrollToLine(tabSearch->GetLineCount());
321 void frmSearch::RemoveSearchSetting( wxCommandEvent& event )
324 // Remove a search setting frame from the list.
326 // Get the integer from the event.
328 std::map<int,void*>::iterator iter;
329 iter = SearchFrames.find(event.GetInt());
331 XABSearchPanel *XABSPPtr;
332 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
334 szrSearch->Detach(XABSPPtr);
336 // Remove the frame from the memory and the list.
338 SearchFrames.erase(event.GetInt());
343 if (SearchFrames.size() < SEARCHSETTINGS_MAX && SearchFrames.size() > 1){
345 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
346 iter != SearchFrames.end(); ++iter){
348 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
350 XABSPPtr->EnableButtons(TRUE, TRUE);
354 } else if (SearchFrames.size() == 1){
356 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
357 iter != SearchFrames.end(); ++iter){
359 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
361 XABSPPtr->EnableButtons(TRUE, FALSE);
367 szrSearch->FitInside(tabSearch);
369 szrSearch->RecalcSizes();
374 void frmSearch::ReloadAccountList( wxCommandEvent& event ){
376 // Currently unimplemented.
380 void frmSearch::SearchBarUpdate( wxCommandEvent& event ){
382 // Update the status bar.
384 wxString *SBData = (wxString*)event.GetClientData();
386 stbBottom->SetStatusText(*SBData, 0);
393 void frmSearch::SearchFinished( wxCommandEvent& event ){
395 // Reset the search button and unlock the search
399 btnSearch->SetLabel(_("Search"));
400 DisableAllSearchSettings(FALSE);
404 void frmSearch::DisableAllSearchSettings(bool Enable){
406 // Check if there is only one search value. If there is, only enable
407 // the add button if this is the case.
409 if (SearchFrames.size() == 1){
411 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
412 XABSPPtr->EnableButtons(TRUE, FALSE);
417 // Check if there is SEARCHSETTINGS_MAX controls set or more, only
418 // enable the remove button if this is the case.
420 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
422 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
423 siter != SearchFrames.end(); siter++){
425 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
426 XABSPPtr->EnableButtons(FALSE, TRUE);
433 // More than one control, so process them.
435 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
436 siter != SearchFrames.end(); siter++){
438 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(siter->second);
440 if (Enable == FALSE){
442 wxCommandEvent enboxes(XABSP_ENABLECONTROLS);
443 wxPostEvent(XABSPPtr, enboxes);
445 } else if (Enable == TRUE){
447 wxCommandEvent disboxes(XABSP_DISABLECONTROLS);
448 wxPostEvent(XABSPPtr, disboxes);
456 void frmSearch::CloseWindow( wxCloseEvent& event ){
458 // Hide the window so users don't panic
459 // whilst clearing up.
465 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
466 iter != SearchFrames.end(); ++iter){
468 XABSearchPanel *XABSPPtr;
470 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
471 szrSearch->Detach(XABSPPtr);
473 // Remove the frame from the memory and the list.
480 SearchFrames.clear();
484 if (SearchMode == false){
486 WindowData *WData = new WindowData;
489 WData->WindowPointer = this;
490 WData->WindowID = SearchUID;
492 wxCommandEvent delevent(WINDOW_CLOSE);
493 delevent.SetClientData(WData);
494 wxPostEvent(GetParent(), delevent);
496 wxCommandEvent rs(CE_REMOVESEARCH);
497 wxPostEvent(this, rs);
507 void frmSearch::CloseWindow( wxCommandEvent& event ){
509 // Close this window.
515 void frmSearch::SetUID(int UID){
517 // Set the UID of the search window.
523 void frmSearch::SetSearchMode(bool SearchModeIn){
525 // Set the search mode of the window.
527 SearchMode = SearchModeIn;
529 if (SearchMode == TRUE){
531 mnuContactEdit->Enable(FALSE);
532 mnuContactReveal->Enable(FALSE);
534 wxFileSystem::AddHandler(new wxMemoryFSHandler);
537 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
538 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
539 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
541 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
542 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
543 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
545 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
546 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
547 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
549 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
550 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
551 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
553 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
554 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
555 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
557 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
558 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
559 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
563 mnuContactEdit->Enable(TRUE);
564 mnuContactReveal->Enable(TRUE);