1 /***************************************************************
2 * Name: ThreadSearchView
3 * Purpose: This class implements the panel that is added to
4 * Code::Blocks Message notebook or C::B layout.
5 * Author: Jerome ANTOINE
6 * Created: 2007-10-08
7 * Copyright: Jerome ANTOINE
8 * License: GPL
9 **************************************************************/
10
11 #include "sdk.h"
12 #include <wx/bitmap.h>
13 #include <wx/bmpbuttn.h>
14 #include <wx/statline.h>
15 #ifndef CB_PRECOMP
16 #include <wx/combobox.h>
17 #include <wx/menu.h>
18 #include <wx/sizer.h>
19 #include <wx/splitter.h>
20 #include <wx/statbox.h>
21 #include <wx/stattext.h>
22 #include <wx/settings.h>
23 #include <wx/toolbar.h>
24
25 #include "cbeditor.h"
26 #include "configmanager.h"
27 #include "editorcolourset.h"
28 #include "infowindow.h"
29 #include "logmanager.h"
30 #endif
31
32 #include "cbstyledtextctrl.h"
33 #include "encodingdetector.h"
34 #include "SearchInPanel.h"
35 #include "DirectoryParamsPanel.h"
36 #include "ThreadSearch.h"
37 #include "ThreadSearchView.h"
38 #include "ThreadSearchEvent.h"
39 #include "ThreadSearchThread.h"
40 #include "ThreadSearchFindData.h"
41 #include "ThreadSearchCommon.h"
42 #include "ThreadSearchConfPanel.h"
43 #include "ThreadSearchControlIds.h"
44 #include "wx/tglbtn.h"
45
46
47 // Max number of items in search history combo box
48 const unsigned int MAX_NB_SEARCH_ITEMS = 20;
49
50 // Timer value for events handling (events sent by worker thread)
51 const int TIMER_PERIOD = 100;
52
53
ThreadSearchView(ThreadSearch & threadSearchPlugin)54 ThreadSearchView::ThreadSearchView(ThreadSearch& threadSearchPlugin)
55 :wxPanel(Manager::Get()->GetAppWindow())
56 ,m_ThreadSearchPlugin(threadSearchPlugin)
57 ,m_Timer(this, controlIDs.Get(ControlIDs::idTmrListCtrlUpdate))
58 ,m_StoppingThread(0)
59 {
60 m_pFindThread = NULL;
61 m_pToolBar = NULL;
62 const wxString &prefix = GetImagePrefix(false, Manager::Get()->GetAppWindow());
63 const double scaleFactor = cbGetContentScaleFactor(*Manager::Get()->GetAppWindow());
64
65 // begin wxGlade: ThreadSearchView::ThreadSearchView
66 m_pSplitter = new wxSplitterWindow(this, -1, wxDefaultPosition, wxSize(1,1), wxSP_3D|wxSP_BORDER|wxSP_PERMIT_UNSPLIT);
67 m_pPnlListLog = new wxPanel(m_pSplitter, -1, wxDefaultPosition, wxSize(1,1));
68 m_pPnlPreview = new wxPanel(m_pSplitter, -1, wxDefaultPosition, wxSize(1,1));
69 m_pSizerSearchDirItems_staticbox = new wxStaticBox(this, -1, _("Directory parameters"));
70 const wxString m_pCboSearchExpr_choices[] = {
71
72 };
73 m_pCboSearchExpr = new wxComboBox(this, controlIDs.Get(ControlIDs::idCboSearchExpr), wxEmptyString,
74 wxDefaultPosition, wxDefaultSize, 0, m_pCboSearchExpr_choices,
75 wxCB_DROPDOWN|wxTE_PROCESS_ENTER);
76 m_pBtnSearch = new wxBitmapButton(this, controlIDs.Get(ControlIDs::idBtnSearch),
77 cbLoadBitmapScaled(prefix + wxT("findf.png"),
78 wxBITMAP_TYPE_PNG, scaleFactor),
79 wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
80 m_pBtnOptions = new wxBitmapButton(this, controlIDs.Get(ControlIDs::idBtnOptions),
81 cbLoadBitmapScaled(prefix + wxT("options.png"),
82 wxBITMAP_TYPE_PNG, scaleFactor),
83 wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
84 m_pStaticLine1 = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL);
85 m_pStaTxtSearchIn = new wxStaticText(this, -1, _("Search in "));
86 m_pPnlSearchIn = new SearchInPanel(this, -1);
87 m_pStaticLine2 = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL);
88 m_pBtnShowDirItems = new wxBitmapButton(this, controlIDs.Get(ControlIDs::idBtnShowDirItemsClick),
89 cbLoadBitmapScaled(prefix + wxT("showdir.png"),
90 wxBITMAP_TYPE_PNG, scaleFactor),
91 wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
92 m_pPnlDirParams = new DirectoryParamsPanel(&threadSearchPlugin.GetFindData(), this, -1);
93 m_pSearchPreview = new cbStyledTextCtrl(m_pPnlPreview, wxID_ANY, wxDefaultPosition, wxSize(1,1));
94 m_pLogger = ThreadSearchLoggerBase::BuildThreadSearchLoggerBase(*this, m_ThreadSearchPlugin,
95 m_ThreadSearchPlugin.GetLoggerType(),
96 m_ThreadSearchPlugin.GetFileSorting(),
97 m_pPnlListLog,
98 controlIDs.Get(ControlIDs::idWndLogger));
99
100 set_properties();
101 do_layout();
102 // end wxGlade
103
104 // Dynamic event connections.
105 // Static events table (BEGIN_EVENT_TABLE) doesn't work for all events
106 long id = m_pSearchPreview->GetId();
107 Connect(id, wxEVT_SCI_MARGINCLICK,
108 (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
109 &ThreadSearchView::OnMarginClick);
110
111 Connect(id, wxEVT_CONTEXT_MENU,
112 (wxObjectEventFunction) (wxEventFunction) (wxContextMenuEventFunction)
113 &ThreadSearchView::OnContextMenu);
114
115 Connect(wxEVT_THREAD_SEARCH_ERROR,
116 (wxObjectEventFunction)&ThreadSearchView::OnThreadSearchErrorEvent);
117 }
118
119
~ThreadSearchView()120 ThreadSearchView::~ThreadSearchView()
121 {
122 if ( m_pFindThread != NULL )
123 {
124 StopThread();
125 }
126
127 // I don't know if it is necessay to remove event connections
128 // so I do it myself
129 long id = m_pSearchPreview->GetId();
130 Disconnect(id, wxEVT_SCI_MARGINCLICK,
131 (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
132 &ThreadSearchView::OnMarginClick);
133
134 Disconnect(id, wxEVT_CONTEXT_MENU,
135 (wxObjectEventFunction) (wxEventFunction) (wxContextMenuEventFunction)
136 &ThreadSearchView::OnContextMenu);
137
138 Disconnect(wxEVT_THREAD_SEARCH_ERROR,
139 (wxObjectEventFunction)&ThreadSearchView::OnThreadSearchErrorEvent);
140
141 m_ThreadSearchPlugin.OnThreadSearchViewDestruction();
142
143 delete m_pLogger;
144 m_pLogger = NULL;
145 }
146
147 // As SearchInPanel and DirectoryParamsPanel are generic, their
148 // events are managed by parent ie this ThreadSearchView class.
149 BEGIN_EVENT_TABLE(ThreadSearchView, wxPanel)
150 // begin wxGlade: ThreadSearchView::event_table
151 EVT_TEXT_ENTER(controlIDs.Get(ControlIDs::idCboSearchExpr), ThreadSearchView::OnCboSearchExprEnter)
152 EVT_TEXT_ENTER(controlIDs.Get(ControlIDs::idSearchDirPath), ThreadSearchView::OnCboSearchExprEnter)
153 EVT_TEXT_ENTER(controlIDs.Get(ControlIDs::idSearchMask), ThreadSearchView::OnCboSearchExprEnter)
154 EVT_BUTTON(controlIDs.Get(ControlIDs::idBtnSearch), ThreadSearchView::OnBtnSearchClick)
155 EVT_BUTTON(controlIDs.Get(ControlIDs::idBtnOptions), ThreadSearchView::OnBtnOptionsClick)
156
157 EVT_MENU(controlIDs.Get(ControlIDs::idOptionDialog), ThreadSearchView::OnShowOptionsDialog)
158 EVT_MENU(controlIDs.Get(ControlIDs::idOptionWholeWord), ThreadSearchView::OnQuickOptions)
159 EVT_MENU(controlIDs.Get(ControlIDs::idOptionStartWord), ThreadSearchView::OnQuickOptions)
160 EVT_MENU(controlIDs.Get(ControlIDs::idOptionMatchCase), ThreadSearchView::OnQuickOptions)
161 EVT_MENU(controlIDs.Get(ControlIDs::idOptionRegEx), ThreadSearchView::OnQuickOptions)
162
163 EVT_UPDATE_UI(controlIDs.Get(ControlIDs::idOptionWholeWord), ThreadSearchView::OnQuickOptionsUpdateUI)
164 EVT_UPDATE_UI(controlIDs.Get(ControlIDs::idOptionStartWord), ThreadSearchView::OnQuickOptionsUpdateUI)
165 EVT_UPDATE_UI(controlIDs.Get(ControlIDs::idOptionMatchCase), ThreadSearchView::OnQuickOptionsUpdateUI)
166 EVT_UPDATE_UI(controlIDs.Get(ControlIDs::idOptionRegEx), ThreadSearchView::OnQuickOptionsUpdateUI)
167
168 EVT_BUTTON(controlIDs.Get(ControlIDs::idBtnShowDirItemsClick), ThreadSearchView::OnBtnShowDirItemsClick)
169 EVT_SPLITTER_DCLICK(-1, ThreadSearchView::OnSplitterDoubleClick)
170 // end wxGlade
171
172 EVT_TOGGLEBUTTON(controlIDs.Get(ControlIDs::idBtnSearchOpenFiles), ThreadSearchView::OnBtnSearchOpenFiles)
173 EVT_TOGGLEBUTTON(controlIDs.Get(ControlIDs::idBtnSearchTargetFiles), ThreadSearchView::OnBtnSearchTargetFiles)
174 EVT_TOGGLEBUTTON(controlIDs.Get(ControlIDs::idBtnSearchProjectFiles), ThreadSearchView::OnBtnSearchProjectFiles)
175 EVT_TOGGLEBUTTON(controlIDs.Get(ControlIDs::idBtnSearchWorkspaceFiles), ThreadSearchView::OnBtnSearchWorkspaceFiles)
176 EVT_TOGGLEBUTTON(controlIDs.Get(ControlIDs::idBtnSearchDirectoryFiles), ThreadSearchView::OnBtnSearchDirectoryFiles)
177
178 EVT_TIMER(controlIDs.Get(ControlIDs::idTmrListCtrlUpdate), ThreadSearchView::OnTmrListCtrlUpdate)
179 END_EVENT_TABLE();
180
181
OnThreadSearchErrorEvent(const ThreadSearchEvent & event)182 void ThreadSearchView::OnThreadSearchErrorEvent(const ThreadSearchEvent& event)
183 {
184 Manager::Get()->GetLogManager()->Log(F(_T("ThreadSearch: %s"), event.GetString().wx_str()));
185 InfoWindow::Display(_("Thread Search Error"), event.GetString());
186 }
187
OnCboSearchExprEnter(wxCommandEvent &)188 void ThreadSearchView::OnCboSearchExprEnter(wxCommandEvent &/*event*/)
189 {
190 // Event handler used when user clicks on enter after typing
191 // in combo box text control.
192 // Runs a multi threaded search.
193 ThreadSearchFindData findData = m_ThreadSearchPlugin.GetFindData();
194 findData.SetFindText(m_pCboSearchExpr->GetValue());
195 ThreadedSearch(findData);
196 }
197
198
OnBtnSearchClick(wxCommandEvent &)199 void ThreadSearchView::OnBtnSearchClick(wxCommandEvent &/*event*/)
200 {
201 // User clicked on Search/Cancel
202 // m_ThreadSearchEventsArray is shared by two threads, we
203 // use m_MutexSearchEventsArray to have a safe access.
204 // As button action depends on m_ThreadSearchEventsArray,
205 // we lock the mutex to process it correctly.
206 if ( m_MutexSearchEventsArray.Lock() == wxMUTEX_NO_ERROR )
207 {
208 int nbEvents = m_ThreadSearchEventsArray.GetCount();
209 m_MutexSearchEventsArray.Unlock();
210 if ( m_pFindThread != NULL )
211 {
212 // A threaded search is running...
213 UpdateSearchButtons(false);
214 StopThread();
215 }
216 else if ( nbEvents > 0 )
217 {
218 // A threaded search has run but the events array is
219 // not completely processed...
220 UpdateSearchButtons(false);
221 if ( ClearThreadSearchEventsArray() == false )
222 {
223 cbMessageBox(_("Failed to clear events array."), _("Error"), wxICON_ERROR);
224 }
225 }
226 else
227 {
228 // We start the thread search
229 ThreadSearchFindData findData = m_ThreadSearchPlugin.GetFindData();
230 findData.SetFindText(m_pCboSearchExpr->GetValue());
231 ThreadedSearch(findData);
232 }
233 }
234 }
235
236
OnBtnOptionsClick(wxCommandEvent &)237 void ThreadSearchView::OnBtnOptionsClick(wxCommandEvent &/*event*/)
238 {
239 wxMenu menu;
240 menu.Append(controlIDs.Get(ControlIDs::idOptionDialog), _("Options"), _("Shows the options dialog"));
241 menu.AppendSeparator();
242 menu.AppendCheckItem(controlIDs.Get(ControlIDs::idOptionWholeWord),
243 _("Whole word"), _("Search text matches only whole words"));
244 menu.AppendCheckItem(controlIDs.Get(ControlIDs::idOptionStartWord),
245 _("Start word"), _("Matches only word starting with search expression"));
246 menu.AppendCheckItem(controlIDs.Get(ControlIDs::idOptionMatchCase), _("Match case"), _("Case sensitive search."));
247 menu.AppendCheckItem(controlIDs.Get(ControlIDs::idOptionRegEx),
248 _("Regular expression"), _("Search expression is a regular expression"));
249
250 PopupMenu(&menu);
251 }
252
OnShowOptionsDialog(wxCommandEvent &)253 void ThreadSearchView::OnShowOptionsDialog(wxCommandEvent &/*event*/)
254 {
255 // Displays a dialog box with a ThreadSearchConfPanel.
256 // All parameters can be set on this dialog.
257 // It is the same as doing 'Settings/environment/Thread search'
258 // Settings are updated by the cbConfigurationDialog
259 cbConfigurationDialog* pDlg = new cbConfigurationDialog(Manager::Get()->GetAppWindow(), -1, _("Options"));
260 ThreadSearchConfPanel* pConfPanel = new ThreadSearchConfPanel(m_ThreadSearchPlugin, pDlg);
261
262 pDlg->AttachConfigurationPanel(pConfPanel);
263 pDlg->ShowModal();
264 pDlg->Destroy();
265 }
266
OnQuickOptions(wxCommandEvent & event)267 void ThreadSearchView::OnQuickOptions(wxCommandEvent &event)
268 {
269 ThreadSearchFindData findData = m_ThreadSearchPlugin.GetFindData();
270 bool hasChange = false;
271 if (event.GetId() == controlIDs.Get(ControlIDs::idOptionWholeWord))
272 {
273 findData.SetMatchWord(event.IsChecked());
274 hasChange = true;
275 }
276 else if (event.GetId() == controlIDs.Get(ControlIDs::idOptionStartWord))
277 {
278 findData.SetStartWord(event.IsChecked());
279 hasChange = true;
280 }
281 else if (event.GetId() == controlIDs.Get(ControlIDs::idOptionMatchCase))
282 {
283 findData.SetMatchCase(event.IsChecked());
284 hasChange = true;
285 }
286 else if (event.GetId() == controlIDs.Get(ControlIDs::idOptionRegEx))
287 {
288 findData.SetRegEx(event.IsChecked());
289 hasChange = true;
290 }
291 if (hasChange)
292 {
293 m_ThreadSearchPlugin.SetFindData(findData);
294 UpdateOptionsButtonImage(findData);
295 }
296 }
297
UpdateOptionsButtonImage(const ThreadSearchFindData & findData)298 void ThreadSearchView::UpdateOptionsButtonImage(const ThreadSearchFindData &findData)
299 {
300 {
301 const wxString name = GetImagePrefix(false, m_pBtnOptions)
302 + (findData.IsOptionEnabled() ? wxT("optionsactive.png") : wxT("options.png"));
303
304 const double scaleFactor = cbGetContentScaleFactor(*m_pBtnOptions);
305 wxBitmap bitmap=cbLoadBitmapScaled(name, wxBITMAP_TYPE_PNG, scaleFactor);
306 m_pBtnOptions->SetBitmapLabel(bitmap);
307 }
308
309 if (m_pToolBar)
310 {
311 const wxString name = GetImagePrefix(true)
312 + (findData.IsOptionEnabled() ? wxT("optionsactive.png") : wxT("options.png"));
313
314 const double scaleFactor = cbGetContentScaleFactor(*m_pToolBar);
315 wxBitmap bitmap=cbLoadBitmapScaled(name, wxBITMAP_TYPE_PNG, scaleFactor);
316 m_pToolBar->SetToolNormalBitmap(controlIDs.Get(ControlIDs::idBtnOptions), bitmap);
317 }
318 }
319
OnQuickOptionsUpdateUI(wxUpdateUIEvent & event)320 void ThreadSearchView::OnQuickOptionsUpdateUI(wxUpdateUIEvent &event)
321 {
322 ThreadSearchFindData &findData = m_ThreadSearchPlugin.GetFindData();
323 if (event.GetId() == controlIDs.Get(ControlIDs::idOptionWholeWord))
324 event.Check(findData.GetMatchWord());
325 else if (event.GetId() == controlIDs.Get(ControlIDs::idOptionStartWord))
326 event.Check(findData.GetStartWord());
327 else if (event.GetId() == controlIDs.Get(ControlIDs::idOptionMatchCase))
328 event.Check(findData.GetMatchCase());
329 else if (event.GetId() == controlIDs.Get(ControlIDs::idOptionRegEx))
330 event.Check(findData.GetRegEx());
331 }
332
OnBtnShowDirItemsClick(wxCommandEvent & WXUNUSED (event))333 void ThreadSearchView::OnBtnShowDirItemsClick(wxCommandEvent& WXUNUSED(event))
334 {
335 // Shows/Hides directory parameters panel and updates button label.
336 wxSizer* pTopSizer = GetSizer();
337 wxASSERT(m_pSizerSearchDirItems && pTopSizer);
338
339 bool show = !m_pPnlDirParams->IsShown();
340 m_ThreadSearchPlugin.SetShowDirControls(show);
341
342 pTopSizer->Show(m_pSizerSearchDirItems, show, true);
343 if ( show == true )
344 {
345 m_pBtnShowDirItems->SetToolTip(_("Hide dir items"));
346 }
347 else
348 {
349 m_pBtnShowDirItems->SetToolTip(_("Show dir items"));
350 }
351 pTopSizer->Layout();
352 }
353
354
OnSplitterDoubleClick(wxSplitterEvent &)355 void ThreadSearchView::OnSplitterDoubleClick(wxSplitterEvent &/*event*/)
356 {
357 m_ThreadSearchPlugin.SetShowCodePreview(false);
358 ApplySplitterSettings(false, m_pSplitter->GetSplitMode());
359
360 // Informs user on how to show code preview later.
361 cbMessageBox(_("To re-enable code preview, check the \"Show code preview editor\" in ThreadSearch options panel."),
362 _("ThreadSearchInfo"), wxICON_INFORMATION);
363 }
364
365 // wxGlade: add ThreadSearchView event handlers
366
367
set_properties()368 void ThreadSearchView::set_properties()
369 {
370 const wxString &prefix = GetImagePrefix(false, this);
371 const double scaleFactor = cbGetContentScaleFactor(*this);
372
373 // begin wxGlade: ThreadSearchView::set_properties
374 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
375 m_pCboSearchExpr->SetMinSize(wxSize(180, -1));
376 m_pBtnSearch->SetToolTip(_("Search in files"));
377 m_pBtnSearch->SetBitmapDisabled(cbLoadBitmapScaled(prefix + wxT("findfdisabled.png"),
378 wxBITMAP_TYPE_PNG, scaleFactor));
379 m_pBtnSearch->SetSize(m_pBtnSearch->GetBestSize());
380 m_pBtnOptions->SetToolTip(_("Options"));
381 m_pBtnOptions->SetBitmapDisabled(cbLoadBitmapScaled(prefix + wxT("optionsdisabled.png"),
382 wxBITMAP_TYPE_PNG, scaleFactor));
383 m_pBtnOptions->SetSize(m_pBtnOptions->GetBestSize());
384 m_pBtnShowDirItems->SetToolTip(_("Show dir Items"));
385 m_pBtnShowDirItems->SetBitmapDisabled(cbLoadBitmapScaled(prefix + wxT("showdirdisabled.png"),
386 wxBITMAP_TYPE_PNG, scaleFactor));
387 m_pBtnShowDirItems->SetSize(m_pBtnShowDirItems->GetBestSize());
388 m_pPnlPreview->SetMinSize(wxSize(25, -1));
389 // end wxGlade
390
391 m_pSearchPreview->SetReadOnly(true);
392
393 ThreadSearchFindData findData;
394 m_ThreadSearchPlugin.GetFindData(findData);
395
396 m_pPnlDirParams->SetSearchDirHidden(findData.GetHiddenSearch());
397 m_pPnlDirParams->SetSearchDirRecursively(findData.GetRecursiveSearch());
398 m_pPnlDirParams->SetSearchDirPath(findData.GetSearchPath());
399 m_pPnlDirParams->SetSearchMask(findData.GetSearchMask());
400
401 m_pPnlSearchIn->SetSearchInOpenFiles(findData.MustSearchInOpenFiles());
402 m_pPnlSearchIn->SetSearchInTargetFiles(findData.MustSearchInTarget());
403 m_pPnlSearchIn->SetSearchInProjectFiles(findData.MustSearchInProject());
404 m_pPnlSearchIn->SetSearchInWorkspaceFiles(findData.MustSearchInWorkspace());
405 m_pPnlSearchIn->SetSearchInDirectory(findData.MustSearchInDirectory());
406
407 UpdateOptionsButtonImage(findData);
408 }
409
410
do_layout()411 void ThreadSearchView::do_layout()
412 {
413 #if wxCHECK_VERSION(3, 0, 0)
414 #define wxADJUST_MINSIZE 0
415 #endif
416 // begin wxGlade: ThreadSearchView::do_layout
417 wxBoxSizer* m_pSizerTop = new wxBoxSizer(wxVERTICAL);
418 wxBoxSizer* m_pSizerSplitter = new wxBoxSizer(wxHORIZONTAL);
419 wxBoxSizer* m_pSizerListLog = new wxBoxSizer(wxHORIZONTAL);
420 wxBoxSizer* m_pSizerSearchPreview = new wxBoxSizer(wxHORIZONTAL);
421 m_pSizerSearchDirItems = new wxStaticBoxSizer(m_pSizerSearchDirItems_staticbox, wxHORIZONTAL);
422 m_pSizerSearchItems = new wxBoxSizer(wxHORIZONTAL);
423 m_pSizerSearchItems->Add(m_pCboSearchExpr, 2, wxALL|wxALIGN_CENTER_VERTICAL|wxADJUST_MINSIZE, 4);
424 m_pSizerSearchItems->Add(m_pBtnSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxADJUST_MINSIZE, 4);
425 m_pSizerSearchItems->Add(m_pBtnOptions, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxADJUST_MINSIZE, 4);
426 m_pSizerSearchItems->Add(m_pStaticLine1, 0, wxLEFT|wxRIGHT|wxEXPAND, 2);
427 m_pSizerSearchItems->Add(m_pStaTxtSearchIn, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxADJUST_MINSIZE, 4);
428 m_pSizerSearchItems->Add(m_pPnlSearchIn, 0, wxALIGN_CENTER_VERTICAL|wxADJUST_MINSIZE, 0);
429 m_pSizerSearchItems->Add(m_pStaticLine2, 0, wxLEFT|wxRIGHT|wxEXPAND, 2);
430 m_pSizerSearchItems->Add(m_pBtnShowDirItems, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxADJUST_MINSIZE, 4);
431 m_pSizerTop->Add(m_pSizerSearchItems, 0, wxEXPAND, 0);
432 m_pSizerSearchDirItems->Add(m_pPnlDirParams, 1, wxALIGN_CENTER_VERTICAL, 0);
433 m_pSizerTop->Add(m_pSizerSearchDirItems, 0, wxBOTTOM|wxEXPAND, 4);
434 m_pSizerSearchPreview->Add(m_pSearchPreview, 1, wxEXPAND|wxADJUST_MINSIZE, 0);
435 m_pPnlPreview->SetAutoLayout(true);
436 m_pPnlPreview->SetSizer(m_pSizerSearchPreview);
437 m_pSizerListLog->Add(m_pLogger->GetWindow(), 1, wxEXPAND|wxFIXED_MINSIZE, 0);
438 m_pPnlListLog->SetAutoLayout(true);
439 m_pPnlListLog->SetSizer(m_pSizerListLog);
440 m_pSplitter->SplitVertically(m_pPnlPreview, m_pPnlListLog);
441 m_pSizerSplitter->Add(m_pSplitter, 1, wxEXPAND|wxADJUST_MINSIZE, 0);
442 m_pSizerTop->Add(m_pSizerSplitter, 1, wxEXPAND, 0);
443 SetAutoLayout(true);
444 SetSizer(m_pSizerTop);
445 m_pSizerTop->Fit(this);
446 m_pSizerTop->SetSizeHints(this);
447 // end wxGlade
448
449 m_pSplitter->SetMinimumPaneSize(50);
450 }
451
452
OnThreadExit()453 void ThreadSearchView::OnThreadExit()
454 {
455 // This method must be called only from ThreadSearchThread::OnExit
456 // because delete is performed in the base class.
457 // We reset the pointer to be sure it is not used.
458 if ( m_pFindThread != NULL )
459 {
460 m_pFindThread = NULL;
461 }
462
463 if ( m_StoppingThread > 0 )
464 {
465 m_StoppingThread--;
466 }
467 }
468
469
ThreadedSearch(const ThreadSearchFindData & aFindData)470 void ThreadSearchView::ThreadedSearch(const ThreadSearchFindData& aFindData)
471 {
472 // We don't search empty patterns
473 if ( aFindData.GetFindText() != wxEmptyString )
474 {
475 ThreadSearchFindData findData(aFindData);
476
477 // Prepares logger
478 m_pLogger->OnSearchBegin(aFindData);
479
480 // Two steps thread creation
481 m_pFindThread = new ThreadSearchThread(this, findData);
482 if ( m_pFindThread != NULL )
483 {
484 if ( m_pFindThread->Create() == wxTHREAD_NO_ERROR )
485 {
486 // Thread execution
487 if ( m_pFindThread->Run() != wxTHREAD_NO_ERROR )
488 {
489 m_pFindThread->Delete();
490 m_pFindThread = NULL;
491 cbMessageBox(_("Failed to run search thread"));
492 }
493 else
494 {
495 // Update combo box search history
496 AddExpressionToSearchCombos(findData.GetFindText(), findData.GetSearchPath(),
497 findData.GetSearchMask());
498 UpdateSearchButtons(true, cancel);
499 EnableControls(false);
500
501 // Starts the timer used to managed events sent by m_pFindThread
502 m_Timer.Start(TIMER_PERIOD, wxTIMER_CONTINUOUS);
503 }
504 }
505 else
506 {
507 // Error
508 m_pFindThread->Delete();
509 m_pFindThread = NULL;
510 cbMessageBox(_("Failed to create search thread (2)"));
511 }
512 }
513 else
514 {
515 // Error
516 cbMessageBox(_("Failed to create search thread (1)"));
517 }
518 }
519 else
520 {
521 // Error
522 cbMessageBox(_("Search expression is empty !"));
523 }
524 }
525
526
UpdatePreview(const wxString & file,long line)527 bool ThreadSearchView::UpdatePreview(const wxString& file, long line)
528 {
529 bool success(true);
530
531 if ( line > 0 )
532 {
533 // Line display begins at 1 but line index at 0
534 line--;
535 }
536
537 // Disable read only
538 m_pSearchPreview->Enable(false);
539 m_pSearchPreview->SetReadOnly(false);
540
541 // Loads file if different from current loaded
542 wxFileName filename(file);
543 if ( (m_PreviewFilePath != file) || (m_PreviewFileDate != filename.GetModificationTime()) )
544 {
545 ConfigManager* mgr = Manager::Get()->GetConfigManager(_T("editor"));
546
547 // Remember current file path and modification time
548 m_PreviewFilePath = file;
549 m_PreviewFileDate = filename.GetModificationTime();
550
551 EncodingDetector enc(m_PreviewFilePath, false);
552 success = enc.IsOK();
553 m_pSearchPreview->SetText(enc.GetWxStr());
554
555 // Colorize
556 cbEditor::ApplyStyles(m_pSearchPreview);
557 EditorColourSet EdColSet;
558 EdColSet.Apply(EdColSet.GetLanguageForFilename(m_PreviewFilePath), m_pSearchPreview, false,
559 true);
560
561 SetFoldingIndicator(mgr->ReadInt(_T("/folding/indicator"), 2));
562 UnderlineFoldedLines(mgr->ReadBool(_T("/folding/underline_folded_line"), true));
563 }
564
565 if ( success == true )
566 {
567 // Display the selected line
568 int onScreen = m_pSearchPreview->LinesOnScreen() >> 1;
569 m_pSearchPreview->GotoLine(line - onScreen);
570 m_pSearchPreview->GotoLine(line + onScreen);
571 m_pSearchPreview->GotoLine(line);
572 m_pSearchPreview->EnsureVisible(line);
573
574 int startPos = m_pSearchPreview->PositionFromLine(line);
575 int endPos = m_pSearchPreview->GetLineEndPosition(line);
576 m_pSearchPreview->SetSelectionVoid(endPos, startPos);
577 }
578
579 // Enable read only
580 m_pSearchPreview->SetReadOnly(true);
581 m_pSearchPreview->Enable(true);
582
583 return success;
584 }
585
586
OnLoggerClick(const wxString & file,long line)587 void ThreadSearchView::OnLoggerClick(const wxString& file, long line)
588 {
589 // Updates preview editor with selected file at requested line.
590 // We don't check that file changed since search was performed.
591 UpdatePreview(file, line);
592 }
593
594
OnLoggerDoubleClick(const wxString & file,long line)595 void ThreadSearchView::OnLoggerDoubleClick(const wxString& file, long line)
596 {
597 cbEditor* ed = Manager::Get()->GetEditorManager()->Open(file);
598 if (!line || !ed)
599 return;
600
601 line -= 1;
602 ed->Activate();
603
604 // cbEditor already implements the line centering
605 ed->GotoLine(line);
606
607 // Show even if line is folded
608 if (cbStyledTextCtrl* control = ed->GetControl()) {
609 control->EnsureVisible(line);
610
611 wxFocusEvent ev(wxEVT_SET_FOCUS);
612 ev.SetWindow(this);
613 #if wxCHECK_VERSION(3, 0, 0)
614 control->GetEventHandler()->AddPendingEvent(ev);
615 #else
616 control->AddPendingEvent(ev);
617 #endif
618 }
619 }
620
OnMarginClick(wxScintillaEvent & event)621 void ThreadSearchView::OnMarginClick(wxScintillaEvent& event)
622 {
623 // We handle click on preview editor margin
624 // For now, all is read only; we manage folding but not
625 // breakpoints and bookmarks.
626 switch (event.GetMargin())
627 {
628 case 2: // folding margin
629 {
630 int lineYpix = event.GetPosition();
631 int line = m_pSearchPreview->LineFromPosition(lineYpix);
632
633 m_pSearchPreview->ToggleFold(line);
634 break;
635 }
636 case 1: // bookmarks and breakpoints margin
637 {
638 // For now I ignore bookmarks and breakpoints
639 /*
640 #define BOOKMARK_MARKER 2
641 int line = m_pSearchPreview->LineFromPosition(event.GetPosition());
642
643 if ( m_pSearchPreview->MarkerGet(line) & (1 << BOOKMARK_MARKER) )
644 {
645 m_pSearchPreview->MarkerDelete(line, BOOKMARK_MARKER);
646 }
647 else
648 {
649 m_pSearchPreview->MarkerAdd(line, BOOKMARK_MARKER);
650 }
651 */
652 break;
653 }
654 default:
655 {
656 break;
657 }
658 }
659 }
660
661
OnContextMenu(wxContextMenuEvent & event)662 void ThreadSearchView::OnContextMenu(wxContextMenuEvent& event)
663 {
664 event.StopPropagation();
665 }
666
667
AddExpressionToSearchCombos(const wxString & expression,const wxString & path,const wxString & mask)668 void ThreadSearchView::AddExpressionToSearchCombos(const wxString& expression, const wxString& path, const wxString& mask)
669 {
670 // We perform tests on view combo and don't check toolbar one
671 // because their contents are identical
672 // Gets toolbar combo pointer
673 const long id = controlIDs.Get(ControlIDs::idCboSearchExpr);
674 wxComboBox* pToolBarCombo = static_cast<wxComboBox*>(m_pToolBar->FindControl(id));
675
676 // Updates combos box with new item
677 // Search item index
678 int index = m_pCboSearchExpr->FindString(expression);
679
680 // Removes item if already in combos box
681 if ( index != wxNOT_FOUND )
682 {
683 m_pCboSearchExpr->Delete(index);
684 pToolBarCombo->Delete(index);
685 }
686
687 // Removes last item if max nb item is reached
688 if ( m_pCboSearchExpr->GetCount() > MAX_NB_SEARCH_ITEMS )
689 {
690 // Removes last one
691 m_pCboSearchExpr->Delete(m_pCboSearchExpr->GetCount()-1);
692 pToolBarCombo->Delete(pToolBarCombo->GetCount()-1);
693 }
694
695 // Adds it to combos
696 m_pCboSearchExpr->Insert(expression, 0);
697 m_pCboSearchExpr->SetSelection(0);
698 pToolBarCombo->Insert(expression, 0);
699 pToolBarCombo->SetSelection(0);
700
701 m_pPnlDirParams->AddExpressionToCombos(path, mask);
702 }
703
704
FocusSearchCombo(const wxString & searchWord)705 void ThreadSearchView::FocusSearchCombo(const wxString &searchWord)
706 {
707 if (!searchWord.empty())
708 m_pCboSearchExpr->SetValue(searchWord);
709 m_pCboSearchExpr->SetFocus();
710 }
711
712
Update()713 void ThreadSearchView::Update()
714 {
715 ThreadSearchFindData findData;
716 m_ThreadSearchPlugin.GetFindData(findData);
717
718 m_pPnlSearchIn->SetSearchInOpenFiles (findData.MustSearchInOpenFiles());
719 m_pPnlSearchIn->SetSearchInTargetFiles (findData.MustSearchInTarget ());
720 m_pPnlSearchIn->SetSearchInProjectFiles (findData.MustSearchInProject ());
721 m_pPnlSearchIn->SetSearchInWorkspaceFiles(findData.MustSearchInWorkspace());
722 m_pPnlSearchIn->SetSearchInDirectory (findData.MustSearchInDirectory());
723
724 m_pPnlDirParams->SetSearchDirHidden (findData.GetHiddenSearch());
725 m_pPnlDirParams->SetSearchDirRecursively (findData.GetRecursiveSearch());
726 m_pPnlDirParams->SetSearchDirPath (findData.GetSearchPath());
727 m_pPnlDirParams->SetSearchMask (findData.GetSearchMask());
728
729 ShowSearchControls(m_ThreadSearchPlugin.GetShowSearchControls());
730 SetLoggerType(m_ThreadSearchPlugin.GetLoggerType());
731 m_pLogger->Update();
732
733 ApplySplitterSettings(m_ThreadSearchPlugin.GetShowCodePreview(), m_ThreadSearchPlugin.GetSplitterMode());
734 }
735
736
OnBtnSearchOpenFiles(wxCommandEvent & event)737 void ThreadSearchView::OnBtnSearchOpenFiles(wxCommandEvent &event)
738 {
739 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeOpenFiles, m_pPnlSearchIn->GetSearchInOpenFiles());
740 event.Skip();
741 }
742
743
OnBtnSearchTargetFiles(wxCommandEvent & event)744 void ThreadSearchView::OnBtnSearchTargetFiles(wxCommandEvent &event)
745 {
746 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeTargetFiles, m_pPnlSearchIn->GetSearchInTargetFiles());
747 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeProjectFiles, false);
748 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeWorkspaceFiles, false);
749 event.Skip();
750 }
751
752
OnBtnSearchProjectFiles(wxCommandEvent & event)753 void ThreadSearchView::OnBtnSearchProjectFiles(wxCommandEvent &event)
754 {
755 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeProjectFiles, m_pPnlSearchIn->GetSearchInProjectFiles());
756 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeTargetFiles, false);
757 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeWorkspaceFiles, false);
758 event.Skip();
759 }
760
761
OnBtnSearchWorkspaceFiles(wxCommandEvent & event)762 void ThreadSearchView::OnBtnSearchWorkspaceFiles(wxCommandEvent &event)
763 {
764 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeWorkspaceFiles, m_pPnlSearchIn->GetSearchInWorkspaceFiles());
765 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeTargetFiles, false);
766 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeProjectFiles, false);
767 event.Skip();
768 }
769
770
OnBtnSearchDirectoryFiles(wxCommandEvent & event)771 void ThreadSearchView::OnBtnSearchDirectoryFiles(wxCommandEvent &event)
772 {
773 m_ThreadSearchPlugin.GetFindData().UpdateSearchScope(ScopeDirectoryFiles, m_pPnlSearchIn->GetSearchInDirectory());
774 event.Skip();
775 }
776
777
EnableControls(bool enable)778 void ThreadSearchView::EnableControls(bool enable)
779 {
780 // Used to disable search parameters controls during
781 // threaded search in notebook panel and toolbar.
782 ControlIDs::IDs idsArray[] = {
783 ControlIDs::idBtnDirSelectClick,
784 ControlIDs::idBtnOptions,
785 ControlIDs::idCboSearchExpr,
786 ControlIDs::idChkSearchDirRecurse,
787 ControlIDs::idChkSearchDirHidden,
788 ControlIDs::idBtnSearchOpenFiles,
789 ControlIDs::idBtnSearchTargetFiles,
790 ControlIDs::idBtnSearchProjectFiles,
791 ControlIDs::idBtnSearchWorkspaceFiles,
792 ControlIDs::idBtnSearchDirectoryFiles,
793 ControlIDs::idSearchDirPath,
794 ControlIDs::idSearchMask
795 };
796
797 ControlIDs::IDs toolBarIdsArray[] = {
798 ControlIDs::idCboSearchExpr
799 };
800
801 for ( unsigned int i = 0; i < sizeof(idsArray)/sizeof(idsArray[0]); ++i )
802 {
803 wxWindow* pWnd = wxWindow::FindWindow(controlIDs.Get(idsArray[i]));
804 if ( pWnd != 0 )
805 {
806 pWnd->Enable(enable);
807 }
808 else
809 {
810 cbMessageBox(wxString::Format(_("Failed to Enable window (id=%ld)"), idsArray[i]).c_str(),
811 _("Error"), wxOK|wxICON_ERROR, this);
812 }
813 }
814
815 for ( unsigned int i = 0; i < sizeof(toolBarIdsArray)/sizeof(toolBarIdsArray[0]); ++i )
816 {
817 m_pToolBar->FindControl(controlIDs.Get(toolBarIdsArray[i]))->Enable(enable);
818 }
819
820 m_pToolBar->EnableTool(controlIDs.Get(ControlIDs::idBtnOptions), enable);
821 m_pToolBar->Update();
822 }
823
824
PostThreadSearchEvent(const ThreadSearchEvent & event)825 void ThreadSearchView::PostThreadSearchEvent(const ThreadSearchEvent& event)
826 {
827 // Clone the worker thread event to the mutex protected m_ThreadSearchEventsArray
828 if ( m_MutexSearchEventsArray.Lock() == wxMUTEX_NO_ERROR )
829 {
830 // Events are handled in ThreadSearchView::OnTmrListCtrlUpdate
831 // ThreadSearchView::OnTmrListCtrlUpdate is called automatically
832 // by m_Timer wxTimer
833 m_ThreadSearchEventsArray.Add(event.Clone());
834 m_MutexSearchEventsArray.Unlock();
835 }
836 }
837
838
OnTmrListCtrlUpdate(wxTimerEvent &)839 void ThreadSearchView::OnTmrListCtrlUpdate(wxTimerEvent& /*event*/)
840 {
841 if ( m_MutexSearchEventsArray.Lock() == wxMUTEX_NO_ERROR )
842 {
843 if ( m_ThreadSearchEventsArray.GetCount() > 0 )
844 {
845 ThreadSearchEvent *pEvent = static_cast<ThreadSearchEvent*>(m_ThreadSearchEventsArray[0]);
846 m_pLogger->OnThreadSearchEvent(*pEvent);
847 delete pEvent;
848 m_ThreadSearchEventsArray.RemoveAt(0,1);
849 }
850
851 if ( (m_ThreadSearchEventsArray.GetCount() == 0) && (m_pFindThread == NULL) )
852 {
853 // Thread search is finished (m_pFindThread == NULL) and m_ThreadSearchEventsArray
854 // is empty (m_ThreadSearchEventsArray.GetCount() == 0).
855 // We stop the timer to spare resources
856 m_Timer.Stop();
857
858 m_pLogger->OnSearchEnd();
859
860 // Restores label and enables all search params graphical widgets.
861 UpdateSearchButtons(true, search);
862 EnableControls(true);
863 }
864
865 m_MutexSearchEventsArray.Unlock();
866 }
867 }
868
869
ClearThreadSearchEventsArray()870 bool ThreadSearchView::ClearThreadSearchEventsArray()
871 {
872 bool success = (m_MutexSearchEventsArray.Lock() == wxMUTEX_NO_ERROR);
873 if ( success == true )
874 {
875 size_t i = m_ThreadSearchEventsArray.GetCount();
876 ThreadSearchEvent* pEvent = NULL;
877 while ( i != 0 )
878 {
879 pEvent = static_cast<ThreadSearchEvent*>(m_ThreadSearchEventsArray[0]);
880 delete pEvent;
881 m_ThreadSearchEventsArray.RemoveAt(0,1);
882 i--;
883 }
884
885 m_MutexSearchEventsArray.Unlock();
886 }
887
888 return success;
889 }
890
891
StopThread()892 bool ThreadSearchView::StopThread()
893 {
894 bool success = false;
895 if ( (m_StoppingThread == 0) && (m_pFindThread != NULL) )
896 {
897 // A search thread is running. We stop it.
898 m_StoppingThread++;
899 m_pFindThread->Delete();
900
901 // We stop the timer responsible for list control update and we wait twice
902 // its period to delete all waiting events (not processed yet)
903 m_Timer.Stop();
904 wxThread::Sleep(2*TIMER_PERIOD);
905
906 success = ClearThreadSearchEventsArray();
907 if ( success == false )
908 {
909 cbMessageBox(_("Failed to clear events array."), _("Error"), wxICON_ERROR);
910 }
911
912 // Restores label and enables all search params graphical widgets.
913 UpdateSearchButtons(true, search);
914 EnableControls(true);
915 }
916
917 return success;
918 }
919
IsSearchRunning()920 bool ThreadSearchView::IsSearchRunning()
921 {
922 bool searchRunning = (m_pFindThread != 0);
923
924 if ( m_MutexSearchEventsArray.Lock() == wxMUTEX_NO_ERROR )
925 {
926 // If user clicked on Cancel or thread is finished, there may be remaining
927 // events to display in the array. In this case, we consider the search is
928 // stil running even if thread is over.
929 searchRunning = searchRunning || (m_ThreadSearchEventsArray.GetCount() > 0);
930 m_MutexSearchEventsArray.Unlock();
931 }
932
933 return searchRunning;
934 }
935
936
UpdateSearchButtons(bool enable,eSearchButtonLabel label)937 void ThreadSearchView::UpdateSearchButtons(bool enable, eSearchButtonLabel label)
938 {
939 // Labels and pictures paths
940 wxString searchButtonLabels[] = {_("Search"), _("Cancel search"), wxEmptyString};
941
942 wxString searchButtonPathsEnabled[] = {wxT("findf.png"),
943 wxT("stop.png") ,
944 wxEmptyString};
945
946 wxString searchButtonPathsDisabled[] = {wxT("findfdisabled.png"),
947 wxT("stopdisabled.png") ,
948 wxEmptyString};
949
950 // Gets toolbar search button pointer
951 // Changes label/bitmap only if requested
952 if (label != skip)
953 {
954 {
955 const wxString &prefix = GetImagePrefix(false, m_pBtnSearch);
956 const double scaleFactor = cbGetContentScaleFactor(*m_pBtnSearch);
957 wxBitmap bmpSearch=cbLoadBitmapScaled(prefix + searchButtonPathsEnabled[label],
958 wxBITMAP_TYPE_PNG, scaleFactor);
959 wxBitmap bmpSearchDisabled=cbLoadBitmapScaled(prefix + searchButtonPathsDisabled[label],
960 wxBITMAP_TYPE_PNG, scaleFactor);
961
962 m_pBtnSearch->SetToolTip(searchButtonLabels[label]);
963 m_pBtnSearch->SetBitmapLabel(bmpSearch);
964 m_pBtnSearch->SetBitmapDisabled(bmpSearchDisabled);
965 }
966
967 {
968 //Toolbar buttons
969 const wxString &prefix = GetImagePrefix(true);
970 const double scaleFactor = cbGetContentScaleFactor(*m_pToolBar);
971 wxBitmap bmpSearch=cbLoadBitmapScaled(prefix + searchButtonPathsEnabled[label],
972 wxBITMAP_TYPE_PNG, scaleFactor);
973 wxBitmap bmpSearchDisabled=cbLoadBitmapScaled(prefix + searchButtonPathsDisabled[label],
974 wxBITMAP_TYPE_PNG, scaleFactor);
975 m_pToolBar->SetToolNormalBitmap(controlIDs.Get(ControlIDs::idBtnSearch), bmpSearch);
976 m_pToolBar->SetToolDisabledBitmap(controlIDs.Get(ControlIDs::idBtnSearch),
977 bmpSearchDisabled);
978 }
979 }
980
981 // Sets enable state
982 m_pBtnSearch->Enable(enable);
983 m_pToolBar->EnableTool(controlIDs.Get(ControlIDs::idBtnSearch), enable);
984 }
985
GetImagePrefix(bool toolbar,wxWindow * window)986 wxString GetImagePrefix(bool toolbar, wxWindow *window)
987 {
988 if (toolbar)
989 {
990 const int size = Manager::Get()->GetImageSize(Manager::UIComponent::Toolbars);
991 return ConfigManager::GetDataFolder()
992 + wxString::Format(wxT("/ThreadSearch.zip#zip:images/%dx%d/"), size, size);
993 }
994 else
995 {
996 cbAssert(window != nullptr);
997 const int targetHeight = floor(16 * cbGetActualContentScaleFactor(*window));
998 const int size = cbFindMinSize16to64(targetHeight);
999 return ConfigManager::GetDataFolder()
1000 + wxString::Format(wxT("/ThreadSearch.zip#zip:images/%dx%d/"), size, size);
1001 }
1002 }
1003
ShowSearchControls(bool show)1004 void ThreadSearchView::ShowSearchControls(bool show)
1005 {
1006 bool redraw = false;
1007 wxSizer* pTopSizer = GetSizer();
1008
1009 // ThreadSearchPlugin update
1010 m_ThreadSearchPlugin.SetShowSearchControls(show);
1011
1012 // We show/hide search controls only if necessary
1013 if ( m_pBtnSearch->IsShown() != show )
1014 {
1015 pTopSizer->Show(m_pSizerSearchItems, show, true);
1016 redraw = true;
1017 }
1018
1019 // When we show search controls, user might have hidden the
1020 // directory search controls to spare space.
1021 // In this case, we restore dir control show state
1022 if ( show == true )
1023 {
1024 show = m_ThreadSearchPlugin.GetShowDirControls();
1025 }
1026
1027 if ( m_pPnlDirParams->IsShown() != show )
1028 {
1029 pTopSizer->Show(m_pSizerSearchDirItems, show, true);
1030 redraw = true;
1031 }
1032
1033 if ( redraw == true )
1034 {
1035 pTopSizer->Layout();
1036 }
1037 }
1038
1039
ApplySplitterSettings(bool showCodePreview,long splitterMode)1040 void ThreadSearchView::ApplySplitterSettings(bool showCodePreview, long splitterMode)
1041 {
1042 if ( showCodePreview == true )
1043 {
1044 if ( (m_pSplitter->IsSplit() == false) || (splitterMode != m_pSplitter->GetSplitMode()) )
1045 {
1046 if ( m_pSplitter->IsSplit() == true ) m_pSplitter->Unsplit();
1047 if ( splitterMode == wxSPLIT_HORIZONTAL )
1048 {
1049 m_pSplitter->SplitHorizontally(m_pPnlListLog, m_pPnlPreview);
1050 }
1051 else
1052 {
1053 m_pSplitter->SplitVertically(m_pPnlPreview, m_pPnlListLog);
1054 }
1055 }
1056 }
1057 else
1058 {
1059 if ( m_pSplitter->IsSplit() == true )
1060 {
1061 m_pSplitter->Unsplit(m_pPnlPreview);
1062 }
1063 }
1064 }
1065
1066
SetLoggerType(ThreadSearchLoggerBase::eLoggerTypes lgrType)1067 void ThreadSearchView::SetLoggerType(ThreadSearchLoggerBase::eLoggerTypes lgrType)
1068 {
1069 if ( lgrType != m_pLogger->GetLoggerType() )
1070 {
1071 delete m_pLogger;
1072 m_pLogger = ThreadSearchLoggerBase::BuildThreadSearchLoggerBase(*this
1073 , m_ThreadSearchPlugin
1074 , lgrType
1075 , m_ThreadSearchPlugin.GetFileSorting()
1076 , m_pPnlListLog
1077 , controlIDs.Get(ControlIDs::idWndLogger));
1078 m_pPnlListLog->GetSizer()->Add(m_pLogger->GetWindow(), 1, wxEXPAND|wxFIXED_MINSIZE, 0);
1079 wxSizer* pTopSizer = m_pPnlListLog->GetSizer();
1080 pTopSizer->Layout();
1081 }
1082 }
1083
1084
SetSashPosition(int position,const bool redraw)1085 void ThreadSearchView::SetSashPosition(int position, const bool redraw)
1086 {
1087 m_pSplitter->SetSashPosition(position, redraw);
1088 }
1089
1090
GetSashPosition() const1091 int ThreadSearchView::GetSashPosition() const
1092 {
1093 return m_pSplitter->GetSashPosition();
1094 }
1095
1096
SetSearchHistory(const wxArrayString & searchPatterns,const wxArrayString & searchDirs,const wxArrayString & searchMasks)1097 void ThreadSearchView::SetSearchHistory(const wxArrayString& searchPatterns, const wxArrayString& searchDirs,
1098 const wxArrayString& searchMasks)
1099 {
1100 m_pCboSearchExpr->Append(searchPatterns);
1101 if ( searchPatterns.GetCount() > 0 )
1102 {
1103 m_pCboSearchExpr->SetSelection(0);
1104 }
1105 m_pPnlDirParams->SetSearchHistory(searchDirs, searchMasks);
1106 }
1107
1108
GetSearchHistory() const1109 wxArrayString ThreadSearchView::GetSearchHistory() const
1110 {
1111 return m_pCboSearchExpr->GetStrings();
1112 }
1113
GetSearchDirsHistory() const1114 wxArrayString ThreadSearchView::GetSearchDirsHistory() const
1115 {
1116 return m_pPnlDirParams->GetSearchDirsHistory();
1117 }
1118
GetSearchMasksHistory() const1119 wxArrayString ThreadSearchView::GetSearchMasksHistory() const
1120 {
1121 return m_pPnlDirParams->GetSearchMasksHistory();
1122 }
1123
1124 // BEGIN Duplicated from cbeditor.cpp to apply folding options
SetMarkerStyle(int marker,int markerType,wxColor fore,wxColor back)1125 void ThreadSearchView::SetMarkerStyle(int marker, int markerType, wxColor fore, wxColor back)
1126 {
1127 m_pSearchPreview->MarkerDefine(marker, markerType);
1128 m_pSearchPreview->MarkerSetForeground(marker, fore);
1129 m_pSearchPreview->MarkerSetBackground(marker, back);
1130 }
1131
1132
UnderlineFoldedLines(bool underline)1133 void ThreadSearchView::UnderlineFoldedLines(bool underline)
1134 {
1135 m_pSearchPreview->SetFoldFlags(underline? 16 : 0);
1136 }
1137
1138
SetFoldingIndicator(int id)1139 void ThreadSearchView::SetFoldingIndicator(int id)
1140 {
1141 //Arrow
1142 if(id == 0)
1143 {
1144 SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_ARROWDOWN, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1145 SetMarkerStyle(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_ARROW, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1146 SetMarkerStyle(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_BACKGROUND, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1147 SetMarkerStyle(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_BACKGROUND, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1148 SetMarkerStyle(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_ARROW, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1149 SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_ARROWDOWN, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1150 SetMarkerStyle(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_BACKGROUND, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1151 }
1152
1153 //Circle
1154 else if(id == 1)
1155 {
1156 SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_CIRCLEMINUS, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1157 SetMarkerStyle(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_CIRCLEPLUS, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1158 SetMarkerStyle(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_VLINE, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1159 SetMarkerStyle(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_LCORNERCURVE, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1160 SetMarkerStyle(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_CIRCLEPLUSCONNECTED, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1161 SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_CIRCLEMINUSCONNECTED, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1162 SetMarkerStyle(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_TCORNER, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1163 }
1164
1165 //Square
1166 else if(id == 2)
1167 {
1168 SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_BOXMINUS, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1169 SetMarkerStyle(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_BOXPLUS, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1170 SetMarkerStyle(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_VLINE, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1171 SetMarkerStyle(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_LCORNER, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1172 SetMarkerStyle(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_BOXPLUSCONNECTED, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1173 SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_BOXMINUSCONNECTED, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1174 SetMarkerStyle(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_TCORNER, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1175 }
1176
1177 //Simple
1178 else if(id == 3)
1179 {
1180 SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_MINUS, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1181 SetMarkerStyle(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_PLUS, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1182 SetMarkerStyle(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_BACKGROUND, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1183 SetMarkerStyle(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_BACKGROUND, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1184 SetMarkerStyle(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_PLUS, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1185 SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_MINUS, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1186 SetMarkerStyle(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_BACKGROUND, wxColor(0xff, 0xff, 0xff), wxColor(0x80, 0x80, 0x80));
1187 }
1188 }
1189 // END Duplicated from cbeditor.cpp to apply folding options
1190