00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TROOT.h"
00013 #include "TGuiFactory.h"
00014 #include "TInspectCanvas.h"
00015 #include "TButton.h"
00016 #include "TClass.h"
00017 #include "TLine.h"
00018 #include "TLink.h"
00019 #include "TDataMember.h"
00020 #include "TDataType.h"
00021 #include "TRealData.h"
00022 #include "TLatex.h"
00023
00024 ClassImp(TInspectCanvas)
00025
00026
00027
00028
00029
00030
00031
00032 class TInspectorObject : public TObject
00033 {
00034
00035
00036
00037 public:
00038
00039 TInspectorObject(void *obj, TClass *cl) : fObj(obj),fClass(cl) {};
00040 ~TInspectorObject(){;}
00041
00042 void *GetObject() const { return fObj; };
00043 void Inspect() const {
00044 gGuiFactory->CreateInspectorImp(this, 400, 200);
00045 };
00046 TClass *IsA() const { return fClass; }
00047
00048 private:
00049 void *fObj;
00050 TClass *fClass;
00051
00052 };
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 TInspectCanvas::TInspectCanvas() : TCanvas()
00068 {
00069
00070
00071 fBackward = 0;
00072 fForward = 0;
00073 fCurObject = 0;
00074 fObjects = 0;
00075 fLogx = kFALSE;
00076 fLogy = kFALSE;
00077 }
00078
00079
00080
00081 TInspectCanvas::TInspectCanvas(UInt_t ww, UInt_t wh)
00082 : TCanvas("inspect","ROOT Object Inspector",ww,wh)
00083 {
00084
00085
00086 fBackward = 0;
00087 fForward = 0;
00088 fCurObject = 0;
00089 fObjects = new TList;
00090 fLogx = kFALSE;
00091 fLogy = kFALSE;
00092 }
00093
00094
00095
00096 TInspectCanvas::~TInspectCanvas()
00097 {
00098
00099
00100 if (fObjects) {
00101 fObjects->Clear("nodelete");
00102 delete fObjects;
00103 }
00104 }
00105
00106
00107
00108 void TInspectCanvas::InspectObject(TObject *obj)
00109 {
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 Int_t cdate = 0;
00122 Int_t ctime = 0;
00123 UInt_t *cdatime = 0;
00124 Bool_t isdate = kFALSE;
00125 Bool_t isbits = kFALSE;
00126 const Int_t kname = 1;
00127 const Int_t kvalue = 25;
00128 const Int_t ktitle = 37;
00129 const Int_t kline = 1024;
00130 char line[kline];
00131 char *pname;
00132
00133 TClass *cl = obj->IsA();
00134 if (cl == 0) return;
00135 TInspectorObject *proxy=0;
00136 if (!cl->InheritsFrom(TObject::Class())) {
00137
00138
00139 proxy = (TInspectorObject*)obj;
00140 obj = (TObject*)proxy->GetObject();
00141 }
00142
00143 if (!cl->GetListOfRealData()) cl->BuildRealData(obj);
00144
00145
00146 TRealData *rd;
00147 TIter next(cl->GetListOfRealData());
00148 Int_t nreal = cl->GetListOfRealData()->GetSize();
00149 if (nreal == 0) return;
00150
00151 Int_t nrows = 33;
00152 if (nreal+7 > nrows) nrows = nreal+7;
00153 Int_t nh = nrows*15;
00154 Int_t nw = 700;
00155 TVirtualPad *canvas = GetVirtCanvas();
00156 canvas->Clear();
00157 canvas->SetCanvasSize(nw, nh);
00158 canvas->Range(0,-3,20,nreal+4);
00159
00160 Float_t xvalue = 5;
00161 Float_t xtitle = 8;
00162 Float_t dy = 1;
00163 Float_t ytext = Float_t(nreal) - 1.5;
00164 Float_t tsize = 0.99/ytext;
00165 if (tsize < 0.02) tsize = 0.02;
00166 if (tsize > 0.03) tsize = 0.03;
00167
00168
00169 TText tname, tvalue, ttitle;
00170 TText *tval;
00171 tname.SetTextFont(61);
00172 tname.SetTextAngle(0);
00173 tname.SetTextAlign(12);
00174 tname.SetTextColor(1);
00175 tname.SetTextSize(tsize);
00176 tvalue.SetTextFont(61);
00177 tvalue.SetTextAngle(0);
00178 tvalue.SetTextAlign(12);
00179 tvalue.SetTextColor(1);
00180 tvalue.SetTextSize(tsize);
00181 ttitle.SetTextFont(62);
00182 ttitle.SetTextAngle(0);
00183 ttitle.SetTextAlign(12);
00184 ttitle.SetTextColor(1);
00185 ttitle.SetTextSize(tsize);
00186
00187 Float_t x1 = 0.2;
00188 Float_t x2 = 19.8;
00189 Float_t y1 = -0.5;
00190 Float_t y2 = Float_t(nreal) - 0.5;
00191 Float_t y3 = y2 + 1;
00192 Float_t y4 = y3 + 1.5;
00193 Float_t db = 25./GetWh();
00194 Float_t btop = 0.999;
00195
00196
00197 fBackward = new TButton("backward","TInspectCanvas::GoBackward();",.01,btop-db,.15,btop);
00198 fBackward->Draw();
00199 fBackward->SetToolTipText("Inspect previous object");
00200 fForward = new TButton("forward", "TInspectCanvas::GoForward();", .21,btop-db,.35,btop);
00201 fForward->Draw();
00202 fForward->SetToolTipText("Inspect next object");
00203
00204
00205 TLine frame;
00206 frame.SetLineColor(1);
00207 frame.SetLineStyle(1);
00208 frame.SetLineWidth(1);
00209 frame.DrawLine(x1, y1, x2, y1);
00210 frame.DrawLine(x2, y1, x2, y4);
00211 frame.DrawLine(x2, y4, x1, y4);
00212 frame.DrawLine(x1, y4, x1, y1);
00213 frame.DrawLine(x1, y2, x2, y2);
00214 frame.DrawLine(x1, y3, x2, y3);
00215 frame.DrawLine(xvalue, y1, xvalue, y3);
00216 frame.DrawLine(xtitle, y1, xtitle, y3);
00217 ttitle.SetTextSize(0.8*tsize);
00218 ttitle.SetTextAlign(21);
00219 ttitle.DrawText(0.5*(x1+xvalue), y2+0.1, "Member Name");
00220 ttitle.DrawText(0.5*(xvalue+xtitle), y2+0.1, "Value");
00221 ttitle.DrawText(0.5*(xtitle+x2), y2+0.1, "Title");
00222 ttitle.SetTextSize(1.2*tsize);
00223 ttitle.SetTextColor(2);
00224 ttitle.SetTextAlign(11);
00225 ttitle.DrawText(x1+0.2, y3+0.1, cl->GetName());
00226 if (proxy==0) {
00227 ttitle.SetTextColor(4);
00228 strlcpy(line,obj->GetName(),kline);
00229 ttitle.DrawText(xvalue+0.2, y3+0.1, line);
00230 ttitle.SetTextColor(6);
00231 ttitle.DrawText(xtitle+2, y3+0.1, obj->GetTitle());
00232 } else {
00233 ttitle.SetTextColor(4);
00234 snprintf(line,1023,"%s:%d","Foreign object",0);
00235 ttitle.DrawText(xvalue+0.2, y3+0.1, line);
00236 ttitle.SetTextColor(6);
00237 ttitle.DrawText(xtitle+2, y3+0.1, "no title given");
00238 }
00239 ttitle.SetTextSize(tsize);
00240 ttitle.SetTextColor(1);
00241 ttitle.SetTextFont(11);
00242 ttitle.SetTextAlign(12);
00243
00244
00245
00246
00247 for (Int_t pass = 0; pass < 3; pass++) {
00248 ytext = y2 - 0.5;
00249 next.Reset();
00250 while ((rd = (TRealData*) next())) {
00251 TDataMember *member = rd->GetDataMember();
00252 if (!member) continue;
00253 TDataType *membertype = member->GetDataType();
00254 isdate = kFALSE;
00255 if (strcmp(member->GetName(),"fDatime") == 0 && strcmp(member->GetTypeName(),"UInt_t") == 0) {
00256 isdate = kTRUE;
00257 }
00258 isbits = kFALSE;
00259 if (strcmp(member->GetName(),"fBits") == 0 && strcmp(member->GetTypeName(),"UInt_t") == 0) {
00260 isbits = kTRUE;
00261 }
00262
00263
00264 pname = &line[kname];
00265 for (Int_t i=0;i<kline;i++) line[i] = ' ';
00266 line[kline-1] = 0;
00267 strlcpy(pname,rd->GetName(),kline-kname);
00268 if (strstr(member->GetFullTypeName(),"**")) strlcat(pname,"**",kline-kname);
00269
00270
00271 tval = &tvalue;
00272 Int_t offset = rd->GetThisOffset();
00273 char *pointer = (char*)obj + offset;
00274 char **ppointer = (char**)(pointer);
00275 TLink *tlink = 0;
00276
00277 TClass *clm=0;
00278 if (!membertype) {
00279 clm = member->GetClass();
00280 }
00281
00282 if (member->IsaPointer()) {
00283 char **p3pointer = (char**)(*ppointer);
00284 if (clm && !clm->IsStartingWithTObject() ) {
00285
00286 p3pointer = (char**)new TInspectorObject(p3pointer,clm);
00287 }
00288
00289 if (!p3pointer) {
00290 snprintf(&line[kvalue],kline-kvalue,"->0");
00291 } else if (!member->IsBasic()) {
00292 if (pass == 1) {
00293 tlink = new TLink(xvalue+0.1, ytext, p3pointer);
00294 }
00295 } else if (membertype) {
00296 if (!strcmp(membertype->GetTypeName(), "char"))
00297 strlcpy(&line[kvalue], *ppointer,kline-kvalue);
00298 else
00299 strlcpy(&line[kvalue], membertype->AsString(p3pointer),kline-kvalue);
00300 } else if (!strcmp(member->GetFullTypeName(), "char*") ||
00301 !strcmp(member->GetFullTypeName(), "const char*")) {
00302 strlcpy(&line[kvalue], *ppointer,kline-kvalue);
00303 } else {
00304 if (pass == 1) tlink = new TLink(xvalue+0.1, ytext, p3pointer);
00305 }
00306 } else if (membertype)
00307 if (isdate) {
00308 cdatime = (UInt_t*)pointer;
00309 TDatime::GetDateTime(cdatime[0],cdate,ctime);
00310 snprintf(&line[kvalue],kline-kvalue,"%d/%d",cdate,ctime);
00311 } else if (isbits) {
00312 snprintf(&line[kvalue],kline-kvalue,"0x%08x", *(UInt_t*)pointer);
00313 } else {
00314 strlcpy(&line[kvalue], membertype->AsString(pointer),kline-kvalue);
00315 }
00316 else
00317 snprintf(&line[kvalue],kline-kvalue,"->%lx ", (Long_t)pointer);
00318
00319
00320 Int_t ltit = 0;
00321 if (isdate == kFALSE && strcmp(member->GetFullTypeName(), "char*") &&
00322 strcmp(member->GetFullTypeName(), "const char*")) {
00323 Int_t lentit = strlen(member->GetTitle());
00324 if (lentit >= kline-ktitle) lentit = kline-ktitle-1;
00325 strlcpy(&line[ktitle],member->GetTitle(),kline-ktitle);
00326 line[ktitle+lentit] = 0;
00327 ltit = ktitle;
00328 }
00329
00330
00331 if (pass == 0)tname.DrawText( x1+0.1, ytext, &line[kname]);
00332 if (pass == 1) {
00333 if (tlink) {
00334 tlink->SetTextFont(61);
00335 tlink->SetTextAngle(0);
00336 tlink->SetTextAlign(12);
00337 tlink->SetTextColor(2);
00338 tlink->SetTextSize(tsize);
00339 tlink->SetBit(kCanDelete);
00340 tlink->Draw();
00341 if (strstr(member->GetFullTypeName(),"**")) tlink->SetBit(TLink::kIsStarStar);
00342 tlink->SetName(member->GetTypeName());
00343 } else {
00344 tval->DrawText(xvalue+0.1, ytext, &line[kvalue]);
00345 }
00346 }
00347 if (pass == 2 && ltit) ttitle.DrawText(xtitle+0.3, ytext, &line[ltit]);
00348 ytext -= dy;
00349 }
00350 }
00351 Update();
00352 fCurObject = obj;
00353 }
00354
00355
00356
00357 void TInspectCanvas::GoBackward()
00358 {
00359
00360
00361 TInspectCanvas *inspect = (TInspectCanvas*)(gROOT->GetListOfCanvases())->FindObject("inspect");
00362 TObject *cur = inspect->GetCurObject();
00363 TObject *obj = inspect->GetObjects()->Before(cur);
00364 if (obj) inspect->InspectObject(obj);
00365 }
00366
00367
00368
00369 void TInspectCanvas::GoForward()
00370 {
00371
00372
00373 TInspectCanvas *inspect = (TInspectCanvas*)(gROOT->GetListOfCanvases())->FindObject("inspect");
00374 TObject *cur = inspect->GetCurObject();
00375 TObject *obj = inspect->GetObjects()->After(cur);
00376 if (obj) inspect->InspectObject(obj);
00377 }
00378
00379
00380
00381 void TInspectCanvas::Inspector(TObject *obj)
00382 {
00383
00384
00385
00386 TVirtualPad *padsav = gPad;
00387 TInspectCanvas *inspect = (TInspectCanvas*)(gROOT->GetListOfCanvases())->FindObject("inspect");
00388 if (!inspect) inspect = new TInspectCanvas(700,600);
00389 else inspect->cd();
00390
00391 inspect->InspectObject(obj);
00392 inspect->GetObjects()->Add(obj);
00393
00394
00395 if (padsav) padsav->cd();
00396 }
00397
00398
00399
00400 void TInspectCanvas::RecursiveRemove(TObject *obj)
00401 {
00402
00403
00404 fObjects->Remove(obj);
00405 TPad::RecursiveRemove(obj);
00406 }