Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
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
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 std::string clname = cl->GetName();
379 if ("TCanvas"s == clname) return kActCanvas;
380 if (("TGeoManager"s == cl->GetName()) || ("TGeoVolume"s == cl->GetName()) || (clname.compare(0, 8, "TGeoNode"s) == 0)) return kActGeom;
381 if (RProvider::CanDraw6(cl)) return kActDraw6;
382 if (RProvider::CanDraw7(cl)) return kActDraw7;
383 if (RProvider::CanHaveChilds(cl)) return kActBrowse;
384 return kActNone;
385}
386
387////////////////////////////////////////////////////////////////////////////////
388/// Check object capability
389
391{
392 auto cl = GetClass();
393 if (!cl) return false;
394
395 std::string clname = cl->GetName();
396
397 switch(action) {
398 case kActBrowse: return RProvider::CanHaveChilds(cl);
399 case kActEdit: return true;
400 case kActImage:
401 case kActDraw6: return RProvider::CanDraw6(cl); // if can draw in TCanvas, can produce image
402 case kActDraw7: return RProvider::CanDraw7(cl);
403 case kActCanvas: return "TCanvas"s == clname;
404 case kActGeom: return ("TGeoManager"s == clname) || ("TGeoVolume"s == clname) || (clname.compare(0, 8, "TGeoNode"s) == 0);
405 default: return false;
406 }
407
408 return false;
409}
410
411////////////////////////////////////////////////////////////////////////////////
412/// Creates iterator for TCollection object
413
414std::unique_ptr<RLevelIter> TObjectElement::GetCollectionIter(const TCollection *coll)
415{
416 return std::make_unique<TCollectionIter>(coll);
417}
418
419// ==============================================================================================
420
421/** \class RTObjectProvider
422\ingroup rbrowser
423
424Provider for all known TObject-based classes
425*/
426
428
429public:
430 //////////////////////////////////////////////////////////////////////////////////
431 // Register TObject-based class with standard browsing/drawing libs
432
433 void RegisterTObject(const std::string &clname, const std::string &iconname, bool can_browse = false, int can_draw = 3)
434 {
435 RegisterClass(clname, iconname, can_browse ? "dflt"s : ""s,
436 can_draw & 1 ? "libROOTObjectDraw6Provider"s : ""s,
437 can_draw & 2 ? "libROOTObjectDraw7Provider"s : ""s);
438 }
439
441 {
442 RegisterClass("TTree", "sap-icon://tree", "libROOTBranchBrowseProvider");
443 RegisterClass("TNtuple", "sap-icon://tree", "libROOTBranchBrowseProvider");
444 RegisterClass("TBranchElement", "sap-icon://e-care", "libROOTBranchBrowseProvider", "libROOTLeafDraw6Provider", "libROOTLeafDraw7Provider");
445 RegisterClass("TLeaf", "sap-icon://e-care", ""s, "libROOTLeafDraw6Provider", "libROOTLeafDraw7Provider");
446 RegisterClass("TBranch", "sap-icon://e-care", "libROOTBranchBrowseProvider"s, "libROOTLeafDraw6Provider", "libROOTLeafDraw7Provider");
447 RegisterClass("TVirtualBranchBrowsable", "sap-icon://e-care", ""s, "libROOTLeafDraw6Provider", "libROOTLeafDraw7Provider");
448 RegisterClass("TColor", "sap-icon://palette");
449 RegisterClass("TStyle", "sap-icon://badge");
450
451 RegisterTObject("TDirectory", "sap-icon://folder-blank", true, 0);
452 RegisterTObject("TH1", "sap-icon://bar-chart");
453 RegisterTObject("TH2", "sap-icon://pixelate");
454 RegisterTObject("TH3", "sap-icon://product");
455 RegisterTObject("TProfile", "sap-icon://vertical-bar-chart");
456 RegisterTObject("TGraph", "sap-icon://line-chart");
457 RegisterTObject("TCanvas", "sap-icon://business-objects-experience", false, 1); // only can use TWebCanvas
458 RegisterTObject("TASImage", "sap-icon://picture", false, 1); // only can use TWebCanvas
459
460 RegisterTObject("THStack", "sap-icon://multiple-bar-chart");
461 RegisterTObject("TMultiGraph", "sap-icon://multiple-line-chart");
462
463 RegisterTObject("TCollection", "sap-icon://list", true, 0);
464 RegisterTObject("TGeoManager", "sap-icon://overview-chart", true, 0);
465 RegisterTObject("TGeoVolume", "sap-icon://product", true, 0);
466 RegisterTObject("TGeoNode", "sap-icon://product", true, 0);
467
468 RegisterBrowse(TFolder::Class(), [](std::unique_ptr<RHolder> &object) -> std::shared_ptr<RElement> {
469 return std::make_shared<TFolderElement>(object);
470 });
471
472 RegisterBrowse(TCollection::Class(), [](std::unique_ptr<RHolder> &object) -> std::shared_ptr<RElement> {
473 return std::make_shared<TCollectionElement>(object);
474 });
475
476 RegisterBrowse(nullptr, [](std::unique_ptr<RHolder> &object) -> std::shared_ptr<RElement> {
477 if (object->CanCastTo<TObject>())
478 return std::make_shared<TObjectElement>(object);
479 return nullptr;
480 });
481 }
482
#define f(i)
Definition RSha256.hxx:104
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, ...
virtual bool Find(const std::string &name, int indx=-1)
Find item with specified name Default implementation, should work for all If index specified,...
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.
static std::shared_ptr< RElement > Browse(std::unique_ptr< RHolder > &obj)
Create browsable element for the object Created element may take ownership over the object.
static bool CanDraw7(const ClassArg &)
Return true if provided class can be drawn on the RCanvas.
static std::string GetClassIcon(const ClassArg &, bool=false)
Return icon name for the given class - either class name or TClass *.
static bool CanHaveChilds(const ClassArg &)
Return true if provided class can have childs.
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
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
The color creation and management class.
Definition TColor.h:19
Int_t GetNumber() const
Definition TColor.h:56
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()
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)
virtual void Copy(TObject &named) const
Copy this to obj.
Definition TNamed.cxx:94
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:41
virtual Bool_t IsFolder() const
Returns kTRUE in case object contains browsable objects (like containers or lists of other objects).
Definition TObject.cxx:545
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:429
virtual void Browse(TBrowser *b)
Browse object. May be overridden for another default action.
Definition TObject.cxx:191
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:200
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:473