Code::Blocks  SVN r11506
classbrowserbuilderthread.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  *
5  * $Revision: 11496 $
6  * $Id: classbrowserbuilderthread.cpp 11496 2018-10-07 07:21:23Z ollydbg $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/plugins/codecompletion/classbrowserbuilderthread.cpp $
8  */
9 
10 #include <sdk.h>
11 
12 #ifndef CB_PRECOMP
13  #include <algorithm>
14 
15  #include <wx/settings.h>
16 #ifdef CC_BUILDTREE_MEASURING
17  #include <wx/stopwatch.h>
18 #endif
19  #include <wx/utils.h>
20 
21  #include <cbproject.h>
22  #include <cbstyledtextctrl.h>
23  #include <globals.h>
24  #include <logmanager.h>
25  #include <manager.h>
26  #include <projectmanager.h>
27 #endif
28 
30 
31 // sanity check for the build tree functions, this function should only be called in a worker thread
32 // also, there should be no termination requested, otherwise, it will return false
33 #define CBBT_SANITY_CHECK ((!::wxIsMainThread() && m_TerminationRequested) || Manager::IsAppShuttingDown())
34 
35 #define CC_BUILDERTHREAD_DEBUG_OUTPUT 0
36 
37 #if defined(CC_GLOBAL_DEBUG_OUTPUT)
38  #if CC_GLOBAL_DEBUG_OUTPUT == 1
39  #undef CC_BUILDERTHREAD_DEBUG_OUTPUT
40  #define CC_BUILDERTHREAD_DEBUG_OUTPUT 1
41  #elif CC_GLOBAL_DEBUG_OUTPUT == 2
42  #undef CC_BUILDERTHREAD_DEBUG_OUTPUT
43  #define CC_BUILDERTHREAD_DEBUG_OUTPUT 2
44  #endif
45 #endif
46 
47 #if CC_BUILDERTHREAD_DEBUG_OUTPUT == 1
48  #define TRACE(format, args...) \
49  CCLogger::Get()->DebugLog(F(format, ##args))
50  #define TRACE2(format, args...)
51 #elif CC_BUILDERTHREAD_DEBUG_OUTPUT == 2
52  #define TRACE(format, args...) \
53  do \
54  { \
55  if (g_EnableDebugTrace) \
56  CCLogger::Get()->DebugLog(F(format, ##args)); \
57  } \
58  while (false)
59  #define TRACE2(format, args...) \
60  CCLogger::Get()->DebugLog(F(format, ##args))
61 #else
62  #define TRACE(format, args...)
63  #define TRACE2(format, args...)
64 #endif
65 
68  m_Parent(evtHandler),
69  m_ClassBrowserSemaphore(sem),
70  m_ClassBrowserBuilderThreadMutex(),
71  m_NativeParser(0),
72  m_CCTreeCtrlTop(0),
73  m_CCTreeCtrlBottom(0),
74  m_UserData(0),
75  m_BrowserOptions(),
76  m_TokenTree(0),
77  m_InitDone(false),
78  m_TerminationRequested(false),
79  m_idThreadEvent(wxID_NONE)
80 
81 {
82 }
83 
85 {
86 }
87 
89  CCTreeCtrl* treeTop,
90  CCTreeCtrl* treeBottom,
91  const wxString& active_filename,
92  void* user_data, // active project
93  const BrowserOptions& bo,
94  TokenTree* tt,
95  int idThreadEvent)
96 {
97  TRACE(_T("ClassBrowserBuilderThread::Init"));
98 
100 
101  m_NativeParser = np;
102  m_CCTreeCtrlTop = treeTop;
103  m_CCTreeCtrlBottom = treeBottom;
104  m_ActiveFilename = active_filename;
105  m_UserData = user_data;
106  m_BrowserOptions = bo;
107  m_TokenTree = tt;
109 
110  m_CurrentFileSet.clear();
111  m_CurrentTokenSet.clear();
112 
114 
115  // fill filter set for current-file-filter
117  && !m_ActiveFilename.IsEmpty() )
118  {
119  // m_ActiveFilename is the full filename up to the extension dot. No extension though.
120  // get all filenames' indices matching our mask
122 
123  // Should add locker after called m_NativeParser->GetAllPathsByFilename
125 
126  TokenFileSet result;
127  for (size_t i = 0; i < paths.GetCount(); ++i)
128  {
129  tree->GetFileMatches(paths[i], result, true, true);
130  for (TokenFileSet::const_iterator tfs_it = result.begin(); tfs_it != result.end(); ++tfs_it)
131  m_CurrentFileSet.insert(*tfs_it);
132  }
133 
135  }
137  && m_UserData )
138  {
140 
141  cbProject* prj = static_cast<cbProject*>(m_UserData);
142  for (FilesList::const_iterator fl_it = prj->GetFilesList().begin();
143  fl_it != prj->GetFilesList().end(); ++fl_it)
144  {
145  ProjectFile* curFile = *fl_it;
146  if (!curFile)
147  continue;
148 
149  const size_t fileIdx = tree->GetFileIndex(curFile->file.GetFullPath());
150  if (fileIdx)
151  m_CurrentFileSet.insert(fileIdx);
152  }
153 
155  }
156 
157  // our token tree has an internal map file -> tokens, so, we can collect all the tokens if we
158  // are given the file set.
159  // the tokens are stored in m_CurrentTokenSet, and the special global scope tokens are stored
160  // in the m_CurrentGlobalTokensSet.
161  if (!m_CurrentFileSet.empty())
162  {
164 
165  m_CurrentTokenSet.clear();
166  m_CurrentGlobalTokensSet.clear();
167  for (TokenFileSet::const_iterator itf = m_CurrentFileSet.begin(); itf != m_CurrentFileSet.end(); ++itf)
168  {
169  const TokenIdxSet* tokens = tree->GetTokensBelongToFile(*itf);
170  if (!tokens)
171  continue;
172 
173  // loop tokens in file
174  for (TokenIdxSet::const_iterator its = tokens->begin(); its != tokens->end(); ++its)
175  {
176  Token* curToken = tree->at(*its);
177  if (curToken)
178  {
179  m_CurrentTokenSet.insert(*its);
180  if (curToken->m_ParentIndex == -1)
181  m_CurrentGlobalTokensSet.insert(*its);
182  }
183  }
184  }
185 
187  }
188 
190 }
191 
192 // Thread function
193 
195 {
197  {
198  // waits here, until the ClassBrowser unlocks
199  // we put a semaphore wait function in the while loop, so the first time if
200  // the semaphore is 1, we can call BuildTree() in the loop, in the meanwhile
201  // the semaphore becomes 0. We will be blocked by semaphore's wait function
202  // in the next while loop. The semaphore post function will be called in the
203  // GUI thread once a new BuildTree() call is needed.
205 
207  break;
208 
209  if (platform::gtk || platform::macosx)
210  {
211  // this code (PART 1/2) seems to be good on linux
212  // because of it the libcairo crash on dualcore processors
213  // is gone, but on windows it has very bad influence,
214  // henceforth the ifdef guard
215  // the questions remains if it is the correct solution
216  if (!::wxIsMainThread())
218  }
219 
220  BuildTree();
221 
222  if (platform::gtk || platform::macosx)
223  {
224  // this code (PART 2/2) seems to be good on linux
225  // because of it the libcairo crash on dualcore processors
226  // is gone, but on windows it has very bad influence,
227  // henceforth the ifdef guard
228  // the questions remains if it is the correct solution
229  if (!::wxIsMainThread())
231  }
232  }
233 
234  m_NativeParser = 0;
235  m_CCTreeCtrlTop = 0;
236  m_CCTreeCtrlBottom = 0;
237 
238  return 0;
239 }
240 
241 // Functions accessible from outside
242 
244 {
245  TRACE(_T("ClassBrowserBuilderThread::ExpandItem"));
246 
247  if (CBBT_SANITY_CHECK || !item.IsOk())
248  return;
249 
250  bool locked = false;
251  if (m_InitDone)
252  {
254  locked = true;
255  }
256 
257 #ifdef CC_BUILDTREE_MEASURING
258  wxStopWatch sw;
259 #endif
260 
262 
263  // we want to show the children of the current node, inheritance information such as
264  // base class or derived class need to be shown
265  CCTreeCtrlData* data = static_cast<CCTreeCtrlData*>(m_CCTreeCtrlTop->GetItemData(item));
266  if (data)
268 
270 
271  if (data)
272  {
273  switch (data->m_SpecialFolder)
274  {
275  case sfRoot:
276  {
279  && m_ActiveFilename.IsEmpty() ) )
281  break;
282  }
283  case sfBase: AddAncestorsOf(m_CCTreeCtrlTop, item, data->m_Token->m_Index); break;
284  case sfDerived: AddDescendantsOf(m_CCTreeCtrlTop, item, data->m_Token->m_Index, false); break;
285  case sfToken:
286  {
287  short int kind = 0;
288  switch (data->m_Token->m_TokenKind)
289  {
290  case tkClass:
291  {
292  // add base and derived classes folders
294  {
295  wxTreeItemId base = m_CCTreeCtrlTop->AppendItem(item, _("Base classes"),
297  new CCTreeCtrlData(sfBase, data->m_Token, tkClass, data->m_Token->m_Index));
298  if (!data->m_Token->m_DirectAncestors.empty())
300  wxTreeItemId derived = m_CCTreeCtrlTop->AppendItem(item, _("Derived classes"),
302  new CCTreeCtrlData(sfDerived, data->m_Token, tkClass, data->m_Token->m_Index));
303  if (!data->m_Token->m_Descendants.empty())
305  }
306  kind = tkClass | tkEnum;
307  break;
308  }
309  case tkNamespace:
310  kind = tkNamespace | tkClass | tkEnum;
311  break;
312  case tkEnum:
313  case tkTypedef:
314  case tkConstructor:
315  case tkDestructor:
316  case tkFunction:
317  case tkVariable:
318  case tkEnumerator:
319  case tkMacroDef:
320  case tkMacroUse:
321  case tkAnyContainer:
322  case tkAnyFunction:
323  case tkUndefined:
324  default:
325  break;
326  }
327  if (kind != 0)
328  AddChildrenOf(m_CCTreeCtrlTop, item, data->m_Token->m_Index, kind);
329  break;
330  }
331  case sfGFuncs:
332  case sfGVars:
333  case sfPreproc:
334  case sfTypedef:
335  case sfMacro:
336  default:
337  break;
338  }
339  }
340 
343 #ifdef CC_BUILDTREE_MEASURING
344  CCLogger::Get()->DebugLog(F(_T("ExpandItems (internally) took : %ld ms for %u items."),sw.Time(),m_CCTreeCtrlTop->GetCount()));
345 #endif
346 
347  if (locked)
349 }
350 
351 #ifndef CC_NO_COLLAPSE_ITEM
353 {
354  TRACE(_T("ClassBrowserBuilderThread::CollapseItem"));
355 
356  if (CBBT_SANITY_CHECK || !item.IsOk())
357  return;
358 
359  bool locked = false;
360  if (m_InitDone)
361  {
363  locked = true;
364  }
365 
366 #if !defined(__WXGTK__) && !defined(__WXMAC__)
367  m_CCTreeCtrlTop->CollapseAndReset(item); // this freezes gtk
368 #else
370 #endif
372 
373  if (locked)
375 }
376 #endif // CC_NO_COLLAPSE_ITEM
377 
379 {
380  TRACE(_T("ClassBrowserBuilderThread::SelectItem"));
381 
382  if (CBBT_SANITY_CHECK || !item.IsOk())
383  return;
384 
386 
387 #ifdef CC_BUILDTREE_MEASURING
388  wxStopWatch sw;
389 #endif
390 
393  && m_ActiveFilename.IsEmpty() ) )
394  AddMembersOf(tree, item);
395 
396 #ifdef CC_BUILDTREE_MEASURING
397  CCLogger::Get()->DebugLog(F(_T("SelectItem (internally) took : %ld ms"),sw.Time()));
398 #endif
399 
401 }
402 
404 {
406  return;
407 
409  {
412  }
413 }
414 
415 // Main worker functions
416 
418 {
420  return; // Called before UI tree construction completed?!
421 
423  e1.SetInt(buildTreeStart);
424  m_Parent->AddPendingEvent(e1);
425 
426 #ifdef CC_BUILDTREE_MEASURING
427  wxStopWatch sw;
428  wxStopWatch sw_total;
429 #endif
430  // 1.) Registration of images
433 
434  // 2.) Create initial root node, if not already there
436  if (!root.IsOk())
437  {
440  }
441 
442  // 3.) Update compare functions
445 
446  // 4.) Save expanded items to restore later
447  m_ExpandedVect.clear();
449 #ifdef CC_BUILDTREE_MEASURING
450  CCLogger::Get()->DebugLog(F(_T("Saving expanded items took : %ld ms"),sw.Time()));
451  sw.Start();
452 #endif
453 
454  // 5.) Save selected item to restore later
456 #ifdef CC_BUILDTREE_MEASURING
457  CCLogger::Get()->DebugLog(F(_T("Saving selected items took : %ld ms"),sw.Time()));
458  sw.Start();
459 #endif
460 
461  // 6.) Hide&Freeze trees shown
463  {
464  m_CCTreeCtrlBottom->Hide();
465  m_CCTreeCtrlBottom->Freeze();
466  }
467  m_CCTreeCtrlTop->Hide();
468  m_CCTreeCtrlTop->Freeze();
469 #ifdef CC_BUILDTREE_MEASURING
470  CCLogger::Get()->DebugLog(F(_T("Hiding and freezing trees took : %ld ms"),sw.Time()));
471  sw.Start();
472 #endif
473 
474  // 7.) Remove any nodes no longer valid (due to update)
476 #ifdef CC_BUILDTREE_MEASURING
477  CCLogger::Get()->DebugLog(F(_T("Removing invalid nodes (top tree) took : %ld ms"),sw.Time()));
478  sw.Start();
479 #endif
480 
482  {
484 #ifdef CC_BUILDTREE_MEASURING
485  CCLogger::Get()->DebugLog(F(_T("Removing invalid nodes (bottom tree) took : %ld ms"),sw.Time()));
486  sw.Start();
487 #endif
488  }
489 
490  // Meanwhile, C::B might want to shutdown?!
491  if (CBBT_SANITY_CHECK)
492  return;
493 #ifdef CC_BUILDTREE_MEASURING
494  CCLogger::Get()->DebugLog(F(_T("TestDestroy() took : %ld ms"),sw.Time()));
495  sw.Start();
496 #endif
497 
498 #ifndef CC_NO_COLLAPSE_ITEM
499  // the tree is completely dynamic: it is populated when a node expands/collapses.
500  // so, by expanding the root node, we already instruct it to fill the top level :)
501  //
502  // this technique makes it really fast to draw (we only draw what's expanded) and
503  // has very minimum memory overhead since it contains as few items as possible.
504  // plus, it doesn't flicker because we're not emptying it and re-creating it each time ;)
505 
506  // 8.) Collapse item
507  CollapseItem(root);
508 #ifdef CC_BUILDTREE_MEASURING
509  CCLogger::Get()->DebugLog(F(_T("Collapsing root item took : %ld ms"),sw.Time()));
510  sw.Start();
511 #endif
512 
513  // 9.) Expand item --> Bottleneck: Takes ~4 secs on C::B workspace
514  m_CCTreeCtrlTop->Expand(root);
515 #ifdef CC_BUILDTREE_MEASURING
516  CCLogger::Get()->DebugLog(F(_T("Expanding root item took : %ld ms"),sw.Time()));
517  sw.Start();
518 #endif
519 #endif // CC_NO_COLLAPSE_ITEM
520 
521  // seems like the "expand" event comes too late in wxGTK, so make it happen now
522  if (platform::gtk || platform::macosx)
523  ExpandItem(root);
524 #ifdef CC_BUILDTREE_MEASURING
525  CCLogger::Get()->DebugLog(F(_T("Expanding root item (gtk only) took : %ld ms"),sw.Time()));
526  sw.Start();
527 #endif
528 
529  // 10.) Expand the items saved before
531 #ifdef CC_BUILDTREE_MEASURING
532  CCLogger::Get()->DebugLog(F(_T("Expanding saved items took : %ld ms"),sw.Time()));
533  sw.Start();
534 #endif
535 
536  // 11.) Select the item saved before --> Bottleneck: Takes ~4 secs on C::B workspace
537  SelectSavedItem();
538 #ifdef CC_BUILDTREE_MEASURING
539  CCLogger::Get()->DebugLog(F(_T("Selecting saved item took : %ld ms"),sw.Time()));
540  sw.Start();
541 #endif
542 
543  // 12.) Show the bottom tree again (it's finished)
545  {
546  m_CCTreeCtrlBottom->Thaw();
547 #ifdef CC_BUILDTREE_MEASURING
548  CCLogger::Get()->DebugLog(F(_T("Thaw bottom tree took : %ld ms"),sw.Time()));
549  sw.Start();
550 #endif
551 
552  m_CCTreeCtrlBottom->Show();
553 #ifdef CC_BUILDTREE_MEASURING
554  CCLogger::Get()->DebugLog(F(_T("Showing bottom tree took : %ld ms"),sw.Time()));
555  sw.Start();
556 #endif
557  }
558 
559  // 13.) Expand namespaces and classes
562 
563 #ifdef CC_BUILDTREE_MEASURING
564  CCLogger::Get()->DebugLog(F(_T("Expanding namespaces took : %ld ms"),sw.Time()));
565  sw.Start();
566 #endif
567 
568  m_CCTreeCtrlTop->Thaw();
569 #ifdef CC_BUILDTREE_MEASURING
570  CCLogger::Get()->DebugLog(F(_T("Thaw top tree took : %ld ms"),sw.Time()));
571  sw.Start();
572 #endif
573 
574  // 14.) Show the top tree again (it's finished) --> Bottleneck: Takes ~4 secs on C::B workspace:
575  m_CCTreeCtrlTop->Show();
576 #ifdef CC_BUILDTREE_MEASURING
577  CCLogger::Get()->DebugLog(F(_T("Show top tree took : %ld ms"),sw.Time()));
578  CCLogger::Get()->DebugLog(F(_T("BuildTree took : %ld ms in total"),sw_total.Time()));
579 #endif
580 
581  // Initialisation is done after Init() and at least *one* call to BuildTree().
582  // Also, in Init() m_InitDone is set to false, directly followed by a
583  // re-launch of the thread resulting in a call to BuildTree() due to
584  // posting the semaphore from ClassBrowser.
585  m_InitDone = true;
586 
588  e2.SetInt(buildTreeEnd);
589  m_Parent->AddPendingEvent(e2);
590 }
591 
593 {
594  TRACE(_T("ClassBrowserBuilderThread::RemoveInvalidNodes"));
595 
596  if (CBBT_SANITY_CHECK || !parent.IsOk())
597  return;
598 
599  // recursively enters all existing nodes and deletes the node if the token it references
600  // is invalid (i.e. m_TokenTree->at() != token_in_data)
601 
602  // we'll loop backwards so we can delete nodes without problems
603  wxTreeItemId existing = tree->GetLastChild(parent);
604  while (parent.IsOk() && existing.IsOk())
605  {
606  bool removeCurrent = false;
607  bool hasChildren = tree->ItemHasChildren(existing);
608  CCTreeCtrlData* data = static_cast<CCTreeCtrlData*>(tree->GetItemData(existing));
609 
610  if (tree == m_CCTreeCtrlBottom)
611  removeCurrent = true;
612  else if (data && data->m_Token)
613  {
614  const Token* token = nullptr;
615  {
617 
618  token = m_TokenTree->at(data->m_TokenIndex);
619 
621  }
622  if ( token != data->m_Token
623  || (data->m_Ticket && data->m_Ticket != data->m_Token->GetTicket())
624  || !TokenMatchesFilter(data->m_Token) )
625  {
626  removeCurrent = true;
627  }
628  }
629 
630  if (removeCurrent)
631  {
632  if (hasChildren)
633  tree->DeleteChildren(existing);
634 
635  wxTreeItemId next = tree->GetPrevSibling(existing);
636  if (!next.IsOk() && parent.IsOk() && tree == m_CCTreeCtrlTop && tree->GetChildrenCount(parent, false) == 1 )
637  {
638 #ifndef CC_NO_COLLAPSE_ITEM
639  CollapseItem(parent);
640  // tree->SetItemHasChildren(parent, false);
641  // existing is the last item an gets deleted in CollapseItem and at least on 64-bit linux it can
642  // lead to a crash, because we use it again some lines later, but m_Item is not 0 in some rare cases,
643  // and therefore IsOk returns true !!
644  // so we leave the function here
645 #endif // CC_NO_COLLAPSE_ITEM
646  return;
647  }
648  else
649  {
650  tree->Delete(existing);
651  existing = next;
652  continue;
653  }
654  }
655  else
656  RemoveInvalidNodes(tree, existing); // re-curse
657 
658  if (existing.IsOk())
659  existing = tree->GetPrevSibling(existing);
660  }
661 }
662 
664 {
665  TRACE(_T("ClassBrowserBuilderThread::ExpandNamespaces"));
666 
667  if (CBBT_SANITY_CHECK || !m_BrowserOptions.expandNS || !node.IsOk() || level <= 0 )
668  return;
669 
670  wxTreeItemIdValue enumerationCookie;
671  wxTreeItemId existing = m_CCTreeCtrlTop->GetFirstChild(node, enumerationCookie);
672  while (existing.IsOk())
673  {
674  CCTreeCtrlData* data = static_cast<CCTreeCtrlData*>(m_CCTreeCtrlTop->GetItemData(existing));
675  if ( data
676  && data->m_Token
677  && (data->m_Token->m_TokenKind == tokenKind) )
678  {
679  TRACE(F(_T("Auto-expanding: ") + data->m_Token->m_Name));
680  m_CCTreeCtrlTop->Expand(existing);
681  ExpandNamespaces(existing, tokenKind, level-1); // re-curse
682  }
683 
684  existing = m_CCTreeCtrlTop->GetNextSibling(existing);
685  }
686 }
687 
688 // checks if there are respective children and colours the nodes
690 {
691  TRACE(_T("ClassBrowserBuilderThread::CreateSpecialFolders"));
692 
693  bool hasGF = false; // has global functions
694  bool hasGV = false; // has global variables
695  bool hasGP = false; // has global macro definition
696  bool hasTD = false; // has type defines
697  bool hasGM = false; // has macro usage, note that this kind of tokens does not exits in the
698  // token tree, so we don't show such special folder
699 
700  // loop all tokens in global namespace and see if we have matches
702 
704 
705  const TokenIdxSet* tis = tt->GetGlobalNameSpaces();
706  for (TokenIdxSet::const_iterator tis_it = tis->begin(); tis_it != tis->end(); ++tis_it)
707  {
708  const Token* token = tt->at(*tis_it);
709  if (token && token->m_IsLocal && TokenMatchesFilter(token, true))
710  {
711  if (!hasGF && token->m_TokenKind == tkFunction)
712  hasGF = true;
713  else if (!hasGM && token->m_TokenKind == tkMacroUse)
714  hasGM = true;
715  else if (!hasGV && token->m_TokenKind == tkVariable)
716  hasGV = true;
717  else if (!hasGP && token->m_TokenKind == tkMacroDef)
718  hasGP = true;
719  else if (!hasTD && token->m_TokenKind == tkTypedef)
720  hasTD = true;
721  }
722 
723  if (hasGF && hasGV && hasGP && hasTD && hasGM)
724  break; // we have everything, stop iterating...
725  }
726 
728 
729  wxTreeItemId gfuncs = AddNodeIfNotThere(m_CCTreeCtrlTop, parent, _("Global functions"),
731  wxTreeItemId tdef = AddNodeIfNotThere(m_CCTreeCtrlTop, parent, _("Global typedefs"),
733  wxTreeItemId gvars = AddNodeIfNotThere(m_CCTreeCtrlTop, parent, _("Global variables"),
735  wxTreeItemId preproc = AddNodeIfNotThere(m_CCTreeCtrlTop, parent, _("Macro definitions"),
737  wxTreeItemId gmacro = AddNodeIfNotThere(m_CCTreeCtrlTop, parent, _("Macro usages"),
739 
740  // the logic here is: if the treeMembers option is on, then all the child members will be shownn
741  // in the bottom, for example, if we have some global functions for the current file, then the
742  // function tokens will be shown in the bottom tree, so we don't have a '+' in the
743  // Symbols(root node)->Global functions(1 level node), when the user click on the "Global functions"
744  // node, all the global functions will be shown in the bottom tree.
745  // if the treeMembers is false, then all the global function tokens will be children of the
746  // Global functions node
747  bool bottom = m_BrowserOptions.treeMembers;
748  m_CCTreeCtrlTop->SetItemHasChildren(gfuncs, !bottom && hasGF);
749  m_CCTreeCtrlTop->SetItemHasChildren(tdef, !bottom && hasTD);
750  m_CCTreeCtrlTop->SetItemHasChildren(gvars, !bottom && hasGV);
751  m_CCTreeCtrlTop->SetItemHasChildren(preproc, !bottom && hasGP);
752  m_CCTreeCtrlTop->SetItemHasChildren(gmacro, !bottom && hasGM);
753 
756 
757  // if we don't have any global function tokens, then we set the label of "Global functions" node
758  // as grey color.
759  tree->SetItemTextColour(gfuncs, hasGF ? black : grey);
760  tree->SetItemTextColour(gvars, hasGV ? black : grey);
761  tree->SetItemTextColour(preproc, hasGP ? black : grey);
762  tree->SetItemTextColour(tdef, hasTD ? black : grey);
763  tree->SetItemTextColour(gmacro, hasGM ? black : grey);
764 
765  return hasGF || hasGV || hasGP || hasTD || hasGM;
766 }
767 
769 {
770  TRACE(_T("ClassBrowserBuilderThread::AddNodeIfNotThere"));
771 
772  wxTreeItemIdValue cookie = 0;
773 
774  wxTreeItemId existing = tree->GetFirstChild(parent, cookie);
775  while (existing)
776  {
777  wxString itemText = tree->GetItemText(existing);
778  if (itemText == name)
779  {
780  // update the existing node's image indices and user-data.
781  // it's not possible to have the same token name more than once
782  // under the same namespace anyway. if we do, there's a bug in the parser :(
783  tree->SetItemImage(existing, imgIndex, wxTreeItemIcon_Normal);
784  tree->SetItemImage(existing, imgIndex, wxTreeItemIcon_Selected);
785  delete tree->GetItemData(existing); // make Valgrind happy
786  tree->SetItemData(existing, data);
787 
788  return existing;
789  }
790  existing = tree->GetNextChild(parent, cookie);
791  }
792  return tree->AppendItem(parent, name, imgIndex, imgIndex, data);
793 }
794 
796  wxTreeItemId parent,
797  int parentTokenIdx,
798  short int tokenKindMask,
799  int tokenScopeMask)
800 {
801  TRACE(_T("ClassBrowserBuilderThread::AddChildrenOf"));
802 
803  if (CBBT_SANITY_CHECK)
804  return false;
805 
806  const Token* parentToken = 0;
807  bool parentTokenError = false;
808  const TokenIdxSet* tokens = 0;
809 
811 
812  if (parentTokenIdx == -1)
813  {
816  tokens = m_TokenTree->GetGlobalNameSpaces();
817  else
818  tokens = &m_CurrentGlobalTokensSet;
819  }
820  else
821  {
822  parentToken = m_TokenTree->at(parentTokenIdx);
823  if (!parentToken)
824  {
825  TRACE(_T("Token not found?!?"));
826  parentTokenError = true;
827  }
828  if (!parentTokenError)
829  tokens = &parentToken->m_Children;
830  }
831 
833 
834  if (parentTokenError) return false;
835 
836  return AddNodes(tree, parent, tokens, tokenKindMask, tokenScopeMask,
838 }
839 
841 {
842  TRACE(_T("ClassBrowserBuilderThread::AddAncestorsOf"));
843 
844  if (CBBT_SANITY_CHECK)
845  return false;
846 
848 
849  Token* token = m_TokenTree->at(tokenIdx);
850  if (token)
852 
854 
855  if (!token)
856  return false;
857 
858  return AddNodes(tree, parent, &token->m_DirectAncestors, tkClass | tkTypedef, 0, true);
859 }
860 
861 bool ClassBrowserBuilderThread::AddDescendantsOf(CCTreeCtrl* tree, wxTreeItemId parent, int tokenIdx, bool allowInheritance)
862 {
863  TRACE(_T("ClassBrowserBuilderThread::AddDescendantsOf"));
864 
865  if (CBBT_SANITY_CHECK)
866  return false;
867 
869 
870  Token* token = m_TokenTree->at(tokenIdx);
871  if (token)
873 
875 
876  if (!token)
877  return false;
878 
879  bool oldShowInheritance = m_BrowserOptions.showInheritance;
880  m_BrowserOptions.showInheritance = allowInheritance;
881 
882  bool ret = AddNodes(tree, parent, &token->m_Descendants, tkClass | tkTypedef, 0, true);
883 
884  m_BrowserOptions.showInheritance = oldShowInheritance;
885  return ret;
886 }
887 
889 {
890  TRACE(_T("ClassBrowserBuilderThread::AddMembersOf"));
891 
892  if (CBBT_SANITY_CHECK || !node.IsOk())
893  return;
894 
895  CCTreeCtrlData* data = static_cast<CCTreeCtrlData*>(m_CCTreeCtrlTop->GetItemData(node));
896 
897  bool bottom = (tree == m_CCTreeCtrlBottom);
898  if (bottom)
899  {
900 #ifdef CC_BUILDTREE_MEASURING
901  wxStopWatch sw;
902 #endif
903  tree->Freeze();
904 #ifdef CC_BUILDTREE_MEASURING
905  CCLogger::Get()->DebugLog(F(_T("tree->Freeze() took : %ld ms"),sw.Time()));
906  sw.Start();
907 #endif
908  tree->DeleteAllItems();
909 #ifdef CC_BUILDTREE_MEASURING
910  CCLogger::Get()->DebugLog(F(_T("tree->DeleteAllItems() took : %ld ms"),sw.Time()));
911  sw.Start();
912 #endif
913  node = tree->AddRoot(_T("Members")); // not visible, so don't translate
914 #ifdef CC_BUILDTREE_MEASURING
915  CCLogger::Get()->DebugLog(F(_T("tree->AddRoot() took : %ld ms"),sw.Time()));
916 #endif
917  }
918 
919  wxTreeItemId firstItem;
920  bool haveFirstItem = false;
921  if (data)
922  {
923  switch (data->m_SpecialFolder)
924  {
925  case sfGFuncs : AddChildrenOf(tree, node, -1, tkFunction, false); break;
926  case sfGVars : AddChildrenOf(tree, node, -1, tkVariable, false); break;
927  case sfPreproc : AddChildrenOf(tree, node, -1, tkMacroDef, false); break;
928  case sfTypedef : AddChildrenOf(tree, node, -1, tkTypedef, false); break;
929  case sfMacro : AddChildrenOf(tree, node, -1, tkMacroUse, false); break;
930  case sfToken:
931  {
932  if (bottom)
933  {
935  && !(data->m_Token->m_TokenKind & tkEnum))
936  {
937  wxTreeItemId rootCtorDtor = tree->AppendItem(node, _("Ctors & Dtors"), PARSER_IMG_CLASS_FOLDER);
938  wxTreeItemId rootFuncs = tree->AppendItem(node, _("Functions"), PARSER_IMG_FUNCS_FOLDER);
939  wxTreeItemId rootVars = tree->AppendItem(node, _("Variables"), PARSER_IMG_VARS_FOLDER);
940  wxTreeItemId rootMacro = tree->AppendItem(node, _("Macros"), PARSER_IMG_MACRO_USE_FOLDER);
941  wxTreeItemId rootOthers = tree->AppendItem(node, _("Others"), PARSER_IMG_OTHERS_FOLDER);
942 
943  AddChildrenOf(tree, rootCtorDtor, data->m_Token->m_Index, tkConstructor | tkDestructor);
944  AddChildrenOf(tree, rootFuncs, data->m_Token->m_Index, tkFunction);
945  AddChildrenOf(tree, rootVars, data->m_Token->m_Index, tkVariable);
946  AddChildrenOf(tree, rootMacro, data->m_Token->m_Index, tkMacroUse);
947  AddChildrenOf(tree, rootOthers, data->m_Token->m_Index, ~(tkNamespace | tkClass | tkEnum | tkAnyFunction | tkVariable | tkMacroUse));
948 
949  firstItem = rootCtorDtor;
950  }
951  else if ( m_BrowserOptions.sortType == bstScope
952  && data->m_Token->m_TokenKind & tkClass )
953  {
954  wxTreeItemId rootPublic = tree->AppendItem(node, _("Public"), PARSER_IMG_CLASS_FOLDER);
955  wxTreeItemId rootProtected = tree->AppendItem(node, _("Protected"), PARSER_IMG_FUNCS_FOLDER);
956  wxTreeItemId rootPrivate = tree->AppendItem(node, _("Private"), PARSER_IMG_VARS_FOLDER);
957 
958  AddChildrenOf(tree, rootPublic, data->m_Token->m_Index, ~(tkNamespace | tkClass | tkEnum), tsPublic);
959  AddChildrenOf(tree, rootProtected, data->m_Token->m_Index, ~(tkNamespace | tkClass | tkEnum), tsProtected);
960  AddChildrenOf(tree, rootPrivate, data->m_Token->m_Index, ~(tkNamespace | tkClass | tkEnum), tsPrivate);
961 
962  firstItem = rootPublic;
963  }
964  else
965  {
966  AddChildrenOf(tree, node, data->m_Token->m_Index, ~(tkNamespace | tkClass | tkEnum));
967  break;
968  }
969 
970  wxTreeItemId existing = tree->GetLastChild(tree->GetRootItem());
971  while (existing.IsOk())
972  {
973  wxTreeItemId next = tree->GetPrevSibling(existing);
974 
975  if (tree->GetChildrenCount(existing) > 0)
976  {
977  tree->SetItemBold(existing, true);
978  // make existing the firstItem, because the former firstItem might get deleted
979  // in the else-clause, if it has no children, what can lead to a crash
980  firstItem = existing;
981  // needed, if no child remains, because firstItem IsOk() returns true anyway
982  // in some cases.
983  haveFirstItem = true;
984  }
985  else
986  {
987  tree->Delete(existing);
988  existing = next;
989  continue;
990  }
991  existing = tree->GetPrevSibling(existing);
992  }
993  }
994  else
995  AddChildrenOf(tree, node, data->m_Token->m_Index, ~(tkNamespace | tkClass | tkEnum));
996 
997  // add all children, except containers
998  // AddChildrenOf(tree, node, data->m_Token->GetSelf(), ~(tkNamespace | tkClass | tkEnum));
999  break;
1000  }
1001  case sfRoot:
1002  case sfBase:
1003  case sfDerived:
1004  default:
1005  break;
1006  }
1007  }
1008 
1009  if (bottom)
1010  {
1011  tree->ExpandAll();
1012  if (haveFirstItem && firstItem.IsOk())
1013  {
1014  tree->ScrollTo(firstItem);
1015  tree->EnsureVisible(firstItem);
1016  }
1017  tree->Thaw();
1018  }
1019 }
1020 
1022  short int tokenKindMask, int tokenScopeMask, bool allowGlobals)
1023 {
1024  TRACE(_T("ClassBrowserBuilderThread::AddNodes"));
1025 
1026  int count = 0;
1027  std::set<unsigned long, std::less<unsigned long> > tickets;
1028 
1029  // Build temporary list of Token tickets - if the token's ticket is present
1030  // among the parent node's children, it's a duplicate node, and we'll skip it.
1031  if (parent.IsOk() && tree == m_CCTreeCtrlTop)
1032  {
1033  wxTreeItemIdValue cookie;
1034  wxTreeItemId curchild = tree->GetFirstChild(parent,cookie);
1035  while (curchild.IsOk())
1036  {
1037  CCTreeCtrlData* data = static_cast<CCTreeCtrlData*>(tree->GetItemData(curchild));
1038  curchild = tree->GetNextSibling(curchild);
1039  if (data && data->m_Ticket)
1040  tickets.insert(data->m_Ticket);
1041  }
1042  }
1043 
1044  TokenIdxSet::const_iterator end = tokens->end();
1045  for (TokenIdxSet::const_iterator start = tokens->begin(); start != end; ++start)
1046  {
1048 
1049  Token* token = m_TokenTree->at(*start);
1050 
1052 
1053  if ( token
1054  && (token->m_TokenKind & tokenKindMask)
1055  && (tokenScopeMask == 0 || token->m_Scope == tokenScopeMask)
1056  && (allowGlobals || token->m_IsLocal || TokenMatchesFilter(token)) )
1057  {
1058  if ( tree == m_CCTreeCtrlTop
1059  && tickets.find(token->GetTicket()) != tickets.end() )
1060  continue; // duplicate node
1061  ++count;
1062  int img = m_NativeParser->GetTokenKindImage(token);
1063 
1064  wxString str = token->m_Name;
1065  if ( (token->m_TokenKind == tkFunction)
1066  || (token->m_TokenKind == tkConstructor)
1067  || (token->m_TokenKind == tkDestructor)
1068  || (token->m_TokenKind == tkMacroUse)
1069  || (token->m_TokenKind == tkClass) )
1070  {
1071  str << token->GetFormattedArgs();
1072  }
1073  if (!token->m_FullType.IsEmpty())
1074  str = str + _T(" : ") + token->m_FullType + token->m_TemplateArgument;
1075 
1076  wxTreeItemId child = tree->AppendItem(parent, str, img, img, new CCTreeCtrlData(sfToken, token, tokenKindMask));
1077 
1078  // mark as expanding if it is a container
1079  int kind = tkClass | tkNamespace | tkEnum;
1080  if (token->m_TokenKind == tkClass)
1081  {
1085  || TokenContainsChildrenOfKind(token, kind));
1086  }
1087  else if (token->m_TokenKind & (tkNamespace | tkEnum))
1088  {
1091  tree->SetItemHasChildren(child, TokenContainsChildrenOfKind(token, kind));
1092  }
1093  }
1094  }
1095 
1096  tree->SortChildren(parent);
1097 // tree->RemoveDoubles(parent);
1098 #ifdef CC_BUILDTREE_MEASURING
1099  CCLogger::Get()->DebugLog(F(_T("Added %d nodes"), count));
1100 #endif
1101  return count != 0;
1102 }
1103 
1105 {
1106  TRACE(_T("ClassBrowserBuilderThread::TokenMatchesFilter"));
1107 
1108  if (!token || token->m_IsTemp)
1109  return false;
1110 
1113  return true;
1114 
1116  {
1117  if (m_CurrentTokenSet.find(token->m_Index) != m_CurrentTokenSet.end())
1118  return true;
1119 
1120  // we got to check all children of this token (recursively)
1121  // to see if any of them matches the filter...
1122  // tis_it -> token index set iterator
1123  for (TokenIdxSet::const_iterator tis_it = token->m_Children.begin();
1124  tis_it != token->m_Children.end();
1125  ++tis_it)
1126  {
1127  if (!locked)
1129 
1130  const Token* curr_token = m_TokenTree->at(*tis_it);
1131 
1132  if (!locked)
1134 
1135  if (!curr_token)
1136  break;
1137 
1138  if ( TokenMatchesFilter(curr_token, locked) )
1139  return true;
1140  }
1141  }
1143  return token->m_UserData == m_UserData;
1144 
1145  return false;
1146 }
1147 
1149 {
1150  TRACE(_T("ClassBrowserBuilderThread::TokenContainsChildrenOfKind"));
1151 
1152  if (!token)
1153  return false;
1154 
1155  bool isOfKind = false;
1156  const TokenTree* tree = token->GetTree();
1157 
1159 
1160  for (TokenIdxSet::const_iterator tis_it = token->m_Children.begin(); tis_it != token->m_Children.end(); ++tis_it)
1161  {
1162  const Token* child = tree->at(*tis_it);
1163  if (child->m_TokenKind & kind)
1164  {
1165  isOfKind = true;
1166  break;
1167  }
1168  }
1169 
1171 
1172  return isOfKind;
1173 }
1174 
1176 {
1177  TRACE(_T("ClassBrowserBuilderThread::SaveExpandedItems"));
1178 
1179  if (CBBT_SANITY_CHECK)
1180  return;
1181 
1182  wxTreeItemIdValue cookie;
1183  wxTreeItemId existing = tree->GetFirstChild(parent, cookie);
1184  while (existing.IsOk())
1185  {
1186  CCTreeCtrlData* data = static_cast<CCTreeCtrlData*>(tree->GetItemData(existing));
1187  if (tree->GetChildrenCount(existing,false) > 0)
1188  {
1189  m_ExpandedVect.push_back(CCTreeCtrlExpandedItemData(data, level));
1190 
1191  SaveExpandedItems(tree, existing, level + 1);
1192  }
1193 
1194  existing = tree->GetNextSibling(existing);
1195  }
1196 }
1197 
1199 {
1200  TRACE(_T("ClassBrowserBuilderThread::ExpandSavedItems"));
1201 
1202  if (CBBT_SANITY_CHECK)
1203  return;
1204 
1205  wxTreeItemIdValue cookie;
1206  wxTreeItemId existing = tree->GetFirstChild(parent, cookie);
1207  while (existing.IsOk() && !m_ExpandedVect.empty())
1208  {
1209  CCTreeCtrlData* data = static_cast<CCTreeCtrlData*>(tree->GetItemData(existing));
1211 
1212  if ( level == saved.GetLevel()
1213  && wxStrcmp(data->m_TokenName, saved.GetData().m_TokenName) == 0
1214  && data->m_TokenKind == saved.GetData().m_TokenKind
1215  && data->m_SpecialFolder == saved.GetData().m_SpecialFolder )
1216  {
1217  tree->Expand(existing);
1218 
1219  m_ExpandedVect.pop_front();
1220 
1221  if (m_ExpandedVect.empty())
1222  return;
1223 
1224  saved = m_ExpandedVect.front(); //next saved
1225  if (saved.GetLevel() < level)
1226  return;
1227 
1228  if (saved.GetLevel() > level)
1229  ExpandSavedItems(tree, existing, saved.GetLevel());
1230  }
1231 
1232  existing = tree->GetNextSibling(existing);
1233  }
1234 
1235  // remove non-existing by now saved items
1236  while (!m_ExpandedVect.empty() && m_ExpandedVect.front().GetLevel() > level)
1237  m_ExpandedVect.pop_front();
1238 }
1239 
1241 {
1242  TRACE(_T("ClassBrowserBuilderThread::SaveSelectedItem"));
1243 
1244  if (CBBT_SANITY_CHECK)
1245  return;
1246 
1247  m_SelectedPath.clear();
1248 
1250  while (item.IsOk() && item != m_CCTreeCtrlTop->GetRootItem())
1251  {
1252  CCTreeCtrlData* data = static_cast<CCTreeCtrlData*>(m_CCTreeCtrlTop->GetItemData(item));
1253  m_SelectedPath.push_front(*data);
1254 
1255  item = m_CCTreeCtrlTop->GetItemParent(item);
1256  }
1257 }
1258 
1260 {
1261  TRACE(_T("ClassBrowserBuilderThread::SelectSavedItem"));
1262 
1263  if (CBBT_SANITY_CHECK)
1264  return;
1265 
1267 
1268  // TODO (Morten#1#): wxTreeCtrl documentation states that cookie is for re-entrancy an must be unique for all calls that belong together.
1269  // So, this needs to be initialized to some value?
1270  // (Which value, though... I'm inclined to just use 1 and 2 for here and below... but no clue if you've used those elsewhere)
1271  wxTreeItemIdValue cookie;
1272  wxTreeItemId item = m_CCTreeCtrlTop->GetFirstChild(parent, cookie);
1273 
1274  while (!m_SelectedPath.empty() && item.IsOk())
1275  {
1276  CCTreeCtrlData* data = static_cast<CCTreeCtrlData*>(m_CCTreeCtrlTop->GetItemData(item));
1277  CCTreeCtrlData* saved = &m_SelectedPath.front();
1278 
1279  if ( data->m_SpecialFolder == saved->m_SpecialFolder
1280  && wxStrcmp(data->m_TokenName, saved->m_TokenName) == 0
1281  && data->m_TokenKind == saved->m_TokenKind )
1282  {
1283  // TODO (Morten#1#): see above. Different value here, I'd assume?
1284  wxTreeItemIdValue cookie2;
1285  parent = item;
1286  item = m_CCTreeCtrlTop->GetFirstChild(item, cookie2);
1287  m_SelectedPath.pop_front();
1288  }
1289  else
1290  item = m_CCTreeCtrlTop->GetNextSibling(item);
1291  }
1292 
1293  if (parent.IsOk())
1294  {
1295  m_SelectItemRequired = parent; // remember what item to select
1296 
1298  e.SetInt(selectItemRequired);
1299  m_Parent->AddPendingEvent(e);
1300  }
1301 
1302  m_SelectedPath.clear();
1303 }
const TokenIdxSet * GetTokensBelongToFile(size_t fileIdx) const
Definition: tokentree.h:196
virtual wxTreeItemId GetNextChild(const wxTreeItemId &item, wxTreeItemIdValue &cookie) const
TokenTree * GetTree() const
get the TokenTree associated with the current Token
Definition: token.h:173
wxString F(const wxChar *msg,...)
sprintf-like function
Definition: logmanager.h:20
void SaveExpandedItems(CCTreeCtrl *tree, wxTreeItemId parent, int level)
destructor class member function
Definition: token.h:51
CCTreeCtrl * m_CCTreeCtrlBottom
pointer to the bottom wxTreeCtrl
#define CC_LOCKER_TRACK_CBBT_MTX_LOCK
Definition: cclogger.h:171
wxMutex s_TokenTreeMutex
Definition: tokentree.cpp:49
variable
Definition: token.h:57
namespace
Definition: token.h:34
void ExpandAll()
int m_ParentIndex
Parent Token index.
Definition: token.h:265
#define PARSER_IMG_TYPEDEF_FOLDER
Definition: parser.h:60
virtual void SetItemBold(const wxTreeItemId &item, bool bold=true)
constructor class member function
Definition: token.h:48
class or struct
Definition: token.h:37
wxArrayString GetAllPathsByFilename(const wxString &filename)
Get the implementation file path if the input is a header file.
#define PARSER_IMG_VARS_FOLDER
Definition: parser.h:55
virtual wxTreeItemId GetItemParent(const wxTreeItemId &item) const
wxString GetFormattedArgs() const
remove all &#39; &#39; in the original function argument string
Definition: token.cpp:199
Token * at(int idx)
Definition: tokentree.h:51
void Init(NativeParser *np, CCTreeCtrl *treeTop, CCTreeCtrl *treeBottom, const wxString &active_filename, void *user_data, const BrowserOptions &bo, TokenTree *tt, int idThreadEvent)
virtual void SetItemHasChildren(const wxTreeItemId &item, bool hasChildren=true)
static CCLogger * Get()
Definition: cclogger.cpp:60
bool IsOk() const
wxString m_Name
Token&#39;s name, it can be searched in the TokenTree.
Definition: token.h:188
std::set< size_t, std::less< size_t > > TokenFileSet
Definition: token.h:19
virtual void * Entry()
typedef, note typedefs are stored as classes inheriting from the typedef&#39;d type, this takes advantage...
Definition: token.h:45
static bool IsAppShuttingDown()
Definition: manager.cpp:333
#define PARSER_IMG_FUNCS_FOLDER
Definition: parser.h:56
virtual void DeleteAllItems()
container like tokens, those tokens can have children tokens
Definition: token.h:70
virtual FilesList & GetFilesList()
Provides an easy way to iterate all the files belonging in this target.
Definition: cbproject.h:685
TokenKind m_TokenKind
a copy of Token::m_TokenKind
Definition: cctreectrl.h:58
#define TRACE(format, args...)
wxFileName file
The full filename of this file.
Definition: projectfile.h:126
const TokenIdxSet * GetGlobalNameSpaces() const
all kinds of tokens under global name spaces
Definition: tokentree.h:186
virtual size_t GetChildrenCount(const wxTreeItemId &item, bool recursively=true) const
#define PARSER_IMG_OTHERS_FOLDER
Definition: parser.h:59
virtual wxTreeItemId GetSelection() const
bool wxIsMainThread()
SpecialFolder m_SpecialFolder
the node&#39;s kind, it could be "root", "normal token",
Definition: cctreectrl.h:52
virtual void EnsureVisible(const wxTreeItemId &item)
a container class to hold all the Tokens getting from parsing stage
Definition: tokentree.h:37
TokenIdxSet m_Children
if it is a class kind token, then it contains all the member tokens
Definition: token.h:268
bool showInheritance
whether the base class or derive class information is shown as a child node default: false ...
Definition: parser_base.h:72
void * m_UserData
custom user-data (the classbrowser expects it to be a pointer to a cbProject), this field is used whe...
Definition: token.h:300
alphabetical
Definition: parser_base.h:52
long Time() const
#define _T(string)
void AddMembersOf(CCTreeCtrl *tree, wxTreeItemId node)
TokenIdxSet m_CurrentTokenSet
Tokens belong to the m_CurrentFileSet file set.
the thread is starting to (re)build the tree
int m_Index
current Token index in the tree, it is index of the std::vector<Token*>, so use the index...
Definition: token.h:262
virtual ~ClassBrowserBuilderThread()
destructor
virtual wxTreeItemData * GetItemData(const wxTreeItemId &item) const
void SetCompareFunction(const BrowserSortType type)
Definition: cctreectrl.cpp:60
virtual wxString GetItemText(const wxTreeItemId &item) const
TokenFileSet m_CurrentFileSet
A file set which contains a header file and the associated implementation file.
bool m_IsTemp
local (automatic) variable
Definition: token.h:245
#define PARSER_IMG_SYMBOLS_FOLDER
Definition: parser.h:54
TokenScope m_Scope
public? private? protected?
Definition: token.h:231
Represents a file in a Code::Blocks project.
Definition: projectfile.h:39
void DebugLog(const wxString &msg)
Definition: cclogger.cpp:107
virtual void SortChildren(const wxTreeItemId &item)
virtual void SetItemTextColour(const wxTreeItemId &item, const wxColour &col)
void RecalcInheritanceChain(Token *token)
convert the Token&#39;s ancestor string to it&#39;s IDs this contains recursive calls, for example in such co...
Definition: tokentree.cpp:643
virtual void CollapseAndReset(const wxTreeItemId &item)
wxString m_TokenName
short name of the Token, it is a copy of Token::m_Name
Definition: cctreectrl.h:63
void ExpandNamespaces(wxTreeItemId node, TokenKind tokenKind, int level)
recursively construct the children of node&#39;s children, which matches tokenKind Called from BuildTree(...
bool expandNS
whether a namespaces node is auto-expand auto-expand means the child of the namespace is automaticall...
Definition: parser_base.h:79
virtual wxTreeItemId GetFirstChild(const wxTreeItemId &item, wxTreeItemIdValue &cookie) const
virtual void DeleteChildren(const wxTreeItemId &item)
Represents a Code::Blocks project.
Definition: cbproject.h:96
display symbols of current project
Definition: parser_base.h:44
#define PARSER_IMG_CLASS_FOLDER
Definition: parser.h:26
a symbol found in the parsed files, it can be many kinds, such as a variable, a class and so on...
Definition: token.h:82
std::set< int, std::less< int > > TokenIdxSet
Definition: token.h:16
display symbols of current file
Definition: parser_base.h:43
size_t GetFileIndex(const wxString &filename)
Definition: tokentree.cpp:851
bool TokenMatchesFilter(const Token *token, bool locked=false)
if the token should be shown in the tree, it will return true
Token * m_Token
a pointer to the associated Token instance in the TokenTree
Definition: cctreectrl.h:44
ClassBrowserBuilderThread(wxEvtHandler *evtHandler, wxSemaphore &sem)
constructor
virtual void SelectItem(const wxTreeItemId &item, bool select=true)
Options for the symbol browser, this specify how the symbol browser will shown.
Definition: parser_base.h:59
virtual void SetItemData(const wxTreeItemId &item, wxTreeItemData *data)
unsigned long m_Ticket
the Token&#39;s ticket in a TokenTree This is actually a copy of Token::m_Ticket,
Definition: cctreectrl.h:73
void ExpandSavedItems(CCTreeCtrl *tree, wxTreeItemId parent, int level)
bool AddNodes(CCTreeCtrl *tree, wxTreeItemId parent, const TokenIdxSet *tokens, short int tokenKindMask=0xffff, int tokenScopeMask=0, bool allowGlobals=false)
static wxColour GetColour(wxSystemColour index)
wxEventType wxEVT_COMMAND_ENTER
wxTreeItemId AddNodeIfNotThere(CCTreeCtrl *tree, wxTreeItemId parent, const wxString &name, int imgIndex=-1, CCTreeCtrlData *data=0)
#define CC_LOCKER_TRACK_TT_MTX_UNLOCK(M)
Definition: cclogger.h:165
bool AddAncestorsOf(CCTreeCtrl *tree, wxTreeItemId parent, int tokenIdx)
virtual wxTreeItemId GetLastChild(const wxTreeItemId &item) const
int m_TokenIndex
a copy of Token::m_TokenIndex
Definition: cctreectrl.h:55
void CollapseItem(wxTreeItemId item)
remove the children of the tree item Called from external, BuildTree(), RemoveInvalidNodes(): ...
const wxString & _(const wxString &string)
#define CC_LOCKER_TRACK_TT_MTX_LOCK(M)
Definition: cclogger.h:159
bool TokenContainsChildrenOfKind(const Token *token, int kind)
NativeParser class is just like a manager class to control Parser objects.
Definition: nativeparser.h:55
wxMutex m_ClassBrowserBuilderThreadMutex
Some member functions of ClassBrowserBuilderThread such as ExpandItem() can either be called from the...
wxString m_TemplateArgument
template argument list, comma separated list string
Definition: token.h:283
virtual void Expand(const wxTreeItemId &item)
ParserBase & GetParser()
return a reference to the currently active Parser object
Definition: nativeparser.h:65
Actual data stored with each node in the symbol tree.
Definition: cctreectrl.h:37
undefined or just "all"
Definition: token.h:76
BrowserDisplayFilter displayFilter
token filter option
Definition: parser_base.h:88
enum
Definition: token.h:40
TokenIdxSet m_Descendants
all the descendants in the inheritance hierarchy
Definition: token.h:277
bool IsEmpty() const
bool treeMembers
show members in the bottom tree.
Definition: parser_base.h:82
size_t GetFileMatches(const wxString &filename, std::set< size_t > &result, bool caseSensitive, bool is_prefix)
Definition: tokentree.cpp:843
void Start(long milliseconds=0)
virtual wxTreeItemId GetNextSibling(const wxTreeItemId &item) const
enumerator
Definition: token.h:60
const CCTreeCtrlData & GetData()
Definition: cctreectrl.h:82
any kind of functions
Definition: token.h:73
bool AddDescendantsOf(CCTreeCtrl *tree, wxTreeItemId parent, int tokenIdx, bool allowInheritance=true)
virtual void SetImageList(wxImageList *imageList)
TokenKind m_TokenKind
See TokenKind class.
Definition: token.h:234
virtual void Delete(const wxTreeItemId &item)
#define CBBT_SANITY_CHECK
general function, not constructor nor destructor
Definition: token.h:54
virtual wxTreeItemId AddRoot(const wxString &text, int image=-1, int selImage=-1, wxTreeItemData *data=NULL)
virtual wxTreeItemId GetPrevSibling(const wxTreeItemId &item) const
wxSemaError Wait()
BrowserSortType sortType
token sort option in the tree default: bstKind
Definition: parser_base.h:93
void RemoveInvalidNodes(CCTreeCtrl *tree, wxTreeItemId parent)
Remove any nodes no longer valid (due to update)
#define CC_LOCKER_TRACK_CBBT_MTX_UNLOCK
Definition: cclogger.h:172
virtual wxTreeItemId GetRootItem() const
size_t GetCount() const
virtual TokenTree * GetTokenTree() const
int GetTokenKindImage(const Token *token)
Returns the image assigned to a specific token for a symbol browser.
display symbols of current workspace
Definition: parser_base.h:45
int idThreadEvent
the event ID which will be sent from worker thread to ClassBrowser
virtual void ScrollTo(const wxTreeItemId &item)
#define PARSER_IMG_MACRO_USE_FOLDER
Definition: parser.h:65
virtual void SetItemImage(const wxTreeItemId &item, int image, wxTreeItemIcon which=wxTreeItemIcon_Normal)
macro definition, such as: #define AAA(x,y) f(x,y), where AAA is a token of tkMacroDef ...
Definition: token.h:63
bool CreateSpecialFolders(CCTreeCtrl *tree, wxTreeItemId parent)
void ExpandItem(wxTreeItemId item)
construct the children of the tree item Called from external, BuildTree():
#define PARSER_IMG_MACRO_DEF_FOLDER
Definition: parser.h:58
Definition: token.h:26
wxString m_FullType
this is the full return value (if any): e.g.
Definition: token.h:182
size_t GetTicket() const
get the ticket value of the current token
Definition: token.h:161
wxString GetFullPath(wxPathFormat format=wxPATH_NATIVE) const
wxImageList * GetImageList()
Used to support Symbol browser and codecompletion UI Image list is used to initialize the symbol brow...
Definition: nativeparser.h:113
class, function, macros
Definition: parser_base.h:53
bool m_IsLocal
if true, means the token belong to a C::B project, it exists in the project&#39;s source/header files...
Definition: token.h:242
TokenIdxSet m_DirectAncestors
the nearest ancestors
Definition: token.h:274
bool m_TerminationRequested
if this variable is true, the Entry() function should return
virtual unsigned int GetCount() const
CCTreeCtrl * m_CCTreeCtrlTop
pointer to the top wxTreeCtrl
void wxMutexGuiEnter()
virtual bool ItemHasChildren(const wxTreeItemId &item) const
wxTreeItemId AppendItem(const wxTreeItemId &parent, const wxString &text, int image=-1, int selImage=-1, wxTreeItemData *data=NULL)
void wxMutexGuiLeave()
TokenKind
Definition: token.h:29
TokenIdxSet m_CurrentGlobalTokensSet
Special global scope tokens belong to the m_CurrentFileSet file set.
the usage of the macro, for example: AAA(1,2)
Definition: token.h:66
bool AddChildrenOf(CCTreeCtrl *tree, wxTreeItemId parent, int parentTokenIdx, short int tokenKindMask=0xffff, int tokenScopeMask=0)
Add the child nodes of the specified token.