1 /***************************************************************
2 * Name: ThreadSearch
3 * Purpose: ThreadSearch Code::Blocks plugin
4 * Most of the interactions with C::B are handled here.
5 * Author: Jerome ANTOINE
6 * Created: 2007-10-08
7 * Copyright: Jerome ANTOINE
8 * License: GPL
9 **************************************************************/
10
11 #include <sdk.h> // Code::Blocks SDK
12 #ifndef CB_PRECOMP
13 #include <wx/combobox.h>
14 #include <wx/menu.h>
15 #include <wx/toolbar.h>
16 #include <wx/xrc/xmlres.h>
17 #include "cbeditor.h"
18 #include "configmanager.h"
19 #include "sdk_events.h"
20 #endif
21
22 #include "cbstyledtextctrl.h"
23 #include "ThreadSearch.h"
24 #include "ThreadSearchView.h"
25 #include "ThreadSearchCommon.h"
26 #include "ThreadSearchConfPanel.h"
27 #include "ThreadSearchControlIds.h"
28 #include "logging.h" //(pecan 2007/7/26)
29
30 // Register the plugin with Code::Blocks.
31 // We are using an anonymous namespace so we don't litter the global one.
32 namespace
33 {
34 PluginRegistrant<ThreadSearch> reg(_T("ThreadSearch"));
35 }
36
37 // ----------------------------------------------------------------------------
38 // CodeBlocks main.cpp managers all the following UI entries in one routine.
39 // So if only one changes, all will change. Therefore, to enable/disable copy/paste,
40 // we have to capture all the following to see if it really belongs to us
41 int idEditUndo = XRCID("idEditUndo");
42 int idEditRedo = XRCID("idEditRedo");
43 int idEditCopy = XRCID("idEditCopy");
44 int idEditCut = XRCID("idEditCut");
45 int idEditPaste = XRCID("idEditPaste");
46 int idEditSwapHeaderSource = XRCID("idEditSwapHeaderSource");
47 int idEditGotoMatchingBrace = XRCID("idEditGotoMatchingBrace");
48 int idEditBookmarks = XRCID("idEditBookmarks");
49 int idEditBookmarksToggle = XRCID("idEditBookmarksToggle");
50 int idEditBookmarksPrevious = XRCID("idEditBookmarksPrevious");
51 int idEditBookmarksNext = XRCID("idEditBookmarksNext");
52 int idEditFoldAll = XRCID("idEditFoldAll");
53 int idEditUnfoldAll = XRCID("idEditUnfoldAll");
54 int idEditToggleAllFolds = XRCID("idEditToggleAllFolds");
55 int idEditFoldBlock = XRCID("idEditFoldBlock");
56 int idEditUnfoldBlock = XRCID("idEditUnfoldBlock");
57 int idEditToggleFoldBlock = XRCID("idEditToggleFoldBlock");
58 int idEditEOLCRLF = XRCID("idEditEOLCRLF");
59 int idEditEOLCR = XRCID("idEditEOLCR");
60 int idEditEOLLF = XRCID("idEditEOLLF");
61 int idEditEncoding = XRCID("idEditEncoding");
62 int idEditSelectAll = XRCID("idEditSelectAll");
63 int idEditCommentSelected = XRCID("idEditCommentSelected");
64 int idEditUncommentSelected = XRCID("idEditUncommentSelected");
65 int idEditToggleCommentSelected = XRCID("idEditToggleCommentSelected");
66 int idEditAutoComplete = XRCID("idEditAutoComplete");
67 // ----------------------------------------------------------------------------
68
69 int idMenuEditCopy = XRCID("idEditCopy");
70 int idMenuEditPaste = XRCID("idEditPaste");
71
72 // events handling
BEGIN_EVENT_TABLE(ThreadSearch,cbPlugin)73 BEGIN_EVENT_TABLE(ThreadSearch, cbPlugin)
74 // add any events you want to handle here
75 EVT_UPDATE_UI (controlIDs.Get(ControlIDs::idMenuViewThreadSearch), ThreadSearch::OnMnuViewThreadSearchUpdateUI)
76 EVT_MENU (controlIDs.Get(ControlIDs::idMenuViewThreadSearch), ThreadSearch::OnMnuViewThreadSearch)
77 EVT_UPDATE_UI (controlIDs.Get(ControlIDs::idMenuViewFocusThreadSearch), ThreadSearch::OnMnuViewFocusThreadSearchUpdateUI)
78 EVT_MENU (controlIDs.Get(ControlIDs::idMenuViewFocusThreadSearch), ThreadSearch::OnMnuViewFocusThreadSearch)
79 EVT_UPDATE_UI (controlIDs.Get(ControlIDs::idMenuSearchThreadSearch), ThreadSearch::OnMnuSearchThreadSearchUpdateUI)
80 EVT_MENU (controlIDs.Get(ControlIDs::idMenuSearchThreadSearch), ThreadSearch::OnMnuSearchThreadSearch)
81 EVT_MENU (controlIDs.Get(ControlIDs::idMenuCtxThreadSearch), ThreadSearch::OnCtxThreadSearch)
82 EVT_MENU (idMenuEditCopy, ThreadSearch::OnMnuEditCopy)
83 EVT_UPDATE_UI (idMenuEditCopy, ThreadSearch::OnMnuEditCopyUpdateUI)
84 EVT_MENU (idMenuEditPaste, ThreadSearch::OnMnuEditPaste)
85 EVT_TOOL (controlIDs.Get(ControlIDs::idBtnOptions), ThreadSearch::OnBtnOptionsClick)
86 EVT_TOOL (controlIDs.Get(ControlIDs::idBtnSearch), ThreadSearch::OnBtnSearchClick)
87 EVT_TEXT_ENTER(controlIDs.Get(ControlIDs::idCboSearchExpr), ThreadSearch::OnCboSearchExprEnter)
88 EVT_TEXT (controlIDs.Get(ControlIDs::idCboSearchExpr), ThreadSearch::OnCboSearchExprEnter)
89 EVT_TEXT_ENTER(controlIDs.Get(ControlIDs::idSearchDirPath), ThreadSearch::OnCboSearchExprEnter)
90 EVT_TEXT_ENTER(controlIDs.Get(ControlIDs::idSearchMask), ThreadSearch::OnCboSearchExprEnter)
91 // ---------------------------------------------------------------------------
92 // CodeBlocks main.cpp managers all the following UI entires in ONE routine.
93 // So if only one changes, all may change.
94 //Therefore, to enable/disable copy/paste, we have to capture all the following
95 // to see if the event actually belongs to us.
96 EVT_UPDATE_UI(idEditUndo, ThreadSearch::OnMnuEditCopyUpdateUI)
97 EVT_UPDATE_UI(idEditRedo, ThreadSearch::OnMnuEditCopyUpdateUI)
98 EVT_UPDATE_UI(idEditCopy, ThreadSearch::OnMnuEditCopyUpdateUI)
99 EVT_UPDATE_UI(idEditCut, ThreadSearch::OnMnuEditCopyUpdateUI)
100 EVT_UPDATE_UI(idEditPaste, ThreadSearch::OnMnuEditCopyUpdateUI)
101 EVT_UPDATE_UI(idEditSwapHeaderSource, ThreadSearch::OnMnuEditCopyUpdateUI)
102 EVT_UPDATE_UI(idEditGotoMatchingBrace, ThreadSearch::OnMnuEditCopyUpdateUI)
103 EVT_UPDATE_UI(idEditFoldAll, ThreadSearch::OnMnuEditCopyUpdateUI)
104 EVT_UPDATE_UI(idEditUnfoldAll, ThreadSearch::OnMnuEditCopyUpdateUI)
105 EVT_UPDATE_UI(idEditToggleAllFolds, ThreadSearch::OnMnuEditCopyUpdateUI)
106 EVT_UPDATE_UI(idEditFoldBlock, ThreadSearch::OnMnuEditCopyUpdateUI)
107 EVT_UPDATE_UI(idEditUnfoldBlock, ThreadSearch::OnMnuEditCopyUpdateUI)
108 EVT_UPDATE_UI(idEditToggleFoldBlock, ThreadSearch::OnMnuEditCopyUpdateUI)
109 EVT_UPDATE_UI(idEditEOLCRLF, ThreadSearch::OnMnuEditCopyUpdateUI)
110 EVT_UPDATE_UI(idEditEOLCR, ThreadSearch::OnMnuEditCopyUpdateUI)
111 EVT_UPDATE_UI(idEditEOLLF, ThreadSearch::OnMnuEditCopyUpdateUI)
112 EVT_UPDATE_UI(idEditEncoding, ThreadSearch::OnMnuEditCopyUpdateUI)
113 EVT_UPDATE_UI(idEditSelectAll, ThreadSearch::OnMnuEditCopyUpdateUI)
114 EVT_UPDATE_UI(idEditBookmarksToggle, ThreadSearch::OnMnuEditCopyUpdateUI)
115 EVT_UPDATE_UI(idEditBookmarksNext, ThreadSearch::OnMnuEditCopyUpdateUI)
116 EVT_UPDATE_UI(idEditBookmarksPrevious, ThreadSearch::OnMnuEditCopyUpdateUI)
117 EVT_UPDATE_UI(idEditCommentSelected, ThreadSearch::OnMnuEditCopyUpdateUI)
118 EVT_UPDATE_UI(idEditAutoComplete, ThreadSearch::OnMnuEditCopyUpdateUI)
119 EVT_UPDATE_UI(idEditUncommentSelected, ThreadSearch::OnMnuEditCopyUpdateUI)
120 EVT_UPDATE_UI(idEditToggleCommentSelected, ThreadSearch::OnMnuEditCopyUpdateUI)
121 END_EVENT_TABLE()
122
123 // constructor
124 ThreadSearch::ThreadSearch()
125 :m_SearchedWord(wxEmptyString),
126 m_pThreadSearchView(NULL),
127 m_pViewManager(NULL),
128 m_pToolbar(NULL),
129 m_CtxMenuIntegration(true),
130 m_UseDefValsForThreadSearch(true),
131 m_ShowSearchControls(true),
132 m_ShowDirControls(false),
133 m_ShowCodePreview(true),
134 m_DeletePreviousResults(true),
135 m_LoggerType(ThreadSearchLoggerBase::TypeList),
136 m_DisplayLogHeaders(true),
137 m_DrawLogLines(false),
138 m_AutosizeLogColumns(false),
139 m_pCboSearchExpr(0),
140 m_SplitterMode(wxSPLIT_VERTICAL),
141 m_FileSorting(InsertIndexManager::SortByFilePath)
142 {
143 }
144
145 // destructor
~ThreadSearch()146 ThreadSearch::~ThreadSearch()
147 {
148 }
149
OnAttach()150 void ThreadSearch::OnAttach()
151 {
152 // NOTE: after this function, the inherited member variable
153 // m_IsAttached will be TRUE...
154 // You should check for it in other functions, because if it
155 // is FALSE, it means that the application did *not* "load"
156 // (see: does not need) this plugin...
157
158 #if LOGGING
159 wxLog::EnableLogging(true);
160 m_pLog = new wxLogWindow(Manager::Get()->GetAppWindow(), _T(" ThreadSearch Plugin"), true, false);
161 wxLog::SetActiveTarget( m_pLog);
162 m_pLog->Flush();
163 m_pLog->GetFrame()->SetSize(20,30,600,300);
164 LOGIT( _T("ThreadSearch Plugin Logging Started"));
165 #endif
166
167 bool showPanel;
168 int sashPosition;
169 ThreadSearchViewManagerBase::eManagerTypes mgrType;
170 wxArrayString searchPatterns, searchDirs, searchMasks;
171
172 // Loads configuration from default.conf
173 LoadConfig(showPanel, sashPosition, mgrType, searchPatterns, searchDirs, searchMasks);
174
175 // Adds window to the manager
176 m_pThreadSearchView = new ThreadSearchView(*this);
177 m_pThreadSearchView->SetSearchHistory(searchPatterns, searchDirs, searchMasks);
178
179 // Builds manager
180 m_pViewManager = ThreadSearchViewManagerBase::BuildThreadSearchViewManagerBase(m_pThreadSearchView, true, mgrType);
181
182 // Ensure view is shown or hidden
183 m_pViewManager->ShowView(showPanel);
184
185 // Sets splitter sash in the middle of the width of the window
186 // and creates columns as it is not managed in ctor on Linux
187 int x, y;
188 m_pThreadSearchView->GetSize(&x, &y);
189 m_pThreadSearchView->SetSashPosition(x/2);
190 m_pThreadSearchView->Update();
191
192 // Set the splitter posn from the config
193 if (sashPosition != 0)
194 m_pThreadSearchView->SetSashPosition(sashPosition);
195
196 // Shows/Hides search widgets on the Messages notebook ThreadSearch panel
197 m_pThreadSearchView->ShowSearchControls(m_ShowSearchControls);
198
199 // true if it enters in OnRelease for the first time
200 m_OnReleased = false;
201 }
202
OnRelease(bool)203 void ThreadSearch::OnRelease(bool /*appShutDown*/)
204 {
205 // do de-initialization for your plugin
206 // if appShutDown is false, the plugin is unloaded because Code::Blocks is being shut down,
207 // which means you must not use any of the SDK Managers
208 // NOTE: after this function, the inherited member variable
209 // m_IsAttached will be FALSE...
210
211 // --------------------------------------------------------------
212 // Carefull! This routine can be entered consecutive times
213 // --------------------------------------------------------------
214 if ( m_OnReleased ) return;
215 m_OnReleased = true;
216
217 // Removes Thread search menu item from the View menu
218 RemoveMenuItems();
219
220 m_pToolbar = 0;
221
222 if ( m_pThreadSearchView != 0 )
223 {
224 m_pViewManager->RemoveViewFromManager();
225 m_pThreadSearchView->Destroy();
226 }
227
228 delete m_pViewManager;
229 m_pViewManager = 0;
230 }
231
232
OnThreadSearchViewDestruction()233 void ThreadSearch::OnThreadSearchViewDestruction()
234 {
235 // Method is called from view destructor.
236 // Destruction is either made by plugin or
237 // Messages Notebook.
238
239 // We show code preview to save a consistent
240 // value of splitter sash position.
241 m_pThreadSearchView->ApplySplitterSettings(m_ShowCodePreview, m_SplitterMode);
242
243 // Saves configuration to default.conf
244 SaveConfig(m_pViewManager->IsViewShown(),
245 m_pThreadSearchView->GetSashPosition(),
246 m_pViewManager->GetManagerType(),
247 m_pThreadSearchView->GetSearchHistory(),
248 m_pThreadSearchView->GetSearchDirsHistory(),
249 m_pThreadSearchView->GetSearchMasksHistory());
250
251 // Reset of the pointer as view is being deleted
252 m_pThreadSearchView = NULL;
253 }
254
BuildMenu(wxMenuBar * menuBar)255 void ThreadSearch::BuildMenu(wxMenuBar* menuBar)
256 {
257 //The application is offering its menubar for your plugin,
258 //to add any menu items you want...
259 //Append any items you need in the menu...
260 //NOTE: Be careful in here... The application's menubar is at your disposal.
261 size_t i;
262 int idx = menuBar->FindMenu(_("&View"));
263 if (idx != wxNOT_FOUND)
264 {
265 wxMenu* menu = menuBar->GetMenu(idx);
266 wxMenuItemList& items = menu->GetMenuItems();
267
268 // find the first separator and insert before it
269 for (i = 0; i < items.GetCount(); ++i)
270 {
271 if (items[i]->IsSeparator())
272 {
273 menu->InsertCheckItem(i, controlIDs.Get(ControlIDs::idMenuViewThreadSearch), _("Thread search"),
274 _("Toggle displaying the 'Thread search' panel"));
275 break;
276 }
277 }
278
279 if ( i == items.GetCount() )
280 {
281 // not found, just append
282 menu->AppendCheckItem(controlIDs.Get(ControlIDs::idMenuViewThreadSearch), _("Thread search"),
283 _("Toggle displaying the 'Thread search' panel"));
284 }
285
286 menu->Append(controlIDs.Get(ControlIDs::idMenuViewFocusThreadSearch), _("Focus Thread Search"),
287 _("Makes the search box of the Thread search panel the focused control"));
288 }
289
290 idx = menuBar->FindMenu(_("Sea&rch"));
291 if (idx != wxNOT_FOUND)
292 {
293 wxMenu* menu = menuBar->GetMenu(idx);
294 wxMenuItemList& items = menu->GetMenuItems();
295
296 // find the first separator and insert separator + entry before it
297 for (i = 0; i < items.GetCount(); ++i)
298 {
299 if (items[i]->IsSeparator())
300 {
301 menu->Insert(i, controlIDs.Get(ControlIDs::idMenuSearchThreadSearch), _("Thread search"),
302 _("Perform a Threaded search with the current word"));
303 menu->InsertSeparator(i);
304 break;
305 }
306 }
307
308 if ( i == items.GetCount() )
309 {
310 // not found, just append
311 menu->Append(controlIDs.Get(ControlIDs::idMenuSearchThreadSearch), _("Thread search"),
312 _("Perform a Threaded search with the current word"));
313 menu->AppendSeparator();
314 }
315 }
316 }
317
RemoveMenuItems()318 void ThreadSearch::RemoveMenuItems()
319 {
320 // Removes 'Thread search' item from View and Search menu
321 wxMenuBar* menuBar = Manager::Get()->GetAppFrame()->GetMenuBar();
322 int idx = menuBar->FindMenu(_("&View"));
323 if (idx != wxNOT_FOUND)
324 {
325 wxMenu* viewMenu = menuBar->GetMenu(idx);
326 if ( viewMenu != 0 )
327 {
328 viewMenu->Remove(controlIDs.Get(ControlIDs::idMenuViewThreadSearch));
329 }
330 }
331
332 idx = menuBar->FindMenu(_("Sea&rch"));
333 if (idx != wxNOT_FOUND)
334 {
335 wxMenu* searchMenu = menuBar->GetMenu(idx);
336 if ( searchMenu != 0 )
337 {
338 searchMenu->Remove(controlIDs.Get(ControlIDs::idMenuSearchThreadSearch));
339 }
340 }
341 }
342
343
OnMnuViewThreadSearch(wxCommandEvent & event)344 void ThreadSearch::OnMnuViewThreadSearch(wxCommandEvent& event)
345 {
346 if ( !IsAttached() )
347 return;
348
349 m_pViewManager->ShowView(event.IsChecked());
350 }
351
352
OnMnuSearchThreadSearch(wxCommandEvent &)353 void ThreadSearch::OnMnuSearchThreadSearch(wxCommandEvent& /*event*/)
354 {
355 if ( !IsAttached() )
356 return;
357
358 // Need to get the cursor word first and ensure it is consistent.
359 if ( (GetCursorWord(m_SearchedWord) == true) && (m_SearchedWord.IsEmpty() == false) )
360 {
361 // m_SearchedWord is Ok => Search
362 RunThreadSearch(m_SearchedWord, true);
363 }
364 else
365 {
366 // Word is KO, just show the panel
367 m_pViewManager->ShowView(true);
368 }
369 }
370
OnMnuViewFocusThreadSearch(wxCommandEvent &)371 void ThreadSearch::OnMnuViewFocusThreadSearch(wxCommandEvent& /*event*/)
372 {
373 if ( !IsAttached() )
374 return;
375
376 GetCursorWord(m_SearchedWord);
377
378 m_pViewManager->ShowView(true);
379 m_pViewManager->Raise();
380 m_pThreadSearchView->FocusSearchCombo(m_SearchedWord);
381 }
382
383
OnCtxThreadSearch(wxCommandEvent &)384 void ThreadSearch::OnCtxThreadSearch(wxCommandEvent& /*event*/)
385 {
386 if ( !IsAttached() )
387 return;
388
389 // m_SearchedWord was set in BuildModuleMenu
390 RunThreadSearch(m_SearchedWord, true);
391 }
392
393
OnMnuViewThreadSearchUpdateUI(wxUpdateUIEvent &)394 void ThreadSearch::OnMnuViewThreadSearchUpdateUI(wxUpdateUIEvent& /*event*/)
395 {
396 if ( !IsAttached() )
397 return;
398
399 wxMenuBar *menubar = Manager::Get()->GetAppFrame()->GetMenuBar();
400 menubar->Check(controlIDs.Get(ControlIDs::idMenuViewThreadSearch), m_pViewManager->IsViewShown());
401 }
402
403
OnMnuSearchThreadSearchUpdateUI(wxUpdateUIEvent & event)404 void ThreadSearch::OnMnuSearchThreadSearchUpdateUI(wxUpdateUIEvent& event)
405 {
406 if ( !IsAttached() )
407 return;
408
409 event.Enable(m_pThreadSearchView->IsSearchRunning() == false);
410 }
411
OnMnuViewFocusThreadSearchUpdateUI(wxUpdateUIEvent & event)412 void ThreadSearch::OnMnuViewFocusThreadSearchUpdateUI(wxUpdateUIEvent& event)
413 {
414 if ( !IsAttached() )
415 return;
416
417 event.Enable(m_pThreadSearchView->IsSearchRunning() == false);
418 }
419
420
BuildModuleMenu(const ModuleType type,wxMenu * pMenu,const FileTreeData *)421 void ThreadSearch::BuildModuleMenu(const ModuleType type, wxMenu* pMenu, const FileTreeData* /*data*/)
422 {
423 wxMenuItem* pMenuItem = NULL;
424 if (!pMenu || !IsAttached())
425 return;
426
427 // Triggs editor events if 'Find occurrences' is integrated in context menu
428 if ( (type == mtEditorManager) && (m_CtxMenuIntegration == true) )
429 {
430 // Gets current word
431 if ( GetCursorWord(m_SearchedWord) == true )
432 {
433 wxString sText = _("Find occurrences of: '") + m_SearchedWord + wxT("'");
434
435 PluginManager *pluginManager = Manager::Get()->GetPluginManager();
436 int dIndex = pluginManager->GetFindMenuItemFirst() + pluginManager->GetFindMenuItemCount();
437 pMenuItem = pMenu->Insert(dIndex, controlIDs.Get(ControlIDs::idMenuCtxThreadSearch), sText);
438 Manager::Get()->GetPluginManager()->RegisterFindMenuItems(false, 1);
439
440 // Disables item if a threaded search is running
441 pMenuItem->Enable(!m_pThreadSearchView->IsSearchRunning());
442 }
443 }
444 }
445
GetConfigurationPanel(wxWindow * parent)446 cbConfigurationPanel* ThreadSearch::GetConfigurationPanel(wxWindow* parent)
447 {
448 if ( !IsAttached() )
449 return NULL;
450
451 return new ThreadSearchConfPanel(*this, parent);
452 }
453
454
Notify()455 void ThreadSearch::Notify()
456 {
457 if ( !IsAttached() )
458 return;
459
460 m_pThreadSearchView->Update();
461 SaveConfig(m_pViewManager->IsViewShown(),
462 m_pThreadSearchView->GetSashPosition(),
463 m_pViewManager->GetManagerType(),
464 m_pThreadSearchView->GetSearchHistory(),
465 m_pThreadSearchView->GetSearchDirsHistory(),
466 m_pThreadSearchView->GetSearchMasksHistory());
467 }
468
469
LoadConfig(bool & showPanel,int & sashPosition,ThreadSearchViewManagerBase::eManagerTypes & mgrType,wxArrayString & searchPatterns,wxArrayString & searchDirs,wxArrayString & searchMasks)470 void ThreadSearch::LoadConfig(bool& showPanel, int& sashPosition,
471 ThreadSearchViewManagerBase::eManagerTypes& mgrType,
472 wxArrayString& searchPatterns, wxArrayString& searchDirs, wxArrayString& searchMasks)
473 {
474 if ( !IsAttached() )
475 return;
476
477 ConfigManager* pCfg = Manager::Get()->GetConfigManager(_T("ThreadSearch"));
478
479 m_FindData.SetMatchWord (pCfg->ReadBool(wxT("/MatchWord"), true));
480 m_FindData.SetStartWord (pCfg->ReadBool(wxT("/StartWord"), false));
481 m_FindData.SetMatchCase (pCfg->ReadBool(wxT("/MatchCase"), true));
482 m_FindData.SetRegEx (pCfg->ReadBool(wxT("/RegEx"), false));
483 m_FindData.SetHiddenSearch (pCfg->ReadBool(wxT("/HiddenSearch"), true));
484 m_FindData.SetRecursiveSearch (pCfg->ReadBool(wxT("/RecursiveSearch"), true));
485
486 m_CtxMenuIntegration = pCfg->ReadBool(wxT("/CtxMenuIntegration"), true);
487 m_UseDefValsForThreadSearch = pCfg->ReadBool(wxT("/UseDefaultValues"), true);
488 m_ShowSearchControls = pCfg->ReadBool(wxT("/ShowSearchControls"), true);
489 m_ShowDirControls = pCfg->ReadBool(wxT("/ShowDirControls"), false);
490 m_ShowCodePreview = pCfg->ReadBool(wxT("/ShowCodePreview"), false);
491 m_DeletePreviousResults = pCfg->ReadBool(wxT("/DeletePreviousResults"), false);
492 m_DisplayLogHeaders = pCfg->ReadBool(wxT("/DisplayLogHeaders"), true);
493 m_DrawLogLines = pCfg->ReadBool(wxT("/DrawLogLines"), false);
494 m_AutosizeLogColumns = pCfg->ReadBool(wxT("/AutosizeLogColumns"), true);
495
496 showPanel = pCfg->ReadBool(wxT("/ShowPanel"), true);
497
498 m_FindData.SetScope (pCfg->ReadInt (wxT("/Scope"), ScopeProjectFiles));
499
500 m_FindData.SetSearchPath (pCfg->Read (wxT("/DirPath"), wxEmptyString));
501 m_FindData.SetSearchMask (pCfg->Read (wxT("/Mask"), wxT("*.cpp;*.c;*.h")));
502
503 sashPosition = pCfg->ReadInt(wxT("/SplitterPosn"), 0);
504 int splitterMode = pCfg->ReadInt(wxT("/SplitterMode"), wxSPLIT_VERTICAL);
505 m_SplitterMode = wxSPLIT_VERTICAL;
506 if ( splitterMode == wxSPLIT_HORIZONTAL )
507 {
508 m_SplitterMode = wxSPLIT_HORIZONTAL;
509 }
510
511 int managerType = pCfg->ReadInt(wxT("/ViewManagerType"), ThreadSearchViewManagerBase::TypeMessagesNotebook);
512 mgrType = ThreadSearchViewManagerBase::TypeMessagesNotebook;
513 if ( managerType == ThreadSearchViewManagerBase::TypeLayout )
514 {
515 mgrType = ThreadSearchViewManagerBase::TypeLayout;
516 }
517
518 int loggerType = pCfg->ReadInt(wxT("/LoggerType"), ThreadSearchLoggerBase::TypeList);
519 m_LoggerType = ThreadSearchLoggerBase::TypeList;
520 if ( loggerType == ThreadSearchLoggerBase::TypeTree )
521 {
522 m_LoggerType = ThreadSearchLoggerBase::TypeTree;
523 }
524
525 searchPatterns = pCfg->ReadArrayString(wxT("/SearchPatterns"));
526 searchDirs = pCfg->ReadArrayString(wxT("/SearchDirs"));
527 if (searchDirs.empty())
528 searchDirs.push_back(m_FindData.GetSearchPath());
529 searchMasks = pCfg->ReadArrayString(wxT("/SearchMasks"));
530 if (searchMasks.empty())
531 searchMasks.push_back(m_FindData.GetSearchMask());
532 }
533
534
SaveConfig(bool showPanel,int sashPosition,ThreadSearchViewManagerBase::eManagerTypes,const wxArrayString & searchPatterns,const wxArrayString & searchDirs,const wxArrayString & searchMasks)535 void ThreadSearch::SaveConfig(bool showPanel, int sashPosition,
536 ThreadSearchViewManagerBase::eManagerTypes /*mgrType*/,
537 const wxArrayString& searchPatterns, const wxArrayString& searchDirs,
538 const wxArrayString& searchMasks)
539 {
540 ConfigManager* pCfg = Manager::Get()->GetConfigManager(_T("ThreadSearch"));
541
542 pCfg->Write(wxT("/MatchWord"), m_FindData.GetMatchWord());
543 pCfg->Write(wxT("/StartWord"), m_FindData.GetStartWord());
544 pCfg->Write(wxT("/MatchCase"), m_FindData.GetMatchCase());
545 pCfg->Write(wxT("/RegEx"), m_FindData.GetRegEx());
546 pCfg->Write(wxT("/HiddenSearch"), m_FindData.GetHiddenSearch());
547 pCfg->Write(wxT("/RecursiveSearch"), m_FindData.GetRecursiveSearch());
548
549 pCfg->Write(wxT("/CtxMenuIntegration"), m_CtxMenuIntegration);
550 pCfg->Write(wxT("/UseDefaultValues"), m_UseDefValsForThreadSearch);
551 pCfg->Write(wxT("/ShowSearchControls"), m_ShowSearchControls);
552 pCfg->Write(wxT("/ShowDirControls"), m_ShowDirControls);
553 pCfg->Write(wxT("/ShowCodePreview"), m_ShowCodePreview);
554 pCfg->Write(wxT("/DeletePreviousResults"), m_DeletePreviousResults);
555 pCfg->Write(wxT("/DisplayLogHeaders"), m_DisplayLogHeaders);
556 pCfg->Write(wxT("/DrawLogLines"), m_DrawLogLines);
557 pCfg->Write(wxT("/AutosizeLogColumns"), m_AutosizeLogColumns);
558
559 pCfg->Write(wxT("/ShowPanel"), showPanel);
560
561 pCfg->Write(wxT("/Scope"), m_FindData.GetScope());
562
563 pCfg->Write(wxT("/DirPath"), m_FindData.GetSearchPath());
564 pCfg->Write(wxT("/Mask"), m_FindData.GetSearchMask());
565
566 pCfg->Write(wxT("/SplitterPosn"), sashPosition);
567 pCfg->Write(wxT("/SplitterMode"), (int)m_SplitterMode);
568 pCfg->Write(wxT("/ViewManagerType"), m_pViewManager->GetManagerType());
569 pCfg->Write(wxT("/LoggerType"), m_LoggerType);
570 pCfg->Write(wxT("/FileSorting"), m_FileSorting);
571
572 pCfg->Write(wxT("/SearchPatterns"), searchPatterns);
573 pCfg->Write(wxT("/SearchDirs"), searchDirs);
574 pCfg->Write(wxT("/SearchMasks"), searchMasks);
575 }
576
BuildToolBar(wxToolBar * toolBar)577 bool ThreadSearch::BuildToolBar(wxToolBar* toolBar)
578 {
579 if ( !IsAttached() || !toolBar )
580 return false;
581
582 m_pToolbar = toolBar;
583 m_pThreadSearchView->SetToolBar(toolBar);
584
585 const wxString &prefix = GetImagePrefix(true);
586
587 m_pCboSearchExpr = new wxComboBox(toolBar, controlIDs.Get(ControlIDs::idCboSearchExpr),
588 wxEmptyString, wxDefaultPosition, wxSize(130, -1), 0, NULL, wxCB_DROPDOWN);
589 m_pCboSearchExpr->SetToolTip(_("Text to search"));
590
591 const double scaleFactor = cbGetContentScaleFactor(*toolBar);
592
593 wxBitmap bmpFind = cbLoadBitmapScaled(prefix + wxT("findf.png"), wxBITMAP_TYPE_PNG,
594 scaleFactor);
595 wxBitmap bmpFindDisabled = cbLoadBitmapScaled(prefix + wxT("findfdisabled.png"),
596 wxBITMAP_TYPE_PNG, scaleFactor);
597 wxBitmap bmpOptions = cbLoadBitmapScaled(prefix + wxT("options.png"), wxBITMAP_TYPE_PNG,
598 scaleFactor);
599 wxBitmap bmpOptionsDisabled = cbLoadBitmapScaled(prefix + wxT("optionsdisabled.png"),
600 wxBITMAP_TYPE_PNG, scaleFactor);
601
602 toolBar->AddControl(m_pCboSearchExpr);
603 toolBar->AddTool(controlIDs.Get(ControlIDs::idBtnSearch), _(""),
604 bmpFind, bmpFindDisabled,
605 wxITEM_NORMAL, _("Run search"));
606 toolBar->AddTool(controlIDs.Get(ControlIDs::idBtnOptions), _(""),
607 bmpOptions, bmpOptionsDisabled,
608 wxITEM_NORMAL, _("Show options window"));
609 m_pThreadSearchView->UpdateOptionsButtonImage(m_FindData);
610
611 m_pCboSearchExpr->Append(m_pThreadSearchView->GetSearchHistory());
612 if ( m_pCboSearchExpr->GetCount() > 0 )
613 {
614 m_pCboSearchExpr->SetSelection(0);
615 }
616
617 toolBar->Realize();
618 toolBar->SetInitialSize();
619
620 return true;
621 }
622
623
OnBtnOptionsClick(wxCommandEvent & event)624 void ThreadSearch::OnBtnOptionsClick(wxCommandEvent &event)
625 {
626 if ( !IsAttached() )
627 return;
628
629 m_pThreadSearchView->OnBtnOptionsClick(event);
630 }
631
632
OnBtnSearchClick(wxCommandEvent & event)633 void ThreadSearch::OnBtnSearchClick(wxCommandEvent &event)
634 {
635 if ( !IsAttached() )
636 return;
637
638 // Behaviour differs if a search is running.
639 if ( m_pThreadSearchView->IsSearchRunning() )
640 {
641 // In this case, user wants to stops search,
642 // we just transmit event
643 m_pThreadSearchView->OnBtnSearchClick(event);
644
645 }
646 else
647 {
648 // User wants to search for a word.
649 // Forwarding the event would search for the view combo text whereas we want
650 // to look for the toolbar combo text.
651 const long id = controlIDs.Get(ControlIDs::idCboSearchExpr);
652 wxComboBox* pCboBox = static_cast<wxComboBox*>(m_pToolbar->FindControl(id));
653 wxASSERT(pCboBox != NULL);
654 RunThreadSearch(pCboBox->GetValue());
655 }
656 }
657
RunThreadSearch(const wxString & text,bool isCtxSearch)658 void ThreadSearch::RunThreadSearch(const wxString& text, bool isCtxSearch/*=false*/)
659 {
660 if ( !IsAttached() )
661 return;
662
663 ThreadSearchFindData findData = m_FindData;
664
665 // User may prefer to set default options for contextual search
666 if ( (isCtxSearch == true) && (m_UseDefValsForThreadSearch == true) )
667 {
668 findData.SetMatchCase(true);
669 findData.SetMatchWord(true);
670 findData.SetStartWord(false);
671 findData.SetRegEx (false);
672 }
673
674 // m_SearchedWord was set in BuildModuleMenu
675 findData.SetFindText(text);
676
677 // Displays m_pThreadSearchView in manager
678 m_pViewManager->ShowView(true);
679
680 // Runs the search through a worker thread
681 m_pThreadSearchView->ThreadedSearch(findData);
682 }
683
684
OnCboSearchExprEnter(wxCommandEvent & event)685 void ThreadSearch::OnCboSearchExprEnter(wxCommandEvent &event)
686 {
687 if ( !IsAttached() )
688 return;
689
690 // Event handler used when user clicks on enter after typing
691 // in combo box text control.
692 // Runs a multi threaded search with combo text
693 const long id = controlIDs.Get(ControlIDs::idCboSearchExpr);
694 wxComboBox* pCboBox = static_cast<wxComboBox*>(m_pToolbar->FindControl(id));
695 wxASSERT(pCboBox != NULL);
696 if ( event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER )
697 RunThreadSearch(pCboBox->GetValue());
698 }
699
700
ShowToolBar(bool show)701 void ThreadSearch::ShowToolBar(bool show)
702 {
703 if ( !IsAttached() )
704 return;
705
706 bool isShown = IsWindowReallyShown(m_pToolbar);
707
708 if ( show != isShown )
709 {
710 CodeBlocksDockEvent evt(show ? cbEVT_SHOW_DOCK_WINDOW : cbEVT_HIDE_DOCK_WINDOW);
711 evt.pWindow = (wxWindow*)m_pToolbar;
712 evt.shown = show;
713 Manager::Get()->ProcessEvent(evt);
714 }
715 }
716
717
IsToolbarVisible()718 bool ThreadSearch::IsToolbarVisible()
719 {
720 if ( !IsAttached() )
721 return false;
722
723 return IsWindowReallyShown(m_pToolbar);
724 }
725
726
GetCursorWord(wxString & sWord)727 bool ThreadSearch::GetCursorWord(wxString& sWord)
728 {
729 bool wordFound = false;
730 sWord = wxEmptyString;
731
732 // Gets active editor
733 cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
734 if ( ed != NULL )
735 {
736 cbStyledTextCtrl* control = ed->GetControl();
737
738 sWord = control->GetSelectedText();
739 if (sWord != wxEmptyString)
740 {
741 sWord.Trim(true);
742 sWord.Trim(false);
743
744 wxString::size_type pos = sWord.find(wxT('\n'));
745 if (pos != wxString::npos)
746 {
747 sWord.Remove(pos, sWord.length() - pos);
748 sWord.Trim(true);
749 sWord.Trim(false);
750 }
751
752 return !sWord.IsEmpty();
753 }
754
755 // Gets word under cursor
756 int pos = control->GetCurrentPos();
757 int ws = control->WordStartPosition(pos, true);
758 int we = control->WordEndPosition(pos, true);
759 const wxString word = control->GetTextRange(ws, we);
760 if (!word.IsEmpty()) // Avoid empty strings
761 {
762 sWord.Clear();
763
764 // m_SearchedWord will be used if 'Find occurrences' ctx menu is clicked
765 sWord << word;
766 wordFound = true;
767 }
768 }
769
770 return wordFound;
771 }
772
773
OnMnuEditCopy(wxCommandEvent & event)774 void ThreadSearch::OnMnuEditCopy(wxCommandEvent& event)
775 {
776 if ( !IsAttached() )
777 {
778 event.Skip();
779 return;
780 }
781
782 wxWindow* pFocused = wxWindow::FindFocus();
783
784 // if the following window have the focus, own the copy.
785 if ( pFocused == m_pCboSearchExpr )
786 {
787 if ( m_pCboSearchExpr->CanCopy() )
788 m_pCboSearchExpr->Copy();
789 LOGIT( _T("OnMnuEditcopy for m_pCboSearchExpr") );
790 }
791 else if ( pFocused == m_pThreadSearchView->m_pCboSearchExpr )
792 {
793 if ( m_pThreadSearchView->m_pCboSearchExpr->CanCopy() )
794 m_pThreadSearchView->m_pCboSearchExpr->Copy();
795 LOGIT( _T("OnMnuEditcopy for m_pThreadSearchView->m_pCboSearchExpr") );
796 }
797 else if ( pFocused == static_cast<wxWindow*>(m_pThreadSearchView->m_pSearchPreview) )
798 {
799 bool hasSel = m_pThreadSearchView->m_pSearchPreview->GetSelectionStart() != m_pThreadSearchView->m_pSearchPreview->GetSelectionEnd();
800 if (hasSel)
801 m_pThreadSearchView->m_pSearchPreview->Copy();
802 LOGIT( _T("OnMnuEditcopy for m_pSearchPreview") );
803 }
804 else
805 {
806 event.Skip();
807 }
808
809 // If you Skip(), CB main.cpp will wrongly paste your text into the current editor
810 // because CB main.cpp thinks it owns the clipboard.
811 //- event.Skip();
812 return; //own the event
813 }
814
815
OnMnuEditCopyUpdateUI(wxUpdateUIEvent & event)816 void ThreadSearch::OnMnuEditCopyUpdateUI(wxUpdateUIEvent& event)
817 {
818 if ( !IsAttached() )
819 {
820 event.Skip(); return;
821 }
822
823 wxWindow* pFocused = wxWindow::FindFocus();
824 if (not pFocused) return;
825
826 wxMenuBar* mbar = Manager::Get()->GetAppFrame()->GetMenuBar();
827 if (not mbar) return;
828
829 bool hasSel = false;
830 // if the following window have the focus, own the copy.
831 if ( pFocused == m_pCboSearchExpr )
832 {
833 //event.Enable(m_pCboSearchExpr->CanCopy());
834 hasSel = m_pCboSearchExpr->CanCopy() ;
835 //LOGIT( _T("OnMnuEditCopyUpdateUI m_pCboSearchExpr") );
836 }
837 else if ( pFocused == m_pThreadSearchView->m_pCboSearchExpr )
838 {
839 //event.Enable(m_pThreadSearchView->m_pCboSearchExpr->CanCopy());
840 hasSel = m_pThreadSearchView->m_pCboSearchExpr->CanCopy();
841 //LOGIT( _T("OnMnuEditCopyUpdateUI m_pThreadSearchView->m_pCboSearchExpr") );
842 }
843 else if ( pFocused == static_cast<wxWindow*>(m_pThreadSearchView->m_pSearchPreview) )
844 {
845 hasSel = m_pThreadSearchView->m_pSearchPreview->GetSelectionStart() != m_pThreadSearchView->m_pSearchPreview->GetSelectionEnd();
846 //LOGIT( _T("OnMnuEditCopyUpdateUI m_pSearchPreview") );
847 }
848 if ( hasSel )
849 {
850 mbar->Enable(idMenuEditCopy, hasSel);
851 wxToolBar* pMainToolBar = (wxToolBar*) ::wxFindWindowByName(wxT("toolbar"), NULL);
852 if (pMainToolBar) pMainToolBar->EnableTool(idMenuEditCopy, hasSel);
853 return;
854 }
855
856 event.Skip();
857 return;
858
859 }
860 // ----------------------------------------------------------------------------
OnMnuEditPaste(wxCommandEvent & event)861 void ThreadSearch::OnMnuEditPaste(wxCommandEvent& event)
862 // ----------------------------------------------------------------------------
863 {
864 // Process clipboard data only if we have the focus
865
866 // ----------------------------------------------------------------
867 // NB: A bug in CB main.cpp causes a ctrl-v to always paste into the
868 // current editor. Here, we'll make checks to see if the paste
869 // is for our search combo boxes and paste the data there.
870 // If the focused window is one of ours that shouldn't get pasted
871 // data, we'll simply ignore it.
872 // If the window isn't one of ours, we'll event.Skip();
873 // ----------------------------------------------------------------
874
875 if ( !IsAttached() )
876 { event.Skip(); return; }
877
878 if (not m_IsAttached) {event.Skip(); return;}
879
880 wxWindow* pFocused = wxWindow::FindFocus();
881 if (not pFocused) { event.Skip(); return; }
882
883 wxString focusedStr = pFocused->GetName();
884 // DBGLOG(wxT("OnMnuEditPaste:Focused[%p][%s]"), pFocused, focusedStr.c_str());
885
886 // don't allow paste when the following windows have the focus
887 if ( (pFocused == m_pThreadSearchView->m_pSearchPreview) ||
888 (pFocused == (wxWindow*)m_pThreadSearchView->m_pLogger) )
889 {
890 return;
891 }
892
893 // if the following window have the focus, own the paste.
894 if ( (pFocused != m_pCboSearchExpr)
895 && (pFocused != m_pThreadSearchView->m_pCboSearchExpr) )
896 { event.Skip(); return;}
897
898 if (pFocused == m_pCboSearchExpr)
899 m_pCboSearchExpr->Paste();
900 if (pFocused == m_pThreadSearchView->m_pCboSearchExpr)
901 m_pThreadSearchView->m_pCboSearchExpr->Paste();
902
903 // If you Skip(), CB main.cpp will wrongly paste your text into the current editor
904 // because CB main.cpp thinks it owns the clipboard.
905 //- event.Skip();
906 return; //own the event
907 }//OnMnuEditPaste
908
909
SetManagerType(ThreadSearchViewManagerBase::eManagerTypes mgrType)910 void ThreadSearch::SetManagerType(ThreadSearchViewManagerBase::eManagerTypes mgrType)
911 {
912 // Is type different from current one ?
913 if ( mgrType != m_pViewManager->GetManagerType() )
914 {
915 // Get show state and destroy current view manager.
916 bool show(true);
917 if ( m_pViewManager != NULL )
918 {
919 show = m_pViewManager->IsViewShown();
920 m_pViewManager->RemoveViewFromManager();
921 delete m_pViewManager;
922 }
923
924 // Create and show new view manager.
925 m_pViewManager = ThreadSearchViewManagerBase::BuildThreadSearchViewManagerBase(m_pThreadSearchView, true, mgrType);
926 m_pViewManager->ShowView(show);
927 }
928 }
929
930
931
932
933