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"
22 #define SEARCHSETTINGS_MAX 15
24 DEFINE_EVENT_TYPE(SE_ADDSEARCHSETTING);
25 DEFINE_EVENT_TYPE(SE_REMOVESEARCHSETTING);
26 DEFINE_EVENT_TYPE(SE_RELOADACCOUNTS);
27 DEFINE_EVENT_TYPE(SE_ADDRESULT);
28 DEFINE_EVENT_TYPE(SE_SBUPDATE);
29 DEFINE_EVENT_TYPE(SE_SEARCHFINISHED);
30 DEFINE_EVENT_TYPE(SE_UPDATERESULT);
31 DEFINE_EVENT_TYPE(SE_DELETERESULT);
32 DEFINE_EVENT_TYPE(SE_OPENCONTACT);
33 DEFINE_EVENT_TYPE(SE_EDITCONTACT);
34 DEFINE_EVENT_TYPE(SE_REVEALCONTACT);
36 BEGIN_EVENT_TABLE(frmSearch, wxFrame)
37 EVT_COMMAND(wxID_ANY, SE_ADDSEARCHSETTING, frmSearch::AddSearchSetting)
38 EVT_COMMAND(wxID_ANY, SE_REMOVESEARCHSETTING, frmSearch::RemoveSearchSetting)
39 EVT_COMMAND(wxID_ANY, SE_RELOADACCOUNTS, frmSearch::ReloadAccountList)
40 EVT_COMMAND(wxID_ANY, SE_ADDRESULT, frmSearch::AddResult)
41 EVT_COMMAND(wxID_ANY, SE_SBUPDATE, frmSearch::SearchBarUpdate)
42 EVT_COMMAND(wxID_ANY, SE_SEARCHFINISHED, frmSearch::SearchFinished)
43 EVT_COMMAND(wxID_ANY, SE_UPDATERESULT, frmSearch::UpdateResult)
44 EVT_COMMAND(wxID_ANY, SE_DELETERESULT, frmSearch::DeleteResult)
45 EVT_COMMAND(wxID_ANY, SE_OPENCONTACT, frmSearch::OpenContact)
46 EVT_COMMAND(wxID_ANY, SE_EDITCONTACT, frmSearch::EditContact)
47 EVT_COMMAND(wxID_ANY, SE_REVEALCONTACT, frmSearch::RevealContact)
50 frmSearch::frmSearch( wxWindow* parent )
52 frmSearchADT( parent )
55 // Setup the application icon.
57 wxMemoryInputStream istream(bigimgs_searchicon_png, sizeof(bigimgs_searchicon_png));
58 wxImage bigimgs_searchiconi(istream, wxBITMAP_TYPE_PNG);
59 wxBitmap searchiconbmp(bigimgs_searchiconi, -1);
61 searchicon.CopyFromBitmap(searchiconbmp);
62 this->SetIcon(searchicon);
64 // Setup the search window.
66 XABSearchPanel *InitPanel = new XABSearchPanel( tabSearch );
67 InitPanel->EnableButtons(TRUE, FALSE);
68 InitPanel->SetupPointers(this);
69 InitPanel->SetupInteger(ScrollGen);
70 szrSearch->Add(InitPanel, 1, wxEXPAND, 0);
71 szrSearch->Fit(tabSearch);
72 SearchFrames.insert(std::make_pair(ScrollGen, InitPanel));
75 // Get the list of accounts and mark them as true.
77 wxString preffilename = GetUserPrefDir();
79 XABPreferences preferences(preffilename);
83 wxString AccDirFullSfx;
85 for (int i = 0; i < preferences.accounts.GetCount(); i++){
86 AccDir = preferences.accounts.GetAccountDirectory(i);
87 AccDirFull = preferences.accounts.GetAccountDirectory(i);
89 AccDirFull.Append(wxT("."));
90 AccDirFullSfx.Append(preferences.accounts.GetAccountType(i));
91 AccDirFullSfx.LowerCase();
93 AccDirFull.Append(AccDirFullSfx);
94 SearchAccountsPaths.insert(std::make_pair(AccDir, AccDirFull));
95 SearchAccounts.insert(std::make_pair(AccDir, TRUE));
96 SearchAccountsNames.insert(std::make_pair(AccDir,
97 preferences.accounts.GetAccountName(i)));
99 AccDirFullSfx.clear();
103 // Setup the columns.
107 item.SetText(_("Name"));
110 lstResults->InsertColumn(0, item);
113 item.SetText(_("Nickname"));
116 lstResults->InsertColumn(1, item);
119 item.SetText(_("Account"));
122 lstResults->InsertColumn(2, item);
126 void frmSearch::SelectAccounts( wxCommandEvent& event )
129 // Create the form and display as modal.
131 frmSearchAccounts *frameSAccount = new frmSearchAccounts ( this );
132 frameSAccount->LoadSearchAccounts(&SearchAccounts, &SearchAccountsNames);
133 frameSAccount->ShowModal();
134 delete frameSAccount;
135 frameSAccount = NULL;
139 void frmSearch::SearchContacts( wxCommandEvent& event )
142 // Check if any accounts has been selected.
144 bool AccountsFound = false;
146 for (std::map<wxString, bool>::iterator saiter = SearchAccounts.begin();
147 saiter != SearchAccounts.end(); saiter++){
149 if (saiter->second == true){
151 AccountsFound = true;
158 if (AccountsFound == false){
160 wxMessageBox(_("No accounts have been selected to search contacts for."),
161 _("No accounts selected"),
167 // Change the button to stop.
169 if (StopMode == FALSE){
171 // Clear the list of search results.
173 lstResults->DeleteAllItems();
174 SearchResultAccount.clear();
175 SearchResultFilename.clear();
177 // Button clicked on as 'Search'.
179 DisableAllSearchSettings(TRUE);
181 btnSearch->SetLabel(_("Stop"));
183 // Spawn a thread so that searching can proceed
184 // without blocking the GUI (and allow the
185 // search to stop when needed).
187 std::thread SearchThread(&frmSearch::SearchContactsThread, this);
188 SearchThread.detach();
192 // Button clicked on as 'Stop'.
195 btnSearch->SetLabel(_("Search"));
196 DisableAllSearchSettings(FALSE);
202 void frmSearch::ResetContacts( wxCommandEvent& event )
205 // Clear all the search settings.
207 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
208 iter != SearchFrames.end(); ++iter){
210 XABSearchPanel *XABSPPtr;
212 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
213 szrSearch->Detach(XABSPPtr);
215 // Remove the frame from the memory and the list.
220 SearchFrames.erase(iter->first);
224 // Clear the list of search results.
226 lstResults->DeleteAllItems();
228 // Clear the account settings.
230 for (std::map<wxString, bool>::iterator iter = SearchAccounts.begin();
231 iter != SearchAccounts.end(); iter++){
237 // Clear the status bar.
239 wxCommandEvent statusResetEvent (SE_SBUPDATE);
241 wxString *statusReset = new wxString(wxT(""));
243 statusResetEvent.SetClientData(statusReset);
244 wxPostEvent(this, statusResetEvent);
246 // Add a search settings with the default things.
250 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
251 NewPanel->EnableButtons(TRUE, FALSE);
252 NewPanel->SetupPointers(this);
253 NewPanel->SetupInteger(ScrollGen);
254 szrSearch->Add(NewPanel, 1, wxEXPAND, 0);
255 szrSearch->Fit(tabSearch);
256 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
261 void frmSearch::AddSearchSetting( wxCommandEvent& event )
264 // Add a search setting frame to the list.
266 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
267 NewPanel->EnableButtons(TRUE, TRUE);
268 NewPanel->SetupPointers(this);
269 NewPanel->SetupInteger(ScrollGen);
270 szrSearch->Add(NewPanel, 1, wxEXPAND|wxGROW, 5);
271 szrSearch->FitInside(tabSearch);
273 szrSearch->RecalcSizes();
275 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
278 // Check if number of search settings is SEARCHSETTINGS_MAX (or over).
279 // If it is, disable the option of adding extra settings
280 // for all frames until one is removed.
282 XABSearchPanel *XABSPPtr;
284 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
286 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
287 iter != SearchFrames.end(); ++iter){
289 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
291 XABSPPtr->EnableButtons(FALSE, TRUE);
295 } else if (SearchFrames.size() >= 2){
297 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
298 iter != SearchFrames.end(); ++iter){
300 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
302 XABSPPtr->EnableButtons(TRUE, TRUE);
308 //tabSearch->SetScrollbar(wxVERTICAL, 32768, 25, 32768, false);
310 //tabSearch->ScrollToLine(tabSearch->GetLineCount());
314 void frmSearch::RemoveSearchSetting( wxCommandEvent& event )
317 // Remove a search setting frame from the list.
319 // Get the integer from the event.
321 std::map<int,void*>::iterator iter;
322 iter = SearchFrames.find(event.GetInt());
324 XABSearchPanel *XABSPPtr;
325 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
327 szrSearch->Detach(XABSPPtr);
329 // Remove the frame from the memory and the list.
331 SearchFrames.erase(event.GetInt());
336 if (SearchFrames.size() < SEARCHSETTINGS_MAX && SearchFrames.size() > 1){
338 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
339 iter != SearchFrames.end(); ++iter){
341 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
343 XABSPPtr->EnableButtons(TRUE, TRUE);
347 } else if (SearchFrames.size() == 1){
349 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
350 iter != SearchFrames.end(); ++iter){
352 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
354 XABSPPtr->EnableButtons(TRUE, FALSE);
360 szrSearch->FitInside(tabSearch);
362 szrSearch->RecalcSizes();
367 void frmSearch::ReloadAccountList( wxCommandEvent& event ){
369 // Currently unimplemented.
373 void frmSearch::SearchBarUpdate( wxCommandEvent& event ){
375 // Update the status bar.
377 wxString *SBData = (wxString*)event.GetClientData();
379 stbBottom->SetStatusText(*SBData, 0);
386 void frmSearch::SearchFinished( wxCommandEvent& event ){
388 // Reset the search button and unlock the search
392 btnSearch->SetLabel(_("Search"));
393 DisableAllSearchSettings(FALSE);
397 void frmSearch::DisableAllSearchSettings(bool Enable){
399 // Check if there is only one search value. If there is, only enable
400 // the add button if this is the case.
402 if (SearchFrames.size() == 1){
404 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
405 XABSPPtr->EnableButtons(TRUE, FALSE);
410 // Check if there is SEARCHSETTINGS_MAX controls set or more, only
411 // enable the remove button if this is the case.
413 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
415 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
416 siter != SearchFrames.end(); siter++){
418 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
419 XABSPPtr->EnableButtons(FALSE, TRUE);
426 // More than one control, so process them.
428 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
429 siter != SearchFrames.end(); siter++){
431 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(siter->second);
433 if (Enable == FALSE){
435 wxCommandEvent enboxes(XABSP_ENABLECONTROLS);
436 wxPostEvent(XABSPPtr, enboxes);
438 } else if (Enable == TRUE){
440 wxCommandEvent disboxes(XABSP_DISABLECONTROLS);
441 wxPostEvent(XABSPPtr, disboxes);
449 void frmSearch::CloseWindow( wxCloseEvent& event ){
451 // Hide the window so users don't panic
452 // whilst clearing up.
458 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
459 iter != SearchFrames.end(); ++iter){
461 XABSearchPanel *XABSPPtr;
463 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
464 szrSearch->Detach(XABSPPtr);
466 // Remove the frame from the memory and the list.
473 SearchFrames.clear();
477 if (SearchMode == false){
479 WindowData *WData = new WindowData;
482 WData->WindowPointer = this;
483 WData->WindowID = SearchUID;
485 wxCommandEvent delevent(WINDOW_CLOSE);
486 delevent.SetClientData(WData);
487 wxPostEvent(GetParent(), delevent);
489 wxCommandEvent rs(CE_REMOVESEARCH);
490 wxPostEvent(this, rs);
500 void frmSearch::CloseWindow( wxCommandEvent& event ){
502 // Close this window.
508 void frmSearch::SetUID(int UID){
510 // Set the UID of the search window.
516 void frmSearch::SetSearchMode(bool SearchModeIn){
518 // Set the search mode of the window.
520 SearchMode = SearchModeIn;
522 if (SearchMode == TRUE){
524 mnuContactEdit->Enable(FALSE);
525 mnuContactReveal->Enable(FALSE);
527 wxFileSystem::AddHandler(new wxMemoryFSHandler);
530 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
531 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
532 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
534 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
535 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
536 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
538 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
539 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
540 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
542 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
543 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
544 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
546 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
547 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
548 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
550 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
551 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
552 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
556 mnuContactEdit->Enable(TRUE);
557 mnuContactReveal->Enable(TRUE);