Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TTreeViewer.cxx
Go to the documentation of this file.
1 // @(#)root/treeviewer:$Id: c8e226dde2f9b6f39946bfe90cabcb778d63dc4f $
2 //Author : Andrei Gheata 16/08/00
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TTreeViewer
13 A graphic user interface designed to handle ROOT trees and to take advantage of
14 TTree class features.
15 
16 It uses ROOT native GUI widgets adapted for "drag and drop" functionality.
17 in the same session.
18 
19 ### The following capabilities are making the viewer a helpful tool for analysis:
20 
21  - several trees may be opened in the same session;
22  - branches and leaves can be easily browsed or scanned;
23  - fast drawing of branch expressions by double-clicking;
24  - new variables/selections easy to compose with the built-in editor;
25  - histograms can be composed by dragging leaves or user-defined expressions
26  to X, Y and Z axis items;
27  - the tree entries to be processed can be selected with a double slider;
28  - selections can be defined and activated by dragging them to the 'Cut' item;
29  - all expressions can be aliased and aliases can be used in composing others;
30  - input/output event lists easy to handle;
31  - menu with histogram drawing options;
32  - user commands may be executed within the viewer and the current command
33  can be echoed;
34  - current 'Draw' event loop is reflected by a progress bar and may be
35  interrupted by the user;
36  - all widgets have self-explaining tool tips and/or context menus;
37  - expressions/leaves can be dragged to a 'scan box' and scanned by
38  double-clicking this item. The result can be redirected to an ASCII file;
39 
40 ### The layout has the following items:
41 
42  - a menu bar with entries : File, Edit, Run, Options and Help;
43  - a toolbar in the upper part where you can issue user commands, change
44  the drawing option and the histogram name, three check buttons Hist, Rec
45  and Scan.HIST toggles histogram drawing mode, REC enables recording of the
46  last command issued and SCAN enables redirecting of TTree::Scan command in
47  an ASCII file (see -Scanning expressions-);
48  - a button bar in the lower part with : buttons DRAW/STOP that issue histogram
49  drawing and stop the current command respectively, two text widgets where
50  input and output event lists can be specified, a message box and a RESET
51  button on the right that clear edited expression content (see Editing...)
52  - a tree-type list on the main left panel where you can select among trees or
53  branches. The tree/branch will be detailed in the right panel.
54  Mapped trees are provided with context menus, activated by right-clicking;
55  - a view-type list on the right panel. The first column contain X, Y and
56  Z expression items, an optional cut and ten optional editable expressions.
57  Expressions and leaf-type items can be dragged or deleted. A right click on
58  the list-box or item activates context menus.
59 
60 ### Opening a new tree and saving a session :
61 
62  To open a new tree in the viewer use `<File/Open tree file>` menu
63 The content of the file (keys) will be listed. Use `<SetTreeName>` function
64 from the context menu of the right panel, entering a tree name among those
65 listed.
66 
67  To save the current session, use `<File/Save>` menu or the `<SaveSource>`
68 function from the context menu of the right panel (to specify the name of the
69 file - name.C)
70 
71  To open a previously saved session for the tree MyTree, first open MyTree
72 in the browser, then use `<File/Open session>` menu.
73 
74 ### Dragging items:
75 
76 Items that can be dragged from the list in the right : expressions and
77 leaves. Dragging an item and dropping to another will copy the content of first
78 to the last (leaf->expression, expression->expression). Items far to the right
79 side of the list can be easily dragged to the left (where expressions are
80 placed) by dragging them to the left at least 10 pixels.
81 
82 ### Editing expressions:
83 
84  Any editable expression from the right panel has two components : a
85 true name (that will be used when TTree::Draw() commands are issued) and an
86 alias. The visible name is the alias. Aliases of user defined expressions have
87 a leading ~ and may be used in new expressions. Expressions containing boolean
88 operators have a specific icon and may be dragged to the active cut (scissors
89 item) position.
90 
91  The expression editor can be activated by double-clicking empty expression,
92 using `<EditExpression>` from the selected expression context menu or using
93 `<Edit/Expression>` menu.
94 
95  The editor will pop-up in the left part, but it can be moved.
96 The editor usage is the following :
97 
98  - you can write C expressions made of leaf names by hand or you can insert
99  any item from the right panel by clicking on it (recommandable);
100  - you can click on other expressions/leaves to paste them in the editor;
101  - you should write the item alias by hand since it not only make the
102  expression meaningful, but it also highly improve the layout for big
103  expressions
104  - you may redefine an old alias - the other expressions depending on it will
105  be modified accordingly. An alias must not be the leading string of other
106  aliases. When Draw commands are issued, the name of the corresponding
107  histogram axes will become the aliases of the expressions.
108 
109 User commands can be issued directly from the textbox labeled "Command"
110 from the upper-left toolbar by typing and pressing Enter at the end.
111 
112  Another way is from the right panel context menu : ExecuteCommand.
113 All commands can be interrupted at any time by pressing the STOP button
114 from the bottom-left
115 You can toggle recording of the current command in the history file by
116 checking the Rec button from the top-right
117 
118 ### Context menus
119 
120  You can activate context menus by right-clicking on items or inside the
121 right panel.
122 
123 Context menus for mapped items from the left tree-type list :
124  The items from the left that are provided with context menus are tree and
125 branch items. You can directly activate the *MENU* marked methods of TTree
126 from this menu.
127 
128 Context menu for the right panel:
129 
130  A general context menu is activated if the user right-clicks the right panel.
131 
132  Commands are :
133  - EmptyAll : clears the content of all expressions;
134  - ExecuteCommand : execute a ROOT command;
135  - MakeSelector : equivalent of TTree::MakeSelector();
136  - NewExpression : add an expression item in the right panel;
137  - Process : equivalent of TTree::Process();
138  - SaveSource : save the current session as a C++ macro;
139  - SetScanFileName : define a name for the file where TTree::Scan command
140  is redirected when the `<Scan>` button is checked;
141  - SetTreeName : open a new tree with this name in the viewer;
142 
143  A specific context menu is activated if expressions/leaves are right-clicked.
144 
145  Commands are :
146  - Draw : draw a histogram for this item;
147  - EditExpression : pops-up the expression editor;
148  - Empty : empty the name and alias of this item;
149  - RemoveItem : removes clicked item from the list;
150  - Scan : scan this expression;
151  - SetExpression : edit name and alias for this item by hand;
152 
153 Starting the viewer
154 
155  1. From the TBrowser: Select a tree in the TBrowser, then call the
156  StartViewer() method from its context menu (right-click on the tree).
157  2. From the command line: Start a ROOT session in the directory where you have
158  your tree. You will need first to load the library for TTreeViewer and
159  optionally other libraries for user defined classes (you can do this later in
160  the session) :
161 ~~~ {.cpp}
162  root [0] gSystem->Load(\"TTreeViewer\");
163 ~~~
164 Supposing you have the tree MyTree in the file MyFile, you can do :
165 ~~~ {.cpp}
166  root [1] TFile file("Myfile");
167  root [2] new TTreeViewer("Mytree");
168 ~~~
169 or :
170 ~~~ {.cpp}
171  root [2] TTreeViewer *tv = new TTreeViewer();
172  root [3] tv->SetTreeName("Mytree");
173 ~~~
174 \image html ttree_treeview.png
175 */
176 
177 #include "RConfigure.h"
178 
179 #include "Riostream.h"
180 #include "TTreeViewer.h"
181 #include "HelpText.h"
182 #include "HelpTextTV.h"
183 #include "TTVLVContainer.h"
184 #include "TTVSession.h"
185 
186 #include "TROOT.h"
187 #include "TError.h"
188 #include "TGMsgBox.h"
189 #include "TTreePlayer.h"
190 #include "TContextMenu.h"
191 #include "TInterpreter.h"
192 #include "TLeaf.h"
193 #include "TRootHelpDialog.h"
194 #include "TSystem.h"
195 #include "TApplication.h"
196 #include "TVirtualX.h"
197 #include "TGClient.h"
198 #include "TKey.h"
199 #include "TFile.h"
200 #include "TGMenu.h"
201 #include "TGFrame.h"
202 #include "TCanvas.h"
203 #include "TH1.h"
204 #include "TFriendElement.h"
205 #include "TObjArray.h"
206 #include "TObjString.h"
207 #include "TGButton.h"
208 #include "TGButtonGroup.h"
209 #include "TGTextEntry.h"
210 #include "TGComboBox.h"
211 #include "TGLabel.h"
212 #include "TGListView.h"
213 #include "TGListTree.h"
214 #include "TGMimeTypes.h"
215 #include "TGSplitter.h"
216 #include "TGDoubleSlider.h"
217 #include "TGToolBar.h"
218 #include "TGStatusBar.h"
219 #include "Getline.h"
220 #include "TTimer.h"
221 #include "TG3DLine.h"
222 #include "TGFileDialog.h"
223 #include "TGProgressBar.h"
224 #include "TClonesArray.h"
225 #include "TSpider.h"
226 
227 #ifdef WIN32
228 #include "TWin32SplashThread.h"
229 #endif
230 
231 // drawing options
232 static const char* gOptgen[16] =
233 {
234  "","AXIS","HIST","SAME","CYL","POL","SPH","PSR","LEGO","LEGO1","LEGO2",
235  "SURF","SURF1","SURF2","SURF3","SURF4"
236 };
237 static const char* gOpt1D[12] =
238 {
239  "","AH","B","C","E","E1","E2","E3","E4","L","P","*H"
240 };
241 static const char* gOpt2D[14] =
242 {
243  "","ARR","BOX","COL","COL2","CONT","CONT0","CONT1","CONT2","CONT3",
244  "FB","BB","SCAT","PROF"
245 };
246 
247 static const char* gOpenTypes[] = {"Root files", "*.root",
248  0, 0 };
249 
250 static const char* gMacroTypes[] = {"C++ macros", "*.C",
251  0, 0 };
252 
253 // Menu command id's
254 enum ERootTreeViewerCommands {
255  kFileCanvas,
256  kFileBrowse,
257  kFileLoadLibrary = 3,
258  kFileOpenSession,
259  kFileSaveMacro,
260  kFilePrint,
261  kFileClose,
262  kFileQuit,
263 
264  kEditExpression,
265  kEditCut,
266  kEditMacro,
267  kEditEvent,
268 
269  kRunCommand,
270  kRunMacro,
271 
272  kOptionsReset,
273  kOptionsGeneral = 20,
274  kOptions1D = 50,
275  kOptions2D = 70,
276 
277  kHelpAbout = 100,
278  kHelpAboutTV,
279  kHelpStart,
280  kHelpLayout,
281  kHelpOpenSave,
282  kHelpDragging,
283  kHelpEditing,
284  kHelpSession,
285  kHelpCommands,
286  kHelpContext,
287  kHelpDrawing,
288  kHelpMacros,
289 
290  kBarCommand,
291  kBarOption,
292  kBarCut,
293  kAxis
294 };
295 
296 // button Id's
297 enum EButtonIdentifiers {
298  kDRAW,
299  kRESET,
300  kSTOP,
301  kCLOSE,
302  kSLIDER,
303  kBGFirst,
304  kBGPrevious,
305  kBGRecord,
306  kBGNext,
307  kBGLast
308 };
309 
310 ClassImp(TTreeViewer);
311 
312 ////////////////////////////////////////////////////////////////////////////////
313 /// TTreeViewer default constructor
314 
315 TTreeViewer::TTreeViewer(const char* treeName) :
316  TGMainFrame(0,10,10,kVerticalFrame),
317  fDimension(0), fVarDraw(0), fScanMode(0),
318  fTreeIndex(0), fDefaultCursor(0), fWatchCursor(0),
319  fCounting(0), fStopMapping(0), fEnableCut(0),fNexpressions(0)
320 {
321  fTree = 0;
322  if (!gClient) return;
323  char command[128];
324  gROOT->ProcessLine("#ifndef GTV_DEFINED\n\
325  TTreeViewer *gTV = 0;\n\
326  TTree *tv__tree = 0;\n\
327  TList *tv__tree_list = 0;\n\
328  TFile *tv__tree_file = 0;\n\
329  #define GTV_DEFINED\n\
330  #endif");
331  snprintf(command,128, "gTV = (TTreeViewer*)0x%lx", (ULong_t)this);
332  gROOT->ProcessLine(command);
333  fTreeList = new TList;
334  gROOT->ProcessLine("tv__tree_list = new TList;");
335  fFilename = "";
336  gInterpreter->SaveContext();
337  BuildInterface();
338  SetTreeName(treeName);
339 }
340 
341 ////////////////////////////////////////////////////////////////////////////////
342 
343 TTreeViewer::TTreeViewer(const TTree *tree) :
344  TGMainFrame(0, 10, 10, kVerticalFrame),
345  fDimension(0), fVarDraw(0), fScanMode(0),
346  fTreeIndex(0), fDefaultCursor(0), fWatchCursor(0),
347  fCounting(0), fStopMapping(0), fEnableCut(0),fNexpressions(0)
348 
349 {
350  // TTreeViewer constructor with a pointer to a Tree
351 
352  fTree = 0;
353  char command[128];
354  gROOT->ProcessLine("#ifndef GTV_DEFINED\n\
355  TTreeViewer *gTV = 0;\n\
356  TTree *tv__tree = 0;\n\
357  TList *tv__tree_list = 0;\n\
358  TFile *tv__tree_file = 0;\n\
359  #define GTV_DEFINED\n\
360  #endif");
361  snprintf(command,128, "gTV = (TTreeViewer*)0x%lx", (ULong_t)this);
362  gROOT->ProcessLine(command);
363  if (!tree) return;
364  fTreeList = new TList;
365  gROOT->ProcessLine("tv__tree_list = new TList;");
366  fFilename = "";
367  gInterpreter->SaveContext();
368  BuildInterface();
369  TDirectory *dirsav = gDirectory;
370  TDirectory *cdir = tree->GetDirectory();
371  if (cdir) cdir->cd();
372 
373  SetTree((TTree *)tree);
374  // If the tree is a chain, the tree directory will be changed by SwitchTree
375  // (called by SetTreeName)
376  cdir = tree->GetDirectory();
377  if (cdir) {
378  if (cdir->GetFile()) fFilename = cdir->GetFile()->GetName();
379  }
380  if (dirsav) dirsav->cd();
381 }
382 ////////////////////////////////////////////////////////////////////////////////
383 /// Allow geting the tree from the context menu.
384 
385 void TTreeViewer::AppendTree(TTree *tree)
386 {
387  if (!tree) return;
388  TTree *ftree;
389  if (fTreeList) {
390  if (fTreeList->FindObject(tree)) {
391  printf("Tree found\n");
392  TIter next(fTreeList);
393  Int_t index = 0;
394  while ((ftree = (TTree*)next())) {
395  if (ftree==tree) {printf("found at index %i\n", index);break;}
396  index++;
397  }
398  SwitchTree(index);
399  if (fTree != fMappedTree) {
400  // switch also the global "tree" variable
401  fLVContainer->RemoveNonStatic();
402  // map it on the right panel
403  MapTree(fTree);
404  fListView->Layout();
405  TGListTreeItem *base = 0;
406  TGListTreeItem *parent = fLt->FindChildByName(base, "TreeList");
407  TGListTreeItem *item = fLt->FindChildByName(parent, fTree->GetName());
408  fLt->ClearHighlighted();
409  fLt->HighlightItem(item);
410  fClient->NeedRedraw(fLt);
411  }
412  return;
413  }
414  }
415  if (fTree != tree) {
416  fTree = tree;
417  // load the tree via the interpreter
418  char command[100];
419  command[0] = 0;
420  // define a global "tree" variable for the same tree
421  snprintf(command,100, "tv__tree = (TTree *)0x%lx;", (ULong_t)tree);
422  ExecuteCommand(command);
423  }
424  //--- add the tree to the list if it is not already in
425  if (fTreeList) fTreeList->Add(fTree);
426  ExecuteCommand("tv__tree_list->Add(tv__tree);");
427  //--- map this tree
428  TGListTreeItem *base = 0;
429  TGListTreeItem *parent = fLt->FindChildByName(base, "TreeList");
430  if (!parent) parent = fLt->AddItem(base, "TreeList", new ULong_t(kLTNoType));
431  ULong_t *itemType = new ULong_t((fTreeIndex << 8) | kLTTreeType);
432  fTreeIndex++;
433  TGListTreeItem *lTreeItem = fLt->AddItem(parent, tree->GetName(), itemType,
434  gClient->GetPicture("tree_t.xpm"), gClient->GetPicture("tree_t.xpm"));
435  MapTree(fTree, lTreeItem, kFALSE);
436  fLt->OpenItem(parent);
437  fLt->HighlightItem(lTreeItem);
438  fClient->NeedRedraw(fLt);
439 
440  //--- map slider and list view
441  SwitchTree(fTreeIndex-1);
442  fLVContainer->RemoveNonStatic();
443  MapTree(fTree);
444  fListView->Layout();
445  SetFile();
446 }
447 ////////////////////////////////////////////////////////////////////////////////
448 /// Change the number of expression widgets.
449 
450 void TTreeViewer::SetNexpressions(Int_t expr)
451 {
452  Int_t diff = expr - fNexpressions;
453  if (diff <= 0) return;
454  if (!fLVContainer) return;
455  for (Int_t i=0; i<TMath::Abs(diff); i++) NewExpression();
456 }
457 ////////////////////////////////////////////////////////////////////////////////
458 /// Set the name of the file where to redirect `<Scan>` output.
459 
460 void TTreeViewer::SetScanFileName(const char *name)
461 {
462  if (fTree) ((TTreePlayer *)fTree->GetPlayer())->SetScanFileName(name);
463 }
464 ////////////////////////////////////////////////////////////////////////////////
465 /// Set the state of Scan check button.
466 
467 void TTreeViewer::SetScanRedirect(Bool_t mode)
468 {
469  if (mode)
470  fBarScan->SetState(kButtonDown);
471  else
472  fBarScan->SetState(kButtonUp);
473 }
474 ////////////////////////////////////////////////////////////////////////////////
475 /// Assign the fTree member from existing tree, e.g. when calling
476 /// tree->StartViewer() from the browser, or even from the command line.
477 
478 void TTreeViewer::SetTree(TTree *tree)
479 {
480  if (!tree) return;
481  if (fTree != tree) {
482  fTree = tree;
483  // load the tree via the interpreter
484  // define a global "tree" variable for the same tree
485  TString command = TString::Format("tv__tree = (TTree *)0x%lx;", (ULong_t)tree);
486  ExecuteCommand(command.Data());
487  }
488  //--- add the tree to the list if it is not already in
489  if (fTreeList) fTreeList->Add(fTree);
490  ExecuteCommand("tv__tree_list->Add(tv__tree);");
491  //--- map this tree
492  TGListTreeItem *base = 0;
493  TGListTreeItem *parent = fLt->FindChildByName(base, "TreeList");
494  if (!parent) parent = fLt->AddItem(base, "TreeList", new ULong_t(kLTNoType));
495  ULong_t *itemType = new ULong_t((fTreeIndex << 8) | kLTTreeType);
496  fTreeIndex++;
497  TGListTreeItem *lTreeItem = fLt->AddItem(parent, tree->GetName(), itemType,
498  gClient->GetPicture("tree_t.xpm"), gClient->GetPicture("tree_t.xpm"));
499  MapTree(fTree, lTreeItem, kFALSE);
500  fLt->OpenItem(parent);
501  fLt->HighlightItem(lTreeItem);
502  fClient->NeedRedraw(fLt);
503 
504  //--- map slider and list view
505  SwitchTree(fTreeIndex-1);
506  fLVContainer->RemoveNonStatic();
507  MapTree(fTree);
508  fListView->Layout();
509  SetFile();
510 }
511 ////////////////////////////////////////////////////////////////////////////////
512 /// Allow geting the tree from the context menu.
513 
514 void TTreeViewer::SetTreeName(const char* treeName)
515 {
516  if (!treeName) return;
517  TTree *tree = (TTree *) gROOT->FindObject(treeName);
518  if (fTreeList) {
519  if (fTreeList->FindObject(treeName)) {
520  printf("Tree found\n");
521  TIter next(fTreeList);
522  Int_t index = 0;
523  while ((tree = (TTree*)next())) {
524  if (!strcmp(treeName, tree->GetName())) {printf("found at index %i\n", index);break;}
525  index++;
526  }
527  SwitchTree(index);
528  if (fTree != fMappedTree) {
529  // switch also the global "tree" variable
530  fLVContainer->RemoveNonStatic();
531  // map it on the right panel
532  MapTree(fTree);
533  fListView->Layout();
534  TGListTreeItem *base = 0;
535  TGListTreeItem *parent = fLt->FindChildByName(base, "TreeList");
536  TGListTreeItem *item = fLt->FindChildByName(parent, fTree->GetName());
537  fLt->ClearHighlighted();
538  fLt->HighlightItem(item);
539  fClient->NeedRedraw(fLt);
540  }
541  return;
542  }
543  }
544  if (!tree) return;
545 // ((TTreePlayer *)tree->GetPlayer())->SetViewer(this);
546  if (fTree != tree) {
547  fTree = tree;
548  // load the tree via the interpreter
549  // define a global "tree" variable for the same tree
550  TString command = TString::Format("tv__tree = (TTree *) gROOT->FindObject(\"%s\");", treeName);
551  ExecuteCommand(command.Data());
552  }
553  //--- add the tree to the list if it is not already in
554  if (fTreeList) fTreeList->Add(fTree);
555  ExecuteCommand("tv__tree_list->Add(tv__tree);");
556  //--- map this tree
557  TGListTreeItem *base = 0;
558  TGListTreeItem *parent = fLt->FindChildByName(base, "TreeList");
559  if (!parent) parent = fLt->AddItem(base, "TreeList", new ULong_t(kLTNoType));
560  ULong_t *itemType = new ULong_t((fTreeIndex << 8) | kLTTreeType);
561  fTreeIndex++;
562  TGListTreeItem *lTreeItem = fLt->AddItem(parent, treeName, itemType,
563  gClient->GetPicture("tree_t.xpm"), gClient->GetPicture("tree_t.xpm"));
564  MapTree(fTree, lTreeItem, kFALSE);
565  fLt->OpenItem(parent);
566  fLt->HighlightItem(lTreeItem);
567  fClient->NeedRedraw(fLt);
568 
569  //--- map slider and list view
570  SwitchTree(fTreeIndex-1);
571  fLVContainer->RemoveNonStatic();
572  MapTree(fTree);
573  fListView->Layout();
574  SetFile();
575 }
576 ////////////////////////////////////////////////////////////////////////////////
577 /// Set file name containing the tree.
578 
579 void TTreeViewer::SetFile()
580 {
581  if (!fTree) return;
582  TSeqCollection *list = gROOT->GetListOfFiles();
583  TTree *tree;
584  TIter next(list);
585  TObject *obj;
586  TFile *file;
587  while ((obj=next())) {
588  file = (TFile*)obj;
589  if (file) {
590  tree = (TTree*)file->Get(fTree->GetName());
591  if (tree) {
592  fFilename = file->GetName();
593  std::cout << "File name : "<< fFilename << std::endl;
594  return;
595  } else {
596  fFilename = "";
597  }
598  }
599  }
600  fFilename = "";
601 }
602 ////////////////////////////////////////////////////////////////////////////////
603 /// Create all viewer widgets.
604 
605 void TTreeViewer::BuildInterface()
606 {
607  //--- timer & misc
608  fCounting = kFALSE;
609  fScanMode = kFALSE;
610  fEnableCut = kTRUE;
611  fTimer = new TTimer(this, 20, kTRUE);
612  fLastOption = "";
613  fSession = new TTVSession(this);
614  //--- cursors
615  fDefaultCursor = gVirtualX->CreateCursor(kPointer);
616  fWatchCursor = gVirtualX->CreateCursor(kWatch);
617  //--- colours
618  ULong_t color;
619  gClient->GetColorByName("blue",color);
620  //--- pictures for X, Y and Z expression items
621  fPicX = gClient->GetPicture("x_pic.xpm");
622  fPicY = gClient->GetPicture("y_pic.xpm");
623  fPicZ = gClient->GetPicture("z_pic.xpm");
624 
625  //--- general context menu
626  fContextMenu = new TContextMenu("TreeViewer context menu","");
627  fMappedTree = 0;
628  fMappedBranch = 0;
629  fDialogBox = 0;
630  fDimension = 0;
631  fVarDraw = kFALSE;
632  fStopMapping = kFALSE;
633 // fFilename = "";
634  fSourceFile = "treeviewer.C";
635  //--- lists : trees and widgets to be removed
636 // fTreeList = 0;
637  fTreeIndex = 0;
638  fWidgets = new TList();
639  //--- create menus --------------------------------------------------------
640  //--- File menu
641  fFileMenu = new TGPopupMenu(fClient->GetRoot());
642  fFileMenu->AddEntry("&New canvas", kFileCanvas);
643  fFileMenu->AddEntry("Open &tree file...", kFileBrowse);
644  fFileMenu->AddEntry("&Load Library...", kFileLoadLibrary);
645  fFileMenu->AddEntry("&Open session", kFileOpenSession);
646  fFileMenu->AddEntry("&Save source...", kFileSaveMacro);
647  fFileMenu->AddSeparator();
648  fFileMenu->AddEntry("&Print", kFilePrint);
649  fFileMenu->AddEntry("&Close", kFileClose);
650  fFileMenu->AddSeparator();
651  fFileMenu->AddEntry("&Quit ROOT", kFileQuit);
652 
653  fFileMenu->DisableEntry(kFilePrint);
654 
655  //--- Edit menu
656  fEditMenu = new TGPopupMenu(gClient->GetRoot());
657  fEditMenu->AddEntry("&Expression...", kEditExpression);
658  fEditMenu->AddEntry("&Cut...", kEditCut);
659  fEditMenu->AddEntry("&Macro...", kEditMacro);
660  fEditMenu->AddEntry("E&Vent...", kEditEvent);
661 
662  fEditMenu->DisableEntry(kEditMacro);
663  fEditMenu->DisableEntry(kEditEvent);
664  //---Run menu
665  fRunMenu = new TGPopupMenu(gClient->GetRoot());
666  fRunMenu->AddEntry("&Macro...", kRunMacro);
667  fRunMenu->DisableEntry(kRunMacro);
668  //--- Options menu
669  //--- General options
670  fOptionsGen = new TGPopupMenu(gClient->GetRoot());
671  fOptionsGen->AddEntry("Default", kOptionsGeneral);
672  fOptionsGen->AddSeparator();
673  fOptionsGen->AddEntry("Axis only", kOptionsGeneral+1); // "AXIS"
674  fOptionsGen->AddEntry("Contour only", kOptionsGeneral+2); // "HIST"
675  fOptionsGen->AddEntry("Superimpose", kOptionsGeneral+3); //"SAME"
676  fOptionsGen->AddEntry("Cylindrical", kOptionsGeneral+4); //"CYL"
677  fOptionsGen->AddEntry("Polar", kOptionsGeneral+5); //"POL"
678  fOptionsGen->AddEntry("Spherical", kOptionsGeneral+6); //"SPH"
679  fOptionsGen->AddEntry("PsRap/Phi", kOptionsGeneral+7); //"PSR"
680  fOptionsGen->AddEntry("Lego HLR", kOptionsGeneral+8); //"LEGO"
681  fOptionsGen->AddEntry("Lego HSR", kOptionsGeneral+9); //"LEGO1"
682  fOptionsGen->AddEntry("Lego Color", kOptionsGeneral+10); //"LEGO2"
683  fOptionsGen->AddEntry("Surface HLR", kOptionsGeneral+11); //"SURF"
684  fOptionsGen->AddEntry("Surface HSR", kOptionsGeneral+12); //"SURF1"
685  fOptionsGen->AddEntry("Surface Col", kOptionsGeneral+13); //"SURF2"
686  fOptionsGen->AddEntry("Surf+Cont", kOptionsGeneral+14); //"SURF3"
687  fOptionsGen->AddEntry("Gouraud", kOptionsGeneral+15); //"SURF4"
688  fOptionsGen->Associate(this);
689  //--- 1D options
690  fOptions1D = new TGPopupMenu(gClient->GetRoot());
691  fOptions1D->AddEntry("Default", kOptions1D);
692  fOptions1D->AddSeparator();
693  fOptions1D->AddEntry("No labels/ticks", kOptions1D+1); // "AH"
694  fOptions1D->AddEntry("Bar chart", kOptions1D+2); // "B"
695  fOptions1D->AddEntry("Smooth curve", kOptions1D+3); // "C"
696  fOptions1D->AddEntry("Errors", kOptions1D+4); // "E"
697  fOptions1D->AddEntry("Errors 1", kOptions1D+5); // "E1"
698  fOptions1D->AddEntry("Errors 2", kOptions1D+6); // "E2"
699  fOptions1D->AddEntry("Errors 3", kOptions1D+7); // "E3"
700  fOptions1D->AddEntry("Errors 4", kOptions1D+8); // "E4"
701  fOptions1D->AddEntry("Line", kOptions1D+9); // "L"
702  fOptions1D->AddEntry("Markers", kOptions1D+10); // "P"
703  fOptions1D->AddEntry("Stars", kOptions1D+11); // "*H"
704  fOptions1D->Associate(this);
705  //--- 2D options
706  fOptions2D = new TGPopupMenu(gClient->GetRoot());
707  fOptions2D->AddEntry("Default", kOptions2D);
708  fOptions2D->AddSeparator();
709  fOptions2D->AddEntry("Arrows", kOptions2D+1); // "ARR"
710  fOptions2D->AddEntry("Box/Surf", kOptions2D+2); // "BOX"
711  fOptions2D->AddEntry("Box/Color", kOptions2D+3); // "COL"
712  fOptions2D->AddEntry("Box/ColMap", kOptions2D+4); // "COLZ"
713  fOptions2D->AddEntry("Contour", kOptions2D+5); // "CONT"
714  fOptions2D->AddEntry("Contour 0", kOptions2D+6); // "CONT0"
715  fOptions2D->AddEntry("Contour 1", kOptions2D+7); // "CONT1"
716  fOptions2D->AddEntry("Contour 2", kOptions2D+8); // "CONT2"
717  fOptions2D->AddEntry("Contour 3", kOptions2D+9); // "CONT3"
718  fOptions2D->AddEntry("No front-box", kOptions2D+10); // "FB"
719  fOptions2D->AddEntry("No back-box", kOptions2D+11); // "BB"
720  fOptions2D->AddEntry("Scatter", kOptions2D+12); // "SCAT"
721  fOptions2D->AddEntry("Profile", kOptions2D+13); // "SCAT"
722  fOptions2D->Associate(this);
723 
724  fOptionsMenu = new TGPopupMenu(gClient->GetRoot());
725  fOptionsMenu->AddPopup("&General Options...", fOptionsGen);
726  fOptionsMenu->AddPopup("&1D Options", fOptions1D);
727  fOptionsMenu->AddPopup("&2D Options", fOptions2D);
728  fOptionsMenu->AddSeparator();
729  fOptionsMenu->AddEntry("&Reset options", kOptionsReset);
730  //--- Help menu
731  fHelpMenu = new TGPopupMenu(gClient->GetRoot());
732  fHelpMenu->AddEntry("&About ROOT...", kHelpAbout);
733  fHelpMenu->AddEntry("&About TreeViewer...", kHelpAboutTV);
734  fHelpMenu->AddSeparator();
735  fHelpMenu->AddEntry("&Starting...", kHelpStart);
736  fHelpMenu->AddEntry("&Layout...", kHelpLayout);
737  fHelpMenu->AddEntry("&Open/Save", kHelpOpenSave);
738  fHelpMenu->AddEntry("&Dragging...", kHelpDragging);
739  fHelpMenu->AddEntry("&Editing expressions...",kHelpEditing);
740  fHelpMenu->AddEntry("&Session...", kHelpSession);
741  fHelpMenu->AddEntry("&User commands...", kHelpCommands);
742  fHelpMenu->AddEntry("&Context menus...", kHelpContext);
743  fHelpMenu->AddEntry("D&rawing...", kHelpDrawing);
744  fHelpMenu->AddEntry("&Macros...", kHelpMacros);
745 
746  fFileMenu->Associate(this);
747  fEditMenu->Associate(this);
748  fRunMenu->Associate(this);
749  fOptionsMenu->Associate(this);
750  fHelpMenu->Associate(this);
751 
752  //--- menubar layout hints
753  fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0,0,1,1);
754  fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
755  fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);
756  //--- create menubar and add popup menus
757  fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
758 
759  fMenuBar->AddPopup("&File", fFileMenu, fMenuBarItemLayout);
760  fMenuBar->AddPopup("&Edit", fEditMenu, fMenuBarItemLayout);
761  fMenuBar->AddPopup("&Run", fRunMenu, fMenuBarItemLayout);
762  fMenuBar->AddPopup("&Options", fOptionsMenu, fMenuBarItemLayout);
763  fMenuBar->AddPopup("&Help", fHelpMenu, fMenuBarHelpLayout);
764 
765  AddFrame(fMenuBar, fMenuBarLayout);
766  //--- toolbar ----------------------------------------------------------------
767  fToolBar = new TGToolBar(this, 10, 10, kHorizontalFrame);
768  fBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX);
769 
770  TGLayoutHints *lo;
771  lo = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 4,4,0,0);
772  fWidgets->Add(lo);
773  //--- label for Command text entry
774  fBarLbl1 = new TGLabel(fToolBar,"Command");
775  fToolBar->AddFrame(fBarLbl1,lo);
776  //--- command text entry
777  fBarCommand = new TGTextEntry(fToolBar, new TGTextBuffer(250),kBarCommand);
778  fBarCommand->SetWidth(120);
779  fBarCommand->Associate(this);
780  fBarCommand->SetToolTipText("User commands executed via interpreter. Type <ENTER> to execute");
781  fToolBar->AddFrame(fBarCommand, lo);
782  //--- first vertical separator
783  TGVertical3DLine *vSeparator = new TGVertical3DLine(fToolBar);
784  lo = new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 4,4,0,0);
785  fWidgets->Add(lo);
786  fWidgets->Add(vSeparator);
787  fToolBar->AddFrame(vSeparator, lo);
788 
789  lo = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 4,4,0,0);
790  fWidgets->Add(lo);
791  //--- label for Option text entry
792  fBarLbl2 = new TGLabel(fToolBar,"Option");
793  fToolBar->AddFrame(fBarLbl2, lo);
794  //--- drawing option text entry
795  fBarOption = new TGTextEntry(fToolBar, new TGTextBuffer(200),kBarOption);
796  fBarOption->SetWidth(100);
797  fBarOption->Associate(this);
798  fBarOption->SetToolTipText("Histogram graphics option. Type option here and click <Draw> (or <ENTER> to update current histogram).");
799  fToolBar->AddFrame(fBarOption, lo);
800  //--- second vertical separator
801  vSeparator = new TGVertical3DLine(fToolBar);
802  lo = new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 4,4,0,0);
803  fWidgets->Add(lo);
804  fWidgets->Add(vSeparator);
805  fToolBar->AddFrame(vSeparator, lo);
806 
807  lo = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 4,4,0,0);
808  fWidgets->Add(lo);
809  //--- label for Histogram text entry
810  fBarLbl3 = new TGLabel(fToolBar,"Histogram");
811  fToolBar->AddFrame(fBarLbl3, lo);
812 
813  //--- histogram name text entry
814  lo = new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 4,4,0,0);
815  fWidgets->Add(lo);
816  fBarHist = new TGTextEntry(fToolBar, new TGTextBuffer(100));
817  fBarHist->Resize(50, fBarHist->GetDefaultHeight());
818  fBarHist->SetDefaultSize(50, fBarHist->GetDefaultHeight());
819  fBarHist->SetText("htemp");
820  fToolBar->AddFrame(fBarHist, lo);
821 
822  //--- Hist check button
823  lo = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 4,4,0,0);
824  fWidgets->Add(lo);
825  fBarH = new TGCheckButton(fToolBar, "Hist");
826  fBarH->SetToolTipText("Checked : redraw only current histogram");
827  fBarH->SetState(kButtonUp);
828  fToolBar->AddFrame(fBarH, lo);
829  //--- Scan check button
830  fBarScan = new TGCheckButton(fToolBar, "Scan");
831  fBarScan->SetState(kButtonUp);
832  fBarScan->SetToolTipText("Check to redirect TTree::Scan command in a file");
833  fToolBar->AddFrame(fBarScan, lo);
834  //--- Rec check button
835  fBarRec = new TGCheckButton(fToolBar, "Rec");
836  fBarRec->SetState(kButtonDown);
837  fBarRec->SetToolTipText("Check to record commands in history file and be verbose");
838  fToolBar->AddFrame(fBarRec, lo);
839  //--- 1'st horizontal tool bar separator ----------------------------------------
840  TGHorizontal3DLine *toolBarSep = new TGHorizontal3DLine(this);
841  fWidgets->Add(toolBarSep);
842  AddFrame(toolBarSep, fBarLayout);
843  AddFrame(fToolBar, fBarLayout);
844  //--- 2'nd horizontal tool bar separator ----------------------------------------
845  toolBarSep = new TGHorizontal3DLine(this);
846  fWidgets->Add(toolBarSep);
847  AddFrame(toolBarSep, fBarLayout);
848 
849  //--- Horizontal mother frame ---------------------------------------------------
850  fHf = new TGHorizontalFrame(this, 10, 10);
851  //--- Vertical frames
852  fSlider = new TGDoubleVSlider(fHf, 10, kDoubleScaleBoth, kSLIDER);
853 // fSlider->SetBackgroundColor(color);
854  fSlider->Associate(this);
855 
856  //--- fV1 -----------------------------------------------------------------------
857  fV1 = new TGVerticalFrame(fHf, 10, 10, kFixedWidth);
858  fTreeHdr = new TGCompositeFrame(fV1, 10, 10, kSunkenFrame | kVerticalFrame);
859 
860  fLbl1 = new TGLabel(fTreeHdr, "Current Folder");
861  lo = new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY, 3, 0, 0, 0);
862  fWidgets->Add(lo);
863  fTreeHdr->AddFrame(fLbl1, lo);
864 
865  lo = new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 0, 1, 0);
866  fWidgets->Add(lo);
867  fV1->AddFrame(fTreeHdr, lo);
868 
869  //--- tree view canvas on the left
870  fTreeView = new TGCanvas(fV1, fV1->GetWidth(), 10, kSunkenFrame | kDoubleBorder);
871  //--- container frame
872  fLt = new TGListTree(fTreeView->GetViewPort(), 10, 10, kHorizontalFrame,
873  GetWhitePixel());
874  fLt->Associate(this);
875  fTreeView->SetContainer(fLt);
876 
877  lo = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 2,0,0,0);
878  fWidgets->Add(lo);
879  fV1->AddFrame(fTreeView, lo);
880 
881  //--- button horizontal frame
882  fHpb = new TGHorizontalFrame(fV1, fTreeHdr->GetWidth(), 10, kSunkenFrame);
883 
884  //--- DRAW button
885  fPicDraw = gClient->GetPicture("draw_t.xpm");
886  fDRAW = new TGPictureButton(fHpb,fPicDraw,kDRAW);
887  fDRAW->SetToolTipText("Draw current selection");
888  fDRAW->Associate(this);
889 
890  lo = new TGLayoutHints(kLHintsTop | kLHintsLeft, 2,2,4,2);
891  fWidgets->Add(lo);
892  fHpb->AddFrame(fDRAW, lo);
893 
894  //--- SPIDER button
895  fSPIDER = new TGTextButton(fHpb,"SPIDER");
896  fSPIDER->SetToolTipText("Scan current selection using a spider plot");
897  fSPIDER->Associate(this);
898 
899  lo = new TGLayoutHints(kLHintsTop | kLHintsLeft, 2,2,4,2);
900  fWidgets->Add(lo);
901  fHpb->AddFrame(fSPIDER,lo);
902  //---connect SPIDER button to ExecuteScan() method
903  fSPIDER->Connect("Clicked()","TTreeViewer",this,"ExecuteSpider()");
904 
905  //--- STOP button (breaks current operation)
906 // fPicStop = gClient->GetPicture("mb_stop_s.xpm");
907  fPicStop = gClient->GetPicture("stop_t.xpm");
908  fSTOP = new TGPictureButton(fHpb,fPicStop,kSTOP);
909  fSTOP->SetToolTipText("Abort current operation");
910  fSTOP->Associate(this);
911 
912  lo = new TGLayoutHints(kLHintsTop | kLHintsLeft, 2,2,4,2);
913  fWidgets->Add(lo);
914  fHpb->AddFrame(fSTOP, lo);
915 
916  //--- REFR button (breaks current operation)
917  fPicRefr = gClient->GetPicture("refresh2.xpm");
918  fREFR = new TGPictureButton(fHpb,fPicRefr,kDRAW);
919  fREFR->SetToolTipText("Update the tree viewer");
920  lo = new TGLayoutHints(kLHintsTop | kLHintsLeft, 2,2,4,2);
921  fWidgets->Add(lo);
922  fHpb->AddFrame(fREFR, lo);
923  //---connect REFR button to DoRefresh() method
924  fREFR->Connect("Clicked()", "TTreeViewer", this, "DoRefresh()");
925 
926  lo = new TGLayoutHints(kLHintsTop | kLHintsLeft, 2,2,2,2);
927  fWidgets->Add(lo);
928  fV1->AddFrame(fHpb, lo);
929 
930  //--- fV2
931  fV2 = new TGVerticalFrame(fHf, 10, 10);
932  fListHdr = new TGCompositeFrame(fV2, 10, 10, kSunkenFrame | kFitHeight);
933  fLbl2 = new TGLabel(fListHdr, "Current Tree: ");
934  lo = new TGLayoutHints(kLHintsTop | kLHintsLeft, 3, 0, 0, 0);
935  fWidgets->Add(lo);
936  fListHdr->AddFrame(fLbl2, lo);
937 
938  //--- progress bar
939  fProgressBar = new TGHProgressBar(fListHdr);
940  fProgressBar->SetBarColor("red");
941  fProgressBar->SetFillType(TGProgressBar::kBlockFill);
942  lo = new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 2,2,4,2);
943  fWidgets->Add(lo);
944  fListHdr->AddFrame(fProgressBar, lo);
945  lo = new TGLayoutHints(kLHintsTop | kLHintsExpandX | kLHintsExpandY, 2,0,1,2);
946  fWidgets->Add(lo);
947  fV2->AddFrame(fListHdr, lo);
948 
949  fV1->Resize(fTreeHdr->GetDefaultWidth()+100, fV1->GetDefaultHeight());
950  lo = new TGLayoutHints(kLHintsLeft | kLHintsExpandY);
951  fWidgets->Add(lo);
952  fHf->AddFrame(fSlider, lo);
953  lo = new TGLayoutHints(kLHintsLeft | kLHintsExpandY);
954  fWidgets->Add(lo);
955  fHf->AddFrame(fV1, lo);
956 
957  //--- vertical splitter
958  TGVSplitter *splitter = new TGVSplitter(fHf);
959  splitter->SetFrame(fV1,kTRUE);
960  lo = new TGLayoutHints(kLHintsLeft | kLHintsExpandY);
961  fWidgets->Add(splitter);
962  fWidgets->Add(lo);
963  fHf->AddFrame(splitter,lo);
964 
965 
966 
967  //-- listview for the content of the tree/branch -----------------------------
968  fListView = new TGListView(fListHdr,400,300);
969  //--- container frame
970  fLVContainer = new TTVLVContainer(fListView->GetViewPort(),400,300);
971  fLVContainer->Associate(this);
972  fLVContainer->SetListView(fListView);
973  fLVContainer->SetViewer(this);
974  fLVContainer->SetBackgroundColor(GetWhitePixel());
975  fListView->GetViewPort()->SetBackgroundColor(GetWhitePixel());
976  fListView->SetContainer(fLVContainer);
977  fListView->SetViewMode(kLVList);
978  lo = new TGLayoutHints(kLHintsRight | kLHintsTop | kLHintsExpandX | kLHintsExpandY);
979  fWidgets->Add(lo);
980 
981  fListHdr->AddFrame(fListView,lo);
982 
983  lo = new TGLayoutHints(kLHintsRight | kLHintsExpandX | kLHintsExpandY);
984  fWidgets->Add(lo);
985  fHf->AddFrame(fV2,lo);
986 
987  AddFrame(fHf, lo);
988  //--- 3rd horizontal tool bar separator ----------------------------------------
989  toolBarSep = new TGHorizontal3DLine(this);
990  fWidgets->Add(toolBarSep);
991  AddFrame(toolBarSep, fBarLayout);
992 
993  //--- label for IList text entry
994  fBFrame = new TGHorizontalFrame(this,10,10);
995  fBLbl4 = new TGLabel(fBFrame,"IList");
996  lo = new TGLayoutHints(kLHintsLeft | kLHintsBottom, 2,2,2,2);
997  fWidgets->Add(lo);
998  fBFrame->AddFrame(fBLbl4, lo);
999  //--- IList text entry
1000  fBarListIn = new TGTextEntry(fBFrame, new TGTextBuffer(100));
1001  fBarListIn->SetWidth(60);
1002  fBarListIn->SetToolTipText("Name of a previously created event list");
1003  fBFrame->AddFrame(fBarListIn, lo);
1004  //--- label for OList text entry
1005  fBLbl5 = new TGLabel(fBFrame,"OList");
1006  fBFrame->AddFrame(fBLbl5, lo);
1007  //--- OList text entry
1008  fBarListOut = new TGTextEntry(fBFrame, new TGTextBuffer(100));
1009  fBarListOut->SetWidth(60);
1010  fBarListOut->SetToolTipText("Output event list. Use <Draw> to generate it.");
1011  fBFrame->AddFrame(fBarListOut, lo);
1012  //--- Status bar
1013  fStatusBar = new TGStatusBar(fBFrame, 10, 10);
1014  fStatusBar->SetWidth(200);
1015  fStatusBar->Draw3DCorner(kFALSE);
1016  lo = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY | kLHintsLeft | kLHintsExpandX, 2,2,2,2);
1017  fWidgets->Add(lo);
1018  fBFrame->AddFrame(fStatusBar, lo);
1019  //--- RESET button
1020  fReset = new TGTextButton(fBFrame,"RESET",kRESET);
1021  fReset->SetToolTipText("Reset variable's fields and drawing options");
1022  fReset->Associate(this);
1023  lo = new TGLayoutHints(kLHintsTop | kLHintsRight, 2,2,2,2);
1024  fWidgets->Add(lo);
1025  fBFrame->AddFrame(fReset,lo);
1026  //--- group of buttons for session handling
1027  fBGFirst = new TGPictureButton(fBFrame,
1028  gClient->GetPicture("first_t.xpm"), kBGFirst);
1029  fBGFirst->SetToolTipText("First record");
1030  fBGFirst->Associate(this);
1031  fBGPrevious = new TGPictureButton(fBFrame,
1032  gClient->GetPicture("previous_t.xpm"), kBGPrevious);
1033  fBGPrevious->SetToolTipText("Previous record");
1034  fBGPrevious->Associate(this);
1035  fBGRecord = new TGPictureButton(fBFrame,
1036  gClient->GetPicture("record_t.xpm"), kBGRecord);
1037  fBGRecord->SetToolTipText("Record");
1038  fBGRecord->Associate(this);
1039  fBGNext = new TGPictureButton(fBFrame,
1040  gClient->GetPicture("next_t.xpm"), kBGNext);
1041  fBGNext->SetToolTipText("Next record");
1042  fBGNext->Associate(this);
1043  fBGLast = new TGPictureButton(fBFrame,
1044  gClient->GetPicture("last_t.xpm"), kBGLast);
1045  fBGLast->SetToolTipText("Last record");
1046  fBGLast->Associate(this);
1047 
1048  fCombo = new TGComboBox(fBFrame, 0);
1049  fCombo->SetHeight(fReset->GetDefaultHeight());
1050  fCombo->SetWidth(100);
1051  fCombo->Associate(this);
1052 
1053  lo = new TGLayoutHints(kLHintsCenterY | kLHintsRight, 0,0,2,0);
1054  fWidgets->Add(lo);
1055  fBFrame->AddFrame(fCombo, lo);
1056  fBFrame->AddFrame(fBGLast, lo);
1057  fBFrame->AddFrame(fBGNext, lo);
1058  fBFrame->AddFrame(fBGRecord, lo);
1059  fBFrame->AddFrame(fBGPrevious, lo);
1060  fBFrame->AddFrame(fBGFirst, lo);
1061  lo = new TGLayoutHints(kLHintsExpandX,2,2,2,0);
1062  fWidgets->Add(lo);
1063  AddFrame(fBFrame,lo);
1064 
1065  // map the window
1066  SetWindowName("TreeViewer");
1067  MapSubwindows();
1068  Resize(GetDefaultSize());
1069  MapWindow();
1070 
1071  // put default items in the listview on the right
1072  const TGPicture *pic, *spic;
1073 
1074  fLVContainer->RemoveAll();
1075  TTVLVEntry* entry;
1076  Char_t symbol;
1077  entry = new TTVLVEntry(fLVContainer,fPicX,fPicX,new TGString(),0,kLVSmallIcons);
1078  symbol = 'X';
1079  entry->SetUserData(new ULong_t((symbol << 8) | kLTExpressionType | kLTTreeType));
1080  entry->SetToolTipText("X expression. Drag and drop expressions here");
1081  //--- X item
1082  fLVContainer->AddThisItem(entry);
1083  entry->Empty();
1084  entry->MapWindow();
1085 
1086  entry = new TTVLVEntry(fLVContainer,fPicY,fPicY,new TGString(),0,kLVSmallIcons);
1087  symbol = 'Y';
1088  entry->SetUserData(new ULong_t((symbol << 8) | kLTExpressionType | kLTTreeType));
1089  entry->SetToolTipText("Y expression. Drag and drop expressions here");
1090  //--- Y item
1091  fLVContainer->AddThisItem(entry);
1092  entry->Empty();
1093  entry->MapWindow();
1094 
1095  entry = new TTVLVEntry(fLVContainer,fPicZ,fPicZ,new TGString(),0,kLVSmallIcons);
1096  symbol = 'Z';
1097  entry->SetUserData(new ULong_t((symbol << 8) | kLTExpressionType | kLTTreeType));
1098  entry->SetToolTipText("Z expression. Drag and drop expressions here");
1099  //--- Z item
1100  fLVContainer->AddThisItem(entry);
1101  entry->Empty();
1102  entry->MapWindow();
1103 
1104  pic = gClient->GetPicture("cut_t.xpm");
1105  spic = gClient->GetPicture("cut_t.xpm");
1106  entry = new TTVLVEntry(fLVContainer,pic,spic,new TGString(),0,kLVSmallIcons);
1107  entry->SetUserData(new ULong_t(kLTExpressionType | kLTCutType));
1108  entry->SetToolTipText("Active cut. Double-click to enable/disable");
1109  //--- Cut item (scissors icon)
1110  fLVContainer->AddThisItem(entry);
1111  entry->Empty();
1112  entry->MapWindow();
1113 
1114  pic = gClient->GetPicture("pack_t.xpm");
1115  spic = gClient->GetPicture("pack-empty_t.xpm");
1116  entry = new TTVLVEntry(fLVContainer,pic,spic,new TGString("Scan box"),0,kLVSmallIcons);
1117  entry->SetUserData(new ULong_t(kLTExpressionType | kLTPackType));
1118  entry->SetToolTipText("Drag and drop expressions/leaves here. Double-click to scan. Check <Scan> to redirect on file.");
1119  //--- Scan Box
1120  fLVContainer->AddThisItem(entry);
1121  entry->MapWindow();
1122  entry->SetTrueName("");
1123 
1124  //--- 10 expression items
1125  fNexpressions = 10;
1126  for (Int_t i=0; i<fNexpressions; i++) {
1127  pic = gClient->GetPicture("expression_t.xpm");
1128  spic = gClient->GetPicture("expression_t.xpm");
1129  entry = new TTVLVEntry(fLVContainer,pic,spic,new TGString(),0,kLVSmallIcons);
1130  entry->SetUserData(new ULong_t(kLTExpressionType | kLTDragType));
1131  entry->SetToolTipText("User defined expression/cut. Double-click to edit");
1132  fLVContainer->AddThisItem(entry);
1133  entry->Empty();
1134  entry->MapWindow();
1135  }
1136 
1137  fListView->Layout();
1138  fListView->Resize();
1139 // EmptyAll();
1140  // map the tree if it was supplied in the constructor
1141 
1142  if (!fTree) {
1143  fSlider->SetRange(0,1000000);
1144  fSlider->SetPosition(0,1000000);
1145  } else {
1146  fSlider->SetRange(0,fTree->GetEntries()-1);
1147  fSlider->SetPosition(0,fTree->GetEntries()-1);
1148  }
1149  PrintEntries();
1150  fProgressBar->SetPosition(0);
1151  fProgressBar->ShowPosition();
1152  ActivateButtons(kFALSE, kFALSE, kFALSE, kFALSE);
1153 
1154  // map the window
1155  ///SetWindowName("TreeViewer");
1156  MapSubwindows();
1157  Resize(GetDefaultSize());
1158  MapWindow();
1159 }
1160 
1161 ////////////////////////////////////////////////////////////////////////////////
1162 /// TTreeViewer destructor.
1163 
1164 TTreeViewer::~TTreeViewer()
1165 {
1166  if (!gClient) return;
1167  gClient->FreePicture(fPicX);
1168  gClient->FreePicture(fPicY);
1169  gClient->FreePicture(fPicZ);
1170  gClient->FreePicture(fPicDraw);
1171  gClient->FreePicture(fPicStop);
1172  gClient->FreePicture(fPicRefr);
1173 
1174  fDialogBox = TGSelectBox::GetInstance();
1175  if (fDialogBox) delete fDialogBox;
1176 
1177  delete fContextMenu;
1178 
1179  delete fBarLbl1;
1180  delete fBarLbl2;
1181  delete fBarLbl3;
1182  delete fBLbl4;
1183  delete fBLbl5;
1184  delete fBarCommand;
1185  delete fBarOption;
1186  delete fBarHist;
1187  delete fBarListIn;
1188  delete fBarListOut;
1189 
1190  delete fBarH;
1191  delete fBarScan;
1192  delete fBarRec;
1193 
1194  delete fToolBar;
1195 
1196  delete fSlider;
1197  delete fV1;
1198  delete fV2;
1199  delete fLbl1;
1200  delete fLbl2;
1201  delete fHf;
1202  delete fTreeHdr;
1203  delete fListHdr;
1204  delete fLt;
1205  delete fTreeView;
1206  delete fLVContainer;
1207  delete fListView;
1208 
1209  delete fProgressBar;
1210  delete fHpb;
1211 
1212  delete fDRAW;
1213  delete fSPIDER;
1214  delete fSTOP;
1215  delete fReset;
1216  delete fBGFirst;
1217  delete fBGPrevious;
1218  delete fBGRecord;
1219  delete fBGNext;
1220  delete fBGLast;
1221  delete fCombo;
1222  delete fBFrame;
1223 
1224  delete fMenuBar;
1225  delete fFileMenu;
1226  delete fEditMenu;
1227 
1228  delete fOptionsGen;
1229  delete fOptions1D;
1230  delete fOptions2D;
1231  delete fOptionsMenu;
1232  delete fHelpMenu;
1233  delete fMenuBarLayout;
1234  delete fMenuBarItemLayout;
1235  delete fMenuBarHelpLayout;
1236  delete fBarLayout;
1237 
1238  fWidgets->Delete();
1239  delete fWidgets;
1240  if (fTreeList) {
1241  delete fTreeList;
1242  }
1243  delete fTimer;
1244  delete fSession;
1245 }
1246 
1247 ////////////////////////////////////////////////////////////////////////////////
1248 /// Enable/disable session buttons.
1249 
1250 void TTreeViewer::ActivateButtons(Bool_t first, Bool_t previous,
1251  Bool_t next, Bool_t last)
1252 {
1253  if (first) fBGFirst->SetState(kButtonUp);
1254  else fBGFirst->SetState(kButtonDisabled);
1255  if (previous) fBGPrevious->SetState(kButtonUp);
1256  else fBGPrevious->SetState(kButtonDisabled);
1257  if (next) fBGNext->SetState(kButtonUp);
1258  else fBGNext->SetState(kButtonDisabled);
1259  if (last) fBGLast->SetState(kButtonUp);
1260  else fBGLast->SetState(kButtonDisabled);
1261 }
1262 
1263 ////////////////////////////////////////////////////////////////////////////////
1264 /// Apply Cut
1265 
1266 const char* TTreeViewer::Cut()
1267 {
1268  return fLVContainer->Cut();
1269 }
1270 
1271 ////////////////////////////////////////////////////////////////////////////////
1272 /// returns scanlist
1273 
1274 const char* TTreeViewer::ScanList()
1275 {
1276  return fLVContainer->ScanList();
1277 }
1278 
1279 ////////////////////////////////////////////////////////////////////////////////
1280 /// Set current session
1281 
1282 void TTreeViewer::SetSession(TTVSession *session)
1283 {
1284  if (session) {
1285  delete fSession;
1286  fSession = session;
1287  }
1288 }
1289 
1290 ////////////////////////////////////////////////////////////////////////////////
1291 /// Empty the bracket content of a string.
1292 
1293 const char* TTreeViewer::EmptyBrackets(const char* name)
1294 {
1295  TString stripped(name);
1296  if (!stripped.Contains("[")) return name;
1297  TString retstr(name);
1298  TObjString *objstr;
1299  Int_t index = 0;
1300  while (stripped.Index("[", index) != kNPOS) {
1301  Int_t start = stripped.Index("[", index);
1302  Int_t end = stripped.Index("]", index);
1303  if (end == kNPOS) {
1304  objstr = new TObjString(retstr.Data());
1305  fWidgets->Add(objstr);
1306  return (objstr->String()).Data();
1307  }
1308  index = start+2;
1309  retstr = stripped.Remove(start+1, end-start-1);
1310  stripped = retstr;
1311  }
1312  objstr = new TObjString(retstr.Data());
1313  fWidgets->Add(objstr);
1314  return (objstr->String()).Data();
1315 }
1316 
1317 ////////////////////////////////////////////////////////////////////////////////
1318 /// Clear the content of all items in the list view.
1319 
1320 void TTreeViewer::EmptyAll()
1321 {
1322  fLVContainer->EmptyAll();
1323 }
1324 
1325 ////////////////////////////////////////////////////////////////////////////////
1326 /// Empty the content of the selected expression.
1327 
1328 void TTreeViewer::Empty()
1329 {
1330  void *p = 0;
1331  TTVLVEntry *item = 0;
1332  if ((item = (TTVLVEntry *) fLVContainer->GetNextSelected(&p)) == 0) {
1333  Warning("Empty", "No item selected.");
1334  return;
1335  }
1336  ULong_t *itemType = (ULong_t *) item->GetUserData();
1337  if (!(*itemType & kLTExpressionType)) {
1338  Warning("Empty", "Not expression type.");
1339  return;
1340  }
1341  if (*itemType & kLTPackType) {
1342  item->SetSmallPic(fClient->GetPicture("pack-empty_t.xpm"));
1343  item->SetTrueName("");
1344  return;
1345  }
1346  item->Empty();
1347 }
1348 
1349 ////////////////////////////////////////////////////////////////////////////////
1350 /// Get the item from a specific position.
1351 
1352 TTVLVEntry * TTreeViewer::ExpressionItem(Int_t index)
1353 {
1354  return fLVContainer->ExpressionItem(index);
1355 }
1356 
1357 ////////////////////////////////////////////////////////////////////////////////
1358 /// Get the list of expression items.
1359 
1360 TList* TTreeViewer::ExpressionList()
1361 {
1362  return fLVContainer->ExpressionList();
1363 }
1364 
1365 ////////////////////////////////////////////////////////////////////////////////
1366 /// Compute dimension of the histogram.
1367 
1368 Int_t TTreeViewer::Dimension()
1369 {
1370  fDimension = 0;
1371  if (Ex() && strlen(Ex())) fDimension++;
1372  if (Ey() && strlen(Ey())) fDimension++;
1373  if (Ez() && strlen(Ez())) fDimension++;
1374  return fDimension;
1375 }
1376 
1377 ////////////////////////////////////////////////////////////////////////////////
1378 /// Called when the DRAW button is executed.
1379 
1380 void TTreeViewer::ExecuteDraw()
1381 {
1382  TString varexp;
1383  TString command;
1384  Int_t dimension = 0;
1385  TString alias[3];
1386  TTVLVEntry *item;
1387  Int_t i;
1388  // fill in expressions
1389  if (fVarDraw) {
1390  void *p = 0;
1391  dimension = 1;
1392  if (!(item = (TTVLVEntry *) fLVContainer->GetNextSelected(&p))) return;
1393  alias[0] = item->GetAlias();
1394  if (alias[0].BeginsWith("~")) alias[0].Remove(0, 1);
1395  varexp = item->ConvertAliases();
1396  } else {
1397  if (Ez() && strlen(Ez())) {
1398  dimension++;
1399  varexp = Ez();
1400  item = ExpressionItem(2);
1401  alias[2] = item->GetAlias();
1402  if (alias[2].BeginsWith("~")) alias[2].Remove(0, 1);
1403  }
1404  if ((Ez() && strlen(Ez())) && ((Ex() &&strlen(Ex())) || (Ey() && strlen(Ey())))) varexp += ":";
1405  if (Ey() && strlen(Ey())) {
1406  dimension++;
1407  varexp += Ey();
1408  item = ExpressionItem(1);
1409  alias[1] = item->GetAlias();
1410  if (alias[1].BeginsWith("~")) alias[1].Remove(0, 1);
1411  }
1412  if (Ey() && strlen(Ey()) && Ex() && strlen(Ex())) varexp += ":";
1413  if (Ex () && strlen(Ex())) {
1414  dimension++;
1415  varexp += Ex();
1416  item = ExpressionItem(0);
1417  alias[0] = item->GetAlias();
1418  if (alias[0].BeginsWith("~")) alias[0].Remove(0, 1);
1419  }
1420  }
1421  if (!dimension && !fScanMode) {
1422  Warning("ExecuteDraw", "Nothing to draw on X,Y,Z.");
1423  return;
1424  }
1425  // find ListIn
1426  fTree->SetEventList(0);
1427  TEventList *elist = 0;
1428  if (strlen(fBarListIn->GetText())) {
1429  elist = (TEventList *) gROOT->FindObject(fBarListIn->GetText());
1430  if (elist) fTree->SetEventList(elist);
1431  }
1432  // find ListOut
1433  if (strlen(fBarListOut->GetText())) varexp = TString::Format(">>%s", fBarListOut->GetText());
1434  // find histogram name
1435  if (strcmp("htemp", fBarHist->GetText())) {
1436  varexp += ">>";
1437  varexp += fBarHist->GetText();
1438  }
1439  // find canvas/pad where to draw
1440  TPad *pad = (TPad*)gROOT->GetSelectedPad();
1441  if (pad) pad->cd();
1442  // find graphics option
1443  const char* gopt = fBarOption->GetText();
1444  // just in case a previous interrupt was posted
1445  gROOT->SetInterrupt(kFALSE);
1446  // check if cut is enabled
1447  const char *cut = "";
1448  if (fEnableCut) cut = Cut();
1449 
1450  // get entries to be processed
1451  Long64_t nentries = (Long64_t)(fSlider->GetMaxPosition() -
1452  fSlider->GetMinPosition() + 1);
1453  Long64_t firstentry =(Long64_t) fSlider->GetMinPosition();
1454 //printf("firstentry=%lld, nentries=%lld\n",firstentry,nentries);
1455  // check if Scan is checked and if there is something in the box
1456  if (fScanMode) {
1457 // fBarScan->SetState(kButtonUp);
1458  fScanMode = kFALSE;
1459  if (ScanList() && strlen(ScanList())) varexp = ScanList();
1460  command = TString::Format("tv__tree->Scan(\"%s\",\"%s\",\"%s\", %lld, %lld);",
1461  varexp.Data(), cut, gopt, nentries, firstentry);
1462  if (fBarScan->GetState() == kButtonDown) {
1463  ((TTreePlayer *)fTree->GetPlayer())->SetScanRedirect(kTRUE);
1464  } else {
1465  ((TTreePlayer *)fTree->GetPlayer())->SetScanRedirect(kFALSE);
1466  }
1467  ExecuteCommand(command.Data(), kTRUE);
1468  return;
1469  }
1470  // check if only histogram has to be updated
1471  if (fBarH->GetState() == kButtonDown) {
1472  // reset 'Hist' mode
1473  fBarH->SetState(kButtonUp);
1474  TH1 *hist = fTree->GetHistogram();
1475  if (hist && gPad) {
1476  //hist = (TH1*)gPad->GetListOfPrimitives()->FindObject(fBarHist->GetText());
1477  if (hist) {
1478  // check if graphic option was modified
1479  TString last(fLastOption);
1480  TString current(gopt);
1481  current.ToUpper();
1482  last.ToUpper();
1483  if (current == last) {
1484  gPad->Update();
1485  return;
1486  }
1487  if (dimension == 3 && strlen(gopt)) {
1488  std::cout << "Graphics option " << gopt << " not valid for 3D histograms" << std::endl;
1489  return;
1490  }
1491  std::cout << " Graphics option for current histogram changed to " << gopt << std::endl;
1492  hist->Draw(gopt);
1493  fLastOption = fBarOption->GetText();
1494  gPad->Update();
1495  return;
1496  }
1497  }
1498  }
1499  // send draw command
1500  fLastOption = fBarOption->GetText();
1501  //if (!gopt[0] && dimension!=3) {
1502  // gopt = "hist";
1503  // fLastOption = "hist";
1504  //}
1505  if (dimension == 3 && strlen(gopt)) {
1506  std::cout << "Graphics option " << gopt << " not valid for 3D histograms" << std::endl;
1507  gopt = "";
1508  fLastOption = "";
1509  }
1510  command = TString::Format("tv__tree->Draw(\"%s\",\"%s\",\"%s\", %lld, %lld);",
1511  varexp.Data(), cut, gopt, nentries, firstentry);
1512  if (fCounting) return;
1513  fCounting = kTRUE;
1514  fTree->SetTimerInterval(200);
1515  fTimer->TurnOn();
1516  ExecuteCommand(command.Data());
1517  HandleTimer(fTimer);
1518  fTimer->TurnOff();
1519  fTree->SetTimerInterval(0);
1520  fCounting = kFALSE;
1521  fProgressBar->SetPosition(0);
1522  fProgressBar->ShowPosition();
1523  TH1 *hist = fTree->GetHistogram();
1524  if (hist) {
1525  // put expressions aliases on axes
1526  Int_t current = 0;
1527  for (i=0; i<3; i++) {
1528  if (alias[i].Length()) {
1529  if (i != current) {
1530  alias[current] = alias[i];
1531  alias[i] = "";
1532  }
1533  current++;
1534  }
1535  }
1536  //hist = (TH1*)gPad->GetListOfPrimitives()->FindObject(fBarHist->GetText());
1537  TAxis *axis[3];
1538  axis[0] = hist->GetXaxis();
1539  axis[1] = hist->GetYaxis();
1540  axis[2] = hist->GetZaxis();
1541  for (Int_t ind=0; ind<3; ind++) axis[ind]->SetTitle(alias[ind].Data());
1542  }
1543  if (gPad) gPad->Update();
1544 }
1545 
1546 ////////////////////////////////////////////////////////////////////////////////
1547 /// Draw a spider plot for the selected entries.
1548 
1549 void TTreeViewer::ExecuteSpider()
1550 {
1551  TString varexp;
1552  Int_t dimension = 0;
1553  TString alias[3];
1554  TTVLVEntry *item;
1555  Bool_t previousexp = kFALSE;
1556  // fill in expressions
1557  if (Ez() && strlen(Ez())) {
1558  previousexp = kTRUE;
1559  dimension++;
1560  varexp = Ez();
1561  item = ExpressionItem(2);
1562  alias[2] = item->GetAlias();
1563  if (alias[2].BeginsWith("~")) alias[2].Remove(0, 1);
1564  }
1565  if ((Ez() && strlen(Ez())) && ((Ex() && strlen(Ex())) || (Ey() && strlen(Ey())))) varexp += ":";
1566  if (Ey() && strlen(Ey())) {
1567  previousexp = kTRUE;
1568  dimension++;
1569  varexp += Ey();
1570  item = ExpressionItem(1);
1571  alias[1] = item->GetAlias();
1572  if (alias[1].BeginsWith("~")) alias[1].Remove(0, 1);
1573  }
1574  if (Ey() && strlen(Ey()) && Ex() && strlen(Ex())) varexp += ":";
1575  if (Ex() && strlen(Ex())) {
1576  previousexp = kTRUE;
1577  dimension++;
1578  varexp += Ex();
1579  item = ExpressionItem(0);
1580  alias[0] = item->GetAlias();
1581  if (alias[0].BeginsWith("~")) alias[0].Remove(0, 1);
1582  }
1583  for(Int_t i=0;i<10;++i){
1584  if(En(i+5) && strlen(En(i+5))){
1585  ++dimension;
1586  if(previousexp){
1587  varexp += ":";
1588  varexp += En(i+5);
1589  } else varexp = En(i+5);
1590  previousexp = kTRUE;
1591  }
1592  }
1593  if (dimension<3) {
1594  Warning("ExecuteSpider", "Need at least 3 variables");
1595  return;
1596  }
1597  // find ListIn
1598  fTree->SetEventList(0);
1599  TEventList *elist = 0;
1600  if (strlen(fBarListIn->GetText())) {
1601  elist = (TEventList *) gROOT->FindObject(fBarListIn->GetText());
1602  if (elist) fTree->SetEventList(elist);
1603  }
1604  // find ListOut
1605  if (strlen(fBarListOut->GetText())) varexp = TString::Format(">>%s", fBarListOut->GetText());
1606  // find canvas/pad where to draw
1607  TPad *pad = (TPad*)gROOT->GetSelectedPad();
1608  if (pad) pad->cd();
1609  // find graphics option
1610  const char* gopt = fBarOption->GetText();
1611  // just in case a previous interrupt was posted
1612  gROOT->SetInterrupt(kFALSE);
1613  // check if cut is enabled
1614  const char *cut = "";
1615  if (fEnableCut) cut = Cut();
1616 
1617  // get entries to be processed
1618  Long64_t nentries = (Long64_t)(fSlider->GetMaxPosition() -
1619  fSlider->GetMinPosition() + 1);
1620  Long64_t firstentry =(Long64_t) fSlider->GetMinPosition();
1621 
1622  // create the spider plot
1623 
1624  TSpider* spider = new TSpider(fTree,varexp.Data(),cut,Form("%s spider average",gopt),nentries,firstentry);
1625  spider->Draw();
1626 
1627  if (gPad) gPad->Update();
1628 }
1629 
1630 ////////////////////////////////////////////////////////////////////////////////
1631 /// Get the expression to be drawn on X axis.
1632 
1633 const char* TTreeViewer::Ex()
1634 {
1635  return fLVContainer->Ex();
1636 }
1637 
1638 ////////////////////////////////////////////////////////////////////////////////
1639 /// Get the expression to be drawn on Y axis.
1640 
1641 const char* TTreeViewer::Ey()
1642 {
1643  return fLVContainer->Ey();
1644 }
1645 
1646 ////////////////////////////////////////////////////////////////////////////////
1647 /// Get the expression to be drawn on Z axis.
1648 
1649 const char* TTreeViewer::Ez()
1650 {
1651  return fLVContainer->Ez();
1652 }
1653 
1654 ////////////////////////////////////////////////////////////////////////////////
1655 /// Get the n'th expression
1656 
1657 const char* TTreeViewer::En(Int_t n)
1658 {
1659  TTVLVEntry *e = fLVContainer->ExpressionItem(n);
1660  if(e) return e->ConvertAliases();
1661  return "";
1662 }
1663 
1664 ////////////////////////////////////////////////////////////////////////////////
1665 /// Start the expression editor.
1666 
1667 void TTreeViewer::EditExpression()
1668 {
1669  void *p = 0;
1670  // get the selected item
1671  TTVLVEntry *item = 0;
1672  if ((item = (TTVLVEntry *) fLVContainer->GetNextSelected(&p)) == 0) {
1673  Warning("EditExpression", "No item selected.");
1674  return;
1675  }
1676  // check if it is an expression
1677  ULong_t *itemType = (ULong_t *) item->GetUserData();
1678  if (!(*itemType & kLTExpressionType)) {
1679  Warning("EditExpression", "Not expression type.");
1680  return;
1681  }
1682  // check if the editor is already active
1683  fDialogBox = TGSelectBox::GetInstance();
1684  if (!fDialogBox) {
1685  fDialogBox = new TGSelectBox(fClient->GetRoot(), this, fV1->GetWidth() - 10);
1686  }
1687  // copy current item data into editor boxes
1688  fDialogBox->SetEntry(item);
1689  fDialogBox->SetWindowName("Expression editor");
1690  // check if you are editing the cut expression
1691  if (*itemType & kLTCutType || item->IsCut()) {
1692  fDialogBox->SetLabel("Selection");
1693  } else {
1694  fDialogBox->SetLabel("Expression");
1695  }
1696 }
1697 
1698 ////////////////////////////////////////////////////////////////////////////////
1699 /// Get use of TTree::MakeSelector() via the context menu.
1700 
1701 Int_t TTreeViewer::MakeSelector(const char* selector)
1702 {
1703  if (!fTree) return 0;
1704  return fTree->MakeSelector(selector);
1705 }
1706 
1707 ////////////////////////////////////////////////////////////////////////////////
1708 /// Get use of TTree::Process() via the context menu.
1709 
1710 Long64_t TTreeViewer::Process(const char* filename, Option_t *option, Long64_t nentries, Long64_t firstentry)
1711 {
1712  if (!fTree) return 0;
1713  return fTree->Process(filename, option, nentries, firstentry);
1714 }
1715 
1716 ////////////////////////////////////////////////////////////////////////////////
1717 /// Get graph option
1718 
1719 const char *TTreeViewer::GetGrOpt()
1720 {
1721  return fBarOption->GetText();
1722 }
1723 
1724 ////////////////////////////////////////////////////////////////////////////////
1725 /// Set graph option
1726 
1727 void TTreeViewer::SetGrOpt(const char *option)
1728 {
1729  fBarOption->SetText(option);
1730 }
1731 
1732 ////////////////////////////////////////////////////////////////////////////////
1733 /// Return kTRUE if scan is redirected
1734 
1735 Bool_t TTreeViewer::IsScanRedirected()
1736 {
1737  return (fBarScan->GetState()==kButtonDown);
1738 }
1739 
1740 ////////////////////////////////////////////////////////////////////////////////
1741 /// Remove the selected item from the list.
1742 
1743 void TTreeViewer::RemoveItem()
1744 {
1745  void *p = 0;
1746  TTVLVEntry *item = 0;
1747  // get the selected item
1748  if ((item = (TTVLVEntry *) fLVContainer->GetNextSelected(&p)) == 0) {
1749  Warning("RemoveItem", "No item selected.");
1750  return;
1751  }
1752  // check if it is removable
1753  ULong_t *itemType = (ULong_t *) item->GetUserData();
1754  if (!(*itemType & kLTDragType)) {
1755  Warning("RemoveItem", "Not removable type.");
1756  return;
1757  }
1758  fLVContainer->RemoveItem(item);
1759  fListView->Layout();
1760 }
1761 
1762 ////////////////////////////////////////////////////////////////////////////////
1763 /// Remove the current record.
1764 
1765 void TTreeViewer::RemoveLastRecord()
1766 {
1767  fSession->RemoveLastRecord();
1768 }
1769 
1770 ////////////////////////////////////////////////////////////////////////////////
1771 /// This function is called by the fTimer object.
1772 
1773 Bool_t TTreeViewer::HandleTimer(TTimer *timer)
1774 {
1775  if (fCounting) {
1776  Float_t first = fSlider->GetMinPosition();
1777  Float_t last = fSlider->GetMaxPosition();
1778  Float_t current = (Float_t)fTree->GetReadEntry();
1779  Float_t percent = (current-first+1)/(last-first+1);
1780  fProgressBar->SetPosition(100.*percent);
1781  fProgressBar->ShowPosition();
1782  }
1783  timer->Reset();
1784  return kFALSE;
1785 }
1786 
1787 ////////////////////////////////////////////////////////////////////////////////
1788 /// Handle menu and other commands generated.
1789 
1790 Bool_t TTreeViewer::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
1791 {
1792  TRootHelpDialog *hd;
1793  TTVRecord *record;
1794 
1795  switch (GET_MSG(msg)) {
1796  case kC_VSLIDER :
1797  // handle slider messages
1798  PrintEntries();
1799  break;
1800  case kC_TEXTENTRY:
1801  switch (GET_SUBMSG(msg)) {
1802  // handle enter posted by the Command text entry
1803  case kTE_ENTER:
1804  if ((ERootTreeViewerCommands)parm1 == kBarCommand) {
1805  ExecuteCommand(fBarCommand->GetText());
1806  fBarCommand->Clear();
1807  }
1808  if ((ERootTreeViewerCommands)parm1 == kBarOption) {
1809  fVarDraw = kFALSE;
1810  fBarH->SetState(kButtonDown);
1811  ExecuteDraw();
1812  fBarH->SetState(kButtonUp);
1813  }
1814  break;
1815  default:
1816  break;
1817  }
1818  break;
1819  case kC_LISTTREE:
1820  switch (GET_SUBMSG(msg)) {
1821  // handle mouse messages in the list-tree (left panel)
1822  case kCT_ITEMCLICK :
1823  // tell coverity that parm1 is a Long_t, and not an enum (even
1824  // if we compare it with an enum value) and the meaning of
1825  // parm1 depends on GET_MSG(msg) and GET_SUBMSG(msg)
1826  // coverity[mixed_enums]
1827  if (((EMouseButton)parm1==kButton1) ||
1828  ((EMouseButton)parm1==kButton3)) {
1829  TGListTreeItem *ltItem = 0;
1830  // get item that sent this
1831  if ((ltItem = fLt->GetSelected()) != 0) {
1832  // get item type
1833  ULong_t *itemType = (ULong_t *)ltItem->GetUserData();
1834  if (!itemType)
1835  break;
1836  if (*itemType & kLTTreeType) {
1837  // already mapped tree item clicked
1838  Int_t index = (Int_t)(*itemType >> 8);
1839  SwitchTree(index);
1840  if (fTree != fMappedTree) {
1841  // switch also the global "tree" variable
1842  fLVContainer->RemoveNonStatic();
1843  // map it on the right panel
1844  MapTree(fTree);
1845  fListView->Layout();
1846  }
1847  // activate context menu for this tree
1848  if (parm1 == kButton3) {
1849  Int_t x = (Int_t)(parm2 &0xffff);
1850  Int_t y = (Int_t)((parm2 >> 16) & 0xffff);
1851  fContextMenu->Popup(x, y, fTree);
1852  }
1853  }
1854 
1855  if (*itemType & kLTBranchType) {
1856  // branch item clicked
1857  SetParentTree(ltItem);
1858  if (!fTree) break; // really needed ?
1859  TBranch *branch = fTree->GetBranch(ltItem->GetText());
1860  if (!branch) break;
1861  // check if it is mapped on the right panel
1862  if (branch != fMappedBranch) {
1863  fLVContainer->RemoveNonStatic();
1864  MapBranch(branch);
1865  fStopMapping = kFALSE;
1866  fListView->Layout();
1867  }
1868  // activate context menu for this branch (no *MENU* methods ):)
1869  if (parm1 == kButton3) {
1870  Int_t x = (Int_t)(parm2 &0xffff);
1871  Int_t y = (Int_t)((parm2 >> 16) & 0xffff);
1872  fContextMenu->Popup(x, y, branch);
1873  }
1874  }
1875 
1876  if (*itemType & kLTLeafType) {
1877  // leaf item clicked
1878  SetParentTree(ltItem);
1879  if (!fTree) break;
1880  // find parent branch
1881  TBranch *branch = fTree->GetBranch(ltItem->GetParent()->GetText());
1882  if (!branch) {
1883  if (fTree != fMappedTree) {
1884  fLVContainer->RemoveNonStatic();
1885  MapTree(fTree);
1886  fListView->Layout();
1887  }
1888  } else {
1889  // check if it is already mapped
1890  if (branch!=fMappedBranch) {
1891  fLVContainer->RemoveNonStatic();
1892  MapBranch(branch);
1893  fStopMapping = kFALSE;
1894  fListView->Layout();
1895  }
1896  }
1897  // select corresponding leaf on the right panel
1898  fLVContainer->SelectItem(ltItem->GetText());
1899  if (parm1 == kButton3) {
1900  // activate context menu for this leaf
1901  ProcessMessage(MK_MSG(kC_CONTAINER, kCT_ITEMCLICK), kButton3, parm2);
1902  }
1903  }
1904  }
1905  }
1906  break;
1907  case kCT_ITEMDBLCLICK :
1908  fClient->NeedRedraw(fLt);
1909  if (parm1 == kButton1) {
1910  // execute double-click action for corresponding item in the right panel
1911  ProcessMessage(MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK), kButton1, parm2);
1912  }
1913  break;
1914  default:
1915  break;
1916  }
1917  break;
1918  case kC_COMMAND:
1919  switch (GET_SUBMSG(msg)) {
1920  case kCM_COMBOBOX:
1921  if ((record = fSession->GetRecord((Int_t)parm2)))
1922  fSession->Show(record);
1923  break;
1924  case kCM_BUTTON:
1925  switch (parm1) {
1926  // handle button messages
1927  case kRESET:
1928  EmptyAll();
1929  break;
1930  case kDRAW:
1931  fVarDraw = kFALSE;
1932  ExecuteDraw();
1933  break;
1934  case kSTOP:
1935  if (fCounting)
1936  gROOT->SetInterrupt(kTRUE);
1937  break;
1938  case kCLOSE:
1939  SendCloseMessage();
1940  break;
1941  case kBGFirst:
1942  if ((record = fSession->First()))
1943  fSession->Show(record);
1944  break;
1945  case kBGPrevious:
1946  if ((record = fSession->Previous()))
1947  fSession->Show(record);
1948  break;
1949  case kBGRecord:
1950  fSession->AddRecord();
1951  break;
1952  case kBGNext:
1953  if ((record = fSession->Next()))
1954  fSession->Show(record);
1955  break;
1956  case kBGLast:
1957  if ((record = fSession->Last()))
1958  fSession->Show(record);
1959  break;
1960  default:
1961  break;
1962  }
1963  break;
1964  case kCM_MENU:
1965  // handle menu messages
1966  // check if sent by Options menu
1967  if ((parm1>=kOptionsReset) && (parm1<kHelpAbout)) {
1968  Dimension();
1969  if ((fDimension==0) && (parm1>=kOptions1D)) {
1970  Warning("ProcessMessage", "Edit expressions first.");
1971  break;
1972  }
1973  if ((fDimension==1) && (parm1>=kOptions2D)) {
1974  Warning("ProcessMessage", "You have only one expression active.");
1975  break;
1976  }
1977  if ((fDimension==2) && (parm1>=kOptions1D) &&(parm1<kOptions2D)) {
1978  Warning("ProcessMessage", "1D drawing options not apply to 2D histograms.");
1979  break;
1980  }
1981  // make composed option
1982  MapOptions(parm1);
1983  break;
1984  }
1985  switch (parm1) {
1986  case kFileCanvas:
1987  gROOT->MakeDefCanvas();
1988  break;
1989  case kFileBrowse:
1990  if (1) {
1991  static TString dir(".");
1992  TGFileInfo info;
1993  info.fFileTypes = gOpenTypes;
1994  info.fIniDir = StrDup(dir);
1995  new TGFileDialog(fClient->GetRoot(), this, kFDOpen, &info);
1996  if (!info.fFilename) return kTRUE;
1997  dir = info.fIniDir;
1998  TString command = TString::Format("tv__tree_file = new TFile(\"%s\");",
1999  gSystem->UnixPathName(info.fFilename));
2000  ExecuteCommand(command.Data());
2001  ExecuteCommand("tv__tree_file->ls();");
2002  std::cout << "Use SetTreeName() from context menu and supply a tree name" << std::endl;
2003  std::cout << "The context menu is activated by right-clicking the panel from right" << std::endl;
2004  }
2005  break;
2006  case kFileLoadLibrary:
2007  fBarCommand->SetText("gSystem->Load(\"\");");
2008  if (1) {
2009  Event_t event;
2010  event.fType = kButtonPress;
2011  event.fCode = kButton1;
2012  event.fX = event.fY = 1;
2013  fBarCommand->HandleButton(&event);
2014  }
2015  fBarCommand->SetCursorPosition(15);
2016  break;
2017  case kFileOpenSession:
2018  if (1) {
2019  static TString dir(".");
2020  TGFileInfo info;
2021  info.fFileTypes = gMacroTypes;
2022  info.fIniDir = StrDup(dir);
2023  new TGFileDialog(fClient->GetRoot(), this, kFDOpen, &info);
2024  if (!info.fFilename) return kTRUE;
2025  dir = info.fIniDir;
2026  gInterpreter->Reset();
2027  if (!gInterpreter->IsLoaded(info.fFilename)) gInterpreter->LoadMacro(info.fFilename);
2028  char command[1024];
2029  command[0] = 0;
2030  snprintf(command,1024,"open_session((void*)0x%lx);", (Long_t)this);
2031  ExecuteCommand(command);
2032  }
2033  break;
2034  case kFileSaveMacro:
2035  fContextMenu->Action(this,(TMethod*)IsA()->GetListOfMethods()->FindObject("SaveSource"));
2036  break;
2037  case kFilePrint:
2038  break;
2039  case kFileClose:
2040  SendCloseMessage();
2041  break;
2042  case kFileQuit:
2043  gApplication->Terminate(0);
2044  break;
2045  case kEditExpression:
2046  EditExpression();
2047  break;
2048  case kEditCut:
2049  EditExpression();
2050  break;
2051  case kEditMacro:
2052  break;
2053  case kEditEvent:
2054  break;
2055  case kRunMacro:
2056  break;
2057  case kHelpAbout:
2058  {
2059 #ifdef R__UNIX
2060  TString rootx = TROOT::GetBinDir() + "/root -a &";
2061  gSystem->Exec(rootx);
2062 #else
2063 #ifdef WIN32
2064  new TWin32SplashThread(kTRUE);
2065 #else
2066  char str[32];
2067  snprintf(str,32, "About ROOT %s...", gROOT->GetVersion());
2068  hd = new TRootHelpDialog(this, str, 600, 400);
2069  hd->SetText(gHelpAbout);
2070  hd->Popup();
2071 #endif
2072 #endif
2073  }
2074  break;
2075  case kHelpAboutTV:
2076  hd = new TRootHelpDialog(this, "About TreeViewer...", 600, 400);
2077  hd->SetText(gTVHelpAbout);
2078  hd->Resize(hd->GetDefaultSize());
2079  hd->Popup();
2080  break;
2081  case kHelpStart:
2082  hd = new TRootHelpDialog(this, "Quick start...", 600, 400);
2083  hd->SetText(gTVHelpStart);
2084  hd->Popup();
2085  break;
2086  case kHelpLayout:
2087  hd = new TRootHelpDialog(this, "Layout...", 600, 400);
2088  hd->SetText(gTVHelpLayout);
2089  hd->Popup();
2090  break;
2091  case kHelpOpenSave:
2092  hd = new TRootHelpDialog(this, "Open/Save...", 600, 400);
2093  hd->SetText(gTVHelpOpenSave);
2094  hd->Popup();
2095  break;
2096  case kHelpDragging:
2097  hd = new TRootHelpDialog(this, "Dragging items...", 600, 400);
2098  hd->SetText(gTVHelpDraggingItems);
2099  hd->Popup();
2100  break;
2101  case kHelpEditing:
2102  hd = new TRootHelpDialog(this, "Editing expressions...", 600, 400);
2103  hd->SetText(gTVHelpEditExpressions);
2104  hd->Popup();
2105  break;
2106  case kHelpSession:
2107  hd = new TRootHelpDialog(this, "Session...", 600, 400);
2108  hd->SetText(gTVHelpSession);
2109  hd->Popup();
2110  break;
2111  case kHelpCommands:
2112  hd = new TRootHelpDialog(this, "Executing user commands...", 600, 400);
2113  hd->SetText(gTVHelpUserCommands);
2114  hd->Popup();
2115  break;
2116  case kHelpContext:
2117  hd = new TRootHelpDialog(this, "Context menus...", 600, 400);
2118  hd->SetText(gTVHelpContext);
2119  hd->Popup();
2120  break;
2121  case kHelpDrawing:
2122  hd = new TRootHelpDialog(this, "Drawing histograms...", 600, 400);
2123  hd->SetText(gTVHelpDrawing);
2124  hd->Popup();
2125  break;
2126  case kHelpMacros:
2127  hd = new TRootHelpDialog(this, "Using macros...", 600, 400);
2128  hd->SetText(gTVHelpMacros);
2129  hd->Popup();
2130  break;
2131  default:
2132  break;
2133  }
2134  break;
2135  default:
2136  break;
2137  }
2138  break;
2139  case kC_CONTAINER:
2140  switch (GET_SUBMSG(msg)) {
2141  // handle messages sent from the listview (right panel)
2142  case kCT_SELCHANGED:
2143  break;
2144  case kCT_ITEMCLICK:
2145  // handle mouse messages
2146  switch (parm1) {
2147  case kButton1:
2148  if (fLVContainer->NumSelected()) {
2149  // get item that sent this
2150  void *p = 0;
2151  TTVLVEntry *item;
2152  if ((item = (TTVLVEntry *) fLVContainer->GetNextSelected(&p)) != 0) {
2153  const char* vname = item->GetTrueName();
2154  TString trueName(vname);
2155  if (trueName.Contains("[]")) {
2156  TIter next(fTree->GetListOfLeaves());
2157  TLeaf *leaf;
2158  while((leaf=(TLeaf*)next())) {
2159  if (!strcmp(vname, EmptyBrackets(leaf->GetName())))
2160  vname = leaf->GetName();
2161  }
2162  }
2163  char* msg2 = new char[2000];
2164  // get item type
2165  ULong_t *itemType = (ULong_t *) item->GetUserData();
2166  if (*itemType & kLTTreeType) {
2167  // X, Y or Z clicked
2168  char symbol = (char)((*itemType) >> 8);
2169  snprintf(msg2,2000, "%c expression : %s", symbol, vname);
2170  } else {
2171  if (*itemType & kLTCutType) {
2172  // scissors clicked
2173  snprintf(msg2,2000, "Cut : %s", vname);
2174  } else {
2175  if (*itemType & kLTPackType) {
2176  snprintf(msg2,2000, "Box : %s", vname);
2177  } else {
2178  if (*itemType & kLTExpressionType) {
2179  // expression clicked
2180  snprintf(msg2,2000, "Expression : %s", vname);
2181  } else {
2182  if (*itemType & kLTBranchType) {
2183  snprintf(msg2,2000, "Branch : %s", vname);
2184  } else {
2185  snprintf(msg2,2000, "Leaf : %s", vname);
2186  }
2187  }
2188  }
2189  }
2190  }
2191  // write who is responsable for this
2192  TString message = msg2;
2193  message = message(0,150);
2194  Message(msg2);
2195  delete[] msg2;
2196  // check if this should be pasted into the expression editor
2197  if ((*itemType & kLTBranchType) || (*itemType & kLTCutType)) break;
2198  fDialogBox = TGSelectBox::GetInstance();
2199  if (!fDialogBox || !vname[0]) break;
2200  if (item == fDialogBox->EditedEntry()) break;
2201  // paste it
2202 // char first = (char) vname[0];
2203  TString insert(item->GetAlias());
2204 // if (first != '(') insert += "(";
2205 // insert += item->GetAlias();
2206 // if (first != '(') insert += ")";
2207 
2208  fDialogBox->GrabPointer();
2209  fDialogBox->InsertText(insert.Data());
2210  // put the cursor at the right position
2211  }
2212  }
2213  break;
2214  case kButton2:
2215  break;
2216  case kButton3:
2217  // activate general context menu
2218  if (fLVContainer->NumSelected()) {
2219  void *p = 0;
2220  Int_t x = (Int_t)(parm2 &0xffff);
2221  Int_t y = (Int_t)((parm2 >> 16) & 0xffff);
2222  TTVLVEntry *item = 0;
2223  if ((item = (TTVLVEntry *) fLVContainer->GetNextSelected(&p)) != 0) {
2224  fContextMenu->Popup(x, y, item->GetContext());
2225  }
2226  } else { // empty click
2227  Int_t x = (Int_t)(parm2 &0xffff);
2228  Int_t y = (Int_t)((parm2 >> 16) & 0xffff);
2229  fContextMenu->Popup(x, y, this);
2230  }
2231  break;
2232  default:
2233  break;
2234  }
2235  break;
2236  case kCT_ITEMDBLCLICK:
2237  switch (parm1) {
2238  case kButton1:
2239  if (fLVContainer->NumSelected()) {
2240  // get item that sent this
2241  void *p = 0;
2242  TTVLVEntry *item;
2243  if ((item = (TTVLVEntry *) fLVContainer->GetNextSelected(&p)) != 0) {
2244  // get item type
2245  ULong_t *itemType = (ULong_t *) item->GetUserData();
2246  if (!(*itemType & kLTCutType) && !(*itemType & kLTBranchType)
2247  && !(*itemType & kLTPackType)) {
2248  if (strlen(item->GetTrueName())) {
2249  fVarDraw = kTRUE;
2250  // draw on double-click
2251  ExecuteDraw();
2252  break;
2253  } else {
2254  // open expression in editor
2255  EditExpression();
2256  }
2257  }
2258  if (*itemType & kLTCutType) {
2259  fEnableCut = !fEnableCut;
2260  if (fEnableCut) {
2261  item->SetSmallPic(gClient->GetPicture("cut_t.xpm"));
2262  } else {
2263  item->SetSmallPic(gClient->GetPicture("cut-disable_t.xpm"));
2264  }
2265  }
2266  if (*itemType & kLTPackType) {
2267  fScanMode = kTRUE;
2268  ExecuteDraw();
2269  }
2270  }
2271  }
2272  break;
2273  case kButton2:
2274  break;
2275  case kButton3:
2276  break;
2277  default:
2278  break;
2279  }
2280  break;
2281  case 4:
2282 // std::cout << "Dragging Item" << std::endl;
2283  default:
2284  break;
2285  }
2286  break;
2287  default:
2288  break;
2289  }
2290  return kTRUE;
2291 }
2292 
2293 ////////////////////////////////////////////////////////////////////////////////
2294 /// Close the viewer.
2295 
2296 void TTreeViewer::CloseWindow()
2297 {
2298  DeleteWindow();
2299 }
2300 
2301 ////////////////////////////////////////////////////////////////////////////////
2302 /// Execute all user commands.
2303 
2304 void TTreeViewer::ExecuteCommand(const char* command, Bool_t fast)
2305 {
2306  // Execute the command, write it to history file and echo it to output
2307  if (fBarRec->GetState() == kButtonDown) {
2308  // show the command on the command line
2309  //printf("%s\n", command);
2310  char comm[2000];
2311  comm[0] = 0;
2312  if (strlen(command) > 1999) {
2313  Warning("ExecuteCommand", "Command too long: aborting.");
2314  return;
2315  }
2316  snprintf(comm,2000, "%s", command);
2317  // print the command to history file
2318  Gl_histadd(comm);
2319  }
2320  // execute it
2321  if (fast) {
2322  gROOT->ProcessLineFast(command);
2323  } else {
2324  gROOT->ProcessLine(command);
2325  }
2326  // make sure that 'draw on double-click' flag is reset
2327  fVarDraw = kFALSE;
2328 }
2329 
2330 ////////////////////////////////////////////////////////////////////////////////
2331 /// Scan the selected options from option menu.
2332 
2333 void TTreeViewer::MapOptions(Long_t parm1)
2334 {
2335  Int_t ind;
2336  if (parm1 == kOptionsReset) {
2337  for (ind=kOptionsGeneral; ind<kOptionsGeneral+16; ind++)
2338  fOptionsGen->UnCheckEntry(ind);
2339  for (ind=kOptions1D; ind<kOptions1D+12; ind++)
2340  fOptions1D->UnCheckEntry(ind);
2341  for (ind=kOptions2D; ind<kOptions2D+14; ind++)
2342  fOptions2D->UnCheckEntry(ind);
2343  }
2344  if ((parm1 < kOptions1D) && (parm1 != kOptionsReset)) {
2345  if (fOptionsGen->IsEntryChecked((Int_t)parm1)) {
2346  fOptionsGen->UnCheckEntry((Int_t)parm1);
2347  } else {
2348  fOptionsGen->CheckEntry((Int_t)parm1);
2349  if ((Int_t)parm1 != kOptionsGeneral) fOptionsGen->UnCheckEntry((Int_t)kOptionsGeneral);
2350  }
2351  if (fOptionsGen->IsEntryChecked((Int_t)kOptionsGeneral)) {
2352  // uncheck all in this menu
2353  for (ind=kOptionsGeneral+1; ind<kOptionsGeneral+16; ind++) {
2354  fOptionsGen->UnCheckEntry(ind);
2355  }
2356  }
2357  }
2358 
2359  if ((parm1 < kOptions2D) && (parm1 >= kOptions1D)) {
2360  if (fOptions1D->IsEntryChecked((Int_t)parm1)) {
2361  fOptions1D->UnCheckEntry((Int_t)parm1);
2362  } else {
2363  fOptions1D->CheckEntry((Int_t)parm1);
2364  if ((Int_t)parm1 != kOptions1D) fOptions1D->UnCheckEntry((Int_t)kOptions1D);
2365  }
2366  if (fOptions1D->IsEntryChecked((Int_t)kOptions1D)) {
2367  // uncheck all in this menu
2368  for (ind=kOptions1D+1; ind<kOptions1D+12; ind++) {
2369  fOptions1D->UnCheckEntry(ind);
2370  }
2371  }
2372  }
2373 
2374  if (parm1 >= kOptions2D) {
2375  if (fOptions2D->IsEntryChecked((Int_t)parm1)) {
2376  fOptions2D->UnCheckEntry((Int_t)parm1);
2377  } else {
2378  fOptions2D->CheckEntry((Int_t)parm1);
2379  if ((Int_t)parm1 != kOptions2D) fOptions2D->UnCheckEntry((Int_t)kOptions2D);
2380  }
2381  if (fOptions2D->IsEntryChecked((Int_t)kOptions2D)) {
2382  // uncheck all in this menu
2383  for (ind=kOptions2D+1; ind<kOptions2D+14; ind++) {
2384  fOptions2D->UnCheckEntry(ind);
2385  }
2386  }
2387  }
2388  // concatenate options
2389  fBarOption->SetText("");
2390  for (ind=kOptionsGeneral; ind<kOptionsGeneral+16; ind++) {
2391  if (fOptionsGen->IsEntryChecked(ind))
2392  fBarOption->AppendText(gOptgen[ind-kOptionsGeneral]);
2393  }
2394  if (Dimension() == 1) {
2395  for (ind=kOptions1D; ind<kOptions1D+12; ind++) {
2396  if (fOptions1D->IsEntryChecked(ind))
2397  fBarOption->AppendText(gOpt1D[ind-kOptions1D]);
2398  }
2399  }
2400  if (Dimension() == 2) {
2401  for (ind=kOptions2D; ind<kOptions2D+14; ind++) {
2402  if (fOptions2D->IsEntryChecked(ind))
2403  fBarOption->AppendText(gOpt2D[ind-kOptions2D]);
2404  }
2405  }
2406 }
2407 
2408 ////////////////////////////////////////////////////////////////////////////////
2409 /// Map current tree and expand its content (including friends) in the lists.
2410 
2411 void TTreeViewer::MapTree(TTree *tree, TGListTreeItem *parent, Bool_t listIt)
2412 {
2413  if (!tree) return;
2414  TObjArray *branches = tree->GetListOfBranches();
2415  if (!branches) return; // A Chain with no underlying trees.
2416  TBranch *branch;
2417  // loop on branches
2418  Int_t id;
2419  for (id=0; id<branches->GetEntries(); id++) {
2420  branch = (TBranch *)branches->At(id);
2421  if (branch->TestBit(kDoNotProcess)) continue;
2422  TString name = branch->GetName();
2423  if (name.Contains("fBits") || name.Contains("fUniqueID")) continue;
2424  // now map sub-branches
2425  MapBranch(branch, "", parent, listIt);
2426  fStopMapping = kFALSE;
2427  }
2428  //Map branches of friend Trees (if any)
2429  //Look at tree->GetTree() to insure we see both the friendss of a chain
2430  //and the friends of the chain members
2431  TIter nextf( tree->GetTree()->GetListOfFriends() );
2432  TFriendElement *fr;
2433  while ((fr = (TFriendElement*)nextf())) {
2434  TTree * t = fr->GetTree();
2435  branches = t->GetListOfBranches();
2436  for (id=0; id<branches->GetEntries(); id++) {
2437  branch = (TBranch *)branches->At(id);
2438  if (branch->TestBit(kDoNotProcess)) continue;
2439  TString name = branch->GetName();
2440  if (name.Contains("fBits") || name.Contains("fUniqueID")) continue;
2441  // now map sub-branches
2442  MapBranch(branch, fr->GetName(), parent, listIt);
2443  fStopMapping = kFALSE;
2444  }
2445  }
2446 
2447  // tell who was last mapped
2448  if (listIt) {
2449  fMappedTree = tree;
2450  fMappedBranch = 0;
2451  }
2452 }
2453 
2454 ////////////////////////////////////////////////////////////////////////////////
2455 /// Map current branch and expand its content in the list view.
2456 
2457 void TTreeViewer::MapBranch(TBranch *branch, const char *prefix, TGListTreeItem *parent, Bool_t listIt)
2458 {
2459  if (!branch) return;
2460  TString name;
2461  if (prefix && strlen(prefix) > 0) {
2462  name = prefix;
2463  if (!name.EndsWith(".")) name += ".";
2464  name += branch->GetName();
2465  }
2466  else name = branch->GetName();
2467  Int_t ind;
2468  TGListTreeItem *branchItem = 0;
2469  ULong_t *itemType;
2470  // map this branch
2471  if (name.Contains("fBits") || name.Contains("fUniqueID")) return;
2472  if (parent) {
2473  // make list tree items for each branch according to the type
2474  const TGPicture *pic, *spic;
2475  if ((branch->GetListOfBranches()->GetEntries()) ||
2476  (branch->GetNleaves())) {
2477  if (branch->GetListOfBranches()->GetEntries()) {
2478  itemType = new ULong_t(kLTBranchType);
2479  if (branch->InheritsFrom("TBranchObject")) {
2480  pic = gClient->GetPicture("branch-ob_t.xpm");
2481  spic = gClient->GetPicture("branch-ob_t.xpm");
2482  } else {
2483  if (branch->InheritsFrom("TBranchClones")) {
2484  pic = gClient->GetPicture("branch-cl_t.xpm");
2485  spic = gClient->GetPicture("branch-cl_t.xpm");
2486  } else {
2487  pic = gClient->GetPicture("branch_t.xpm");
2488  spic = gClient->GetPicture("branch_t.xpm");
2489  }
2490  }
2491  branchItem = fLt->AddItem(parent, EmptyBrackets(name), itemType, pic, spic);
2492  } else {
2493  if (branch->GetNleaves() > 1) {
2494  itemType = new ULong_t(kLTBranchType);
2495  pic = gClient->GetPicture("branch_t.xpm");
2496  spic = gClient->GetPicture("branch_t.xpm");
2497  branchItem = fLt->AddItem(parent, EmptyBrackets(name), itemType,pic, spic);
2498  TObjArray *leaves = branch->GetListOfLeaves();
2499  TLeaf *leaf = 0;
2500  TString leafName;
2501  for (Int_t lf=0; lf<leaves->GetEntries(); lf++) {
2502  leaf = (TLeaf *)leaves->At(lf);
2503  leafName = name;
2504  if (!leafName.EndsWith(".")) leafName.Append(".");
2505  leafName.Append(EmptyBrackets(leaf->GetName()));
2506  itemType = new ULong_t(kLTLeafType);
2507  pic = gClient->GetPicture("leaf_t.xpm");
2508  spic = gClient->GetPicture("leaf_t.xpm");
2509  fLt->AddItem(branchItem, leafName.Data(), itemType, pic, spic);
2510  }
2511  } else {
2512  itemType = new ULong_t(kLTLeafType);
2513  pic = gClient->GetPicture("leaf_t.xpm");
2514  spic = gClient->GetPicture("leaf_t.xpm");
2515  branchItem = fLt->AddItem(parent, EmptyBrackets(name), itemType, pic, spic);
2516  }
2517  }
2518  }
2519  }
2520  // list branch in list view if necessary
2521  if (listIt) {
2522  TGString *textEntry = 0;
2523  const TGPicture *pic, *spic;
2524  TTVLVEntry *entry;
2525  // make list view items in the right frame
2526  if (!fStopMapping) {
2527  fMappedBranch = branch;
2528  fMappedTree = 0;
2529  fStopMapping = kTRUE;
2530  }
2531  if ((branch->GetListOfBranches()->GetEntries()) ||
2532  (branch->GetNleaves())) {
2533  textEntry = new TGString(EmptyBrackets(name.Data()));
2534  if (branch->GetListOfBranches()->GetEntries()) {
2535  if (branch->InheritsFrom("TBranchObject")) {
2536  pic = gClient->GetPicture("branch-ob_t.xpm");
2537  spic = gClient->GetPicture("branch-ob_t.xpm");
2538  } else {
2539  if (branch->InheritsFrom("TBranchClones")) {
2540  pic = gClient->GetPicture("branch-cl_t.xpm");
2541  spic = gClient->GetPicture("branch-cl_t.xpm");
2542  } else {
2543  pic = gClient->GetPicture("branch_t.xpm");
2544  spic = gClient->GetPicture("branch_t.xpm");
2545  }
2546  }
2547  entry = new TTVLVEntry(fLVContainer,pic,spic,textEntry,0,kLVSmallIcons);
2548  entry->SetUserData(new UInt_t(kLTBranchType));
2549  entry->SetToolTipText("Branch with sub-branches. Can not be dragged");
2550  fLVContainer->AddThisItem(entry);
2551  entry->MapWindow();
2552  entry->SetAlias(textEntry->GetString());
2553  } else {
2554  if (branch->GetNleaves() > 1) {
2555  if (textEntry) delete textEntry;
2556  textEntry = new TGString(EmptyBrackets(name.Data()));
2557  pic = gClient->GetPicture("branch_t.xpm");
2558  spic = gClient->GetPicture("branch_t.xpm");
2559  entry = new TTVLVEntry(fLVContainer, pic, spic, textEntry,0,kLVSmallIcons);
2560  entry->SetUserData(new UInt_t(kLTBranchType));
2561  entry->SetToolTipText("Branch with more than one leaf. Can not be dragged");
2562  fLVContainer->AddThisItem(entry);
2563  entry->MapWindow();
2564  entry->SetAlias(textEntry->GetString());
2565 
2566  TObjArray *leaves = branch->GetListOfLeaves();
2567  TLeaf *leaf = 0;
2568  TString leafName;
2569  for (Int_t lf=0; lf<leaves->GetEntries(); lf++) {
2570  leaf = (TLeaf *)leaves->At(lf);
2571  leafName = name;
2572  if (!leafName.EndsWith(".")) leafName.Append(".");
2573  leafName.Append(EmptyBrackets(leaf->GetName()));
2574  textEntry = new TGString(leafName.Data());
2575  pic = gClient->GetPicture("leaf_t.xpm");
2576  spic = gClient->GetPicture("leaf_t.xpm");
2577  entry = new TTVLVEntry(fLVContainer, pic, spic, textEntry,0,kLVSmallIcons);
2578  entry->SetUserData(new UInt_t(kLTDragType | kLTLeafType));
2579  entry->SetToolTipText("Double-click to draw. Drag to X, Y, Z or scan box.");
2580  fLVContainer->AddThisItem(entry);
2581  entry->MapWindow();
2582  entry->SetAlias(textEntry->GetString());
2583  }
2584  } else {
2585  pic = (gClient->GetMimeTypeList())->GetIcon("TLeaf",kFALSE);
2586  if (!pic) pic = gClient->GetPicture("leaf_t.xpm");
2587  spic = gClient->GetMimeTypeList()->GetIcon("TLeaf",kTRUE);
2588  if (!spic) spic = gClient->GetPicture("leaf_t.xpm");
2589  entry = new TTVLVEntry(fLVContainer,pic,spic,textEntry,0,kLVSmallIcons);
2590  entry->SetUserData(new UInt_t(kLTDragType | kLTLeafType));
2591  entry->SetToolTipText("Double-click to draw. Drag to X, Y, Z or scan box.");
2592  fLVContainer->AddThisItem(entry);
2593  entry->MapWindow();
2594  entry->SetAlias(textEntry->GetString());
2595  }
2596  }
2597  }
2598  }
2599 
2600  TObjArray *branches = branch->GetListOfBranches();
2601  TBranch *branchDaughter = 0;
2602 
2603  // loop all sub-branches
2604  for (ind=0; ind<branches->GetEntries(); ind++) {
2605  branchDaughter = (TBranch *)branches->UncheckedAt(ind);
2606  // map also all sub-branches
2607  MapBranch(branchDaughter, "", branchItem, listIt);
2608  }
2609 }
2610 
2611 ////////////////////////////////////////////////////////////////////////////////
2612 /// Create new expression
2613 
2614 void TTreeViewer::NewExpression()
2615 {
2616  fLVContainer->RemoveNonStatic();
2617  const TGPicture *pic = gClient->GetPicture("expression_t.xpm");
2618  const TGPicture *spic = gClient->GetPicture("expression_t.xpm");
2619 
2620  TTVLVEntry *entry = new TTVLVEntry(fLVContainer,pic,spic,
2621  new TGString(),0,kLVSmallIcons);
2622  entry->SetUserData(new ULong_t(kLTExpressionType | kLTDragType));
2623  fLVContainer->AddThisItem(entry);
2624  entry->MapWindow();
2625  entry->Empty();
2626  if (fMappedTree) MapTree(fTree);
2627  if (fMappedBranch) MapBranch(fMappedBranch);
2628  fListView->Layout();
2629  fNexpressions++;
2630 }
2631 
2632 ////////////////////////////////////////////////////////////////////////////////
2633 /// Find parent tree of a clicked item.
2634 
2635 void TTreeViewer::SetParentTree(TGListTreeItem *item)
2636 {
2637  if (!item) return;
2638  ULong_t *itemType = (ULong_t *)item->GetUserData();
2639  if (!itemType) return;
2640  TGListTreeItem *parent = 0;
2641  Int_t index;
2642  if (!(*itemType & kLTTreeType)) {
2643  parent = item->GetParent();
2644  SetParentTree(parent);
2645  } else {
2646  index = (Int_t)(*itemType >> 8);
2647  SwitchTree(index);
2648  }
2649 }
2650 
2651 ////////////////////////////////////////////////////////////////////////////////
2652 /// Send a message on the status bar.
2653 
2654 void TTreeViewer::Message(const char* msg)
2655 {
2656  fStatusBar->SetText(msg);
2657 }
2658 
2659 ////////////////////////////////////////////////////////////////////////////////
2660 /// Put error/warning into TMsgBox and also forward to console.
2661 
2662 void TTreeViewer::DoError(int level, const char *location, const char *fmt, va_list va) const
2663 {
2664  TObject::DoError(level, location, fmt, va);
2665 
2666  // in case level will abort we will not come here...
2667 
2668  static const int buf_size = 2048;
2669  char buf[buf_size], *bp;
2670 
2671  int n = vsnprintf(buf, buf_size, fmt, va);
2672  // old vsnprintf's return -1 if string is truncated new ones return
2673  // total number of characters that would have been written
2674  if (n == -1 || n >= buf_size) {
2675  TObject::Warning("DoError", "Error message string truncated...");
2676  }
2677  if (level >= kSysError && level < kFatal)
2678  bp = Form("%s (%s)", buf, gSystem->GetError());
2679  else
2680  bp = buf;
2681 
2682  const char *title = "";
2683  if (level == kInfo)
2684  title = "Info";
2685  if (level == kWarning)
2686  title = "Warning";
2687  if (level == kError)
2688  title = "Error";
2689  if (level == kSysError)
2690  title = "System Error";
2691 
2692  new TGMsgBox(fClient->GetRoot(), this, title, bp, kMBIconExclamation);
2693 }
2694 
2695 ////////////////////////////////////////////////////////////////////////////////
2696 /// Print the number of selected entries on status-bar.
2697 
2698 void TTreeViewer::PrintEntries()
2699 {
2700  if (!fTree) return;
2701  char * msg = new char[100];
2702  snprintf(msg,100, "First entry : %lld Last entry : %lld",
2703  (Long64_t)fSlider->GetMinPosition(), (Long64_t)fSlider->GetMaxPosition());
2704  Message(msg);
2705  delete[] msg;
2706 }
2707 
2708 ////////////////////////////////////////////////////////////////////////////////
2709 /// Save current session as a C++ macro file.
2710 
2711 void TTreeViewer::SaveSource(const char* filename, Option_t *)
2712 {
2713  if (!fTree) return;
2714  char quote = '"';
2715  std::ofstream out;
2716  Int_t lenfile = strlen(filename);
2717  char * fname;
2718  if (!lenfile) {
2719  fname = (char*)fSourceFile;
2720  lenfile = strlen(fname);
2721  } else {
2722  fname = (char*)filename;
2723  fSourceFile = filename;
2724  }
2725  // if filename is given, open this file, otherwise create a file
2726  // with a name : treeviewer.C
2727  if (lenfile) {
2728  out.open(fname, std::ios::out);
2729  } else {
2730  fname = new char[13];
2731  strlcpy(fname, "treeviewer.C",13);
2732  out.open(fname, std::ios::out);
2733  }
2734  if (!out.good ()) {
2735  printf("SaveSource cannot open file : %s\n", fname);
2736  fSourceFile = "treeviewer.C";
2737  if (!lenfile) delete [] fname;
2738  return;
2739  }
2740  // Write macro header and date/time stamp
2741  TDatime t;
2742  TString sname(fname);
2743  sname = sname.ReplaceAll(".C", "");
2744  out <<"void open_session(void *p = 0);"<<std::endl<<std::endl;
2745  out <<"void "<<sname.Data()<<"() {"<<std::endl;
2746  out <<"//=========Macro generated by ROOT version"<<gROOT->GetVersion()<<std::endl;
2747  out <<"//=========for tree "<<quote<<fTree->GetName()<<quote<<" ("<<t.AsString()<<")"<<std::endl;
2748  out <<"//===This macro can be opened from a TreeViewer session after loading"<<std::endl;
2749  out <<"//===the corresponding tree, or by running root with the macro name argument"<<std::endl<<std::endl;
2750  out <<" open_session();"<<std::endl;
2751  out <<"}"<<std::endl<<std::endl;
2752  out <<"void open_session(void *p = 0) {"<<std::endl;
2753  out <<" gSystem->Load("<<quote<<"libTreeViewer"<<quote<<");"<<std::endl;
2754  out <<" TTreeViewer *treeview = (TTreeViewer *) p;"<<std::endl;
2755  out <<" if (!treeview) treeview = new TTreeViewer();"<<std::endl;
2756  out <<" TTree *tv_tree = (TTree*)gROOT->FindObject("<<quote<<fTree->GetName()<<quote<<");"<<std::endl;
2757  out <<" TFile *tv_file = (TFile*)gROOT->GetListOfFiles()->FindObject("<<quote<<fFilename<<quote<<");"<<std::endl;
2758  out <<" if (!tv_tree) {"<<std::endl;
2759  out <<" if (!tv_file) tv_file = new TFile("<<quote<<fFilename<<quote<<");"<<std::endl;
2760  out <<" if (tv_file) tv_tree = (TTree*)tv_file->Get("<<quote<<fTree->GetName()<<quote<<");"<<std::endl;
2761  out <<" if(!tv_tree) {"<<std::endl;
2762  out <<" printf(\"Tree %s not found\", "<<quote<<fTree->GetName()<<quote<<");"<<std::endl;
2763  out <<" return;"<<std::endl;
2764  out <<" }"<<std::endl;
2765  out <<" }"<<std::endl<<std::endl;
2766  out <<" treeview->SetTreeName("<<quote<<fTree->GetName()<<quote<<");"<<std::endl;
2767  out <<" treeview->SetNexpressions("<<fNexpressions<<");"<<std::endl;
2768  // get expressions
2769  TTVLVEntry *item;
2770  out <<"// Set expressions on axis and cut"<<std::endl;
2771  out <<" TTVLVEntry *item;"<<std::endl;
2772  for (Int_t i=0; i<4; i++) {
2773  switch (i) {
2774  case 0:
2775  out <<"// X expression"<<std::endl;
2776  break;
2777  case 1:
2778  out <<"// Y expression"<<std::endl;
2779  break;
2780  case 2:
2781  out <<"// Z expression"<<std::endl;
2782  break;
2783  case 3:
2784  out <<"// Cut expression"<<std::endl;
2785  break;
2786  default:
2787  break;
2788  }
2789  item = ExpressionItem(i);
2790  out <<" item = treeview->ExpressionItem("<<i<<");"<<std::endl;
2791  out <<" item->SetExpression("<<quote<<item->GetTrueName()<<quote
2792  <<", "<<quote<<item->GetAlias()<<quote<<");"<<std::endl;
2793  }
2794  out <<"// Scan list"<<std::endl;
2795  item = ExpressionItem(4);
2796  out <<" item = treeview->ExpressionItem(4);"<<std::endl;
2797  out <<" item->SetExpression("<<quote<<item->GetTrueName()<<quote
2798  <<", "<<quote<<"Scan box"<<quote<<");"<<std::endl;
2799  out <<"// User defined expressions"<<std::endl;
2800  TString itemType;
2801  for (Int_t crt=5; crt<fNexpressions+5; crt++) {
2802  item = ExpressionItem(crt);
2803  if (item->IsCut())
2804  itemType = "kTRUE";
2805  else
2806  itemType = "kFALSE";
2807  out <<" item = treeview->ExpressionItem("<<crt<<");"<<std::endl;
2808  out <<" item->SetExpression("<<quote<<item->GetTrueName()<<quote
2809  <<", "<<quote<<item->GetAlias()<<quote<<", "<<itemType.Data()<<");"<<std::endl;
2810  }
2811  fSession->SaveSource(out);
2812  out <<"}"<<std::endl;
2813  out.close();
2814  printf("C++ Macro file: %s has been generated\n", fname);
2815  if (!lenfile) delete [] fname;
2816 }
2817 
2818 ////////////////////////////////////////////////////////////////////////////////
2819 /// Makes current the tree at a given index in the list.
2820 
2821 Bool_t TTreeViewer::SwitchTree(Int_t index)
2822 {
2823  TTree *tree = (TTree *) fTreeList->At(index);
2824  if (!tree) {
2825  Warning("SwitchTree", "No tree found.");
2826  return kFALSE;
2827  }
2828  if ((tree == fTree) && (tree == fMappedTree)) return kFALSE; // nothing to switch
2829  std::string command;
2830  if (tree != fTree) {
2831  command = "tv__tree = (TTree *) tv__tree_list->At";
2832  command += Form("(%i)",index);
2833  ExecuteCommand(command.c_str());
2834  }
2835 
2836  fTree = tree;
2837  fSlider->SetRange(0,fTree->GetEntries()-1);
2838  fSlider->SetPosition(0,fTree->GetEntries()-1);
2839  command = "Current Tree : ";
2840  command += fTree->GetName();
2841  fLbl2->SetText(new TGString(command.c_str()));
2842  fTreeHdr->Layout();
2843  MapSubwindows();
2844  Resize(GetDefaultSize());
2845  MapWindow();
2846  ///Resize(); //ia
2847  PrintEntries();
2848  return kTRUE;
2849 }
2850 
2851 ////////////////////////////////////////////////////////////////////////////////
2852 /// Set record name
2853 
2854 void TTreeViewer::SetRecordName(const char *name)
2855 {
2856  fSession->SetRecordName(name);
2857 }
2858 
2859 ////////////////////////////////////////////////////////////////////////////////
2860 /// Set current record
2861 
2862 void TTreeViewer::SetCurrentRecord(Long64_t entry)
2863 {
2864  fCombo->Select(entry);
2865 }
2866 
2867 ////////////////////////////////////////////////////////////////////////////////
2868 /// Set title of Histogram
2869 
2870 void TTreeViewer::SetHistogramTitle(const char *title)
2871 {
2872  if (!gPad) return;
2873  TH1 *hist = (TH1*)gPad->GetListOfPrimitives()->FindObject(fBarHist->GetText());
2874  if (hist) {
2875  hist->SetTitle(title);
2876  gPad->Update();
2877  }
2878 }
2879 
2880 ////////////////////////////////////////////////////////////////////////////////
2881 /// user defined command for current record
2882 
2883 void TTreeViewer::SetUserCode(const char *code, Bool_t autoexec)
2884 {
2885  TTVRecord *rec = fSession->GetCurrent();
2886  if (rec) rec->SetUserCode(code, autoexec);
2887 }
2888 
2889 ////////////////////////////////////////////////////////////////////////////////
2890 /// Updates combo box to current session entries.
2891 
2892 void TTreeViewer::UpdateCombo()
2893 {
2894  TTVRecord *record;
2895  fCombo->RemoveEntries(0, 1000);
2896  for (Long64_t entry=0; entry<fSession->GetEntries(); entry++) {
2897  if ((record = fSession->GetRecord(entry)))
2898  fCombo->AddEntry(record->GetName(), entry);
2899  }
2900 }
2901 
2902 ////////////////////////////////////////////////////////////////////////////////
2903 /// Updates current record to new X, Y, Z items.
2904 
2905 void TTreeViewer::UpdateRecord(const char *name)
2906 {
2907  fSession->UpdateRecord(name);
2908 }
2909 
2910 ////////////////////////////////////////////////////////////////////////////////
2911 /// This slot is called when button REFR is clicked
2912 
2913 void TTreeViewer::DoRefresh()
2914 {
2915  fTree->Refresh();
2916  Float_t min = fSlider->GetMinPosition();
2917  Float_t max = (Float_t)fTree->GetEntries()-1;
2918  fSlider->SetRange(min,max);
2919  fSlider->SetPosition(min,max);
2920  ExecuteDraw();
2921 }