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->FitInside(tabSearch);
262 szrSearch->RecalcSizes();
264 SearchFrames.insert(std::make_pair(ScrollGen, NewPanel));
267 // Check if number of search settings is SEARCHSETTINGS_MAX (or over).
268 // If it is, disable the option of adding extra settings
269 // for all frames until one is removed.
271 XABSearchPanel *XABSPPtr;
273 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
275 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
276 iter != SearchFrames.end(); ++iter){
278 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
280 XABSPPtr->EnableButtons(FALSE, TRUE);
284 } else if (SearchFrames.size() >= 2){
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(TRUE, TRUE);
297 //tabSearch->SetScrollbar(wxVERTICAL, 32768, 25, 32768, false);
299 //tabSearch->ScrollToLine(tabSearch->GetLineCount());
303 void frmSearch::RemoveSearchSetting( wxCommandEvent& event )
306 // Remove a search setting frame from the list.
308 // Get the integer from the event.
310 std::map<int,void*>::iterator iter;
311 iter = SearchFrames.find(event.GetInt());
313 XABSearchPanel *XABSPPtr;
314 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
316 szrSearch->Detach(XABSPPtr);
318 // Remove the frame from the memory and the list.
320 SearchFrames.erase(event.GetInt());
325 if (SearchFrames.size() < SEARCHSETTINGS_MAX && SearchFrames.size() > 1){
327 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
328 iter != SearchFrames.end(); ++iter){
330 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
332 XABSPPtr->EnableButtons(TRUE, TRUE);
336 } else if (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, FALSE);
349 szrSearch->FitInside(tabSearch);
351 szrSearch->RecalcSizes();
356 void frmSearch::ReloadAccountList( wxCommandEvent& event ){
358 // Currently unimplemented.
362 void frmSearch::SearchBarUpdate( wxCommandEvent& event ){
364 // Update the status bar.
366 wxString *SBData = (wxString*)event.GetClientData();
368 stbBottom->SetStatusText(*SBData, 0);
375 void frmSearch::SearchFinished( wxCommandEvent& event ){
377 // Reset the search button and unlock the search
381 btnSearch->SetLabel(_("Search"));
382 DisableAllSearchSettings(FALSE);
386 void frmSearch::DisableAllSearchSettings(bool Enable){
388 // Check if there is only one search value. If there is, only enable
389 // the add button if this is the case.
391 if (SearchFrames.size() == 1){
393 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
394 XABSPPtr->EnableButtons(TRUE, FALSE);
399 // Check if there is SEARCHSETTINGS_MAX controls set or more, only
400 // enable the remove button if this is the case.
402 if (SearchFrames.size() >= SEARCHSETTINGS_MAX){
404 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
405 siter != SearchFrames.end(); siter++){
407 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(SearchFrames.begin()->second);
408 XABSPPtr->EnableButtons(FALSE, TRUE);
415 // More than one control, so process them.
417 for (std::map<int, void*>::iterator siter = SearchFrames.begin();
418 siter != SearchFrames.end(); siter++){
420 XABSearchPanel *XABSPPtr = static_cast<XABSearchPanel*>(siter->second);
422 if (Enable == FALSE){
424 wxCommandEvent enboxes(XABSP_ENABLECONTROLS);
425 wxPostEvent(XABSPPtr, enboxes);
427 } else if (Enable == TRUE){
429 wxCommandEvent disboxes(XABSP_DISABLECONTROLS);
430 wxPostEvent(XABSPPtr, disboxes);
438 void frmSearch::CloseWindow( wxCloseEvent& event ){
440 // Hide the window so users don't panic
441 // whilst clearing up.
447 for (std::map<int,void*>::iterator iter = SearchFrames.begin();
448 iter != SearchFrames.end(); ++iter){
450 XABSearchPanel *XABSPPtr;
452 XABSPPtr = static_cast<XABSearchPanel*>(iter->second);
453 szrSearch->Detach(XABSPPtr);
455 // Remove the frame from the memory and the list.
462 SearchFrames.clear();
466 WindowData *WData = new WindowData;
469 WData->WindowPointer = this;
470 WData->WindowID = SearchUID;
472 wxCommandEvent delevent(WINDOW_CLOSE);
473 delevent.SetClientData(WData);
474 wxPostEvent(GetParent(), delevent);
476 wxCommandEvent rs(CE_REMOVESEARCH);
477 wxPostEvent(this, rs);
485 void frmSearch::CloseWindow( wxCommandEvent& event ){
487 // Close this window.
493 void frmSearch::SetUID(int UID){
495 // Set the UID of the search window.
501 void frmSearch::SetSearchMode(bool SearchModeIn){
503 // Set the search mode of the window.
505 SearchMode = SearchModeIn;
507 if (SearchMode == TRUE){
509 mnuContactEdit->Enable(FALSE);
510 mnuContactReveal->Enable(FALSE);
512 wxFileSystem::AddHandler(new wxMemoryFSHandler);
515 wxMemoryInputStream ciptostream(icons_cipto_png, sizeof(icons_cipto_png));
516 ciicon_png.LoadFile(ciptostream, wxBITMAP_TYPE_PNG);
517 wxMemoryFSHandler::AddFile(wxT("cipto.png"), ciicon_png, wxBITMAP_TYPE_PNG);
519 wxMemoryInputStream cilogstream(icons_cilog_png, sizeof(icons_cilog_png));
520 ciicon_png.LoadFile(cilogstream, wxBITMAP_TYPE_PNG);
521 wxMemoryFSHandler::AddFile(wxT("cilog.png"), ciicon_png, wxBITMAP_TYPE_PNG);
523 wxMemoryInputStream cisndstream(icons_cisnd_png, sizeof(icons_cisnd_png));
524 ciicon_png.LoadFile(cisndstream, wxBITMAP_TYPE_PNG);
525 wxMemoryFSHandler::AddFile(wxT("cisnd.png"), ciicon_png, wxBITMAP_TYPE_PNG);
527 wxMemoryInputStream cikeystream(icons_cikey_png, sizeof(icons_cikey_png));
528 ciicon_png.LoadFile(cikeystream, wxBITMAP_TYPE_PNG);
529 wxMemoryFSHandler::AddFile(wxT("cikey.png"), ciicon_png, wxBITMAP_TYPE_PNG);
531 wxMemoryInputStream civenstream(icons_civen_png, sizeof(icons_civen_png));
532 ciicon_png.LoadFile(civenstream, wxBITMAP_TYPE_PNG);
533 wxMemoryFSHandler::AddFile(wxT("civen.png"), ciicon_png, wxBITMAP_TYPE_PNG);
535 wxMemoryInputStream ciextstream(icons_ciext_png, sizeof(icons_ciext_png));
536 ciicon_png.LoadFile(ciextstream, wxBITMAP_TYPE_PNG);
537 wxMemoryFSHandler::AddFile(wxT("ciext.png"), ciicon_png, wxBITMAP_TYPE_PNG);
541 mnuContactEdit->Enable(TRUE);
542 mnuContactReveal->Enable(TRUE);