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 // Clear the status bar.
237 wxCommandEvent statusResetEvent (SE_SBUPDATE);
239 wxString *statusReset = new wxString(wxT(""));
241 statusResetEvent.SetClientData(statusReset);
242 wxPostEvent(this, statusResetEvent);
244 // Add a search settings with the default things.
248 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
249 NewPanel->EnableButtons(TRUE, FALSE);
250 NewPanel->SetupPointers(this);
251 NewPanel->SetupInteger(ScrollGen);
252 szrSearch->Add(NewPanel, 1, wxEXPAND, 0);
253 szrSearch->Fit(tabSearch);
254 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
259 void frmSearch::AddSearchSetting( wxCommandEvent& event )
262 // Add a search setting frame to the list.
264 XABSearchPanel *NewPanel = new XABSearchPanel( tabSearch );
265 NewPanel->EnableButtons(TRUE, TRUE);
266 NewPanel->SetupPointers(this);
267 NewPanel->SetupInteger(ScrollGen);
268 szrSearch->Add(NewPanel, 1, wxEXPAND|wxGROW, 5);
269 szrSearch->FitInside(tabSearch);
271 szrSearch->RecalcSizes();
273 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
276 // Check if number of search settings is SEARCHSETTINGS_MAX (or over).
277 // If it is, disable the option of adding extra settings
278 // for all frames until one is removed.
280 XABSearchPanel *XABSPPtr;
282 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
284 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
285 iter != SearchFrames.end(); ++iter){
287 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
289 XABSPPtr->EnableButtons(FALSE, TRUE);
293 } else if (SearchFrames.size() >= 2){
295 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
296 iter != SearchFrames.end(); ++iter){
298 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
300 XABSPPtr->EnableButtons(TRUE, TRUE);
306 //tabSearch->SetScrollbar(wxVERTICAL, 32768, 25, 32768, false);
308 //tabSearch->ScrollToLine(tabSearch->GetLineCount());
312 void frmSearch::RemoveSearchSetting( wxCommandEvent& event )
315 // Remove a search setting frame from the list.
317 // Get the integer from the event.
319 std::map<int,void*>::iterator iter;
320 iter = SearchFrames.find(event.GetInt());
322 XABSearchPanel *XABSPPtr;
323 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
325 szrSearch->Detach(XABSPPtr);
327 // Remove the frame from the memory and the list.
329 SearchFrames.erase(event.GetInt());
334 if (SearchFrames.size() < SEARCHSETTINGS_MAX && SearchFrames.size() > 1){
336 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
337 iter != SearchFrames.end(); ++iter){
339 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
341 XABSPPtr->EnableButtons(TRUE, TRUE);
345 } else if (SearchFrames.size() == 1){
347 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
348 iter != SearchFrames.end(); ++iter){
350 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
352 XABSPPtr->EnableButtons(TRUE, FALSE);
358 szrSearch->FitInside(tabSearch);
360 szrSearch->RecalcSizes();
365 void frmSearch::ReloadAccountList( wxCommandEvent& event ){
367 // Currently unimplemented.
371 void frmSearch::SearchBarUpdate( wxCommandEvent& event ){
373 // Update the status bar.
375 wxString *SBData = (wxString*)event.GetClientData();
377 stbBottom->SetStatusText(*SBData, 0);
384 void frmSearch::SearchFinished( wxCommandEvent& event ){
386 // Reset the search button and unlock the search
390 btnSearch->SetLabel(_("Search"));
391 DisableAllSearchSettings(FALSE);
395 void frmSearch::DisableAllSearchSettings(bool Enable){
397 // Check if there is only one search value. If there is, only enable
398 // the add button if this is the case.
400 if (SearchFrames.size() == 1){
402 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
403 XABSPPtr->EnableButtons(TRUE, FALSE);
408 // Check if there is SEARCHSETTINGS_MAX controls set or more, only
409 // enable the remove button if this is the case.
411 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
413 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
414 siter != SearchFrames.end(); siter++){
416 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
417 XABSPPtr->EnableButtons(FALSE, TRUE);
424 // More than one control, so process them.
426 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
427 siter != SearchFrames.end(); siter++){
429 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(siter->second);
431 if (Enable == FALSE){
433 wxCommandEvent enboxes(XABSP_ENABLECONTROLS);
434 wxPostEvent(XABSPPtr, enboxes);
436 } else if (Enable == TRUE){
438 wxCommandEvent disboxes(XABSP_DISABLECONTROLS);
439 wxPostEvent(XABSPPtr, disboxes);
447 void frmSearch::CloseWindow( wxCloseEvent& event ){
449 // Hide the window so users don't panic
450 // whilst clearing up.
456 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
457 iter != SearchFrames.end(); ++iter){
459 XABSearchPanel *XABSPPtr;
461 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
462 szrSearch->Detach(XABSPPtr);
464 // Remove the frame from the memory and the list.
471 SearchFrames.clear();
475 if (SearchMode == false){
477 WindowData *WData = new WindowData;
480 WData->WindowPointer = this;
481 WData->WindowID = SearchUID;
483 wxCommandEvent delevent(WINDOW_CLOSE);
484 delevent.SetClientData(WData);
485 wxPostEvent(GetParent(), delevent);
487 wxCommandEvent rs(CE_REMOVESEARCH);
488 wxPostEvent(this, rs);
498 void frmSearch::CloseWindow( wxCommandEvent& event ){
500 // Close this window.
506 void frmSearch::SetUID(int UID){
508 // Set the UID of the search window.
514 void frmSearch::SetSearchMode(bool SearchModeIn){
516 // Set the search mode of the window.
518 SearchMode = SearchModeIn;
520 if (SearchMode == TRUE){
522 mnuContactEdit->Enable(FALSE);
523 mnuContactReveal->Enable(FALSE);
525 wxFileSystem::AddHandler(new wxMemoryFSHandler);
528 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
529 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
530 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
532 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
533 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
534 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
536 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
537 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
538 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
540 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
541 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
542 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
544 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
545 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
546 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
548 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
549 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
550 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
554 mnuContactEdit->Enable(TRUE);
555 mnuContactReveal->Enable(TRUE);