30 ClassImp(TVirtualBranchBrowsable);
76 std::list<TVirtualBranchBrowsable::MethodCreateListOfBrowsables_t>
77 TVirtualBranchBrowsable::fgGenerators;
78 Bool_t TVirtualBranchBrowsable::fgGeneratorsSet=kFALSE;
83 TVirtualBranchBrowsable::TVirtualBranchBrowsable(
const TBranch* branch, TClass* type,
85 const TVirtualBranchBrowsable* parent ):
86 fBranch(branch), fParent(parent), fLeaves(0), fClass(type), fTypeIsPointer(typeIsPointer)
88 if (!fgGeneratorsSet) RegisterDefaultGenerators();
90 Warning(
"TVirtualBranchBrowsable",
"branch is NULL!");
96 TVirtualBranchBrowsable::~TVirtualBranchBrowsable()
105 void TVirtualBranchBrowsable::Browse(TBrowser *b)
108 || (fClass->GetCollectionProxy()
109 && fClass->GetCollectionProxy()->GetType() > 0)) {
116 name.ReplaceAll(
".@",
"@.");
117 name.ReplaceAll(
"->@",
"@->");
121 Error(
"Browse",
"branch not set - might access wrong tree!");
123 }
else tree=fBranch->GetTree();
124 tree->Draw(name,
"", b ? b->GetDrawOption() :
"");
125 if (gPad) gPad->Update();
127 if (GetLeaves()) GetLeaves()->Browse(b);
137 Int_t TVirtualBranchBrowsable::FillListOfBrowsables(TList& li,
const TBranch* branch,
138 const TVirtualBranchBrowsable* parent )
140 if (!fgGeneratorsSet) RegisterDefaultGenerators();
141 std::list<MethodCreateListOfBrowsables_t>::iterator iGenerator;
143 for (iGenerator=fgGenerators.begin(); iGenerator!=fgGenerators.end(); ++iGenerator)
144 numCreated+=(*(*iGenerator))(li, branch, parent);
159 TClass* TVirtualBranchBrowsable::GetCollectionContainedType(
const TBranch* branch,
160 const TVirtualBranchBrowsable* parent,
166 type=parent->GetClassType();
168 if (branch->IsA()==TBranchElement::Class()) {
170 TBranchElement* be=(TBranchElement*) branch;
173 const char* clonesname=be->GetClonesName();
174 if (clonesname && strlen(clonesname))
175 contained=TClass::GetClass(clonesname);
179 TStreamerElement *element=0;
180 if (be->GetID()>=0 && be->GetInfo()
181 && (be->GetID() < be->GetInfo()->GetNelement())
182 && be->GetInfo()->IsCompiled()
183 && (element=be->GetInfo()->GetElement(be->GetID()))) {
189 return element->GetClassPointer();
191 type=element->GetClassPointer();
192 }
else if (clonesname && strlen(clonesname)) {
194 contained=TClass::GetClass(clonesname);
195 return TClass::GetClass(be->GetClassName());
197 type=TClass::GetClass(be->GetClassName());
198 }
else if (branch->IsA()==TBranchObject::Class()) {
200 TBranchObject* bo=(TBranchObject*)branch;
201 const char* clonesname=bo->GetClassName();
203 if (!clonesname || !clonesname[0])
return 0;
204 type=TClass::GetClass(clonesname);
207 ::Warning(
"TVirtualBranchBrowsable::GetCollectionContainedType",
"Neither branch nor parent given!");
213 TBranch* branchNonCost=
const_cast<TBranch*
>(branch);
214 if (type->InheritsFrom(TClonesArray::Class())
215 && branch->IsA()==TBranchObject::Class()
216 && branchNonCost->GetListOfLeaves()
217 && branchNonCost->GetListOfLeaves()->GetEntriesFast()==1) {
223 if (branch->GetReadEntry()==-1) branchNonCost->GetEntry(0);
225 TLeafObject* lo = (TLeafObject*)branchNonCost->GetListOfLeaves()->First();
227 TObject* objContainer = lo->GetObject();
228 if (objContainer && objContainer->IsA()==TClonesArray::Class()) {
229 contained = ((TClonesArray*)objContainer)->GetClass();
233 }
else if (type->InheritsFrom(TClonesArray::Class())
234 && branch->IsA()==TBranchElement::Class()
235 && branchNonCost->GetListOfLeaves()
236 && branchNonCost->GetListOfLeaves()->GetEntriesFast()==1) {
254 }
else if (type->InheritsFrom(TCollection::Class())) {
257 }
else if (type->GetCollectionProxy()) {
258 contained=type->GetCollectionProxy()->GetValueClass();
260 }
else if (type->InheritsFrom(TRef::Class()))
270 TList* TVirtualBranchBrowsable::GetLeaves()
const
273 TList* leaves=
new TList();
275 FillListOfBrowsables(*leaves, GetBranch(),
this);
276 const_cast<TVirtualBranchBrowsable*
>(
this)->fLeaves=leaves;
284 std::list<TVirtualBranchBrowsable::MethodCreateListOfBrowsables_t>& TVirtualBranchBrowsable::GetRegisteredGenerators()
295 void TVirtualBranchBrowsable::GetScope(TString & scope)
const
298 fParent->GetScope(scope);
300 scope=fBranch->GetName();
301 Ssiz_t pos = scope.First(
'[');
305 if (!scope.EndsWith(
".")) scope+=
".";
306 const TBranch* mother=fBranch;
307 while (mother != mother->GetMother() && (mother=mother->GetMother())) {
308 TString nameMother(mother->GetName());
309 if (!nameMother.EndsWith(
".")) {
311 scope.Prepend(nameMother);
313 if (mother != mother->GetMother()) {
317 scope.Prepend(nameMother);
322 if (GetName() && GetName()[0]==
'.')
323 scope+=(GetName()+1);
326 if (fClass && !scope.EndsWith(
".")) {
340 void TVirtualBranchBrowsable::RegisterDefaultGenerators()
342 if (fgGeneratorsSet)
return;
344 fgGenerators.push_back(&TMethodBrowsable::GetBrowsables);
345 fgGenerators.push_back(&TNonSplitBrowsable::GetBrowsables);
346 fgGenerators.push_back(&TCollectionPropertyBrowsable::GetBrowsables);
347 fgGeneratorsSet=kTRUE;
355 void TVirtualBranchBrowsable::RegisterGenerator(MethodCreateListOfBrowsables_t generator)
357 if (!fgGeneratorsSet) RegisterDefaultGenerators();
359 fgGenerators.remove(generator);
360 fgGenerators.push_back(generator);
371 void TVirtualBranchBrowsable::UnregisterGenerator(MethodCreateListOfBrowsables_t generator)
373 if (!fgGeneratorsSet) RegisterDefaultGenerators();
374 fgGenerators.remove(generator);
377 ClassImp(TMethodBrowsable);
408 TMethodBrowsable::TMethodBrowsable(
const TBranch* branch, TMethod* m,
409 const TVirtualBranchBrowsable* parent ):
410 TVirtualBranchBrowsable(branch, 0, kFALSE, parent), fMethod(m)
412 TString name(m->GetName());
414 if (name.EndsWith(
" const")) name.Remove(name.Length()-6);
417 name=m->GetPrototype();
418 if (m->GetCommentString() && strlen(m->GetCommentString()))
419 name.Append(
" // ").Append(m->GetCommentString());
422 TString plainReturnType(m->GetReturnTypeName());
423 if (plainReturnType.EndsWith(
"*")) {
425 plainReturnType.Remove(plainReturnType.Length()-1);
426 plainReturnType.Strip();
427 if(plainReturnType.BeginsWith(
"const")) {
428 plainReturnType.Remove(0,5);
429 plainReturnType.Strip();
432 SetType(TClass::GetClass(plainReturnType));
443 void TMethodBrowsable::GetBrowsableMethodsForClass(TClass* cl, TList& li)
449 if (cl->IsLoaded()) {
450 for(TObjLink* lnk=allClasses.FirstLink();
451 lnk; lnk=lnk->Next()) {
452 cl=(TClass*)lnk->GetObject();
453 TList* bases=cl->GetListOfBases();
456 while ((base=(TBaseClass*)iB())) {
457 TClass* bc=base->GetClassPointer();
458 if (bc) allClasses.Add(bc);
462 TVirtualStreamerInfo *info = cl->GetStreamerInfo();
463 for(
int el = 0; el < info->GetElements()->GetEntries(); ++el) {
464 TStreamerElement *element = (TStreamerElement *)info->GetElements()->UncheckedAt(el);
465 if (element->IsBase()) {
466 TClass *bc = element->GetClassPointer();
467 if (bc) allClasses.Add(bc);
473 TIter iC(&allClasses);
474 while ((cl=(TClass*)iC())) {
475 TList* methods=cl->GetListOfMethods();
476 if (!methods)
continue;
479 while ((method=(TMethod*)iM()))
480 if (method && !allMethods.FindObject(method->GetName()))
481 allMethods.Add(method);
484 TIter iM(&allMethods);
486 while ((m=(TMethod*)iM())) {
487 if (TMethodBrowsable::IsMethodBrowsable(m)) {
500 Int_t TMethodBrowsable::GetBrowsables(TList& li,
const TBranch* branch,
501 const TVirtualBranchBrowsable* parent )
506 GetCollectionContainedType(branch, parent, cl);
510 GetBrowsableMethodsForClass(cl, listMethods);
512 TIter iMethods(&listMethods);
513 while ((method=(TMethod*)iMethods())) {
514 li.Add(
new TMethodBrowsable(branch, method, parent));
516 return listMethods.GetSize();
529 Bool_t TMethodBrowsable::IsMethodBrowsable(
const TMethod* m)
531 long property = m->Property();
532 if (m->GetNargs() - m->GetNargsOpt() == 0
533 && (
property & kIsConstant)
534 && !(property & (kIsPrivate | kIsProtected | kIsPureVirtual) )
535 && m->GetReturnTypeName()
536 && strcmp(
"void",m->GetReturnTypeName())
537 && !strstr(m->GetName(),
"DeclFile")
538 && !strstr(m->GetName(),
"ImplFile")
539 && strcmp(m->GetName(),
"IsA")
540 && strcmp(m->GetName(),
"Class")
541 && strcmp(m->GetName(),
"CanBypassStreamer")
542 && strcmp(m->GetName(),
"Class_Name")
543 && strcmp(m->GetName(),
"ClassName")
544 && strcmp(m->GetName(),
"Clone")
545 && strcmp(m->GetName(),
"DrawClone")
546 && strcmp(m->GetName(),
"GetName")
547 && strcmp(m->GetName(),
"GetDrawOption")
548 && strcmp(m->GetName(),
"GetIconName")
549 && strcmp(m->GetName(),
"GetOption")
550 && strcmp(m->GetName(),
"GetTitle")
551 && strcmp(m->GetName(),
"GetUniqueID")
552 && strcmp(m->GetName(),
"Hash")
553 && strcmp(m->GetName(),
"IsFolder")
554 && strcmp(m->GetName(),
"IsOnHeap")
555 && strcmp(m->GetName(),
"IsSortable")
556 && strcmp(m->GetName(),
"IsZombie")) {
559 TClass* cl=m->GetClass();
560 if (!cl)
return kTRUE;
561 TList* members=cl->GetListOfDataMembers();
562 if (!members)
return kTRUE;
563 const char* baseName=m->GetName();
564 if (!strncmp(m->GetName(),
"Get", 3) ||
565 !strncmp(m->GetName(),
"get", 3))
567 if (!baseName[0])
return kTRUE;
570 const char* arrMemberNames[3]={
"f%s",
"_%s",
"m%s"};
571 for (Int_t i=0; !mem && i<3; i++)
572 mem=members->FindObject(TString::Format(arrMemberNames[i],baseName));
573 return (!mem ||! ((TDataMember*)mem)->IsPersistent());
583 void TMethodBrowsable::Register()
585 TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables);
593 void TMethodBrowsable::Unregister()
595 TVirtualBranchBrowsable::UnregisterGenerator(GetBrowsables);
598 ClassImp(TNonSplitBrowsable);
620 TNonSplitBrowsable::TNonSplitBrowsable(
const TStreamerElement* element,
const TBranch* branch,
621 const TVirtualBranchBrowsable* parent ):
622 TVirtualBranchBrowsable(branch, element->GetClassPointer(),
623 element->IsaPointer(), parent)
625 SetNameTitle(element->GetName(), element->GetTitle());
633 Int_t TNonSplitBrowsable::GetBrowsables(TList& li,
const TBranch* branch,
634 const TVirtualBranchBrowsable* parent )
639 (const_cast<TBranch*>(branch)->GetListOfBranches()
640 && const_cast<TBranch*>(branch)->GetListOfBranches()->GetEntries()!=0)
648 TClass* clContained=0;
649 GetCollectionContainedType(branch, parent, clContained);
650 TVirtualStreamerInfo* streamerInfo= clContained?clContained->GetStreamerInfo():0;
652 || !streamerInfo->GetElements()
653 || !streamerInfo->GetElements()->GetSize())
return 0;
655 if (!branch && parent) branch=parent->GetBranch();
658 TList myStreamerElementsToCheck;
659 myStreamerElementsToCheck.AddAll(streamerInfo->GetElements());
662 TStreamerElement* streamerElement=0;
663 for (TObjLink *link = myStreamerElementsToCheck.FirstLink();
665 link = link->Next() ) {
666 streamerElement = (TStreamerElement*)link->GetObject();
667 if (streamerElement->IsBase()) {
670 TClass* base=streamerElement->GetClassPointer();
671 if (!base || !base->GetStreamerInfo())
continue;
676 TObjArray* baseElements=base->GetStreamerInfo()->GetElements();
677 if (!baseElements)
continue;
678 TIter iBaseSE(baseElements);
679 TStreamerElement* baseSE=0;
680 while ((baseSE=(TStreamerElement*)iBaseSE()))
682 myStreamerElementsToCheck.Add(baseSE);
683 }
else if (!strcmp(streamerElement->GetName(),
"This")
684 && !strcmp(clContained->GetName(), streamerElement->GetTypeName())) {
687 TClass* clElements=streamerElement->GetClassPointer();
688 TVirtualCollectionProxy* collProxy=clElements?clElements->GetCollectionProxy():0;
689 clElements=collProxy?collProxy->GetValueClass():0;
690 if (!clElements)
continue;
693 streamerInfo = clElements->GetStreamerInfo();
695 TIter iElem(streamerInfo->GetElements());
696 TStreamerElement* elem=0;
697 while ((elem=(TStreamerElement*)iElem())) {
698 TNonSplitBrowsable* nsb=
new TNonSplitBrowsable(elem, branch, parent);
703 ::Error(
"TNonSplitBrowsable::GetBrowsables",
704 "Missing the StreamerInfo for the class \"%s\" for the branch \"%s\" in the TTree \"%s\".",
705 clElements->GetName(), branch->GetName(), branch->GetTree()->GetName());
709 TNonSplitBrowsable* nsb=
new TNonSplitBrowsable(streamerElement, branch, parent);
722 void TNonSplitBrowsable::Register()
724 TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables);
732 void TNonSplitBrowsable::Unregister()
734 TVirtualBranchBrowsable::UnregisterGenerator(GetBrowsables);
737 ClassImp(TCollectionPropertyBrowsable);
760 void TCollectionPropertyBrowsable::Browse(TBrowser *b)
762 GetBranch()->GetTree()->Draw(GetDraw(),
"", b ? b->GetDrawOption() :
"");
763 if (gPad) gPad->Update();
775 Int_t TCollectionPropertyBrowsable::GetBrowsables(TList& li,
const TBranch* branch,
776 const TVirtualBranchBrowsable* parent )
778 TClass* clContained=0;
779 TClass* clCollection=GetCollectionContainedType(branch, parent, clContained);
780 if (!clCollection || !clContained)
return 0;
785 parent->GetScope(scope);
786 branch=parent->GetBranch();
788 scope=branch->GetName();
790 const TBranch* mother=branch;
791 while (mother != mother->GetMother() && (mother=mother->GetMother())) {
792 TString nameMother(mother->GetName());
793 if (!nameMother.EndsWith(
".")) {
795 scope.Prepend(nameMother);
797 if (mother != mother->GetMother()) {
801 scope.Prepend(nameMother);
806 ::Warning(
"TCollectionPropertyBrowsable::GetBrowsables",
"Neither branch nor parent is set!");
811 if (scope.EndsWith(
".")) scope.Remove(scope.Length()-1, 1);
812 else if (scope.EndsWith(
"->")) scope.Remove(scope.Length()-2, 2);
816 Ssiz_t lastDot=scope.Last(
'.');
817 Ssiz_t lastArrow=scope.Last(
'>');
818 Ssiz_t lastPart=lastDot;
819 if (lastPart==kNPOS || (lastArrow!=kNPOS && lastPart<lastArrow))
821 if (lastPart==kNPOS) lastPart=0;
824 TString size_title(
"size of ");
825 size_title += clCollection->GetName();
827 size_title +=
" of ";
828 size_title += clContained->GetName();
831 if (clCollection->GetCollectionProxy() || clCollection==TClonesArray::Class()) {
834 TCollectionPropertyBrowsable* cpb;
835 if ( clCollection->GetCollectionProxy() &&
836 ( (clCollection->GetCollectionProxy()->GetValueClass()==0)
837 ||(clCollection->GetCollectionProxy()->GetValueClass()->GetCollectionProxy()!=0
838 && clCollection->GetCollectionProxy()->GetValueClass()->GetCollectionProxy()->GetValueClass()==0)
841 cpb =
new TCollectionPropertyBrowsable(
"values",
"values in the container",
842 scope, branch, parent);
845 scope.Insert(lastPart,
"@");
846 cpb =
new TCollectionPropertyBrowsable(
"@size", size_title,
847 scope+
".size()", branch, parent);
851 else if (clCollection->InheritsFrom(TCollection::Class())) {
854 if (clCollection->InheritsFrom(TObjArray::Class()))
855 scope+=
"@.GetEntries()";
856 else scope+=
"@.GetSize()";
857 TCollectionPropertyBrowsable* cpb=
858 new TCollectionPropertyBrowsable(
"@size", size_title, scope, branch, parent);
870 void TCollectionPropertyBrowsable::Register()
872 TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables);
880 void TCollectionPropertyBrowsable::Unregister()
882 TVirtualBranchBrowsable::UnregisterGenerator(GetBrowsables);
885 ClassImp(TCollectionMethodBrowsable);
909 TCollectionMethodBrowsable::TCollectionMethodBrowsable(
const TBranch* branch, TMethod* m,
910 const TVirtualBranchBrowsable* parent ):
911 TMethodBrowsable(branch, m, parent)
913 SetName(TString(
"@")+GetName());
923 Int_t TCollectionMethodBrowsable::GetBrowsables(TList& li,
const TBranch* branch,
924 const TVirtualBranchBrowsable* parent )
926 TClass* clContained=0;
928 TClass* clContainer=GetCollectionContainedType(branch, parent, clContained);
929 if (!clContainer || !clContained)
return 0;
932 GetBrowsableMethodsForClass(clContainer, listMethods);
934 TIter iMethods(&listMethods);
935 while ((method=(TMethod*)iMethods()))
936 li.Add(
new TCollectionMethodBrowsable(branch, method, parent));
942 if (!listMethods.GetSize() && clContainer->GetCollectionProxy()) {
943 std::list<MethodCreateListOfBrowsables_t>& listGenerators=GetRegisteredGenerators();
944 std::list<MethodCreateListOfBrowsables_t>::iterator iIsRegistered
945 = std::find(listGenerators.begin(), listGenerators.end(), &TCollectionPropertyBrowsable::GetBrowsables);
946 if (iIsRegistered==listGenerators.end()) {
947 TCollectionPropertyBrowsable::GetBrowsables(li, branch, parent);
951 return listMethods.GetSize();
959 void TCollectionMethodBrowsable::Register()
961 TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables);
969 void TCollectionMethodBrowsable::Unregister()
971 TVirtualBranchBrowsable::UnregisterGenerator(GetBrowsables);