Logo ROOT  
Reference Guide
TObjectElement.cxx
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (C) 1995-2021, Rene Brun and Fons Rademakers. *
3 * All rights reserved. *
4 * *
5 * For the licensing terms see $ROOTSYS/LICENSE. *
6 * For the list of contributors see $ROOTSYS/README/CREDITS. *
7 *************************************************************************/
8
14
15#include <ROOT/RLogger.hxx>
16
17#include "TBrowser.h"
18#include "TBrowserImp.h"
19#include "TFolder.h"
20#include "TList.h"
21#include "TColor.h"
22#include "TDirectory.h"
23#include "TBufferJSON.h"
24
25#include <sstream>
26
27using namespace std::string_literals;
28
29using namespace ROOT::Experimental::Browsable;
30
31/** \class TObjectLevelIter
32\ingroup rbrowser
33
34Iterator over list of elements, designed for support TBrowser usage
35*/
36
38
39 std::vector<std::shared_ptr<RElement>> fElements;
40
41 int fCounter{-1};
42
43public:
44 explicit TObjectLevelIter() {}
45
46 virtual ~TObjectLevelIter() = default;
47
48 void AddElement(std::shared_ptr<RElement> &&elem)
49 {
50 fElements.emplace_back(std::move(elem));
51 }
52
53 auto NumElements() const { return fElements.size(); }
54
55 bool Next() override { return ++fCounter < (int) fElements.size(); }
56
57 // use default implementation for now
58 // bool Find(const std::string &name) override { return FindDirEntry(name); }
59
60 std::string GetItemName() const override { return fElements[fCounter]->GetName(); }
61
62 bool CanItemHaveChilds() const override
63 {
64 std::shared_ptr<TObjectElement> telem = std::dynamic_pointer_cast<TObjectElement>(fElements[fCounter]);
65 return telem ? telem->IsFolder() : false;
66 }
67
68 /** Create element for the browser */
69 std::unique_ptr<RItem> CreateItem() override
70 {
71 std::shared_ptr<TObjectElement> elem = std::dynamic_pointer_cast<TObjectElement>(fElements[fCounter]);
72 // should never happen
73 if (!elem) return nullptr;
74
75 auto cl = elem->GetClass();
76
77 auto nchilds = elem->GetNumChilds();
78 if ((nchilds == 0) && elem->IsFolder()) nchilds = -1; // indicate that TObject is container
79
80 auto item = std::make_unique<TObjectItem>(elem->GetName(), nchilds);
81
82 item->SetClassName(cl ? cl->GetName() : "");
83
84 item->SetIcon(RProvider::GetClassIcon(cl, nchilds > 0));
85
86 item->SetTitle(elem->GetTitle());
87
88 auto sz = elem->GetSize();
89 if (sz >= 0)
90 item->SetSize(std::to_string(sz));
91
92 return item;
93 }
94
95 /** Returns full information for current element */
96 std::shared_ptr<RElement> GetElement() override
97 {
98 return fElements[fCounter];
99 }
100
101 bool Find(const std::string &name, int indx = -1) override
102 {
103 if ((indx >= 0) && (indx < (int) fElements.size()) && (name == fElements[indx]->GetName())) {
104 fCounter = indx;
105 return true;
106 }
107
108 return RLevelIter::Find(name, -1);
109 }
110
111};
112
113// ===============================================================================================================
114
116 TObjectLevelIter *fIter{nullptr}; ///<! back-reference on iterator
117 const TObject *fBrowseObj{nullptr}; ///<! object which wil be browsed
118 bool fDuplicated{false}; ///<! is object was duplicated?
119
120public:
121
122 TMyBrowserImp(TObjectLevelIter *iter, TObject *obj) : TBrowserImp(nullptr), fIter(iter), fBrowseObj(obj) {}
123 virtual ~TMyBrowserImp() = default;
124
125 bool IsDuplicated() const { return fDuplicated; }
126
127 void Add(TObject* obj, const char* name, Int_t) override
128 {
129 // prevent duplication of object itself - ignore such browsing
130 if (fBrowseObj == obj) fDuplicated = true;
131 if (fDuplicated) return;
132
133 std::unique_ptr<RHolder> holder = std::make_unique<TObjectHolder>(obj);
134
135 std::shared_ptr<RElement> elem = RProvider::Browse(holder);
136
137 if (name && *name) {
138 std::shared_ptr<TObjectElement> telem = std::dynamic_pointer_cast<TObjectElement>(elem);
139 if (telem) telem->SetName(name);
140 }
141
142 fIter->AddElement(std::move(elem));
143
144 }
145
146};
147
148// ===============================================================================================================
149
150/** \class TCollectionIter
151\ingroup rbrowser
152
153Iterator over elements in TCollection
154*/
155
157
159
160public:
161 explicit TCollectionIter(const TFolder *f) : RLevelIter(), fIter(f->GetListOfFolders()) {};
162
163 explicit TCollectionIter(const TCollection *coll) : RLevelIter(), fIter(coll) {};
164
165 virtual ~TCollectionIter() = default;
166
167 bool Next() override { return fIter.Next() != nullptr; }
168
169 // use default implementation for now
170 // bool Find(const std::string &name) override { return FindDirEntry(name); }
171
172 std::string GetItemName() const override { return (*fIter)->GetName(); }
173
174 bool CanItemHaveChilds() const override
175 {
176 TObject *obj = *fIter;
177 return obj ? obj->IsFolder() : false;
178 }
179
180 /** Create item for current TObject */
181 std::unique_ptr<RItem> CreateItem() override
182 {
183 TObject *obj = *fIter;
184 if (!obj) return nullptr;
185
186 auto item = std::make_unique<TObjectItem>(obj->GetName(), obj->IsFolder() ? -1 : 0);
187
188 item->SetClassName(obj->ClassName());
189
190 item->SetIcon(RProvider::GetClassIcon(obj->IsA(), obj->IsFolder()));
191
192 item->SetTitle(obj->GetTitle());
193
194 if (obj->IsA() == TColor::Class()) {
195 if (item->GetName().empty())
196 item->SetName("Color"s + std::to_string(static_cast<TColor *>(obj)->GetNumber()));
197 }
198
199 return item;
200 }
201
202 /** Returns full information for current element */
203 std::shared_ptr<RElement> GetElement() override
204 {
205 std::unique_ptr<RHolder> holder = std::make_unique<TObjectHolder>(*fIter, kFALSE);
206
207 return RProvider::Browse(holder);
208 }
209
210};
211
212
213// ==============================================================================================
214
215/** \class TFolderElement
216\ingroup rbrowser
217
218Browsable element for TFolder
219*/
220
221
223
224public:
225
226 TFolderElement(std::unique_ptr<RHolder> &obj) : TObjectElement(obj) {}
227
228 std::unique_ptr<RLevelIter> GetChildsIter() override
229 {
230 auto folder = fObject->Get<TFolder>();
231 if (folder)
232 return std::make_unique<TCollectionIter>(folder->GetListOfFolders());
233
234 return TObjectElement::GetChildsIter();
235 }
236
237 int GetNumChilds() override
238 {
239 auto folder = fObject->Get<TFolder>();
240 return folder && folder->GetListOfFolders() ? folder->GetListOfFolders()->GetEntries() : 0;
241 }
242};
243
244// ==============================================================================================
245
246/** \class TCollectionElement
247\ingroup rbrowser
248
249Browsable element for TCollection
250*/
251
252
254public:
255
256 TCollectionElement(std::unique_ptr<RHolder> &obj) : TObjectElement(obj) {}
257
258 std::unique_ptr<RLevelIter> GetChildsIter() override
259 {
260 auto coll = fObject->Get<TCollection>();
261 if (coll && (coll->GetSize() > 0))
262 return std::make_unique<TCollectionIter>(coll);
263
264 return TObjectElement::GetChildsIter();
265 }
266
267 int GetNumChilds() override
268 {
269 auto coll = fObject->Get<TCollection>();
270 return coll ? coll->GetSize() : 0;
271 }
272};
273
274// =================================================================================
275
276////////////////////////////////////////////////////////////////////////////////
277/// Constructor with plain TObject* as argument - ownership is not defined
278
279TObjectElement::TObjectElement(TObject *obj, const std::string &name) : fObj(obj), fName(name)
280{
281 fObject = std::make_unique<TObjectHolder>(fObj);
282 if (fName.empty())
283 fName = fObj->GetName();
284}
285
286////////////////////////////////////////////////////////////////////////////////
287/// Constructor with std::unique_ptr<RHolder> as argument
288
289TObjectElement::TObjectElement(std::unique_ptr<RHolder> &obj, const std::string &name)
290{
291 fObject = std::move(obj); // take responsibility
292 fObj = const_cast<TObject *>(fObject->Get<TObject>()); // try to cast into TObject
293
294 fName = name;
295 if (!fObj)
296 fObject.reset();
297 else if (fName.empty())
298 fName = fObj->GetName();
299}
300
301////////////////////////////////////////////////////////////////////////////////
302/// Returns name of the TObject
303
304std::string TObjectElement::GetName() const
305{
306 if (!fName.empty()) return fName;
307 return fObj ? fObj->GetName() : "";
308}
309
310////////////////////////////////////////////////////////////////////////////////
311/// Returns title of the TObject
312
313std::string TObjectElement::GetTitle() const
314{
315 return fObj ? fObj->GetTitle() : "";
316}
317
318////////////////////////////////////////////////////////////////////////////////
319/// Returns IsFolder of contained TObject
320
322{
323 return fObj ? fObj->IsFolder() : false;
324}
325
326////////////////////////////////////////////////////////////////////////////////
327/// Create iterator for childs elements if any
328
329std::unique_ptr<RLevelIter> TObjectElement::GetChildsIter()
330{
331 if (!IsFolder()) return nullptr;
332
333 auto iter = std::make_unique<TObjectLevelIter>();
334
335 TMyBrowserImp *imp = new TMyBrowserImp(iter.get(), fObj);
336
337 // must be new, otherwise TBrowser constructor ignores imp
338 TBrowser *br = new TBrowser("name", "title", imp);
339
340 fObj->Browse(br);
341
342 auto dupl = imp->IsDuplicated();
343
344 delete br; // also will destroy implementaion
345
346 if (dupl || (iter->NumElements() == 0)) return nullptr;
347
348 return iter;
349}
350
351////////////////////////////////////////////////////////////////////////////////
352/// Returns copy of TObject holder - if possible
353
354std::unique_ptr<RHolder> TObjectElement::GetObject()
355{
356 if (!fObject)
357 return nullptr;
358
359 return fObject->Copy();
360}
361
362////////////////////////////////////////////////////////////////////////////////
363/// Returns class for contained object
364
366{
367 return fObj ? fObj->IsA() : nullptr;
368}
369
370
371////////////////////////////////////////////////////////////////////////////////
372/// Provides default action which can be performed with the object
373
375{
376 auto cl = GetClass();
377 if (!cl) return kActNone;
378 if ("TCanvas"s == cl->GetName()) return kActCanvas;
379 if (("TGeoManager"s == cl->GetName()) || ("TGeoVolume"s == cl->GetName())) return kActGeom;
380 if (RProvider::CanDraw6(cl)) return kActDraw6;
381 if (RProvider::CanDraw7(cl)) return kActDraw7;
382 if (RProvider::CanHaveChilds(cl)) return kActBrowse;
383 return kActNone;
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Check object capability
388
390{
391 auto cl = GetClass();
392 if (!cl) return false;
393
394 switch(action) {
395 case kActBrowse: return RProvider::CanHaveChilds(cl);
396 case kActEdit: return true;
397 case kActImage:
398 case kActDraw6: return RProvider::CanDraw6(cl); // if can draw in TCanvas, can produce image
399 case kActDraw7: return RProvider::CanDraw7(cl);
400 case kActCanvas: return "TCanvas"s == cl->GetName();
401 case kActGeom: return ("TGeoManager"s == cl->GetName()) || ("TGeoVolume"s == cl->GetName());
402 default: return false;
403 }
404
405 return false;
406}
407
408////////////////////////////////////////////////////////////////////////////////
409/// Creates iterator for TCollection object
410
411std::unique_ptr<RLevelIter> TObjectElement::GetCollectionIter(const TCollection *coll)
412{
413 return std::make_unique<TCollectionIter>(coll);
414}
415
416// ==============================================================================================
417
418/** \class RTObjectProvider
419\ingroup rbrowser
420
421Provider for all known TObject-based classes
422*/
423
425
426public:
427 //////////////////////////////////////////////////////////////////////////////////
428 // Register TObject-based class with standard browsing/drawing libs
429
430 void RegisterTObject(const std::string &clname, const std::string &iconname, bool can_browse = false, int can_draw = 3)
431 {
432 RegisterClass(clname, iconname, can_browse ? "dflt"s : ""s,
433 can_draw & 1 ? "libROOTObjectDraw6Provider"s : ""s,
434 can_draw & 2 ? "libROOTObjectDraw7Provider"s : ""s);
435 }
436
438 {
439 RegisterClass("TTree", "sap-icon://tree", "libROOTBranchBrowseProvider");
440 RegisterClass("TNtuple", "sap-icon://tree", "libROOTBranchBrowseProvider");
441 RegisterClass("TBranchElement", "sap-icon://e-care", "libROOTBranchBrowseProvider", "libROOTLeafDraw6Provider", "libROOTLeafDraw7Provider");
442 RegisterClass("TLeaf", "sap-icon://e-care", ""s, "libROOTLeafDraw6Provider", "libROOTLeafDraw7Provider");
443 RegisterClass("TBranch", "sap-icon://e-care", "libROOTBranchBrowseProvider"s, "libROOTLeafDraw6Provider", "libROOTLeafDraw7Provider");
444 RegisterClass("TVirtualBranchBrowsable", "sap-icon://e-care", ""s, "libROOTLeafDraw6Provider", "libROOTLeafDraw7Provider");
445 RegisterClass("TColor", "sap-icon://palette");
446 RegisterClass("TStyle", "sap-icon://badge");
447
448 RegisterTObject("TDirectory", "sap-icon://folder-blank", true, 0);
449 RegisterTObject("TH1", "sap-icon://bar-chart");
450 RegisterTObject("TH2", "sap-icon://pixelate");
451 RegisterTObject("TH3", "sap-icon://product");
452 RegisterTObject("TProfile", "sap-icon://vertical-bar-chart");
453 RegisterTObject("TGraph", "sap-icon://line-chart");
454 RegisterTObject("TCanvas", "sap-icon://business-objects-experience", false, 1); // only can use TWebCanvas
455 RegisterTObject("TASImage", "sap-icon://picture", false, 1); // only can use TWebCanvas
456
457 RegisterTObject("THStack", "sap-icon://multiple-bar-chart");
458 RegisterTObject("TMultiGraph", "sap-icon://multiple-line-chart");
459
460 RegisterTObject("TCollection", "sap-icon://list", true, 0);
461 RegisterTObject("TGeoManager", "sap-icon://overview-chart", true, 0);
462 RegisterTObject("TGeoVolume", "sap-icon://product", true, 0);
463 RegisterTObject("TGeoNode", "sap-icon://product", true, 0);
464
465 RegisterBrowse(TFolder::Class(), [](std::unique_ptr<RHolder> &object) -> std::shared_ptr<RElement> {
466 return std::make_shared<TFolderElement>(object);
467 });
468
469 RegisterBrowse(TCollection::Class(), [](std::unique_ptr<RHolder> &object) -> std::shared_ptr<RElement> {
470 return std::make_shared<TCollectionElement>(object);
471 });
472
473 RegisterBrowse(nullptr, [](std::unique_ptr<RHolder> &object) -> std::shared_ptr<RElement> {
474 if (object->CanCastTo<TObject>())
475 return std::make_shared<TObjectElement>(object);
476 return nullptr;
477 });
478 }
479
void Class()
Definition: Class.C:29
#define f(i)
Definition: RSha256.hxx:104
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
char name[80]
Definition: TGX11.cxx:110
RTObjectProvider newRTObjectProvider
EActionKind
Possible actions on double-click.
Definition: RElement.hxx:49
@ kActEdit
can provide data for text editor
Definition: RElement.hxx:52
@ kActCanvas
indicate that it is canvas and should be drawn directly
Definition: RElement.hxx:56
@ kActBrowse
just browse (expand) item
Definition: RElement.hxx:51
@ kActGeom
can be shown in geometry viewer
Definition: RElement.hxx:57
@ kActDraw7
can be drawn inside ROOT7 canvas
Definition: RElement.hxx:55
@ kActImage
can be shown in image viewer, can provide image
Definition: RElement.hxx:53
@ kActDraw6
can be drawn inside ROOT6 canvas
Definition: RElement.hxx:54
Iterator over single level hierarchy like any array, keys list, ...
Definition: RLevelIter.hxx:30
Provider of different browsing methods for supported classes.
Definition: RProvider.hxx:36
static bool CanDraw6(const ClassArg &)
Return true if provided class can be drawn on the TCanvas.
Definition: RProvider.cxx:383
static bool CanDraw7(const ClassArg &)
Return true if provided class can be drawn on the RCanvas.
Definition: RProvider.cxx:397
static bool CanHaveChilds(const ClassArg &)
Return true if provided class can have childs.
Definition: RProvider.cxx:375
Access to TObject basic properties for RBrowsable.
std::unique_ptr< RHolder > GetObject() override
Return copy of TObject holder - if possible.
const TClass * GetClass() const
Returns class for contained object.
TObjectElement(TObject *obj, const std::string &name="")
Constructor with plain TObject* as argument - ownership is not defined.
bool IsCapable(EActionKind) const override
Check object capability.
static std::unique_ptr< RLevelIter > GetCollectionIter(const TCollection *)
Creates iterator for TCollection object.
bool IsFolder() const
Returns IsFolder of contained TObject.
std::string GetTitle() const override
Title of TObject.
std::unique_ptr< RLevelIter > GetChildsIter() override
Create iterator for childs elements if any.
EActionKind GetDefaultAction() const override
Provides default action which can be performed with the object.
std::string GetName() const override
Name of TObject.
Provider for all known TObject-based classes.
void RegisterTObject(const std::string &clname, const std::string &iconname, bool can_browse=false, int can_draw=3)
ABC describing GUI independent browser implementation protocol.
Definition: TBrowserImp.h:29
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
Browsable element for TCollection.
int GetNumChilds() override
Returns number of childs By default creates iterator and iterates over all items.
std::unique_ptr< RLevelIter > GetChildsIter() override
Create iterator for childs elements if any.
TCollectionElement(std::unique_ptr< RHolder > &obj)
Iterator over elements in TCollection.
std::unique_ptr< RItem > CreateItem() override
Create item for current TObject.
TCollectionIter(const TFolder *f)
bool CanItemHaveChilds() const override
Returns true if current item can have childs.
bool Next() override
Shift to next entry.
virtual ~TCollectionIter()=default
TCollectionIter(const TCollection *coll)
std::shared_ptr< RElement > GetElement() override
Returns full information for current element.
std::string GetItemName() const override
Returns current entry name
Collection abstract base class.
Definition: TCollection.h:65
virtual Int_t GetEntries() const
Definition: TCollection.h:179
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:184
The color creation and management class.
Definition: TColor.h:19
Browsable element for TFolder.
TFolderElement(std::unique_ptr< RHolder > &obj)
std::unique_ptr< RLevelIter > GetChildsIter() override
Create iterator for childs elements if any.
int GetNumChilds() override
Returns number of childs By default creates iterator and iterates over all items.
A TFolder object is a collection of objects and folders.
Definition: TFolder.h:30
TCollection * GetListOfFolders() const
Definition: TFolder.h:55
TObject * Next()
Definition: TCollection.h:251
bool fDuplicated
! is object was duplicated?
virtual ~TMyBrowserImp()=default
TObjectLevelIter * fIter
! back-reference on iterator
void Add(TObject *obj, const char *name, Int_t) override
const TObject * fBrowseObj
! object which wil be browsed
bool IsDuplicated() const
TMyBrowserImp(TObjectLevelIter *iter, TObject *obj)
Iterator over list of elements, designed for support TBrowser usage.
std::unique_ptr< RItem > CreateItem() override
Create element for the browser.
std::vector< std::shared_ptr< RElement > > fElements
bool CanItemHaveChilds() const override
Returns true if current item can have childs.
std::string GetItemName() const override
Returns current entry name
void AddElement(std::shared_ptr< RElement > &&elem)
auto NumElements() const
bool Next() override
Shift to next entry.
std::shared_ptr< RElement > GetElement() override
Returns full information for current element.
bool Find(const std::string &name, int indx=-1) override
Find item with specified name Default implementation, should work for all If index specified,...
virtual ~TObjectLevelIter()=default
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Bool_t IsFolder() const
Returns kTRUE in case object contains browsable objects (like containers or lists of other objects).
Definition: TObject.cxx:475
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
virtual void Browse(TBrowser *b)
Browse object. May be overridden for another default action.
Definition: TObject.cxx:121
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:403
static constexpr double s
UInt_t Find(std::list< std::pair< const Node< T > *, Float_t > > &nlist, const Node< T > *node, const T &event, UInt_t nfind)