1 /*
2 * This file is licensed under the GNU General Public License, version 3
3 * http://www.gnu.org/licenses/gpl-3.0.html
4 *
5 */
6
7 #include "workspacebrowserf.h" // class's header file
8
9 #include <sdk.h>
10 #ifndef CB_PRECOMP
11 #include <wx/intl.h>
12 #include <wx/treectrl.h>
13 #include <wx/listctrl.h>
14 #include <wx/sizer.h>
15 #include <wx/stattext.h>
16 #include <wx/choice.h>
17 #include <wx/menu.h>
18 #include <wx/splitter.h>
19 #include <wx/button.h>
20 #include <wx/utils.h> // wxBusyCursor
21 #include <wx/tipwin.h>
22 #include <wx/tokenzr.h>
23 #include <wx/combobox.h>
24 #include <wx/settings.h>
25 #include <wx/choicdlg.h>
26
27 #include <cbproject.h>
28 #include <cbeditor.h>
29 #include <configmanager.h>
30 #include <editormanager.h>
31 #include <globals.h>
32 #include <manager.h>
33 #include <pluginmanager.h>
34 #include <projectmanager.h>
35 #include <cbstyledtextctrl.h>
36 #endif
37
38 #include "nativeparserf.h"
39 #include "fortranproject.h"
40
41 namespace {
42 int idMenuJumpToImplementation = wxNewId();
43 int idMenuRefreshTree = wxNewId();
44 int idMenuForceReparse = wxNewId();
45 int idMenuDoNotSort = wxNewId();
46 int idMenuSortAlphabetically = wxNewId();
47 int idMenuTopTree = wxNewId();
48 int idMenuBottomTree = wxNewId();
49 int idCmbSearch = wxNewId();
50 int idBtnHome = wxNewId();
51 int idCmbView = wxNewId();
52 }
53
BEGIN_EVENT_TABLE(WorkspaceBrowserF,wxPanel)54 BEGIN_EVENT_TABLE(WorkspaceBrowserF, wxPanel)
55 // m_TreeBottom
56 EVT_TREE_ITEM_ACTIVATED(idMenuBottomTree, WorkspaceBrowserF::OnTreeItemDoubleClick)
57 EVT_TREE_ITEM_RIGHT_CLICK(idMenuBottomTree, WorkspaceBrowserF::OnTreeItemRightClick)
58 // m_TreeTop
59 EVT_TREE_ITEM_ACTIVATED(idMenuTopTree, WorkspaceBrowserF::OnTreeItemDoubleClick)
60 EVT_TREE_ITEM_RIGHT_CLICK(idMenuTopTree, WorkspaceBrowserF::OnTreeItemRightClick)
61 EVT_TREE_SEL_CHANGED(idMenuTopTree, WorkspaceBrowserF::OnTreeItemSelected)
62 EVT_TREE_ITEM_EXPANDING(idMenuTopTree, WorkspaceBrowserF::OnTreeItemExpanding)
63 EVT_TREE_ITEM_COLLAPSING(idMenuTopTree, WorkspaceBrowserF::OnTreeItemCollapsing)
64
65 EVT_TEXT_ENTER(idCmbSearch, WorkspaceBrowserF::OnSearch)
66 EVT_COMBOBOX(idCmbSearch, WorkspaceBrowserF::OnSearch)
67
68 EVT_BUTTON(idBtnHome, WorkspaceBrowserF::OnMakeVisible)
69
70 EVT_MENU(idMenuJumpToImplementation, WorkspaceBrowserF::OnJumpTo)
71 EVT_MENU(idMenuRefreshTree, WorkspaceBrowserF::OnRefreshTree)
72 EVT_MENU(idMenuForceReparse, WorkspaceBrowserF::OnForceReparse)
73 EVT_CHOICE(idCmbView, WorkspaceBrowserF::OnViewScope)
74
75 EVT_MENU(idMenuDoNotSort, WorkspaceBrowserF::OnChangeSort)
76 EVT_MENU(idMenuSortAlphabetically, WorkspaceBrowserF::OnChangeSort)
77 EVT_MENU(idMenuBottomTree, WorkspaceBrowserF::OnChangeMode)
78 END_EVENT_TABLE()
79
80
81 // class constructor
82 WorkspaceBrowserF::WorkspaceBrowserF(wxWindow* parent, NativeParserF* np, ParserF* par)
83 : m_NativeParser(np),
84 m_TreeForPopupMenu(0),
85 m_pParser(par),
86 m_pActiveProject(0),
87 m_pBrowserBuilder(0)
88 {
89 ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("fortran_project"));
90
91 m_BrowserOptions.visibleBottomTree = cfg->ReadBool(_T("/visible_bottom_tree"), true);
92 m_BrowserOptions.sortAlphabetically = cfg->ReadBool(_T("/browser_sort_alphabetically"), true);
93 m_BrowserOptions.showLocalVariables = cfg->ReadBool(_T("/browser_show_local_variables"), true);
94 m_BrowserOptions.showIncludeSeparately = cfg->ReadBool(_T("/browser_show_include_files_separately"), true);
95
96 Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("WorkspaceBrowserF"));
97 CreateControlsWBF();
98
99 if (platform::windows)
100 m_Search->SetWindowStyle(wxTE_PROCESS_ENTER); // it's a must on windows to catch EVT_TEXT_ENTER
101
102 int filter = cfg->ReadInt(_T("/browser_display_filter"), bdfWorkspace);
103 m_CmbViewWBF->SetSelection(filter);
104 m_BrowserOptions.displayFilter = (BrowserDisplayFilter)filter;
105
106 // if the classbrowser is put under the control of a wxFlatNotebook,
107 // somehow the main panel is like "invisible" :/
108 // so we force the correct color for the panel here...
109 m_WBFMainPanel->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
110 }
111
112
CreateControlsWBF()113 void WorkspaceBrowserF::CreateControlsWBF()
114 {
115 const int imageSize = Manager::Get()->GetImageSize(Manager::UIComponent::Main);
116 const int uiScaleFactor = Manager::Get()->GetUIScaleFactor(Manager::UIComponent::Main);
117 wxString prefix = ConfigManager::GetDataFolder() +
118 wxString::Format(wxT("/FortranProject.zip#zip:images/%dx%d/"), imageSize, imageSize);
119 wxBitmap bmp_makevisible = cbLoadBitmapScaled(prefix + _T("fprojectmakevisible.png"), wxBITMAP_TYPE_PNG, uiScaleFactor);
120
121 wxBoxSizer* BoxSizer1;
122 wxBoxSizer* BoxSizer2;
123 wxBoxSizer* BoxSizer3;
124 wxBoxSizer* BoxSizer4;
125 wxFlexGridSizer* FlexGridSizer1;
126 wxStaticText* StaticText1;
127 wxStaticText* StaticText2;
128
129 BoxSizer1 = new wxBoxSizer(wxVERTICAL);
130 m_WBFMainPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("WBFMainPanel"));
131 BoxSizer2 = new wxBoxSizer(wxVERTICAL);
132 FlexGridSizer1 = new wxFlexGridSizer(2, 2, 2, 2);
133 FlexGridSizer1->AddGrowableCol(1);
134 StaticText1 = new wxStaticText(m_WBFMainPanel, wxID_ANY, _("View:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1"));
135 FlexGridSizer1->Add(StaticText1, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
136 BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
137 m_CmbViewWBF = new wxChoice(m_WBFMainPanel, idCmbView, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("cmbViewWBF"));
138 m_CmbViewWBF->Append(_("Current file\'s symbols"));
139 m_CmbViewWBF->Append(_("Active project\'s symbols"));
140 m_CmbViewWBF->SetSelection( m_CmbViewWBF->Append(_("All local symbols (workspace)")) );
141 BoxSizer3->Add(m_CmbViewWBF, 1, wxEXPAND, 0);
142 m_BtnHome = new wxBitmapButton(m_WBFMainPanel, idBtnHome, bmp_makevisible, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, _T("btnHome"));
143 m_BtnHome->SetDefault();
144 BoxSizer3->Add(m_BtnHome, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
145 FlexGridSizer1->Add(BoxSizer3, 1, wxALL|wxEXPAND, 0);
146 StaticText2 = new wxStaticText(m_WBFMainPanel, wxID_ANY, _("Search:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2"));
147 FlexGridSizer1->Add(StaticText2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
148 BoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
149 m_Search = new wxComboBox(m_WBFMainPanel, idCmbSearch, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, 0, wxCB_DROPDOWN|wxTE_PROCESS_ENTER, wxDefaultValidator, _T("cmbSearchWBF"));
150 BoxSizer4->Add(m_Search, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
151 FlexGridSizer1->Add(BoxSizer4, 1, wxALL|wxEXPAND, 0);
152 BoxSizer2->Add(FlexGridSizer1, 0, wxALL|wxEXPAND, 4);
153 m_SplitterWin = new wxSplitterWindow(m_WBFMainPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_LIVE_UPDATE, _T("splitterWinWBF"));
154 m_SplitterWin->SetSashGravity(0.5);
155 m_TreeTop = new wxTreeCtrl(m_SplitterWin, idMenuTopTree, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE, wxDefaultValidator, _T("treeAllWBF"));
156 m_TreeBottom = new wxTreeCtrl(m_SplitterWin, idMenuBottomTree, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT|wxTR_DEFAULT_STYLE, wxDefaultValidator, _T("treeMembersWBF"));
157 m_SplitterWin->SplitHorizontally(m_TreeTop, m_TreeBottom);
158 BoxSizer2->Add(m_SplitterWin, 1, wxALL|wxEXPAND, 0);
159 m_WBFMainPanel->SetSizer(BoxSizer2);
160 BoxSizer2->Fit(m_WBFMainPanel);
161 BoxSizer2->SetSizeHints(m_WBFMainPanel);
162 BoxSizer1->Add(m_WBFMainPanel, 1, wxALL|wxEXPAND, 0);
163 SetSizer(BoxSizer1);
164 BoxSizer1->Fit(this);
165 BoxSizer1->SetSizeHints(this);
166 }
167
168 // class destructor
~WorkspaceBrowserF()169 WorkspaceBrowserF::~WorkspaceBrowserF()
170 {
171 int pos = m_SplitterWin->GetSashPosition();
172 Manager::Get()->GetConfigManager(_T("fortran_project"))->Write(_T("/splitter_pos"), pos);
173 int filter = m_CmbViewWBF->GetSelection();
174 Manager::Get()->GetConfigManager(_T("fortran_project"))->Write(_T("/browser_display_filter"), filter);
175
176 if (m_pBrowserBuilder)
177 {
178 delete m_pBrowserBuilder;
179 }
180 }
181
UpdateSash()182 void WorkspaceBrowserF::UpdateSash()
183 {
184 int pos = Manager::Get()->GetConfigManager(_T("fortran_project"))->ReadInt(_T("/splitter_pos"), 250);
185 m_SplitterWin->SetSashPosition(pos, false);
186 }
187
UpdateView()188 void WorkspaceBrowserF::UpdateView()
189 {
190 m_pActiveProject = 0;
191 m_ActiveFilename.Clear();
192 if (Manager::IsAppShuttingDown())
193 return;
194
195 if (m_pParser)
196 {
197 m_pActiveProject = Manager::Get()->GetProjectManager()->GetActiveProject();
198 cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
199 if (ed)
200 m_ActiveFilename = ed->GetFilename();
201
202 if (m_pActiveProject)
203 BuildTree();
204 else if (m_pBrowserBuilder)
205 m_pBrowserBuilder->DeleteTopRootChildren();
206 }
207 else
208 m_TreeTop->DeleteAllItems();
209
210 }
211
ShowMenu(wxTreeCtrl * tree,wxTreeItemId id,cb_unused const wxPoint & pt)212 void WorkspaceBrowserF::ShowMenu(wxTreeCtrl* tree, wxTreeItemId id, cb_unused const wxPoint& pt)
213 {
214 // NOTE: local variables are tricky! If you build two local menus
215 // and attach menu B to menu A, on function exit both menu A and menu B
216 // will be destroyed. But when destroying menu A, menu B will be destroyed
217 // again. Its already-freed memory will be accessed, generating a segfault.
218
219 // A safer approach is to make all menus heap-based, and delete the topmost
220 // on exit.
221
222 m_TreeForPopupMenu = tree;
223 if ( !id.IsOk() )
224 return;
225
226 #if wxUSE_MENUS
227 wxString caption;
228 wxMenu *menu=new wxMenu(wxEmptyString);
229
230 TreeDataF* ctd = (TreeDataF*)tree->GetItemData(id);
231 if (ctd)
232 {
233 if (ctd->m_SpecialFolder==sfToken)
234 {
235 menu->Append(idMenuJumpToImplementation, _("Jump to &implementation"));
236 }
237 }
238
239 if (tree == m_TreeTop)
240 {
241 // only in top tree
242 if (menu->GetMenuItemCount() != 0)
243 menu->AppendSeparator();
244
245 menu->Append(idMenuRefreshTree, _("&Refresh tree"));
246
247 if (id == m_TreeTop->GetRootItem())
248 {
249 menu->Append(idMenuForceReparse, _("Re-&parse now"));
250 }
251 }
252 menu->AppendSeparator();
253 menu->AppendCheckItem(idMenuDoNotSort, _("Do not sort"));
254 menu->Check(idMenuDoNotSort, !m_BrowserOptions.sortAlphabetically);
255 menu->AppendCheckItem(idMenuSortAlphabetically, _("Sort alphabetically"));
256 menu->Check(idMenuSortAlphabetically, m_BrowserOptions.sortAlphabetically);
257
258 menu->AppendSeparator();
259 menu->AppendCheckItem(idMenuBottomTree, _("Display bottom tree"));
260 menu->Check(idMenuBottomTree, m_BrowserOptions.visibleBottomTree);
261
262
263 if (menu->GetMenuItemCount() != 0)
264 PopupMenu(menu);
265 delete menu; // Prevents memory leak
266 #endif // wxUSE_MENUS
267 }
268
269 // events
270
OnTreeItemRightClick(wxTreeEvent & event)271 void WorkspaceBrowserF::OnTreeItemRightClick(wxTreeEvent& event)
272 {
273 wxTreeCtrl* tree = (wxTreeCtrl*)event.GetEventObject();
274 tree->SelectItem(event.GetItem());
275 ShowMenu(tree, event.GetItem(), event.GetPoint());// + tree->GetPosition());
276 }
277
JumpToToken(TokenF * pToken)278 void WorkspaceBrowserF::JumpToToken(TokenF* pToken)
279 {
280 if (pToken)
281 {
282 LineAddress jumpStart;
283 LineAddress jumpFinish;
284 if(cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor())
285 {
286 cbStyledTextCtrl* control = ed->GetControl();
287 int curLine = control->LineFromPosition(control->GetCurrentPos());
288 jumpStart.Init(ed->GetFilename(), curLine, false);
289 }
290 EditorManager* edMan = Manager::Get()->GetEditorManager();
291 if (cbEditor* ed = edMan->Open(pToken->m_Filename))
292 {
293 ed->GotoLine(pToken->m_LineStart - 1);
294 wxFocusEvent ev(wxEVT_SET_FOCUS);
295 ev.SetWindow(this);
296 #if wxCHECK_VERSION(3, 0, 0)
297 ed->GetControl()->GetEventHandler()->AddPendingEvent(ev);
298 #else
299 ed->GetControl()->AddPendingEvent(ev);
300 #endif
301
302 // Track jump history
303 cbStyledTextCtrl* control = ed->GetControl();
304 int curLine = control->LineFromPosition(control->GetCurrentPos());
305 jumpFinish.Init(ed->GetFilename(), curLine, true);
306
307 m_NativeParser->GetJumpTracker()->TakeJump(jumpStart, jumpFinish);
308 m_NativeParser->GetFortranProject()->CheckEnableToolbar();
309 }
310 else
311 {
312 cbMessageBox(wxString::Format(_("Declaration not found: %s"), pToken->m_DisplayName.c_str()), _("Warning"), wxICON_WARNING);
313 }
314 }
315 }
316
OnJumpTo(cb_unused wxCommandEvent & event)317 void WorkspaceBrowserF::OnJumpTo(cb_unused wxCommandEvent& event)
318 {
319 wxTreeCtrl* tree = m_TreeForPopupMenu;
320 wxTreeItemId id = tree->GetSelection();
321 TreeDataF* ctd = (TreeDataF*)tree->GetItemData(id);
322 if (ctd && ctd->m_pToken)
323 {
324 JumpToToken(ctd->m_pToken);
325 }
326 }
327
OnTreeItemDoubleClick(wxTreeEvent & event)328 void WorkspaceBrowserF::OnTreeItemDoubleClick(wxTreeEvent& event)
329 {
330 wxTreeCtrl* tree = (wxTreeCtrl*)event.GetEventObject();
331 wxTreeItemId id = event.GetItem();
332 TreeDataF* ctd = (TreeDataF*)tree->GetItemData(id);
333 if (ctd && ctd->m_pToken)
334 {
335 JumpToToken(ctd->m_pToken);
336 }
337 }
338
OnRefreshTree(cb_unused wxCommandEvent & event)339 void WorkspaceBrowserF::OnRefreshTree(cb_unused wxCommandEvent& event)
340 {
341 UpdateView();
342 }
343
OnForceReparse(cb_unused wxCommandEvent & event)344 void WorkspaceBrowserF::OnForceReparse(cb_unused wxCommandEvent& event)
345 {
346 if (m_NativeParser)
347 {
348 switch (m_BrowserOptions.displayFilter)
349 {
350 case bdfWorkspace:
351 {
352 m_NativeParser->ForceReparseWorkspace();
353 break;
354 }
355 case bdfProject:
356 {
357 // NOTE (darius#1#): Force reparse workspace, just because currently only the workspace parsing is running on a secondary thread.
358 //m_NativeParser->ReparseProject(m_pActiveProject);
359 m_NativeParser->ForceReparseWorkspace();
360 UpdateView();
361 break;
362 }
363 case bdfFile:
364 {
365 wxString pFN;
366 if (m_pActiveProject)
367 pFN = m_pActiveProject->GetFilename();
368 m_NativeParser->ReparseFile(pFN, m_ActiveFilename);
369 UpdateView();
370 break;
371 }
372 }
373 }
374 }
375
OnViewScope(wxCommandEvent & event)376 void WorkspaceBrowserF::OnViewScope(wxCommandEvent& event)
377 {
378 m_BrowserOptions.displayFilter = (BrowserDisplayFilter)event.GetSelection();
379 UpdateView();
380 }
381
OnChangeSort(wxCommandEvent & event)382 void WorkspaceBrowserF::OnChangeSort(wxCommandEvent& event)
383 {
384 if (event.GetId() == idMenuDoNotSort)
385 m_BrowserOptions.sortAlphabetically = !event.IsChecked();
386 else if (event.GetId() == idMenuSortAlphabetically)
387 m_BrowserOptions.sortAlphabetically = event.IsChecked();
388 UpdateView();
389
390 ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("fortran_project"));
391 cfg->Write(_T("/browser_sort_alphabetically"),m_BrowserOptions.sortAlphabetically);
392 }
393
OnChangeMode(wxCommandEvent & event)394 void WorkspaceBrowserF::OnChangeMode(wxCommandEvent& event)
395 {
396 if (event.GetId() == idMenuBottomTree)
397 {
398 m_BrowserOptions.visibleBottomTree = event.IsChecked();
399
400 ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("fortran_project"));
401 cfg->Write(_T("/visible_bottom_tree"), m_BrowserOptions.visibleBottomTree);
402 }
403 UpdateView();
404 }
405
FindMatchTokens(wxString search,TokensArrayF & result)406 size_t WorkspaceBrowserF::FindMatchTokens(wxString search, TokensArrayF& result)
407 {
408 size_t count=0;
409 switch (m_BrowserOptions.displayFilter)
410 {
411 case bdfFile:
412 {
413 count = m_pParser->FindMatchTokens(m_ActiveFilename, search, result);
414 break;
415 }
416 case bdfProject:
417 {
418 for (FilesList::iterator it = m_pActiveProject->GetFilesList().begin(); it != m_pActiveProject->GetFilesList().end(); ++it)
419 {
420 ProjectFile* pf = *it;
421 count = m_pParser->FindMatchTokens(pf->file.GetFullPath(), search, result);
422 }
423 break;
424 }
425 case bdfWorkspace:
426 {
427 ProjectsArray* projects = Manager::Get()->GetProjectManager()->GetProjects();
428 for (size_t i=0; i < projects->GetCount(); ++i)
429 {
430 cbProject* project = projects->Item(i);
431 for (FilesList::iterator it = project->GetFilesList().begin(); it != project->GetFilesList().end(); ++it)
432 {
433 ProjectFile* pf = *it;
434 count = m_pParser->FindMatchTokens(pf->file.GetFullPath(), search, result);
435 }
436 }
437 break;
438 }
439 }
440 return count;
441 }
442
OnSearch(cb_unused wxCommandEvent & event)443 void WorkspaceBrowserF::OnSearch(cb_unused wxCommandEvent& event)
444 {
445 wxString search = m_Search->GetValue();
446 if (search.IsEmpty())
447 return;
448
449 TokenF* token = 0;
450 TokensArrayF result;
451 size_t count = FindMatchTokens(search, result);
452
453 size_t j=0;
454 while (j < count)
455 {
456 if ((result.Item(j)->m_TokenKind == tkVariable) ||
457 (result.Item(j)->m_TokenKind == tkCallFunction) ||
458 (result.Item(j)->m_TokenKind == tkCallSubroutine))
459 {
460 result.RemoveAt(j);
461 count--;
462 }
463 else
464 {
465 j++;
466 }
467 }
468
469 if (count == 0)
470 {
471 cbMessageBox(_("No matches were found: ") + search, _("Search failed"));
472 return;
473 }
474 else if (count == 1)
475 {
476 token = *result.begin();
477 }
478 else if (count > 1)
479 {
480 wxArrayString selections;
481 for (size_t i=0; i<count; ++i)
482 {
483 wxString inf = result.Item(i)->m_DisplayName;;
484 wxFileName fn = wxFileName(result.Item(i)->m_Filename);
485 inf << _T("::") << result.Item(i)->GetTokenKindString() << _T(", ") << fn.GetFullName() << _T(" : ");
486 inf << wxString::Format(_T("%d"), int(result.Item(i)->m_LineStart));
487 selections.Add(inf);
488 }
489 int sel = wxGetSingleChoiceIndex(_("Please make a selection:"), _("Multiple matches"), selections);
490 if (sel == -1)
491 return;
492 token = result.Item(sel);
493 }
494
495 // store the search in the combobox
496 if (m_Search->FindString(token->m_DisplayName) == wxNOT_FOUND)
497 m_Search->Append(token->m_DisplayName);
498
499 JumpToToken(token);
500 m_pBrowserBuilder->SelectItem(token);
501 }
502
BuildTree()503 void WorkspaceBrowserF::BuildTree()
504 {
505 if (Manager::IsAppShuttingDown())
506 return;
507
508 // create the WorkspaceBrowserBuilder if needed
509 if (!m_pBrowserBuilder)
510 {
511 m_pBrowserBuilder = new WorkspaceBrowserBuilder(m_pParser, m_TreeTop, m_TreeBottom);
512 }
513
514 if (m_BrowserOptions.visibleBottomTree)
515 {
516 m_SplitterWin->SplitHorizontally(m_TreeTop, m_TreeBottom);
517 m_TreeBottom->Show(true);
518 }
519 else
520 {
521 m_SplitterWin->Unsplit();
522 m_TreeBottom->Show(false);
523 }
524
525 // build tree
526 m_pBrowserBuilder->Init(
527 m_ActiveFilename,
528 m_pActiveProject,
529 m_BrowserOptions);
530 } // end of BuildTree
531
OnTreeItemSelected(wxTreeEvent & event)532 void WorkspaceBrowserF::OnTreeItemSelected(wxTreeEvent& event)
533 {
534 if (Manager::IsAppShuttingDown())
535 return;
536
537 if (m_pBrowserBuilder)
538 {
539 if (!m_pBrowserBuilder->SelectNode(event.GetItem()))
540 return;
541 }
542 event.Allow();
543
544 EditorManager* edMan = Manager::Get()->GetEditorManager();
545 if (!edMan)
546 return;
547 cbEditor* ed = edMan->GetBuiltinActiveEditor();
548 if (!ed)
549 return;
550 cbStyledTextCtrl* control = ed->GetControl();
551 int currentLine = control->GetCurrentLine() + 1;
552 wxString activeFilename = ed->GetFilename();
553 if (activeFilename.IsEmpty())
554 return;
555 MarkSymbol(UnixFilename(activeFilename), currentLine);
556 }
557
OnTreeItemExpanding(wxTreeEvent & event)558 void WorkspaceBrowserF::OnTreeItemExpanding(wxTreeEvent& event)
559 {
560 if (Manager::IsAppShuttingDown())
561 return;
562
563 m_pBrowserBuilder->ExpandTopNode(event.GetItem());
564 }
565
OnTreeItemCollapsing(wxTreeEvent & event)566 void WorkspaceBrowserF::OnTreeItemCollapsing(wxTreeEvent& event)
567 {
568 m_pBrowserBuilder->CollapsTopNode(event.GetItem());
569 //event.Allow();
570 }
571
GetTokenKindImageIdx(TokenF * token)572 int WorkspaceBrowserF::GetTokenKindImageIdx(TokenF* token)
573 {
574 if (m_pBrowserBuilder)
575 return m_pBrowserBuilder->GetTokenKindImageIdx(token);
576 return 0;
577 }
578
MarkSymbol(wxString filename,int line)579 void WorkspaceBrowserF::MarkSymbol(wxString filename, int line)
580 {
581 if (m_pBrowserBuilder)
582 {
583 m_pBrowserBuilder->MarkSymbol(filename, line);
584 }
585 }
586
SelectSymbol(wxString filename,int line)587 void WorkspaceBrowserF::SelectSymbol(wxString filename, int line)
588 {
589 if (m_pBrowserBuilder)
590 {
591 m_pBrowserBuilder->SelectSymbol(filename, line);
592 }
593 }
594
RereadOptions()595 void WorkspaceBrowserF::RereadOptions()
596 {
597 ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("fortran_project"));
598 if (cfg->ReadBool(_("/use_symbols_browser"), true))
599 {
600 m_BrowserOptions.visibleBottomTree = cfg->ReadBool(_("/visible_bottom_tree"), true);
601 m_BrowserOptions.sortAlphabetically = cfg->ReadBool(_("/browser_sort_alphabetically"), true);
602 m_BrowserOptions.showLocalVariables = cfg->ReadBool(_T("/browser_show_local_variables"), true);
603 m_BrowserOptions.showIncludeSeparately = cfg->ReadBool(_T("/browser_show_include_files_separately"), true);
604 UpdateView();
605 }
606 }
607
DeleteAllItems()608 void WorkspaceBrowserF::DeleteAllItems()
609 {
610 m_TreeTop->DeleteAllItems();
611 m_TreeBottom->DeleteAllItems();
612 }
613
OnMakeVisible(cb_unused wxCommandEvent & event)614 void WorkspaceBrowserF::OnMakeVisible(cb_unused wxCommandEvent& event)
615 {
616 if (m_pBrowserBuilder)
617 {
618 m_pBrowserBuilder->MakeVisibleCurrent();
619 }
620 }
621
OnMenuEditPaste(wxCommandEvent & event)622 void WorkspaceBrowserF::OnMenuEditPaste(wxCommandEvent& event)
623 {
624 wxWindow* pFocused = wxWindow::FindFocus();
625 if (!pFocused)
626 {
627 event.Skip();
628 return;
629 }
630
631 if (pFocused == m_Search)
632 m_Search->Paste();
633 else
634 event.Skip();
635
636 return;
637 }
638
SetActiveProject(cbProject * prj)639 void WorkspaceBrowserF::SetActiveProject(cbProject* prj)
640 {
641 m_pActiveProject = prj;
642 if (m_pBrowserBuilder)
643 {
644 m_pBrowserBuilder->SetActiveProject(prj);
645 }
646 }
647
648
649