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 <sdk.h>
8 #ifndef CB_PRECOMP
9 #include <wx/settings.h>
10 #include <wx/utils.h>
11 #include <wx/string.h>
12
13 #include <globals.h>
14 #include <manager.h>
15 #include <projectmanager.h>
16 #include <cbproject.h>
17 #endif
18
19 #include "workspacebrowserbuilder.h"
20
WorkspaceBrowserBuilder(ParserF * parser,wxTreeCtrl * treeTop,wxTreeCtrl * treeBottom)21 WorkspaceBrowserBuilder::WorkspaceBrowserBuilder(ParserF* parser, wxTreeCtrl* treeTop, wxTreeCtrl* treeBottom)
22 : m_pActiveProject(0),
23 m_Options()
24 {
25 m_AtWork = false;
26
27 m_pParser = parser;
28 m_pTreeTop = treeTop;
29 m_pTreeBottom = treeBottom;
30 int targetHeight = floor(16 * cbGetActualContentScaleFactor(*m_pTreeTop));
31 m_pImlist = new FPImageList(targetHeight);
32 m_pTreeTop->SetImageList(m_pImlist->GetImageList());
33 m_pTreeBottom->SetImageList(m_pImlist->GetImageList());
34 }
35
~WorkspaceBrowserBuilder()36 WorkspaceBrowserBuilder::~WorkspaceBrowserBuilder()
37 {
38 //dtor
39 delete m_pImlist;
40 }
41
Init(const wxString & active_filename,cbProject * active_project,const BrowserOptions & options)42 void WorkspaceBrowserBuilder::Init(const wxString& active_filename,
43 cbProject* active_project,
44 const BrowserOptions& options)
45 {
46 m_ActiveFilename = active_filename;
47 m_pActiveProject = active_project;
48 m_Options = options;
49
50 BuildTree();
51 }
52
BuildTree()53 void WorkspaceBrowserBuilder::BuildTree()
54 {
55 if (Manager::IsAppShuttingDown())
56 return;
57
58 if (!m_pParser)
59 return;
60
61 m_AtWork = true;
62
63 wxTreeItemId root = m_pTreeTop->GetRootItem();
64 if (!root.IsOk())
65 {
66 root = m_pTreeTop->AddRoot(_("Symbols"), m_pImlist->GetImageIdx("symbols_folder"), m_pImlist->GetImageIdx("symbols_folder"), new TreeDataF(sfRoot));
67 m_pTreeTop->SetItemHasChildren(root);
68 }
69
70 wxString oldSelText;
71 wxString oldParentText;
72 bool oldParent_isRoot = false;
73 wxTreeItemId oldSel = m_pTreeTop->GetSelection();
74 if (oldSel.IsOk())
75 {
76 oldSelText = m_pTreeTop->GetItemText(oldSel);
77 wxTreeItemId oldParent = m_pTreeTop->GetItemParent(oldSel);
78 oldParent_isRoot = (root == oldParent);
79 if (oldParent.IsOk())
80 {
81 oldParentText = m_pTreeTop->GetItemText(oldParent);
82 }
83 }
84
85 m_pTreeTop->Hide();
86 m_pTreeTop->Freeze();
87 wxArrayString expandedBottomNodes;
88 if (m_Options.visibleBottomTree)
89 {
90 MakeExpandedNodesArray(expandedBottomNodes);
91 m_pTreeBottom->Hide();
92 m_pTreeBottom->Freeze();
93 }
94
95 m_pTreeTop->DeleteChildren(root);
96
97 wxTreeItemId root_bot = m_pTreeBottom->GetRootItem();
98 if (root_bot.IsOk())
99 m_pTreeBottom->DeleteChildren(root_bot);
100
101 if (!Manager::IsAppShuttingDown())
102 {
103 ExpandTop();
104 m_pTreeTop->Expand(root);
105 if (!m_Options.visibleBottomTree)
106 {
107 size_t i=0;
108 while ( i < m_ExpandedNodes.GetCount() )
109 {
110 wxTreeItemId item = FindItemByName(m_pTreeTop, m_ExpandedNodes[i]);
111 if (item.IsOk())
112 {
113 m_pTreeTop->Expand(item);
114 i++;
115 }
116 else
117 {
118 m_ExpandedNodes.RemoveAt(i);
119 }
120 }
121 }
122 else
123 m_ExpandedNodes.Clear();
124 }
125
126 if (m_Options.visibleBottomTree)
127 {
128 m_pTreeBottom->Thaw();
129 m_pTreeBottom->Show();
130 }
131
132 m_pTreeTop->Thaw();
133 m_pTreeTop->Show();
134
135 m_AtWork = false;
136
137 if (!oldSelText.IsEmpty())
138 {
139 if ( !oldParent_isRoot )
140 {
141 wxTreeItemId item = FindItemByName(m_pTreeTop, oldParentText, oldSelText); // refresh selection
142 if (item.IsOk())
143 m_pTreeTop->SelectItem(item);
144 }
145 else
146 {
147 wxTreeItemId item = FindItemByName(m_pTreeTop, oldSelText); // refresh selection
148 if (item.IsOk())
149 {
150 m_pTreeTop->SelectItem(item);
151 ExpandBottomNodes(expandedBottomNodes);
152 }
153 }
154 }
155 }
156
DeleteTopRootChildren()157 void WorkspaceBrowserBuilder::DeleteTopRootChildren()
158 {
159 if (Manager::IsAppShuttingDown())
160 return;
161
162 wxTreeItemId root = m_pTreeTop->GetRootItem();
163 if (root.IsOk())
164 {
165 m_pTreeTop->DeleteChildren(root);
166 }
167 }
168
MakeExpandedNodesArray(wxArrayString & expandedBottomNodes)169 void WorkspaceBrowserBuilder::MakeExpandedNodesArray(wxArrayString &expandedBottomNodes)
170 {
171 if (!m_Options.visibleBottomTree)
172 return;
173
174 wxTreeItemIdValue cookie;
175 wxTreeItemId root = m_pTreeBottom->GetRootItem();
176 if (!root.IsOk())
177 return;
178 wxTreeItemId item = m_pTreeBottom->GetFirstChild(root, cookie);
179 while (item.IsOk())
180 {
181 if (m_pTreeBottom->IsExpanded(item))
182 {
183 wxTreeItemIdValue cookie2;
184 wxTreeItemId item2 = m_pTreeBottom->GetFirstChild(item, cookie2);
185 while (item2.IsOk())
186 {
187 if (m_pTreeBottom->IsExpanded(item2))
188 {
189 expandedBottomNodes.Add(m_pTreeBottom->GetItemText(item));
190 expandedBottomNodes.Add(m_pTreeBottom->GetItemText(item2));
191 }
192 item2 = m_pTreeBottom->GetNextChild(item, cookie2);
193 }
194 }
195 item = m_pTreeBottom->GetNextChild(root, cookie);
196 }
197 }
198
ExpandBottomNodes(wxArrayString & expandedBottomNodes)199 void WorkspaceBrowserBuilder::ExpandBottomNodes(wxArrayString &expandedBottomNodes)
200 {
201 if (!m_Options.visibleBottomTree)
202 return;
203
204 for (size_t i=1; i<expandedBottomNodes.Count(); i+=2)
205 {
206 wxTreeItemId item = FindItemByName(m_pTreeBottom, expandedBottomNodes.Item(i-1), expandedBottomNodes.Item(i));
207 if (item.IsOk())
208 m_pTreeBottom->Expand(item);
209 }
210 }
211
HasChildren(TokenF * tokenParent,int tokenKindMask)212 bool WorkspaceBrowserBuilder::HasChildren(TokenF* tokenParent, int tokenKindMask)
213 {
214 bool has = false;
215 size_t chilCount = tokenParent->m_Children.GetCount();
216 for (size_t j=0; j<chilCount; ++j)
217 {
218 TokenF* tok1 = tokenParent->m_Children.Item(j);
219 if (tok1->m_TokenKind & tokenKindMask)
220 {
221 has = true;
222 break;
223 }
224 }
225 return has;
226 }
227
HasGlobalFunctionsOthers(int tokenKindMask)228 bool WorkspaceBrowserBuilder::HasGlobalFunctionsOthers(int tokenKindMask)
229 {
230 bool has = false;
231 if (Manager::IsAppShuttingDown())
232 return has;
233
234 switch (m_Options.displayFilter)
235 {
236 case bdfFile:
237 {
238 if (!m_ActiveFilename.IsEmpty())
239 has = FileHasTokens(UnixFilename(m_ActiveFilename), tokenKindMask);
240 break;
241 }
242 case bdfProject:
243 {
244 for (FilesList::iterator it = m_pActiveProject->GetFilesList().begin(); it != m_pActiveProject->GetFilesList().end(); ++it)
245 {
246 ProjectFile* pf = *it;
247 if (FileHasTokens(UnixFilename(pf->file.GetFullPath()), tokenKindMask))
248 {
249 has = true;
250 break;
251 }
252 }
253 break;
254 }
255 case bdfWorkspace:
256 {
257
258 TokensArrayF* pTokens = m_pParser->GetTokens();
259 for (size_t i=0; i< pTokens->GetCount(); ++i)
260 {
261 TokenF* token = pTokens->Item(i);
262 if (token->m_TokenKind == tkFile)
263 {
264 for (size_t j=0; j < token->m_Children.GetCount(); ++j)
265 {
266 TokenF* tok1 = token->m_Children.Item(j);
267 if (tok1->m_TokenKind & tokenKindMask)
268 {
269 has = true;
270 break;
271 }
272 }
273 if (has)
274 break;
275 }
276 }
277 break;
278 }
279 }
280 return has;
281 }
282
FileHasTokens(const wxString & fileName,int tokenKindMask)283 bool WorkspaceBrowserBuilder::FileHasTokens(const wxString& fileName, int tokenKindMask)
284 {
285 TokensArrayF* pTokens = m_pParser->GetTokens();
286 bool has = false;
287
288 for (size_t i=0; i< pTokens->GetCount(); ++i)
289 {
290 TokenF* token = pTokens->Item(i);
291
292 if (token->m_TokenKind == tkFile && token->m_Filename.IsSameAs(fileName))
293 {
294 for (size_t j=0; j < token->m_Children.GetCount(); ++j)
295 {
296 TokenF* tok1 = token->m_Children.Item(j);
297 if (tok1->m_TokenKind & tokenKindMask)
298 {
299 has = true;
300 break;
301 }
302 }
303 break;
304 }
305 }
306 return has;
307 }
308
AddTreeChildren(wxTreeCtrl * tree,wxTreeItemId parent,int tokenKindMask)309 void WorkspaceBrowserBuilder::AddTreeChildren(wxTreeCtrl* tree, wxTreeItemId parent, int tokenKindMask)
310 {
311 if (Manager::IsAppShuttingDown())
312 return;
313
314 switch (m_Options.displayFilter)
315 {
316 case bdfFile:
317 {
318 if (!m_ActiveFilename.IsEmpty() &&
319 (!m_Options.showIncludeSeparately ||
320 (m_Options.showIncludeSeparately && !m_pParser->IsIncludeFile(m_ActiveFilename))))
321 {
322 AddFileNodes(tree, parent, UnixFilename(m_ActiveFilename), tokenKindMask);
323 }
324 break;
325 }
326 case bdfProject:
327 {
328 for (FilesList::iterator it = m_pActiveProject->GetFilesList().begin(); it != m_pActiveProject->GetFilesList().end(); ++it)
329 {
330 ProjectFile* pf = *it;
331 if (!m_Options.showIncludeSeparately ||
332 (m_Options.showIncludeSeparately && !m_pParser->IsIncludeFile(pf->file.GetFullPath())))
333 AddFileNodes(tree, parent, UnixFilename(pf->file.GetFullPath()), tokenKindMask);
334 }
335 break;
336 }
337 case bdfWorkspace:
338 {
339 TokensArrayF* pTokens = m_pParser->GetTokens();
340 if (!pTokens)
341 break;
342 for (size_t i=0; i< pTokens->GetCount(); ++i)
343 {
344 TokenF* token = pTokens->Item(i);
345 if (token->m_TokenKind == tkFile &&
346 (!m_Options.showIncludeSeparately ||
347 (m_Options.showIncludeSeparately && !m_pParser->IsIncludeFile(token->m_Filename))))
348 {
349 AddChildrenNodes(tree, parent, token, tokenKindMask);
350 }
351 }
352 break;
353 }
354 }
355 }
356
AddFileNodes(wxTreeCtrl * tree,wxTreeItemId parent,wxString file,int tokenKindMask)357 bool WorkspaceBrowserBuilder::AddFileNodes(wxTreeCtrl* tree, wxTreeItemId parent, wxString file, int tokenKindMask)
358 {
359 TokensArrayF* pTokens = m_pParser->GetTokens();
360
361 size_t tokCount = pTokens->GetCount();
362 for (size_t i=0; i<tokCount; ++i)
363 {
364 TokenF* token = pTokens->Item(i);
365
366 if (token->m_TokenKind == tkFile && token->m_Filename.IsSameAs(file))
367 {
368 return AddChildrenNodes(tree, parent, token, tokenKindMask);
369 }
370 }
371 return false;
372 }
373
AddChildrenNodes(wxTreeCtrl * tree,wxTreeItemId parent,TokenF * parToken,int tokenKindMask)374 bool WorkspaceBrowserBuilder::AddChildrenNodes(wxTreeCtrl* tree, wxTreeItemId parent, TokenF* parToken, int tokenKindMask)
375 {
376 int count = 0;
377 bool sorted = m_Options.sortAlphabetically || (tree == m_pTreeTop && parToken->m_TokenKind == tkFile);
378 TokensArrayF* pTokens = &parToken->m_Children;
379
380 if (parToken->m_TokenKind == tkType)
381 {
382 count += AddTypeChildren(tree, parent, pTokens);
383 return count != 0;
384 }
385
386 int childKM = tkFunction | tkProgram | tkSubroutine | tkPreprocessor | tkInterface | tkInterfaceExplicit | tkBlockData |
387 tkType | tkVariable | tkProcedure | tkAccessList;
388 int interfaceMask = tkInterface | tkInterfaceExplicit;
389 int funChildKM = childKM ^ tkVariable;
390
391 if (!m_Options.showLocalVariables && (parToken->m_TokenKind == tkSubroutine || parToken->m_TokenKind == tkFunction || parToken->m_TokenKind == tkProgram))
392 {
393 childKM = childKM ^ tkVariable;
394 if (tokenKindMask & tkVariable)
395 tokenKindMask = tokenKindMask ^ tkVariable;
396 }
397
398 size_t tokCount = pTokens->GetCount();
399 for (size_t i=0; i<tokCount; ++i)
400 {
401 TokenF* token = pTokens->Item(i);
402 if (token->m_TokenKind & tokenKindMask)
403 {
404 if (token->m_TokenKind & interfaceMask)
405 {
406 count += AddInterfaceNode(tree, parent, token);
407 }
408 else
409 {
410 wxString nameDisp = token->m_DisplayName;
411 if (token->m_TokenKind == tkVariable)
412 nameDisp << _T(" : ") << token->m_PartFirst;
413 wxTreeItemId idni = AddNodeIfNotThere(tree, parent, nameDisp, GetTokenKindImageIdx(token), new TreeDataF(sfToken, token), sorted);
414 count++;
415 if (tree == m_pTreeTop && !m_Options.visibleBottomTree)
416 {
417 if (!m_Options.showLocalVariables && (token->m_TokenKind == tkSubroutine || token->m_TokenKind == tkFunction))
418 {
419 if (HasChildren(token, funChildKM))
420 tree->SetItemHasChildren(idni);
421 }
422 else
423 {
424 if (HasChildren(token, childKM))
425 tree->SetItemHasChildren(idni);
426 }
427 }
428 else if(tree == m_pTreeBottom && HasChildren(token, childKM))
429 {
430 AddChildrenNodes(tree, idni, token, childKM);
431 }
432 }
433 }
434 }
435 return count != 0;
436 }
437
AddInterfaceNode(wxTreeCtrl * tree,wxTreeItemId parent,TokenF * parToken)438 int WorkspaceBrowserBuilder::AddInterfaceNode(wxTreeCtrl* tree, wxTreeItemId parent, TokenF* parToken)
439 {
440 int count = 0;
441 bool sorted = m_Options.sortAlphabetically;
442
443 if (!parToken->m_Name.IsEmpty())
444 {
445 wxString name;
446 if (parToken->m_DisplayName.StartsWith(_T("%%")))
447 {
448 name = parToken->m_DisplayName.Mid(2);
449 }
450 else
451 {
452 name = parToken->m_DisplayName;
453 }
454 AddNodeIfNotThere(tree, parent, name, GetTokenKindImageIdx(parToken), new TreeDataF(sfToken, parToken), sorted);
455 count++;
456 }
457 else
458 {
459 TokensArrayF* pTokens = &parToken->m_Children;
460 if (pTokens)
461 {
462 int childKM = tkFunction | tkSubroutine;
463 int imageIdx;
464 for (size_t i=0; i< pTokens->GetCount(); ++i)
465 {
466 TokenF* token = pTokens->Item(i);
467 if (token->m_TokenKind & childKM)
468 {
469 if (token->m_TokenKind == tkFunction)
470 {
471 if (token->m_TokenAccess == taPublic)
472 imageIdx = m_pImlist->GetImageIdx("interface_function");
473 else
474 imageIdx = m_pImlist->GetImageIdx("interface_function_private");
475 }
476 else
477 {
478 if (token->m_TokenAccess == taPublic)
479 imageIdx = m_pImlist->GetImageIdx("interface_subroutine");
480 else
481 imageIdx = m_pImlist->GetImageIdx("interface_subroutine_private");
482 }
483 AddNodeIfNotThere(tree, parent, token->m_DisplayName, imageIdx, new TreeDataF(sfToken, token), sorted);
484 count++;
485 }
486 }
487 }
488 }
489 return count;
490 }
491
AddTypeChildren(wxTreeCtrl * tree,wxTreeItemId parent,TokensArrayF * pTokens)492 int WorkspaceBrowserBuilder::AddTypeChildren(wxTreeCtrl* tree, wxTreeItemId parent, TokensArrayF* pTokens)
493 {
494 int count = 0;
495 bool sorted = m_Options.sortAlphabetically;
496 TokensArrayF varTokens;
497 TokensArrayF otherTokens;
498
499 size_t tokCount = pTokens->GetCount();
500 for (size_t i=0; i<tokCount; ++i)
501 {
502 TokenF* token = pTokens->Item(i);
503 if (token->m_TokenKind == tkVariable)
504 {
505 if (sorted)
506 {
507 size_t j;
508 for (j=0; j<varTokens.GetCount(); j++)
509 {
510 if (token->m_DisplayName.CmpNoCase(varTokens.Item(j)->m_DisplayName) < 0)
511 break;
512 }
513 varTokens.Insert(token, j);
514 }
515 else
516 {
517 varTokens.Add(token);
518 }
519 }
520 else
521 {
522 if (sorted)
523 {
524 wxString name;
525 if (token->m_DisplayName.StartsWith(_T("%%")))
526 name = token->m_DisplayName.Mid(2);
527 else
528 name = token->m_DisplayName;
529 size_t j;
530 for (j=0; j<otherTokens.GetCount(); j++)
531 {
532 if (name.CmpNoCase(otherTokens.Item(j)->m_DisplayName) < 0)
533 break;
534 }
535 otherTokens.Insert(token, j);
536 }
537 else
538 {
539 otherTokens.Add(token);
540 }
541 }
542 }
543
544 tokCount = varTokens.GetCount();
545 for (size_t i=0; i<tokCount; ++i)
546 {
547 wxString nameDisp;
548 nameDisp << varTokens.Item(i)->m_DisplayName << _T(" : ") << varTokens.Item(i)->m_PartFirst;
549 AddNodeIfNotThere(tree, parent, nameDisp,
550 GetTokenKindImageIdx(varTokens.Item(i)), new TreeDataF(sfToken, varTokens.Item(i)), false);
551 count++;
552 }
553
554 tokCount = otherTokens.GetCount();
555 for (size_t i=0; i<tokCount; ++i)
556 {
557 wxString name;
558 if (otherTokens.Item(i)->m_DisplayName.StartsWith(_T("%%")))
559 name = otherTokens.Item(i)->m_DisplayName.Mid(2);
560 else
561 name = otherTokens.Item(i)->m_DisplayName;
562 AddNodeIfNotThere(tree, parent, name,
563 GetTokenKindImageIdx(otherTokens.Item(i)), new TreeDataF(sfToken, otherTokens.Item(i)), false);
564 count++;
565 }
566
567 return count;
568 }
569
SelectNode(wxTreeItemId node)570 bool WorkspaceBrowserBuilder::SelectNode(wxTreeItemId node)
571 {
572 // m_pTreeTop node was selected
573 if (Manager::IsAppShuttingDown() || (!(node.IsOk())) || m_AtWork)
574 return false;
575
576 m_pTreeBottom->Freeze();
577 wxTreeItemId root = m_pTreeBottom->GetRootItem();
578 if (!root)
579 root = m_pTreeBottom->AddRoot(_T("Members"));
580 else
581 m_pTreeBottom->DeleteChildren(root);
582 TreeDataF* data = (TreeDataF*)m_pTreeTop->GetItemData(node);
583 if (data)
584 {
585 switch (data->m_SpecialFolder)
586 {
587 case sfGFuncs:
588 {
589 AddTreeChildren(m_pTreeBottom, root, tkFunction | tkProgram | tkSubroutine);
590 break;
591 }
592 case sfOthers:
593 {
594 AddTreeChildren(m_pTreeBottom, root, tkPreprocessor | tkInterface | tkBlockData);
595 if (m_Options.showIncludeSeparately)
596 AddIncludeFiles(m_pTreeBottom, root);
597 break;
598 }
599 case sfToken:
600 {
601 wxTreeItemId rootTypes = m_pTreeBottom->AppendItem(root, _("Types"), m_pImlist->GetImageIdx("typedefs_folder"));
602 wxTreeItemId rootOthers = m_pTreeBottom->AppendItem(root, _("Others"), m_pImlist->GetImageIdx("others_folder"));
603 wxTreeItemId rootFuncs = m_pTreeBottom->AppendItem(root, _("Procedures"), m_pImlist->GetImageIdx("function_folder"));
604
605 TokenF* pToken = data->m_pToken;
606 AddChildrenNodes(m_pTreeBottom, rootTypes, pToken, tkType);
607 AddChildrenNodes(m_pTreeBottom, rootOthers, pToken, tkInterface | tkInterfaceExplicit | tkAccessList | tkVariable);
608 AddChildrenNodes(m_pTreeBottom, rootFuncs, pToken, tkFunction | tkSubroutine | tkProcedure);
609
610 m_pTreeBottom->Expand(rootTypes);
611 m_pTreeBottom->Expand(rootOthers);
612 m_pTreeBottom->Expand(rootFuncs);
613 //ExpandAll();
614
615 break;
616 }
617 default: break;
618 }
619 }
620 m_pTreeBottom->Thaw();
621 return true;
622 }
623
AddNodeIfNotThere(wxTreeCtrl * tree,wxTreeItemId parent,const wxString & name,int imgIndex,TreeDataF * data,bool sorted)624 wxTreeItemId WorkspaceBrowserBuilder::AddNodeIfNotThere(wxTreeCtrl* tree, wxTreeItemId parent, const wxString& name, int imgIndex, TreeDataF* data, bool sorted)
625 {
626 SpecialFolder new_type = data->m_SpecialFolder;
627
628 wxTreeItemIdValue cookie = 0;
629
630 wxTreeItemId insert_after; // node to insert after; we 'll be looping all children so we might as well sort at the same time
631 wxTreeItemId existing = tree->GetFirstChild(parent, cookie);
632 while (existing.IsOk())
633 {
634 wxString itemText = tree->GetItemText(existing);
635 if (itemText.IsSameAs(name))
636 {
637 if (tree->GetItemImage(existing) == imgIndex)
638 {
639 tree->SetItemImage(existing, imgIndex, wxTreeItemIcon_Normal);
640 tree->SetItemImage(existing, imgIndex, wxTreeItemIcon_Selected);
641 delete tree->GetItemData(existing); // make Valgrind happy
642 tree->SetItemData(existing, data);
643
644 return existing;
645 }
646 }
647
648 if (sorted)
649 {
650 TreeDataF* existing_data = (TreeDataF*)tree->GetItemData(existing);
651 if (existing_data)
652 {
653 SpecialFolder existing_type = existing_data->m_SpecialFolder;
654
655 // first go special folders
656 if ((existing_type & (sfGFuncs | sfOthers)) &&
657 !(new_type & (sfGFuncs | sfOthers)))
658 {
659 insert_after = existing;
660 }
661 // then everything else, alphabetically
662 else if (name.CmpNoCase(itemText) >= 0)
663 {
664 insert_after = existing;
665 }
666 else // name.CmpNoCase(itemText) < 0
667 {
668 break;
669 }
670 }
671 }
672 existing = tree->GetNextChild(parent, cookie);
673 }
674
675 if (sorted)
676 existing = tree->InsertItem(parent, insert_after, name, imgIndex, imgIndex, data);
677 else
678 existing = tree->AppendItem(parent, name, imgIndex, imgIndex, data);
679 return existing;
680 }
681
CreateSpecialFolders()682 void WorkspaceBrowserBuilder::CreateSpecialFolders()
683 {
684 wxTreeItemId parent = m_pTreeTop->GetRootItem();
685 wxTreeItemId gfuncs = AddNodeIfNotThere(m_pTreeTop, parent, _("Global procedures"), m_pImlist->GetImageIdx("function_folder"), new TreeDataF(sfGFuncs, 0));
686 wxTreeItemId others = AddNodeIfNotThere(m_pTreeTop, parent, _("Others"), m_pImlist->GetImageIdx("others_folder"), new TreeDataF(sfOthers, 0));
687
688 if (!m_Options.visibleBottomTree)
689 {
690 if (HasGlobalFunctionsOthers(tkFunction | tkProgram | tkSubroutine))
691 m_pTreeTop->SetItemHasChildren(gfuncs);
692 if (HasGlobalFunctionsOthers(tkPreprocessor | tkInterface | tkBlockData) ||
693 (m_Options.showIncludeSeparately && m_pParser->HasIncludeFiles()))
694 m_pTreeTop->SetItemHasChildren(others);
695 }
696 }
697
ExpandTop()698 void WorkspaceBrowserBuilder::ExpandTop()
699 {
700 if (Manager::IsAppShuttingDown())
701 return;
702
703 CreateSpecialFolders();
704 wxTreeItemId root = m_pTreeTop->GetRootItem();
705 AddTreeChildren(m_pTreeTop, root, tkModule | tkSubmodule);
706 }
707
ExpandTopNode(wxTreeItemId node)708 void WorkspaceBrowserBuilder::ExpandTopNode(wxTreeItemId node)
709 {
710 if (Manager::IsAppShuttingDown() || (!(node.IsOk())) || (node == m_pTreeTop->GetRootItem()))
711 return;
712
713 m_pTreeTop->Freeze();
714 TreeDataF* data = (TreeDataF*)m_pTreeTop->GetItemData(node);
715 if (data)
716 {
717 wxString disName;
718 switch (data->m_SpecialFolder)
719 {
720 case sfGFuncs:
721 {
722 AddTreeChildren(m_pTreeTop, node, tkFunction | tkProgram | tkSubroutine);
723 break;
724 }
725 case sfOthers:
726 {
727 AddTreeChildren(m_pTreeTop, node, tkPreprocessor | tkInterface | tkBlockData);
728 if (m_Options.showIncludeSeparately)
729 AddIncludeFiles(m_pTreeTop, node);
730 break;
731 }
732 case sfToken:
733 {
734 TokenF* pToken = data->m_pToken;
735 AddChildrenNodes(m_pTreeTop, node, pToken, tkFunction | tkSubroutine | tkInterface | tkType | tkVariable |
736 tkProcedure | tkAccessList | tkInterfaceExplicit);
737 break;
738 }
739 default: break;
740 }
741 disName = m_pTreeTop->GetItemText(node);
742 if (m_ExpandedNodes.Index(disName) == wxNOT_FOUND)
743 m_ExpandedNodes.Add(disName);
744 }
745 m_pTreeTop->Thaw();
746 }
747
CollapsTopNode(wxTreeItemId node)748 void WorkspaceBrowserBuilder::CollapsTopNode(wxTreeItemId node)
749 {
750 if (Manager::IsAppShuttingDown() || (!(node.IsOk())) || (node == m_pTreeTop->GetRootItem()))
751 return;
752
753 int indx = m_ExpandedNodes.Index(m_pTreeTop->GetItemText(node));
754 if (indx != wxNOT_FOUND)
755 {
756 m_ExpandedNodes.RemoveAt(indx);
757 }
758 }
759
SelectItem(TokenF * token)760 void WorkspaceBrowserBuilder::SelectItem(TokenF* token)
761 {
762 if (Manager::IsAppShuttingDown())
763 return;
764
765 wxTreeItemId item;
766 if (token && token->m_pParent)
767 {
768 if (token->m_pParent->m_TokenKind == tkFile)
769 {
770 if (token->m_TokenKind == tkFunction)
771 {
772 item = FindItemByName(m_pTreeTop, _("Global procedures"));
773 if (item.IsOk())
774 {
775 m_pTreeTop->SelectItem(item);
776 item = FindItemByName(m_pTreeBottom, token->m_DisplayName);
777 if (item.IsOk())
778 m_pTreeBottom->SelectItem(item);
779 }
780 }
781 else if (token->m_TokenKind == tkPreprocessor)
782 {
783 item = FindItemByName(m_pTreeTop, _("Preprocessor symbols"));
784 if (item.IsOk())
785 {
786 m_pTreeTop->SelectItem(item);
787 item = FindItemByName(m_pTreeBottom, token->m_DisplayName);
788 if (item.IsOk())
789 m_pTreeBottom->SelectItem(item);
790 }
791 }
792 else if (token->m_TokenKind == tkModule || token->m_TokenKind == tkSubmodule)
793 {
794 item = FindItemByName(m_pTreeTop, token->m_DisplayName);
795 if (item.IsOk())
796 m_pTreeTop->SelectItem(item);
797 }
798 }
799 else if (token->m_pParent->m_TokenKind == tkModule || token->m_pParent->m_TokenKind == tkSubmodule)
800 {
801 item = FindItemByName(m_pTreeTop, token->m_pParent->m_DisplayName);
802 if (item.IsOk())
803 {
804 m_pTreeTop->SelectItem(item);
805 item = FindItemByName(m_pTreeBottom, token->m_DisplayName);
806 if (item.IsOk())
807 m_pTreeBottom->SelectItem(item);
808 }
809 }
810 }
811 }
812
FindItemByName(wxTreeCtrl * tree,wxString name,wxString name2)813 wxTreeItemId WorkspaceBrowserBuilder::FindItemByName(wxTreeCtrl* tree, wxString name, wxString name2)
814 {
815 bool foundFirst = false;
816 wxTreeItemId firstItem;
817
818 wxTreeItemIdValue cookie;
819 wxTreeItemId root = tree->GetRootItem();
820 if (!root.IsOk())
821 return root;
822 wxTreeItemId item = tree->GetFirstChild(root, cookie);
823 while (item.IsOk())
824 {
825 if (tree->GetItemText(item).IsSameAs(name))
826 {
827 if (name2.IsEmpty())
828 return item;
829 else
830 {
831 firstItem = item;
832 foundFirst = true;
833 break;
834 }
835 }
836 else if(name2.IsEmpty())
837 {
838 wxTreeItemIdValue cookie2;
839 wxTreeItemId item2 = tree->GetFirstChild(item, cookie2);
840 while (item2.IsOk())
841 {
842 if (tree->GetItemText(item2).IsSameAs(name))
843 {
844 return item2;
845 }
846 item2 = tree->GetNextChild(item, cookie2);
847 }
848 }
849 item = tree->GetNextChild(root, cookie);
850 }
851 if (!name2.IsEmpty() && foundFirst)
852 {
853 wxTreeItemIdValue cookie3;
854 wxTreeItemId item2 = tree->GetFirstChild(firstItem, cookie3);
855 while (item2.IsOk())
856 {
857 if (tree->GetItemText(item2).IsSameAs(name2))
858 {
859 return item2;
860 }
861 item2 = tree->GetNextChild(item, cookie3);
862 }
863 return firstItem;
864 }
865 item.Unset();
866 return item;
867 }
868
GetTokenKindImageIdx(TokenF * token)869 int WorkspaceBrowserBuilder::GetTokenKindImageIdx(TokenF* token)
870 {
871 return m_pImlist->GetTokenKindImageIdx(token);
872 }
873
SelectSymbol(const wxString & filename,int line)874 void WorkspaceBrowserBuilder::SelectSymbol(const wxString& filename, int line)
875 {
876 if (Manager::IsAppShuttingDown() || m_AtWork)
877 return;
878
879 bool found = false;
880 wxTreeItemIdValue cookie;
881 wxTreeItemId root = m_pTreeTop->GetRootItem();
882 if(!root.IsOk())
883 return;
884 wxTreeItemId item = m_pTreeTop->GetFirstChild(root, cookie);
885 wxTreeItemId itemGlob;
886 bool haveGlob = false;
887 wxTreeItemId itemOthers;
888 while (item.IsOk())
889 {
890 TreeDataF* data = (TreeDataF*)m_pTreeTop->GetItemData(item);
891 if (data)
892 {
893 switch (data->m_SpecialFolder)
894 {
895 case sfGFuncs:
896 {
897 itemGlob = item;
898 haveGlob = true;
899 break;
900 }
901 case sfToken:
902 {
903 if (data->m_pToken->m_Filename.IsSameAs(filename))
904 {
905 if (((int)data->m_pToken->m_LineStart <= line) && ((int)data->m_pToken->m_LineEnd >= line))
906 {
907 m_pTreeTop->SelectItem(item);
908 if (m_Options.visibleBottomTree)
909 {
910 SelectBottomSymbol(filename, line);
911 }
912 found = true;
913 }
914 }
915 break;
916 }
917 default:
918 {
919 break;
920 }
921 }
922 if (found)
923 break;
924 }
925 item = m_pTreeTop->GetNextChild(root, cookie);
926 }
927
928 if (!found && haveGlob)
929 {
930 if (m_Options.visibleBottomTree)
931 {
932 m_pTreeTop->SelectItem(itemGlob);
933 SelectBottomSymbol(filename, line);
934 }
935 }
936 }
937
SelectBottomSymbol(const wxString & filename,int line)938 bool WorkspaceBrowserBuilder::SelectBottomSymbol(const wxString& filename, int line)
939 {
940 wxTreeItemIdValue cookie;
941 wxTreeItemId root = m_pTreeBottom->GetRootItem();
942 if (!root.IsOk())
943 return false;
944 wxTreeItemId item = m_pTreeBottom->GetFirstChild(root, cookie);
945 while (item.IsOk())
946 {
947 TreeDataF* data = (TreeDataF*)m_pTreeBottom->GetItemData(item);
948 if (data)
949 {
950 if (data->m_SpecialFolder == sfToken)
951 {
952 if (data->m_pToken->m_Filename.IsSameAs(filename))
953 {
954 if (((int)data->m_pToken->m_LineStart <= line) && ((int)data->m_pToken->m_LineEnd >= line))
955 {
956 m_pTreeBottom->SelectItem(item);
957 return true;
958 }
959 }
960 }
961 else if(data->m_SpecialFolder == sfFile)
962 {
963 if (data->m_pToken->m_Filename.IsSameAs(filename))
964 {
965 m_pTreeBottom->SelectItem(item);
966 return true;
967 }
968 }
969 }
970 else
971 {
972 wxTreeItemIdValue cookie2;
973 wxTreeItemId item2 = m_pTreeBottom->GetFirstChild(item, cookie2);
974 while (item2.IsOk())
975 {
976 TreeDataF* data2 = (TreeDataF*)m_pTreeBottom->GetItemData(item2);
977 if (data2)
978 {
979 if (data2->m_SpecialFolder == sfToken)
980 {
981 if (data2->m_pToken->m_Filename.IsSameAs(filename)
982 && (int)data2->m_pToken->m_LineStart <= line
983 && (int)data2->m_pToken->m_LineEnd >= line)
984 {
985 m_pTreeBottom->SelectItem(item2);
986 return true;
987 }
988 }
989 }
990 item2 = m_pTreeBottom->GetNextChild(item, cookie2);
991 }
992 }
993 item = m_pTreeBottom->GetNextChild(root, cookie);
994 }
995 return false;
996 }
997
MarkSymbol(const wxString & filename,int line)998 void WorkspaceBrowserBuilder::MarkSymbol(const wxString& filename, int line)
999 {
1000 if (Manager::IsAppShuttingDown() || m_AtWork)
1001 return;
1002
1003 bool found = false;
1004 bool unmarked = true;
1005 wxTreeItemIdValue cookie;
1006 wxTreeItemId root = m_pTreeTop->GetRootItem();
1007 if(!root.IsOk())
1008 return;
1009 wxTreeItemId item = m_pTreeTop->GetFirstChild(root, cookie);
1010 wxTreeItemId itemGlob;
1011 bool haveGlob = false;
1012 wxTreeItemId itemOthers;
1013 bool haveOthers = false;
1014 while (item.IsOk())
1015 {
1016 TreeDataF* data = (TreeDataF*)m_pTreeTop->GetItemData(item);
1017 if (data)
1018 {
1019 switch (data->m_SpecialFolder)
1020 {
1021 case sfGFuncs:
1022 {
1023 itemGlob = item;
1024 haveGlob = true;
1025 break;
1026 }
1027 case sfOthers:
1028 {
1029 itemOthers = item;
1030 haveOthers = true;
1031 break;
1032 }
1033 case sfToken:
1034 {
1035 if (m_pTreeTop->IsBold(item))
1036 {
1037 if (!data->m_pToken->m_Filename.IsSameAs(filename)
1038 || ((int)data->m_pToken->m_LineStart > line)
1039 || ((int)data->m_pToken->m_LineEnd < line))
1040 {
1041 MarkItem(m_pTreeTop, item, false);
1042 if (!m_Options.visibleBottomTree && m_pTreeTop->HasChildren(item))
1043 {
1044 MarkChildSymbol(m_pTreeTop, item, line, false);
1045 }
1046 unmarked = true;
1047 }
1048 else
1049 unmarked = false;
1050 }
1051 if (!found)
1052 {
1053 if (data->m_pToken->m_Filename.IsSameAs(filename))
1054 {
1055 if (((int)data->m_pToken->m_LineStart <= line) && ((int)data->m_pToken->m_LineEnd >= line))
1056 {
1057 if (unmarked)
1058 MarkItem(m_pTreeTop, item);
1059 if ((m_pTreeTop->GetSelection() == item) && m_Options.visibleBottomTree)
1060 {
1061 MarkBottomSymbol(filename, line);
1062 }
1063 else if (m_Options.visibleBottomTree)
1064 {
1065 UnmarkBottomSymbol();
1066 }
1067 else if (!m_Options.visibleBottomTree && m_pTreeTop->HasChildren(item))
1068 {
1069 MarkChildSymbol(m_pTreeTop, item, line);
1070 }
1071 found = true;
1072 }
1073 }
1074 }
1075 break;
1076 }
1077 default:
1078 {
1079 break;
1080 }
1081 }
1082 }
1083 item = m_pTreeTop->GetNextChild(root, cookie);
1084 }
1085
1086 if (haveGlob && found)
1087 {
1088 if (m_Options.visibleBottomTree && (m_pTreeTop->GetSelection() == itemGlob))
1089 {
1090 UnmarkBottomSymbol();
1091 }
1092 else if (!m_Options.visibleBottomTree && m_pTreeTop->HasChildren(itemGlob) && m_pTreeTop->GetLastChild(itemGlob).IsOk())
1093 {
1094 MarkChildSymbol(m_pTreeTop, itemGlob, line, false);
1095 }
1096 if (m_pTreeTop->IsBold(itemGlob))
1097 MarkItem(m_pTreeTop, itemGlob, false);
1098 }
1099 else if (haveGlob)
1100 {
1101 bool foundGlob = false;
1102 if (m_Options.visibleBottomTree && (m_pTreeTop->GetSelection() == itemGlob))
1103 {
1104 foundGlob = MarkBottomSymbol(filename, line);
1105 }
1106 else if (!m_Options.visibleBottomTree && m_pTreeTop->HasChildren(itemGlob) && m_pTreeTop->GetLastChild(itemGlob).IsOk())
1107 {
1108 foundGlob = MarkGlobalSymbol(m_pTreeTop, itemGlob, filename, line);
1109 }
1110 else
1111 {
1112 foundGlob = IsLineInGlobals(filename, line);
1113 if (m_Options.visibleBottomTree && foundGlob && (m_pTreeTop->GetSelection() != itemGlob))
1114 {
1115 UnmarkBottomSymbol();
1116 }
1117 }
1118 if (foundGlob)
1119 {
1120 MarkItem(m_pTreeTop, itemGlob);
1121 found = true;
1122 }
1123 else if (m_pTreeTop->IsBold(itemGlob))
1124 {
1125 MarkItem(m_pTreeTop, itemGlob, false);
1126 }
1127 }
1128
1129 if (haveOthers && found)
1130 {
1131 if (m_Options.visibleBottomTree && (m_pTreeTop->GetSelection() == itemOthers))
1132 {
1133 UnmarkBottomSymbol();
1134 }
1135 else if (!m_Options.visibleBottomTree && m_pTreeTop->HasChildren(itemOthers) && m_pTreeTop->GetLastChild(itemOthers).IsOk())
1136 {
1137 MarkChildSymbol(m_pTreeTop, itemOthers, line, false);
1138 MarkGlobalSymbol(m_pTreeTop, itemOthers, filename, line);
1139 }
1140 if (m_pTreeTop->IsBold(itemOthers))
1141 MarkItem(m_pTreeTop, itemOthers, false);
1142 }
1143 else if (haveOthers)
1144 {
1145 bool foundOthers = false;
1146 if (m_Options.visibleBottomTree && (m_pTreeTop->GetSelection() == itemOthers))
1147 {
1148 foundOthers = MarkBottomSymbol(filename, line);
1149 }
1150 else if (!m_Options.visibleBottomTree && m_pTreeTop->HasChildren(itemOthers) && m_pTreeTop->GetLastChild(itemOthers).IsOk())
1151 {
1152 foundOthers = MarkGlobalSymbol(m_pTreeTop, itemOthers, filename, line);
1153 }
1154 else
1155 {
1156 foundOthers = (m_Options.showIncludeSeparately && m_pParser->IsIncludeFile(filename));
1157 if (m_Options.visibleBottomTree && foundOthers && (m_pTreeTop->GetSelection() != itemOthers))
1158 {
1159 UnmarkBottomSymbol();
1160 }
1161 }
1162 if (foundOthers)
1163 {
1164 MarkItem(m_pTreeTop, itemOthers);
1165 found = true;
1166 }
1167 else if (m_pTreeTop->IsBold(itemOthers))
1168 {
1169 MarkItem(m_pTreeTop, itemOthers, false);
1170 }
1171 }
1172
1173 if (!found && m_Options.visibleBottomTree)
1174 {
1175 UnmarkBottomSymbol();
1176 }
1177 }
1178
MarkItem(wxTreeCtrl * tree,wxTreeItemId & item,bool mark)1179 void WorkspaceBrowserBuilder::MarkItem(wxTreeCtrl* tree, wxTreeItemId& item, bool mark)
1180 {
1181 if (item.IsOk())
1182 {
1183 tree->SetItemBold(item, mark);
1184 #ifdef __WXGTK__
1185 tree->Refresh();
1186 #endif
1187 }
1188 }
1189
MarkBottomSymbol(const wxString & filename,int line)1190 bool WorkspaceBrowserBuilder::MarkBottomSymbol(const wxString& filename, int line)
1191 {
1192 bool found = false;
1193 bool foundFile = false;
1194 bool unmarked = true;
1195 wxTreeItemIdValue cookie;
1196 wxTreeItemId root = m_pTreeBottom->GetRootItem();
1197 if (!root.IsOk())
1198 return false;
1199 wxTreeItemId item = m_pTreeBottom->GetFirstChild(root, cookie);
1200 while (item.IsOk())
1201 {
1202 bool goInside = false;
1203 TreeDataF* data = (TreeDataF*)m_pTreeBottom->GetItemData(item);
1204 if (data)
1205 {
1206 if (data->m_SpecialFolder == sfToken)
1207 {
1208 if (m_pTreeBottom->IsBold(item))
1209 {
1210 if (!data->m_pToken->m_Filename.IsSameAs(filename)
1211 || (int)data->m_pToken->m_LineStart > line
1212 || (int)data->m_pToken->m_LineEnd < line)
1213 {
1214 MarkItem(m_pTreeBottom, item, false);
1215 unmarked = true;
1216 }
1217 else
1218 unmarked = false;
1219 }
1220 if (!found)
1221 {
1222 if (data->m_pToken->m_Filename.IsSameAs(filename))
1223 {
1224 if (((int)data->m_pToken->m_LineStart <= line) && ((int)data->m_pToken->m_LineEnd >= line))
1225 {
1226 if (unmarked)
1227 MarkItem(m_pTreeBottom, item);
1228 found = true;
1229 }
1230 }
1231 }
1232 }
1233 else if(data->m_SpecialFolder == sfFile)
1234 {
1235 if (data->m_pToken->m_Filename.IsSameAs(filename))
1236 {
1237 MarkItem(m_pTreeBottom, item);
1238 goInside = true;
1239 foundFile = true;
1240 }
1241 else
1242 MarkItem(m_pTreeBottom, item, false);
1243 }
1244 }
1245 else
1246 goInside = true;
1247
1248 if (goInside)
1249 {
1250 bool unmarked2 = true;
1251 wxTreeItemIdValue cookie2;
1252 wxTreeItemId item2 = m_pTreeBottom->GetFirstChild(item, cookie2);
1253 while (item2.IsOk())
1254 {
1255 TreeDataF* data2 = (TreeDataF*)m_pTreeBottom->GetItemData(item2);
1256 if (data2)
1257 {
1258 if (data2->m_SpecialFolder == sfToken)
1259 {
1260 if (m_pTreeBottom->IsBold(item2))
1261 {
1262 if (!data2->m_pToken->m_Filename.IsSameAs(filename)
1263 || (int)data2->m_pToken->m_LineStart > line
1264 || (int)data2->m_pToken->m_LineEnd < line)
1265 {
1266 MarkItem(m_pTreeBottom, item2, false);
1267 unmarked2 = true;
1268 }
1269 else
1270 unmarked2 = false;
1271 }
1272 if (!found)
1273 {
1274 if (data2->m_pToken->m_Filename.IsSameAs(filename))
1275 {
1276 if (((int)data2->m_pToken->m_LineStart <= line) && ((int)data2->m_pToken->m_LineEnd >= line))
1277 {
1278 if (unmarked2)
1279 MarkItem(m_pTreeBottom, item2);
1280 found = true;
1281 }
1282 }
1283 }
1284 }
1285 }
1286 item2 = m_pTreeBottom->GetNextChild(item, cookie2);
1287 }
1288 }
1289 item = m_pTreeBottom->GetNextChild(root, cookie);
1290 }
1291 return (found || foundFile);
1292 }
1293
1294
UnmarkBottomSymbol()1295 void WorkspaceBrowserBuilder::UnmarkBottomSymbol()
1296 {
1297 bool found = false;
1298 bool goInside = false;
1299 wxTreeItemIdValue cookie;
1300 wxTreeItemId root = m_pTreeBottom->GetRootItem();
1301 if (!root.IsOk())
1302 return;
1303 wxTreeItemId item = m_pTreeBottom->GetFirstChild(root, cookie);
1304 while (item.IsOk())
1305 {
1306 TreeDataF* data = (TreeDataF*)m_pTreeBottom->GetItemData(item);
1307 if (data)
1308 {
1309 if (m_pTreeBottom->IsBold(item))
1310 {
1311 MarkItem(m_pTreeBottom, item, false);
1312 found = true;
1313 goInside = true;
1314 }
1315 }
1316 else
1317 goInside = true;
1318
1319 if (goInside)
1320 {
1321 wxTreeItemIdValue cookie2;
1322 wxTreeItemId item2 = m_pTreeBottom->GetFirstChild(item, cookie2);
1323 while (item2.IsOk())
1324 {
1325 TreeDataF* data2 = (TreeDataF*)m_pTreeBottom->GetItemData(item2);
1326 if (data2)
1327 {
1328 if (data2->m_SpecialFolder == sfToken)
1329 {
1330 if (m_pTreeBottom->IsBold(item2))
1331 {
1332 MarkItem(m_pTreeBottom, item2, false);
1333 found = true;
1334 break;
1335 }
1336 }
1337 }
1338 item2 = m_pTreeBottom->GetNextChild(item, cookie2);
1339 }
1340 }
1341 if (found)
1342 break;
1343 item = m_pTreeBottom->GetNextChild(root, cookie);
1344 }
1345 }
1346
1347
MarkChildSymbol(wxTreeCtrl * tree,wxTreeItemId & root,int line,bool mark)1348 void WorkspaceBrowserBuilder::MarkChildSymbol(wxTreeCtrl* tree, wxTreeItemId& root, int line, bool mark)
1349 {
1350 bool found = false;
1351 bool unmarked = true;
1352 wxTreeItemIdValue cookie;
1353 if (!root.IsOk())
1354 return;
1355 wxTreeItemId item = tree->GetFirstChild(root, cookie);
1356 while (item.IsOk())
1357 {
1358 TreeDataF* data = (TreeDataF*)tree->GetItemData(item);
1359 if (data)
1360 {
1361 if (data->m_SpecialFolder == sfToken)
1362 {
1363 if (tree->IsBold(item))
1364 {
1365 if (mark)
1366 {
1367 if (((int)data->m_pToken->m_LineStart > line) || ((int)data->m_pToken->m_LineEnd < line))
1368 {
1369 MarkItem(tree, item, false);
1370 unmarked = true;
1371 }
1372 else
1373 unmarked = false;
1374 }
1375 else
1376 MarkItem(tree, item, false);
1377 }
1378 if (!found && mark)
1379 {
1380 if (((int)data->m_pToken->m_LineStart <= line) && ((int)data->m_pToken->m_LineEnd >= line))
1381 {
1382 if (unmarked)
1383 MarkItem(tree, item);
1384 found = true;
1385 }
1386 }
1387 }
1388 else if (data->m_SpecialFolder == sfFile)
1389 {
1390 if ((tree->IsBold(item) && !mark) || (!tree->IsBold(item) && mark))
1391 MarkItem(tree, item, mark);
1392 MarkChildSymbol(tree, item, line, mark);
1393 }
1394 }
1395 item = tree->GetNextChild(root, cookie);
1396 }
1397 }
1398
MarkGlobalSymbol(wxTreeCtrl * tree,wxTreeItemId & root,const wxString & filename,int line)1399 bool WorkspaceBrowserBuilder::MarkGlobalSymbol(wxTreeCtrl* tree, wxTreeItemId& root, const wxString& filename, int line)
1400 {
1401 bool found = false;
1402 bool foundFile = false;
1403 wxTreeItemIdValue cookie;
1404 if (!root.IsOk())
1405 return false;
1406 wxTreeItemId item = tree->GetFirstChild(root, cookie);
1407 while (item.IsOk())
1408 {
1409 TreeDataF* data = (TreeDataF*)tree->GetItemData(item);
1410 if (data)
1411 {
1412 if (data->m_SpecialFolder == sfToken)
1413 {
1414 if (tree->IsBold(item))
1415 {
1416 MarkItem(tree, item, false);
1417 }
1418 if (!found)
1419 {
1420 if (data->m_pToken->m_Filename.IsSameAs(filename))
1421 {
1422 if (((int)data->m_pToken->m_LineStart <= line) && ((int)data->m_pToken->m_LineEnd >= line))
1423 {
1424 MarkItem(tree, item);
1425 found = true;
1426 }
1427 }
1428 }
1429 }
1430 else if (data->m_SpecialFolder == sfFile)
1431 {
1432 bool isSameFile = data->m_pToken->m_Filename.IsSameAs(filename);
1433 if (isSameFile)
1434 {
1435 MarkItem(tree, item);
1436 foundFile = true;
1437 }
1438 else
1439 MarkItem(tree, item, false);
1440 wxTreeItemIdValue cookie2;
1441 wxTreeItemId item2 = tree->GetFirstChild(item, cookie2);
1442
1443 while (item2.IsOk())
1444 {
1445 TreeDataF* data2 = (TreeDataF*)tree->GetItemData(item2);
1446 if (data2)
1447 {
1448 if (data2->m_SpecialFolder == sfToken)
1449 {
1450 if (tree->IsBold(item2))
1451 {
1452 MarkItem(tree, item2, false);
1453 }
1454 if (!found && isSameFile)
1455 {
1456 if (((int)data2->m_pToken->m_LineStart <= line) && ((int)data2->m_pToken->m_LineEnd >= line))
1457 {
1458 MarkItem(tree, item2);
1459 found = true;
1460 }
1461 }
1462 }
1463 }
1464 item2 = tree->GetNextChild(item, cookie2);
1465 }
1466 }
1467 }
1468 item = tree->GetNextChild(root, cookie);
1469 }
1470 return (found || foundFile);
1471 }
1472
1473
IsLineInGlobals(const wxString & file,int line)1474 bool WorkspaceBrowserBuilder::IsLineInGlobals(const wxString& file, int line)
1475 {
1476 if (!m_pParser)
1477 return false;
1478 if (m_Options.showIncludeSeparately && m_pParser->IsIncludeFile(file))
1479 return false;
1480
1481 int tokenKindMask = tkFunction | tkProgram | tkSubroutine;
1482 TokensArrayF* pTokens = m_pParser->GetTokens();
1483 bool found = false;
1484 bool foundFileToken = false;
1485 for (size_t i=0; i < pTokens->GetCount(); ++i)
1486 {
1487 TokenF* token = pTokens->Item(i);
1488
1489 if (token->m_TokenKind == tkFile && token->m_Filename.IsSameAs(file))
1490 {
1491 switch (m_Options.displayFilter)
1492 {
1493 case bdfFile:
1494 {
1495 foundFileToken = true;
1496 break;
1497 }
1498 case bdfProject:
1499 {
1500 for (FilesList::iterator it = m_pActiveProject->GetFilesList().begin(); it != m_pActiveProject->GetFilesList().end(); ++it)
1501 {
1502 ProjectFile* pf = *it;
1503 foundFileToken = UnixFilename(pf->file.GetFullPath()).IsSameAs(file);
1504 if(foundFileToken)
1505 break;
1506 }
1507 break;
1508 }
1509 default: // bdfWorkspace
1510 {
1511 foundFileToken = true;
1512 break;
1513 }
1514 }
1515 if (foundFileToken)
1516 {
1517 TokensArrayF* children = &token->m_Children;
1518 for (size_t j=0; j < children->GetCount(); ++j)
1519 {
1520 TokenF* childToken = children->Item(j);
1521 if (childToken->m_TokenKind & tokenKindMask)
1522 {
1523 if ( ((int)childToken->m_LineStart <= line) && ((int)childToken->m_LineEnd >= line) )
1524 {
1525 found = true;
1526 break;
1527 }
1528 }
1529 }
1530 }
1531 break;
1532 }
1533 }
1534 return found;
1535 }
1536
1537
MakeVisibleCurrent()1538 void WorkspaceBrowserBuilder::MakeVisibleCurrent()
1539 {
1540 if (Manager::IsAppShuttingDown() || m_AtWork)
1541 return;
1542
1543 wxTreeItemIdValue cookie;
1544 wxTreeItemId root = m_pTreeTop->GetRootItem();
1545 if (!root.IsOk())
1546 return;
1547 wxTreeItemId item = m_pTreeTop->GetFirstChild(root, cookie);
1548 while (item.IsOk())
1549 {
1550 if (m_pTreeTop->IsBold(item))
1551 {
1552 m_pTreeTop->SelectItem(item);
1553 m_pTreeTop->EnsureVisible(item);
1554 break;
1555 }
1556 item = m_pTreeTop->GetNextChild(root, cookie);
1557 }
1558
1559 if (m_Options.visibleBottomTree)
1560 {
1561 root = m_pTreeBottom->GetRootItem();
1562 if (!root.IsOk())
1563 return;
1564 item = m_pTreeBottom->GetFirstChild(root, cookie);
1565 bool found = false;
1566 while (item.IsOk())
1567 {
1568 if (m_pTreeBottom->IsBold(item))
1569 {
1570 m_pTreeBottom->SelectItem(item);
1571 m_pTreeBottom->EnsureVisible(item);
1572 break;
1573 }
1574 else if (m_pTreeBottom->HasChildren(item))
1575 {
1576 wxTreeItemIdValue cookie2;
1577 wxTreeItemId item2 = m_pTreeBottom->GetFirstChild(item, cookie2);
1578 while (item2.IsOk())
1579 {
1580 if (m_pTreeBottom->IsBold(item2))
1581 {
1582 m_pTreeBottom->SelectItem(item2);
1583 m_pTreeBottom->EnsureVisible(item2);
1584 found = true;
1585 break;
1586 }
1587 item2 = m_pTreeBottom->GetNextChild(item, cookie2);
1588 }
1589 if (found)
1590 break;
1591 }
1592 item = m_pTreeBottom->GetNextChild(root, cookie);
1593 }
1594 }
1595 }
1596
AddIncludeFiles(wxTreeCtrl * tree,wxTreeItemId parent)1597 void WorkspaceBrowserBuilder::AddIncludeFiles(wxTreeCtrl* tree, wxTreeItemId parent)
1598 {
1599 if (Manager::IsAppShuttingDown())
1600 return;
1601
1602 int tokenKindMask = tkModule | tkFunction | tkProgram | tkSubroutine | tkInterface | tkInterfaceExplicit | tkBlockData |
1603 tkType | tkVariable | tkProcedure | tkAccessList | tkCommonblock | tkSubmodule;
1604
1605 bool sorted = m_Options.sortAlphabetically;
1606 switch (m_Options.displayFilter)
1607 {
1608 case bdfFile:
1609 {
1610 if (m_pParser->IsIncludeFile(m_ActiveFilename))
1611 {
1612 TokenF* fileToken= m_pParser->FindFile(m_ActiveFilename);
1613 if (fileToken)
1614 {
1615 wxChar sep = wxFileName::GetPathSeparator();
1616 wxString tn = _("include '");
1617 tn << m_ActiveFilename.AfterLast(sep) << _("'");
1618 wxTreeItemId idni = AddNodeIfNotThere(tree, parent, tn, m_pImlist->GetImageIdx("symbols_folder"), new TreeDataF(sfFile, fileToken), sorted);
1619 AddFileNodes(tree, idni, UnixFilename(m_ActiveFilename), tokenKindMask);
1620 }
1621 }
1622 break;
1623 }
1624 case bdfProject:
1625 {
1626 for (FilesList::iterator it = m_pActiveProject->GetFilesList().begin(); it != m_pActiveProject->GetFilesList().end(); ++it)
1627 {
1628 ProjectFile* pf = *it;
1629 if (m_pParser->IsIncludeFile(pf->file.GetFullPath()))
1630 {
1631 TokenF* fileToken= m_pParser->FindFile(pf->file.GetFullPath());
1632 if (fileToken)
1633 {
1634 wxString tn = _("include '");
1635 tn << pf->file.GetFullName() << _("'");
1636 wxTreeItemId idni = AddNodeIfNotThere(tree, parent, tn, m_pImlist->GetImageIdx("symbols_folder"), new TreeDataF(sfFile, fileToken), sorted);
1637 AddFileNodes(tree, idni, UnixFilename(pf->file.GetFullPath()), tokenKindMask);
1638 }
1639 }
1640 }
1641 break;
1642 }
1643 case bdfWorkspace:
1644 {
1645 TokensArrayF* pTokens = m_pParser->GetTokens();
1646 for (size_t i=0; i< pTokens->GetCount(); ++i)
1647 {
1648 TokenF* token = pTokens->Item(i);
1649 if (token->m_TokenKind == tkFile &&
1650 m_pParser->IsIncludeFile(token->m_Filename))
1651 {
1652 wxString tn = _("include '");
1653 tn << token->m_DisplayName << _("'");
1654 wxTreeItemId idni = AddNodeIfNotThere(tree, parent, tn, m_pImlist->GetImageIdx("symbols_folder"), new TreeDataF(sfFile, token), sorted);
1655 AddChildrenNodes(tree, idni, token, tokenKindMask);
1656 }
1657 }
1658 break;
1659 }
1660 }
1661 }
1662
SetActiveProject(cbProject * prj)1663 void WorkspaceBrowserBuilder::SetActiveProject(cbProject* prj)
1664 {
1665 m_pActiveProject = prj;
1666 }
1667
1668