Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TRootBrowserLite.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Fons Rademakers 27/02/98
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 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TRootBrowserLite //
15 // //
16 // This class creates a ROOT object browser (looking like Windows //
17 // Explorer). The widgets used are the new native ROOT GUI widgets. //
18 // //
19 //////////////////////////////////////////////////////////////////////////
20 
21 #include "RConfigure.h"
22 
23 #include "TRootBrowserLite.h"
24 #include "TRootApplication.h"
25 #include "TGCanvas.h"
26 #include "TGMenu.h"
27 #include "TGFileDialog.h"
28 #include "TGStatusBar.h"
29 #include "TGFSComboBox.h"
30 #include "TGLabel.h"
31 #include "TGButton.h"
32 #include "TGListView.h"
33 #include "TGListTree.h"
34 #include "TGToolBar.h"
35 #include "TGSplitter.h"
36 #include "TG3DLine.h"
37 #include "TGFSContainer.h"
38 #include "TGMimeTypes.h"
39 #include "TRootHelpDialog.h"
40 #include "TGTextEntry.h"
41 #include "TGTextEdit.h"
42 #include "TGTextEditDialogs.h"
43 
44 #include "TROOT.h"
45 #include "TEnv.h"
46 #include "TBrowser.h"
47 #include "TApplication.h"
48 #include "TFile.h"
49 #include "TKey.h"
50 #include "TKeyMapFile.h"
51 #include "TClass.h"
52 #include "TContextMenu.h"
53 #include "TSystem.h"
54 #include "TSystemDirectory.h"
55 #include "TSystemFile.h"
56 #include "TRemoteObject.h"
57 #include "TInterpreter.h"
58 #include "TGuiBuilder.h"
59 #include "TImage.h"
60 #include "TVirtualPad.h"
61 #include "KeySymbols.h"
62 #include "THashTable.h"
63 #include "TColor.h"
64 #include "TObjString.h"
65 #include "TGDNDManager.h"
66 #include "TBufferFile.h"
67 #include "TFolder.h"
68 #include "Getline.h"
69 
70 #include "HelpText.h"
71 
72 #ifdef WIN32
73 #include "TWin32SplashThread.h"
74 #endif
75 
76 // Browser menu command ids
77 enum ERootBrowserCommands {
78  kFileNewBrowserLite,
79  kFileNewBrowser,
80  kFileNewCanvas,
81  kFileNewBuilder,
82  kFileOpen,
83  kFileSave,
84  kFileSaveAs,
85  kFilePrint,
86  kFileCloseBrowser,
87  kFileQuit,
88 
89  kViewToolBar,
90  kViewStatusBar,
91  kViewLargeIcons,
92  kViewSmallIcons,
93  kViewList,
94  kViewDetails,
95  kViewLineUp,
96  kViewHidden,
97  kViewRefresh,
98  kViewFind,
99  kViewExec,
100  kViewInterrupt,
101  kViewSave,
102 
103  kViewArrangeByName, // Arrange submenu
104  kViewArrangeByType,
105  kViewArrangeBySize,
106  kViewArrangeByDate,
107  kViewArrangeAuto,
108  kViewGroupLV,
109 
110  kHistoryBack,
111  kHistoryForw,
112 
113  kOptionShowCycles,
114  kOptionAutoThumbnail,
115 
116  kOneLevelUp, // One level up toolbar button
117  kFSComboBox, // File system combobox in toolbar
118 
119  kHelpAbout,
120  kHelpOnBrowser,
121  kHelpOnCanvas,
122  kHelpOnMenus,
123  kHelpOnGraphicsEd,
124  kHelpOnObjects,
125  kHelpOnPS,
126  kHelpOnRemote
127 };
128 
129 
130 //----- Struct for default icons
131 
132 struct DefaultIcon_t {
133  const char *fPicnamePrefix;
134  const TGPicture *fIcon[2];
135 };
136 
137 #if 0
138 static DefaultIcon_t gDefaultIcon[] = {
139  { "folder", { 0, 0 } },
140  { "app", { 0, 0 } },
141  { "doc", { 0, 0 } },
142  { "slink", { 0, 0 } },
143  { "histo", { 0, 0 } },
144  { "object", { 0, 0 } }
145 };
146 #endif
147 
148 
149 //----- Toolbar stuff...
150 
151 static ToolBarData_t gToolBarData[] = {
152  { "tb_uplevel.xpm", "Up One Level", kFALSE, kOneLevelUp, 0 },
153  { "", "", kFALSE, -1, 0 },
154  { "tb_bigicons.xpm", "Large Icons", kTRUE, kViewLargeIcons, 0 },
155  { "tb_smicons.xpm", "Small Icons", kTRUE, kViewSmallIcons, 0 },
156  { "tb_list.xpm", "List", kTRUE, kViewList, 0 },
157  { "tb_details.xpm", "Details", kTRUE, kViewDetails, 0 },
158  { "", "", kFALSE, -1, 0 },
159  { "tb_back.xpm", "Back", kFALSE, kHistoryBack, 0 },
160  { "tb_forw.xpm", "Forward", kFALSE, kHistoryForw, 0 },
161  { "tb_refresh.xpm", "Refresh (F5)", kFALSE, kViewRefresh, 0 },
162  { "", "", kFALSE, -1, 0 },
163  { "tb_find.xpm", "Find (Ctrl-F)", kFALSE, kViewFind, 0 },
164  { "", "", kFALSE, -1, 0 },
165  { "macro_t.xpm", "Execute Macro", kFALSE, kViewExec, 0 },
166  { "interrupt.xpm", "Interrupt Macro",kFALSE, kViewInterrupt, 0 },
167  { "filesaveas.xpm", "Save Macro", kFALSE, kViewSave, 0 },
168  { 0, 0, kFALSE, 0, 0 }
169 };
170 
171 
172 //----- TGFileDialog file types
173 
174 static const char *gOpenTypes[] = { "ROOT files", "*.root",
175  "All files", "*",
176  0, 0 };
177 
178 ////////////////////////////////////////////////////////////////////////////////////
179 class TRootBrowserHistoryCursor : public TObject {
180 public:
181  TGListTreeItem *fItem;
182 
183  TRootBrowserHistoryCursor(TGListTreeItem *item) : fItem(item) {}
184  void Print(Option_t *) const { if (fItem) printf("%s\n", fItem->GetText()); }
185 };
186 
187 
188 ////////////////////////////////////////////////////////////////////////////////////
189 class TRootBrowserHistory : public TList {
190 public:
191  void RecursiveRemove(TObject *obj) {
192  TRootBrowserHistoryCursor *cur;
193  TIter next(this);
194 
195  while ((cur = (TRootBrowserHistoryCursor*)next())) {
196  if (cur->fItem->GetUserData() == obj) {
197  Remove(cur);
198  delete cur;
199  }
200  }
201  }
202 
203  void DeleteItem(TGListTreeItem *item) {
204  TRootBrowserHistoryCursor *cur;
205  TIter next(this);
206 
207  while ((cur = (TRootBrowserHistoryCursor*)next())) {
208  if (cur->fItem == item) {
209  Remove(cur);
210  delete cur;
211  }
212  }
213  }
214 };
215 
216 
217 ////////////////////////////////////////////////////////////////////////////////////
218 class TRootBrowserCursorSwitcher {
219 private:
220  TGWindow *fW1;
221  TGWindow *fW2;
222 public:
223  TRootBrowserCursorSwitcher(TGWindow *w1, TGWindow *w2) : fW1(w1), fW2(w2) {
224  if (w1) gVirtualX->SetCursor(w1->GetId(), gVirtualX->CreateCursor(kWatch));
225  if (w2) gVirtualX->SetCursor(w2->GetId(), gVirtualX->CreateCursor(kWatch));
226  }
227  ~TRootBrowserCursorSwitcher() {
228  if (fW1) gVirtualX->SetCursor(fW1->GetId(), gVirtualX->CreateCursor(kPointer));
229  if (fW2) gVirtualX->SetCursor(fW2->GetId(), gVirtualX->CreateCursor(kPointer));
230  }
231 };
232 
233 ////////////////////////////////////////////////////////////////////////////////////
234 class TIconBoxThumb : public TObject {
235 public:
236  TString fName;
237  const TGPicture *fSmall;
238  const TGPicture *fLarge;
239 
240  TIconBoxThumb(const char *name, const TGPicture *spic, const TGPicture *pic) {
241  fName = name;
242  fSmall = spic;
243  fLarge = pic;
244  }
245  ULong_t Hash() const { return fName.Hash(); }
246  const char *GetName() const { return fName.Data(); }
247 };
248 
249 
250 
251 //----- Special ROOT object item (this are items in the icon box, see
252 //----- TRootIconBox)
253 ////////////////////////////////////////////////////////////////////////////////////
254 class TRootObjItem : public TGFileItem {
255 public:
256  TRootObjItem(const TGWindow *p, const TGPicture *bpic,
257  const TGPicture *spic, TGString *name,
258  TObject *obj, TClass *cl, EListViewMode viewMode = kLVSmallIcons);
259 
260  virtual TDNDData *GetDNDData(Atom_t) {
261  TObject *object = 0;
262  if (fObj->IsA() == TKey::Class())
263  object = ((TKey *)fObj)->ReadObj();
264  else
265  object = fObj;
266  if (object) {
267  if (!fBuf) fBuf = new TBufferFile(TBuffer::kWrite);
268  fBuf->WriteObject(object);
269  fDNDData.fData = fBuf->Buffer();
270  fDNDData.fDataLength = fBuf->Length();
271  }
272  fDNDData.fDataType = gVirtualX->InternAtom("application/root", kFALSE);
273  return &fDNDData;
274  }
275 
276  virtual Bool_t HandleDNDFinished() {
277  if (GetParent())
278  return ((TGFrame *)GetParent())->HandleDNDFinished();
279  return kFALSE;
280  }
281 
282 protected:
283  TObject *fObj;
284  TDNDData fDNDData;
285 };
286 
287 ////////////////////////////////////////////////////////////////////////////////
288 /// Create an icon box item.
289 
290 TRootObjItem::TRootObjItem(const TGWindow *p, const TGPicture *bpic,
291  const TGPicture *spic, TGString *name,
292  TObject *obj, TClass *, EListViewMode viewMode) :
293  TGFileItem(p, bpic, 0, spic, 0, name, 0, 0, 0, 0, 0, viewMode)
294 {
295  fObj = obj;
296  fDNDData.fData = 0;
297  fDNDData.fDataLength = 0;
298 
299  if (fSubnames) {
300  for (Int_t i = 0; fSubnames[i] != 0; ++i) delete fSubnames[i];
301  }
302  delete [] fSubnames;
303  fSubnames = new TGString* [2];
304 
305  fSubnames[0] = new TGString(obj->GetTitle());
306 
307  fSubnames[1] = 0;
308 
309  if (obj->IsA()->HasDefaultConstructor()) {
310  SetDNDSource(kTRUE);
311  }
312  if ((obj->IsA() == TFolder::Class()) ||
313  (obj->IsA() == TClass::Class())) {
314  SetDNDSource(kFALSE);
315  }
316 
317  int i;
318  for (i = 0; fSubnames[i] != 0; ++i)
319  ;
320  fCtw = new int[i];
321  for (i = 0; fSubnames[i] != 0; ++i)
322  fCtw[i] = gVirtualX->TextWidth(fFontStruct, fSubnames[i]->GetString(),
323  fSubnames[i]->GetLength());
324 }
325 
326 class TRootIconBox;
327 ////////////////////////////////////////////////////////////////////////////////////
328 class TRootIconList : public TList {
329 
330 private:
331  TRootIconBox *fIconBox; // iconbox to which list belongs
332  const TGPicture *fPic; // list view icon
333 
334 public:
335  TRootIconList(TRootIconBox* box = 0);
336  virtual ~TRootIconList();
337  void UpdateName();
338  const char *GetTitle() const { return "ListView Container"; }
339  Bool_t IsFolder() const { return kFALSE; }
340  void Browse(TBrowser *b);
341  const TGPicture *GetPicture() const { return fPic; }
342 };
343 
344 ////////////////////////////////////////////////////////////////////////////////
345 /// constructor
346 
347 TRootIconList::TRootIconList(TRootIconBox* box)
348 {
349  fPic = gClient->GetPicture("listview.xpm");
350  fIconBox = box;
351  fName = "empty";
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// destructor
356 
357 TRootIconList::~TRootIconList()
358 {
359  gClient->FreePicture(fPic);
360 }
361 
362 ////////////////////////////////////////////////////////////////////////////////
363 /// composite name
364 
365 void TRootIconList::UpdateName()
366 {
367  if (!First()) return;
368 
369  if (fSize==1) {
370  fName = First()->GetName();
371  return;
372  }
373 
374  fName = First()->GetName();
375  fName += "-";
376  fName += Last()->GetName();
377 }
378 
379 //----- Special ROOT object container (this is the icon box on the
380 //----- right side of the browser)
381 ////////////////////////////////////////////////////////////////////////////////////
382 class TRootIconBox : public TGFileContainer {
383 friend class TRootIconList;
384 friend class TRootBrowserLite;
385 
386 private:
387  Bool_t fCheckHeaders; // if true check headers
388  TRootIconList *fCurrentList; //
389  TRootObjItem *fCurrentItem; //
390  Bool_t fGrouped; //
391  TString fCachedPicName; //
392  TList *fGarbage; // garbage for TRootIconList's
393  Int_t fGroupSize; // the total number of items when icon box switched to "global view" mode
394  TGString *fCurrentName; //
395  const TGPicture *fLargeCachedPic; //
396  const TGPicture *fSmallCachedPic; //
397  Bool_t fWasGrouped;
398  TObject *fActiveObject; //
399  Bool_t fIsEmpty;
400  THashTable *fThumbnails; // hash table with thumbnailed pictures
401  Bool_t fAutoThumbnail; //
402  TRootBrowserLite *fBrowser;
403 
404  void *FindItem(const TString& name,
405  Bool_t direction = kTRUE,
406  Bool_t caseSensitive = kTRUE,
407  Bool_t beginWith = kFALSE);
408  void RemoveGarbage();
409 
410 public:
411  TRootIconBox(TRootBrowserLite *browser, TGListView *lv,
412  UInt_t options = kSunkenFrame,
413  ULong_t back = GetDefaultFrameBackground());
414 
415  virtual ~TRootIconBox();
416 
417  void AddObjItem(const char *name, TObject *obj, TClass *cl);
418  void GetObjPictures(const TGPicture **pic, const TGPicture **spic,
419  TObject *obj, const char *name);
420  void SetObjHeaders();
421  void Refresh();
422  void RemoveAll();
423  void SetGroupSize(Int_t siz) { fGroupSize = siz; }
424  Int_t GetGroupSize() const { return fGroupSize; }
425  TGFrameElement *FindFrame(Int_t x, Int_t y, Bool_t exclude=kTRUE) { return TGContainer::FindFrame(x,y,exclude); }
426  Bool_t WasGrouped() const { return fWasGrouped; }
427 };
428 
429 ////////////////////////////////////////////////////////////////////////////////
430 /// Create iconbox containing ROOT objects in browser.
431 
432 TRootIconBox::TRootIconBox(TRootBrowserLite *browser, TGListView *lv, UInt_t options,
433  ULong_t back) : TGFileContainer(lv, options, back)
434 {
435  fListView = lv;
436  fBrowser = browser;
437 
438  fCheckHeaders = kTRUE;
439  fTotal = 0;
440  fGarbage = new TList();
441  fCurrentList = 0;
442  fCurrentItem = 0;
443  fGrouped = kFALSE;
444  fGroupSize = 1000;
445  fCurrentName = 0;
446  fWasGrouped = kFALSE;
447  fActiveObject = 0;
448  fIsEmpty = kTRUE;
449  fLargeCachedPic = 0;
450  fSmallCachedPic = 0;
451 
452  // Don't use timer HERE (timer is set in TBrowser).
453  StopRefreshTimer();
454  fRefresh = 0;
455  fThumbnails = new THashTable(50);
456  fAutoThumbnail = kTRUE;
457 }
458 
459 ////////////////////////////////////////////////////////////////////////////////
460 /// destructor
461 
462 TRootIconBox::~TRootIconBox()
463 {
464  RemoveAll();
465  RemoveGarbage();
466  delete fGarbage;
467  delete fThumbnails;
468 }
469 
470 ////////////////////////////////////////////////////////////////////////////////
471 /// Retrieve icons associated with class "name". Association is made
472 /// via the user's ~/.root.mimes file or via $ROOTSYS/etc/root.mimes.
473 
474 void TRootIconBox::GetObjPictures(const TGPicture **pic, const TGPicture **spic,
475  TObject *obj, const char *name)
476 {
477  static TImage *im = 0;
478  if (!im) {
479  im = TImage::Create();
480  }
481 
482  TString xpm_magic(name, 3);
483  Bool_t xpm = xpm_magic == "/* ";
484  const char *iconname = xpm ? obj->GetName() : name;
485 
486  if (obj->IsA()->InheritsFrom("TGeoVolume")) {
487  iconname = obj->GetIconName() ? obj->GetIconName() : obj->IsA()->GetName();
488  }
489 
490  if (fCachedPicName == iconname) {
491  *pic = fLargeCachedPic;
492  *spic = fSmallCachedPic;
493  return;
494  }
495 
496  *pic = fClient->GetMimeTypeList()->GetIcon(iconname, kFALSE);
497 
498  if (!(*pic) && xpm) {
499  if (im && im->SetImageBuffer((char**)&name, TImage::kXpm)) {
500  *pic = fClient->GetPicturePool()->GetPicture(iconname, im->GetPixmap(),
501  im->GetMask());
502  im->Scale(im->GetWidth()/2, im->GetHeight()/2);
503  *spic = fClient->GetPicturePool()->GetPicture(iconname, im->GetPixmap(),
504  im->GetMask());
505  }
506 
507  fClient->GetMimeTypeList()->AddType("[thumbnail]", iconname, iconname, iconname, "->Browse()");
508  return;
509  }
510 
511  if (*pic == 0) {
512  if (obj->IsFolder()) {
513  *pic = fFolder_s;
514  } else {
515  *pic = fDoc_s;
516  }
517  }
518  fLargeCachedPic = *pic;
519 
520  *spic = fClient->GetMimeTypeList()->GetIcon(iconname, kTRUE);
521 
522  if (*spic == 0) {
523  if (obj->IsFolder())
524  *spic = fFolder_t;
525  else
526  *spic = fDoc_t;
527  }
528  fSmallCachedPic = *spic;
529  fCachedPicName = iconname;
530 }
531 
532 ////////////////////////////////////////////////////////////////////////////////
533 /// delete all TRootIconLists from garbage
534 
535 void TRootIconBox::RemoveGarbage()
536 {
537  TIter next(fGarbage);
538  TList *li;
539 
540  while ((li=(TList *)next())) {
541  li->Clear("nodelete");
542  }
543  fGarbage->Delete();
544 }
545 
546 ////////////////////////////////////////////////////////////////////////////////
547 /// Add object to iconbox. Class is used to get the associated icons
548 /// via the mime file (see GetObjPictures()).
549 
550 void TRootIconBox::AddObjItem(const char *name, TObject *obj, TClass *cl)
551 {
552  if (!cl) return;
553 
554  Bool_t isSystemFile = kFALSE;
555  TGFileItem *fi;
556  fWasGrouped = kFALSE;
557  const TGPicture *pic = 0;
558  const TGPicture *spic = 0;
559 
560  if (obj->InheritsFrom("TRemoteObject")) {
561  // check if the real remote object is a system file or directory
562  TRemoteObject *robj = (TRemoteObject *)obj;
563  if ((TString(robj->GetClassName()) == "TSystemFile") ||
564  (TString(robj->GetClassName()) == "TSystemDirectory"))
565  isSystemFile = kTRUE;
566  }
567 
568  if (isSystemFile || obj->IsA() == TSystemFile::Class() ||
569  obj->IsA() == TSystemDirectory::Class()) {
570  if (fCheckHeaders) {
571  if (strcmp(fListView->GetHeader(1), "Attributes")) {
572  fListView->SetDefaultHeaders();
573  TGTextButton** buttons = fListView->GetHeaderButtons();
574  if (buttons) {
575  buttons[0]->Connect("Clicked()", "TRootBrowserLite", fBrowser,
576  TString::Format("SetSortMode(=%d)", kViewArrangeByName));
577  buttons[1]->Connect("Clicked()", "TRootBrowserLite", fBrowser,
578  TString::Format("SetSortMode(=%d)", kViewArrangeByType));
579  buttons[2]->Connect("Clicked()", "TRootBrowserLite", fBrowser,
580  TString::Format("SetSortMode(=%d)", kViewArrangeBySize));
581  buttons[5]->Connect("Clicked()", "TRootBrowserLite", fBrowser,
582  TString::Format("SetSortMode(=%d)", kViewArrangeByDate));
583  }
584  }
585  fCheckHeaders = kFALSE;
586  }
587 
588  TIconBoxThumb *thumb = 0;
589  char *thumbname = gSystem->ConcatFileName(gSystem->WorkingDirectory(), name);
590  thumb = (TIconBoxThumb *)fThumbnails->FindObject(gSystem->IsAbsoluteFileName(name) ? name :
591  thumbname);
592  delete []thumbname;
593 
594  if (thumb) {
595  spic = thumb->fSmall;
596  pic = thumb->fLarge;
597  }
598 
599  if (obj->InheritsFrom("TRemoteObject"))
600  // special case for remote object
601  fi = AddRemoteFile(obj, spic, pic);
602  else
603  fi = AddFile(name, spic, pic);
604  if (fi) {
605  fi->SetUserData(obj);
606  if (obj->IsA() == TSystemFile::Class()) {
607  TString str;
608  TDNDData data;
609  str = TString::Format("file://%s/%s\r\n",
610  gSystem->UnixPathName(obj->GetTitle()),
611  obj->GetName());
612  data.fData = (void *)str.Data();
613  data.fDataLength = str.Length()+1;
614  data.fDataType = gVirtualX->InternAtom("text/uri-list", kFALSE);
615  fi->SetDNDData(&data);
616  fi->SetDNDSource(kTRUE);
617  }
618  }
619 
620  fIsEmpty = kFALSE;
621  return;
622  }
623 
624  if (!fCurrentList) {
625  fCurrentList = new TRootIconList(this);
626  fGarbage->Add(fCurrentList);
627  }
628 
629  fCurrentList->Add(obj);
630  fCurrentList->UpdateName();
631  fIsEmpty = kFALSE;
632 
633  TGFrameElement *el;
634  TIter next(fList);
635  while ((el = (TGFrameElement *) next())) {
636  TGLVEntry *f = (TGLVEntry *) el->fFrame;
637  if (f->GetUserData() == obj) {
638  return;
639  }
640  }
641 
642  if (fGrouped && fCurrentItem && (fCurrentList->GetSize()>1)) {
643  fCurrentName->SetString(fCurrentList->GetName());
644  }
645 
646  EListViewMode view = fListView->GetViewMode();
647 
648  if ((fCurrentList->GetSize() < fGroupSize) && !fGrouped) {
649  GetObjPictures(&pic, &spic, obj, obj->GetIconName() ?
650  obj->GetIconName() : cl->GetName());
651 
652  if (fCheckHeaders) {
653  if (strcmp(fListView->GetHeader(1), "Title")) {
654  SetObjHeaders();
655  }
656  fCheckHeaders = kFALSE;
657  }
658 
659  fi = new TRootObjItem(this, pic, spic, new TGString(name), obj, cl, view);
660 
661  fi->SetUserData(obj);
662  AddItem(fi);
663  return;
664  }
665 
666  if (fGrouped && (fCurrentList->GetSize()==1)) {
667  fCurrentName = new TGString(fCurrentList->GetName());
668  fCurrentItem = new TRootObjItem(this, fCurrentList->GetPicture(), fCurrentList->GetPicture(),
669  fCurrentName,fCurrentList, TList::Class(), view);
670  fCurrentItem->SetUserData(fCurrentList);
671  AddItem(fCurrentItem);
672  fTotal = fList->GetSize();
673  return;
674  }
675 
676  if ((fCurrentList->GetSize()==fGroupSize) && !fGrouped) {
677  fGrouped = kTRUE;
678 
679  // clear fList
680  TGFrameElement *el2;
681  TIter nextl(fList);
682 
683  while ((el2 = (TGFrameElement *) nextl())) {
684  el2->fFrame->DestroyWindow();
685  delete el2->fFrame;
686  fList->Remove(el2);
687  delete el2;
688  }
689 
690  fCurrentName = new TGString(fCurrentList->GetName());
691  fi = new TRootObjItem(this, fCurrentList->GetPicture(), fCurrentList->GetPicture(),
692  fCurrentName, fCurrentList, TList::Class(), view);
693  fi->SetUserData(fCurrentList);
694  AddItem(fi);
695 
696  fCurrentList = new TRootIconList(this);
697  fGarbage->Add(fCurrentList);
698  fTotal = 1;
699  return;
700  }
701 
702  if ((fCurrentList->GetSize()==fGroupSize) && fGrouped) {
703  fCurrentList = new TRootIconList(this);
704  fGarbage->Add(fCurrentList);
705  return;
706  }
707 }
708 
709 ////////////////////////////////////////////////////////////////////////////////
710 /// browse icon list
711 
712 void TRootIconList::Browse(TBrowser *)
713 {
714  if (!fIconBox) return;
715 
716  TObject *obj;
717  TGFileItem *fi;
718  const TGPicture *pic = 0;
719  const TGPicture *spic = 0;
720  TClass *cl;
721  TString name;
722  TKey *key = 0;
723 
724  fIconBox->RemoveAll();
725  TObjLink *lnk = FirstLink();
726 
727  while (lnk) {
728  obj = lnk->GetObject();
729  lnk = lnk->Next();
730 
731  if (obj->IsA() == TKey::Class()) {
732  cl = TClass::GetClass(((TKey *)obj)->GetClassName());
733  key = (TKey *)obj;
734  } else if (obj->IsA() == TKeyMapFile::Class()) {
735  cl = TClass::GetClass(((TKeyMapFile *)obj)->GetTitle());
736  } else if (obj->InheritsFrom("TRemoteObject")) {
737  // special case for remote object: get real object class
738  TRemoteObject *robj = (TRemoteObject *)obj;
739  cl = TClass::GetClass(robj->GetClassName());
740  } else {
741  cl = obj->IsA();
742  }
743 
744  name = obj->GetName();
745 
746  if (key && obj->IsA() == TKey::Class()) {
747  name += ";";
748  name += key->GetCycle();
749  }
750 
751  fIconBox->GetObjPictures(&pic, &spic, obj, obj->GetIconName() ?
752  obj->GetIconName() : cl->GetName());
753 
754  fi = new TRootObjItem((const TGWindow*)fIconBox, pic, spic, new TGString(name.Data()),
755  obj, cl, (EListViewMode)fIconBox->GetViewMode());
756  fi->SetUserData(obj);
757  fIconBox->AddItem(fi);
758  fIconBox->fTotal++;
759 
760  if (obj==fIconBox->fActiveObject) {
761  fIconBox->ActivateItem((TGFrameElement*)fIconBox->fList->Last());
762  }
763  }
764 
765  fIconBox->fGarbage->Remove(this);
766  fIconBox->RemoveGarbage();
767  fIconBox->fGarbage->Add(this); // delete this later
768 
769  fIconBox->Refresh();
770  fIconBox->AdjustPosition();
771 
772  fIconBox->fWasGrouped = kTRUE;
773 }
774 
775 ////////////////////////////////////////////////////////////////////////////////
776 /// Find a frame which assosiated object has a name containing a "name" string.
777 
778 void *TRootIconBox::FindItem(const TString& name, Bool_t direction,
779  Bool_t caseSensitive,Bool_t beginWith)
780 {
781  if (!fGrouped) {
782  return TGContainer::FindItem(name, direction, caseSensitive, beginWith);
783  }
784 
785  if (name.IsNull()) return 0;
786  int idx = kNPOS;
787 
788  TGFrameElement* el = 0;
789  TString str;
790  TString::ECaseCompare cmp = caseSensitive ? TString::kExact : TString::kIgnoreCase;
791 
792  fLastDir = direction;
793  fLastCase = caseSensitive;
794  fLastName = name;
795 
796  if (fLastActiveEl) {
797  el = fLastActiveEl;
798 
799  if (direction) {
800  el = (TGFrameElement *)fList->After(el);
801  } else {
802  el = (TGFrameElement *)fList->Before(el);
803  }
804  } else {
805  if (direction) el = (TGFrameElement *)fList->First();
806  else el = (TGFrameElement *)fList->Last();
807  }
808 
809  TGLVEntry* lv = 0;
810  TObject* obj = 0;
811  TList* li = 0;
812 
813  while (el) {
814  lv = (TGLVEntry*)el->fFrame;
815  li = (TList*)lv->GetUserData();
816 
817  TIter next(li);
818 
819  while ((obj=next())) {
820  str = obj->GetName();
821  idx = str.Index(name,0,cmp);
822 
823  if (idx!=kNPOS) {
824  if (beginWith) {
825  if (idx==0) {
826  fActiveObject = obj;
827  return el;
828  }
829  } else {
830  fActiveObject = obj;
831  return el;
832  }
833  }
834  }
835  if (direction) {
836  el = (TGFrameElement *)fList->After(el);
837  } else {
838  el = (TGFrameElement *)fList->Before(el);
839  }
840  }
841  fActiveObject = 0;
842  return 0;
843 }
844 
845 ////////////////////////////////////////////////////////////////////////////////
846 /// Set list box headers used to display detailed object iformation.
847 /// Currently this is only "Name" and "Title".
848 
849 void TRootIconBox::SetObjHeaders()
850 {
851  fListView->SetHeaders(2);
852  fListView->SetHeader("Name", kTextLeft, kTextLeft, 0);
853  fListView->SetHeader("Title", kTextLeft, kTextLeft, 1);
854 }
855 
856 ////////////////////////////////////////////////////////////////////////////////
857 /// Sort icons, and send message to browser with number of objects
858 /// in box.
859 
860 void TRootIconBox::Refresh()
861 {
862  // This automatically calls layout
863  Sort(fSortType);
864 
865  // Make TRootBrowserLite display total objects in status bar
866  SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED), fTotal, fSelected);
867 
868  MapSubwindows();
869  fListView->AdjustHeaders();
870 }
871 
872 ////////////////////////////////////////////////////////////////////////////////
873 /// Remove all items from icon box
874 
875 void TRootIconBox::RemoveAll()
876 {
877  if (fIsEmpty) return;
878 
879  fCheckHeaders = kTRUE;
880  TGFileContainer::RemoveAll();
881  fGrouped = kFALSE;
882  fCurrentItem = 0;
883  fCurrentList = 0;
884  fIsEmpty = kTRUE;
885 }
886 
887 
888 //_____________________________________________________________________________
889 //
890 // TRootBrowserLite
891 //
892 // ROOT object browser (looking like Windows Explorer).
893 //_____________________________________________________________________________
894 
895 ClassImp(TRootBrowserLite);
896 
897 ////////////////////////////////////////////////////////////////////////////////
898 /// Create browser with a specified width and height.
899 
900 TRootBrowserLite::TRootBrowserLite(TBrowser *b, const char *name, UInt_t width, UInt_t height)
901  : TGMainFrame(gClient->GetDefaultRoot(), width, height), TBrowserImp(b)
902 {
903  CreateBrowser(name);
904 
905  Resize(width, height);
906  if (b) Show();
907 }
908 
909 ////////////////////////////////////////////////////////////////////////////////
910 /// Create browser with a specified width and height and at position x, y.
911 
912 TRootBrowserLite::TRootBrowserLite(TBrowser *b, const char *name, Int_t x, Int_t y,
913  UInt_t width, UInt_t height)
914  : TGMainFrame(gClient->GetDefaultRoot(), width, height), TBrowserImp(b)
915 {
916  CreateBrowser(name);
917 
918  MoveResize(x, y, width, height);
919  SetWMPosition(x, y);
920  if (b) Show();
921 }
922 
923 ////////////////////////////////////////////////////////////////////////////////
924 /// Browser destructor.
925 
926 TRootBrowserLite::~TRootBrowserLite()
927 {
928  if (fIconPic) gClient->FreePicture(fIconPic);
929 
930  delete fToolBarSep;
931 
932  fToolBar->Cleanup();
933  delete fToolBar;
934  delete fStatusBar;
935  delete fV1;
936  delete fV2;
937  delete fLbl1;
938  delete fLbl2;
939  delete fHf;
940  delete fTreeHdr;
941  delete fListHdr;
942  delete fIconBox;
943  delete fListView;
944  delete fLt;
945  delete fTreeView;
946 
947  delete fMenuBar;
948  delete fFileMenu;
949  delete fViewMenu;
950  delete fOptionMenu;
951  delete fHelpMenu;
952  delete fSortMenu;
953 
954  delete fMenuBarLayout;
955  delete fMenuBarItemLayout;
956  delete fMenuBarHelpLayout;
957  delete fBarLayout;
958 
959  delete fTextEdit;
960 
961  if (fWidgets) fWidgets->Delete();
962  delete fWidgets;
963 
964  fHistory->Delete();
965  delete fHistory;
966 }
967 
968 ////////////////////////////////////////////////////////////////////////////////
969 /// Create the actual browser.
970 
971 void TRootBrowserLite::CreateBrowser(const char *name)
972 {
973  fWidgets = new TList;
974  fHistory = new TRootBrowserHistory;
975  fHistoryCursor = 0;
976  fBrowseTextFile = kFALSE;
977 
978  // Create menus
979  fFileMenu = new TGPopupMenu(fClient->GetDefaultRoot());
980  fFileMenu->AddEntry("&New Browser", kFileNewBrowser);
981  fFileMenu->AddEntry("New Browser &Lite", kFileNewBrowserLite);
982  fFileMenu->AddEntry("New Canvas", kFileNewCanvas);
983  fFileMenu->AddEntry("&Gui Builder", kFileNewBuilder);
984  fFileMenu->AddEntry("&Open...", kFileOpen);
985  fFileMenu->AddSeparator();
986  fFileMenu->AddEntry("&Save", kFileSave);
987  fFileMenu->AddEntry("Save &As...", kFileSaveAs);
988  fFileMenu->AddSeparator();
989  fFileMenu->AddEntry("&Print...", kFilePrint);
990  fFileMenu->AddSeparator();
991  fFileMenu->AddEntry("&Close Browser", kFileCloseBrowser);
992  fFileMenu->AddSeparator();
993  fFileMenu->AddEntry("&Quit ROOT", kFileQuit);
994 
995  //fFileMenu->DefaultEntry(kFileNewCanvas);
996  fFileMenu->DisableEntry(kFileSave);
997  fFileMenu->DisableEntry(kFileSaveAs);
998  fFileMenu->DisableEntry(kFilePrint);
999 
1000  fSortMenu = new TGPopupMenu(fClient->GetDefaultRoot());
1001  fSortMenu->AddEntry("By &Name", kViewArrangeByName);
1002  fSortMenu->AddEntry("By &Type", kViewArrangeByType);
1003  fSortMenu->AddEntry("By &Size", kViewArrangeBySize);
1004  fSortMenu->AddEntry("By &Date", kViewArrangeByDate);
1005  fSortMenu->AddSeparator();
1006  fSortMenu->AddEntry("&Auto Arrange", kViewArrangeAuto);
1007 
1008  fSortMenu->CheckEntry(kViewArrangeAuto);
1009 
1010  fViewMenu = new TGPopupMenu(fClient->GetDefaultRoot());
1011  fViewMenu->AddEntry("&Toolbar", kViewToolBar);
1012  fViewMenu->AddEntry("Status &Bar", kViewStatusBar);
1013  fViewMenu->AddSeparator();
1014  fViewMenu->AddEntry("Lar&ge Icons", kViewLargeIcons);
1015  fViewMenu->AddEntry("S&mall Icons", kViewSmallIcons);
1016  fViewMenu->AddEntry("&List", kViewList);
1017  fViewMenu->AddEntry("&Details", kViewDetails);
1018  fViewMenu->AddSeparator();
1019  fViewMenu->AddEntry("Show &Hidden", kViewHidden);
1020  fViewMenu->AddPopup("Arrange &Icons", fSortMenu);
1021  fViewMenu->AddEntry("Lin&e up Icons", kViewLineUp);
1022  fViewMenu->AddEntry("&Group Icons", kViewGroupLV);
1023 
1024  fViewMenu->AddSeparator();
1025  fViewMenu->AddEntry("&Refresh (F5)", kViewRefresh);
1026 
1027  fViewMenu->CheckEntry(kViewToolBar);
1028  fViewMenu->CheckEntry(kViewStatusBar);
1029 
1030  if (fBrowser) {
1031  if (gEnv->GetValue("Browser.ShowHidden", 0)) {
1032  fViewMenu->CheckEntry(kViewHidden);
1033  fBrowser->SetBit(TBrowser::kNoHidden, kFALSE);
1034  } else {
1035  fViewMenu->UnCheckEntry(kViewHidden);
1036  fBrowser->SetBit(TBrowser::kNoHidden, kTRUE);
1037  }
1038  }
1039 
1040  fOptionMenu = new TGPopupMenu(fClient->GetDefaultRoot());
1041  fOptionMenu->AddEntry("&Show Cycles", kOptionShowCycles);
1042  fOptionMenu->AddEntry("&AutoThumbnail", kOptionAutoThumbnail);
1043 
1044  fHelpMenu = new TGPopupMenu(fClient->GetDefaultRoot());
1045  fHelpMenu->AddEntry("&About ROOT...", kHelpAbout);
1046  fHelpMenu->AddSeparator();
1047  fHelpMenu->AddEntry("Help On Browser...", kHelpOnBrowser);
1048  fHelpMenu->AddEntry("Help On Canvas...", kHelpOnCanvas);
1049  fHelpMenu->AddEntry("Help On Menus...", kHelpOnMenus);
1050  fHelpMenu->AddEntry("Help On Graphics Editor...", kHelpOnGraphicsEd);
1051  fHelpMenu->AddEntry("Help On Objects...", kHelpOnObjects);
1052  fHelpMenu->AddEntry("Help On PostScript...", kHelpOnPS);
1053  fHelpMenu->AddEntry("Help On Remote Session...", kHelpOnRemote);
1054 
1055  // This main frame will process the menu commands
1056  fFileMenu->Associate(this);
1057  fViewMenu->Associate(this);
1058  fSortMenu->Associate(this);
1059  fOptionMenu->Associate(this);
1060  fHelpMenu->Associate(this);
1061 
1062  // Create menubar layout hints
1063  fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1);
1064  fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
1065  fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);
1066 
1067  // Create menubar
1068  fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
1069  fMenuBar->AddPopup("&File", fFileMenu, fMenuBarItemLayout);
1070  fMenuBar->AddPopup("&View", fViewMenu, fMenuBarItemLayout);
1071  fMenuBar->AddPopup("&Options", fOptionMenu, fMenuBarItemLayout);
1072  fMenuBar->AddPopup("&Help", fHelpMenu, fMenuBarHelpLayout);
1073 
1074  AddFrame(fMenuBar, fMenuBarLayout);
1075 
1076  // Create toolbar and separator
1077 
1078  fToolBarSep = new TGHorizontal3DLine(this);
1079  fToolBar = new TGToolBar(this, 60, 20, kHorizontalFrame);
1080  fFSComboBox = new TGFSComboBox(fToolBar, kFSComboBox);
1081 
1082  fComboLayout = new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 0, 0, 2, 2);
1083  fToolBar->AddFrame(fFSComboBox, fComboLayout);
1084  fFSComboBox->Resize(190, fFSComboBox->GetDefaultHeight());
1085  fFSComboBox->Associate(this);
1086 
1087  int spacing = 8;
1088 
1089  for (int i = 0; gToolBarData[i].fPixmap; i++) {
1090  if (strlen(gToolBarData[i].fPixmap) == 0) {
1091  spacing = 8;
1092  continue;
1093  }
1094  fToolBar->AddButton(this, &gToolBarData[i], spacing);
1095  spacing = 0;
1096  }
1097 
1098  fDrawOption = new TGComboBox(fToolBar, "");
1099  TGTextEntry *dropt_entry = fDrawOption->GetTextEntry();
1100  dropt_entry->SetToolTipText("Object Draw Option", 300);
1101  fDrawOption->Resize(80, 10);
1102  TGListBox *lb = fDrawOption->GetListBox();
1103  lb->Resize(lb->GetWidth(), 120);
1104  Int_t dropt = 1;
1105  fDrawOption->AddEntry("", dropt++);
1106  fDrawOption->AddEntry("same", dropt++);
1107  fDrawOption->AddEntry("box", dropt++);
1108  fDrawOption->AddEntry("lego", dropt++);
1109  fDrawOption->AddEntry("colz", dropt++);
1110  fDrawOption->AddEntry("alp", dropt++);
1111  fDrawOption->AddEntry("text", dropt++);
1112 
1113  fToolBar->AddFrame(fDrawOption, new TGLayoutHints(kLHintsCenterY | kLHintsRight | kLHintsExpandY,2,2,2,0));
1114  fToolBar->AddFrame(new TGLabel(fToolBar,"Option"),
1115  new TGLayoutHints(kLHintsCenterY | kLHintsRight, 2,2,2,0));
1116 
1117  fBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX);
1118  AddFrame(fToolBarSep, fBarLayout);
1119  AddFrame(fToolBar, fBarLayout);
1120 
1121  // Create panes
1122 
1123  fHf = new TGHorizontalFrame(this, 10, 10);
1124 
1125  fV1 = new TGVerticalFrame(fHf, 10, 10, kFixedWidth);
1126  fV2 = new TGVerticalFrame(fHf, 10, 10);
1127  fTreeHdr = new TGCompositeFrame(fV1, 10, 10, kSunkenFrame);
1128  fListHdr = new TGCompositeFrame(fV2, 10, 10, kSunkenFrame);
1129 
1130  fLbl1 = new TGLabel(fTreeHdr, "All Folders");
1131  fLbl2 = new TGLabel(fListHdr, "Contents of \".\"");
1132 
1133  TGLayoutHints *lo;
1134 
1135  lo = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 0, 0);
1136  fWidgets->Add(lo);
1137  fTreeHdr->AddFrame(fLbl1, lo);
1138  fListHdr->AddFrame(fLbl2, lo);
1139 
1140  lo = new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 1, 2);
1141  fWidgets->Add(lo);
1142  fV1->AddFrame(fTreeHdr, lo);
1143  fV2->AddFrame(fListHdr, lo);
1144 
1145  fV1->Resize(fTreeHdr->GetDefaultWidth()+100, fV1->GetDefaultHeight());
1146 
1147  lo = new TGLayoutHints(kLHintsLeft | kLHintsExpandY);
1148  fWidgets->Add(lo);
1149  fHf->AddFrame(fV1, lo);
1150 
1151  TGVSplitter *splitter = new TGVSplitter(fHf);
1152  splitter->SetFrame(fV1, kTRUE);
1153  lo = new TGLayoutHints(kLHintsLeft | kLHintsExpandY);
1154  fWidgets->Add(splitter);
1155  fWidgets->Add(lo);
1156  fHf->AddFrame(splitter, lo);
1157 
1158  lo = new TGLayoutHints(kLHintsRight | kLHintsExpandX | kLHintsExpandY);
1159  fWidgets->Add(lo);
1160  fHf->AddFrame(fV2, lo);
1161 
1162  // Create tree
1163  fTreeView = new TGCanvas(fV1, 10, 10, kSunkenFrame | kDoubleBorder); // canvas
1164  fLt = new TGListTree(fTreeView, kHorizontalFrame,fgWhitePixel); // container
1165  fLt->Associate(this);
1166  fLt->SetAutoTips();
1167 
1168  fExpandLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
1169  fWidgets->Add(fExpandLayout);
1170  fV1->AddFrame(fTreeView, fExpandLayout);
1171 
1172  // Create list view (icon box)
1173  fListView = new TGListView(fV2, 520, 250); // canvas
1174  // container
1175  fIconBox = new TRootIconBox(this, fListView, kHorizontalFrame, fgWhitePixel);
1176  fIconBox->Associate(this);
1177  fListView->SetIncrements(1, 19); // set vertical scroll one line height at a time
1178  fViewMode = fListView->GetViewMode();
1179 
1180  TString str = gEnv->GetValue("Browser.AutoThumbnail", "yes");
1181  str.ToLower();
1182  fIconBox->fAutoThumbnail = (str == "yes") || atoi(str.Data());
1183  fIconBox->fAutoThumbnail ? fOptionMenu->CheckEntry(kOptionAutoThumbnail) :
1184  fOptionMenu->UnCheckEntry(kOptionAutoThumbnail);
1185 
1186  str = gEnv->GetValue("Browser.GroupView", "10000");
1187  Int_t igv = atoi(str.Data());
1188 
1189  if (igv>10) {
1190  fViewMenu->CheckEntry(kViewGroupLV);
1191  fIconBox->SetGroupSize(igv);
1192  }
1193 
1194  // reuse lo from "create tree"
1195  fV2->AddFrame(fListView, fExpandLayout);
1196 
1197  AddFrame(fHf, lo);
1198 
1199  // Statusbar
1200 
1201  int parts[] = { 26, 74 };
1202  fStatusBar = new TGStatusBar(this, 60, 10);
1203  fStatusBar->SetParts(parts, 2);
1204  lo = new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 0, 0, 3, 0);
1205  AddFrame(fStatusBar, lo);
1206 
1207  fTextEdit = 0;
1208 
1209  // Misc
1210  TString bname(name);
1211  bname.Prepend("Old ");
1212  SetWindowName(bname.Data());
1213  SetIconName(bname.Data());
1214  fIconPic = SetIconPixmap("rootdb_s.xpm");
1215  SetClassHints("ROOT", "Browser");
1216 
1217  SetWMSizeHints(600, 350, 10000, 10000, 2, 2);
1218 
1219  fListLevel = 0;
1220  fTreeLock = kFALSE;
1221 
1222  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Escape), 0, kTRUE);
1223  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_F5), 0, kTRUE);
1224  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Right), kKeyMod1Mask, kTRUE);
1225  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Left), kKeyMod1Mask, kTRUE);
1226  ClearHistory();
1227  SetEditDisabled(kEditDisable);
1228 
1229  gVirtualX->SetDNDAware(fId, fDNDTypeList);
1230  MapSubwindows();
1231  SetDefaults();
1232  Resize();
1233  ShowMacroButtons(kFALSE);
1234 
1235  printf("\n You are using the old ROOT browser! A new version is available. To use it:\n");
1236  printf(" Select the \"New Browser\" entry from the \"File\" menu in the browser, or change\n");
1237  printf(" \"Browser.Name:\" from \"TRootBrowserLite\" to \"TRootBrowser\" in system.rootrc\n\n");
1238 
1239  Connect(fLt, "Checked(TObject*, Bool_t)", "TRootBrowserLite",
1240  this, "Checked(TObject *,Bool_t)");
1241 }
1242 
1243 ////////////////////////////////////////////////////////////////////////////////
1244 /// handle keys
1245 
1246 Bool_t TRootBrowserLite::HandleKey(Event_t *event)
1247 {
1248  if (event->fType == kGKeyPress) {
1249  UInt_t keysym;
1250  char input[10];
1251  gVirtualX->LookupString(event, input, sizeof(input), keysym);
1252 
1253  if (!event->fState && (EKeySym)keysym == kKey_F5) {
1254  Refresh(kTRUE);
1255  return kTRUE;
1256  }
1257  if (!event->fState && (EKeySym)keysym == kKey_Escape) {
1258  if (gDNDManager->IsDragging()) gDNDManager->EndDrag();
1259  }
1260 
1261  if (event->fState & kKeyMod1Mask) {
1262  switch ((EKeySym)keysym & ~0x20) {
1263  case kKey_Right:
1264  HistoryForward();
1265  return kTRUE;
1266  case kKey_Left:
1267  HistoryBackward();
1268  return kTRUE;
1269  default:
1270  break;
1271  }
1272  }
1273  }
1274  return TGMainFrame::HandleKey(event);
1275 }
1276 
1277 ////////////////////////////////////////////////////////////////////////////////
1278 /// Add items to the browser. This function has to be called
1279 /// by the Browse() member function of objects when they are
1280 /// called by a browser. If check < 0 (default) no check box is drawn,
1281 /// if 0 then unchecked checkbox is added, if 1 checked checkbox is added.
1282 
1283 void TRootBrowserLite::Add(TObject *obj, const char *name, Int_t check)
1284 {
1285  if (!obj)
1286  return;
1287  if (obj->InheritsFrom("TObjectSpy"))
1288  return;
1289  if (!name) name = obj->GetName();
1290 
1291  AddToBox(obj, name);
1292  if (check > -1) {
1293  TGFrameElement *el;
1294  TIter next(fIconBox->fList);
1295  if (!obj->IsFolder()) {
1296  while ((el = (TGFrameElement *) next())) {
1297  TGLVEntry *f = (TGLVEntry *) el->fFrame;
1298  if (f->GetUserData() == obj) {
1299  f->SetCheckedEntry(check);
1300  }
1301  }
1302  }
1303  }
1304 
1305  // Don't show current dir and up dir links in the tree
1306  if (name[0] == '.' && ((name[1] == '\0') || (name[1] == '.' && name[2] == '\0')))
1307  return;
1308 
1309  if (obj->IsFolder())
1310  AddToTree(obj, name, check);
1311 }
1312 
1313 ////////////////////////////////////////////////////////////////////////////////
1314 /// Add a checkbox in the TGListTreeItem corresponding to obj
1315 /// and a checkmark on TGLVEntry if check = kTRUE.
1316 
1317 void TRootBrowserLite::AddCheckBox(TObject *obj, Bool_t check)
1318 {
1319  if (obj) {
1320  TGListTreeItem *item = fLt->FindItemByObj(fLt->GetFirstItem(), obj);
1321  while (item) {
1322  fLt->SetCheckBox(item, kTRUE);
1323  fLt->CheckItem(item, check);
1324  item = fLt->FindItemByObj(item->GetNextSibling(), obj);
1325  }
1326  TGFrameElement *el;
1327  TIter next(fIconBox->fList);
1328  while ((el = (TGFrameElement *) next())) {
1329  TGLVEntry *f = (TGLVEntry *) el->fFrame;
1330  if (f->GetUserData() == obj) {
1331  f->SetCheckedEntry(check);
1332  }
1333  }
1334  }
1335 }
1336 
1337 ////////////////////////////////////////////////////////////////////////////////
1338 /// Check / uncheck the TGListTreeItem corresponding to this
1339 /// object and add a checkmark on TGLVEntry if check = kTRUE.
1340 
1341 void TRootBrowserLite::CheckObjectItem(TObject *obj, Bool_t check)
1342 {
1343  if (obj) {
1344  TGListTreeItem *item = fLt->FindItemByObj(fLt->GetFirstItem(), obj);
1345  while (item) {
1346  fLt->CheckItem(item, check);
1347  item = fLt->FindItemByObj(item->GetNextSibling(), obj);
1348  TGFrameElement *el;
1349  TIter next(fIconBox->fList);
1350  if (!obj->IsFolder()) {
1351  while ((el = (TGFrameElement *) next())) {
1352  TGLVEntry *f = (TGLVEntry *) el->fFrame;
1353  if (f->GetUserData() == obj) {
1354  f->SetCheckedEntry(check);
1355  }
1356  }
1357  }
1358  }
1359  }
1360 }
1361 
1362 ////////////////////////////////////////////////////////////////////////////////
1363 /// Remove checkbox from TGListTree and checkmark from TGListView.
1364 
1365 void TRootBrowserLite::RemoveCheckBox(TObject *obj)
1366 {
1367  if (obj) {
1368  TGListTreeItem *item = fLt->FindItemByObj(fLt->GetFirstItem(), obj);
1369  while (item) {
1370  fLt->SetCheckBox(item, kFALSE);
1371  item = fLt->FindItemByObj(item->GetNextSibling(), obj);
1372  TGFrameElement *el;
1373  TIter next(fIconBox->fList);
1374  if (!obj->IsFolder()) {
1375  while ((el = (TGFrameElement *) next())) {
1376  TGLVEntry *f = (TGLVEntry *) el->fFrame;
1377  if (f->GetUserData() == obj) {
1378  f->SetCheckedEntry(kFALSE);
1379  }
1380  }
1381  }
1382  }
1383  }
1384 }
1385 
1386 ////////////////////////////////////////////////////////////////////////////////
1387 /// Add items to the iconbox of the browser.
1388 
1389 void TRootBrowserLite::AddToBox(TObject *obj, const char *name)
1390 {
1391  if (obj) {
1392  if (!name) name = obj->GetName() ? obj->GetName() : "NoName";
1393  //const char *titlePtr = obj->GetTitle() ? obj->GetTitle() : " ";
1394 
1395  TClass *objClass = 0;
1396 
1397  if (obj->IsA() == TKey::Class())
1398  objClass = TClass::GetClass(((TKey *)obj)->GetClassName());
1399  else if (obj->IsA() == TKeyMapFile::Class())
1400  objClass = TClass::GetClass(((TKeyMapFile *)obj)->GetTitle());
1401  else if (obj->InheritsFrom("TRemoteObject")) {
1402  // special case for remote object: get real object class
1403  TRemoteObject *robj = (TRemoteObject *)obj;
1404  if (!strcmp(robj->GetClassName(), "TKey"))
1405  objClass = TClass::GetClass(robj->GetKeyClassName());
1406  else
1407  objClass = TClass::GetClass(robj->GetClassName());
1408  }
1409  else
1410  objClass = obj->IsA();
1411 
1412  fIconBox->AddObjItem(name, obj, objClass);
1413  }
1414 }
1415 
1416 ////////////////////////////////////////////////////////////////////////////////
1417 /// Add items to the current TGListTree of the browser.
1418 
1419 void TRootBrowserLite::AddToTree(TObject *obj, const char *name, Int_t check)
1420 {
1421  if (!obj)
1422  return;
1423  if (obj->InheritsFrom("TApplication"))
1424  fListLevel = 0;
1425  if (!fTreeLock) {
1426  if (!name) name = obj->GetName();
1427  if (name[0] == '.' && name[1] == '.')
1428  Info("AddToTree", "up one level %s", name);
1429  if(check > -1) {
1430  TGListTreeItem *item = fLt->AddItem(fListLevel, name, obj, 0, 0, kTRUE);
1431  if (item) fLt->CheckItem(item, (Bool_t)check);
1432  TString tip(obj->ClassName());
1433  if (obj->GetTitle()) {
1434  tip += " ";
1435  tip += obj->GetTitle();
1436  }
1437  fLt->SetToolTipItem(item, tip.Data());
1438  } else {
1439  // special case for remote object
1440  if (obj->InheritsFrom("TRemoteObject")) {
1441  // Nothing to do
1442  } else if (fListLevel) {
1443  // check also if one of its parents is a remote object
1444  TGListTreeItem *top = fListLevel;
1445  while (top->GetParent()) {
1446  TObject *tobj = (TObject *) top->GetUserData();
1447  if (tobj && (tobj->InheritsFrom("TRemoteObject") ||
1448  tobj->InheritsFrom("TApplicationRemote"))) {
1449  break;
1450  }
1451  top = top->GetParent();
1452  }
1453  }
1454  // add the object only if not already in the list
1455  if ((!fLt->FindChildByName(fListLevel, name)) &&
1456  (!fLt->FindChildByData(fListLevel, obj))) {
1457  TGListTreeItem *it = fLt->AddItem(fListLevel, name, obj);
1458  Long64_t bsize, fsize, objsize = 0;
1459  TString objinfo = obj->GetObjectInfo(1, 1);
1460  TString infos = obj->GetName();
1461  infos += "\n";
1462  infos += obj->GetTitle();
1463  if (!objinfo.IsNull() && !objinfo.BeginsWith("x=")) {
1464  objsize = objinfo.Atoll();
1465  if (objsize > 0) {
1466  infos += "\n";
1467  bsize = fsize = objsize;
1468  if (fsize > 1024) {
1469  fsize /= 1024;
1470  if (fsize > 1024) {
1471  // 3.7MB is more informative than just 3MB
1472  infos += TString::Format("Size: %lld.%lldM", fsize/1024,
1473  (fsize%1024)/103);
1474  } else {
1475  infos += TString::Format("Size: %lld.%lldK", bsize/1024,
1476  (bsize%1024)/103);
1477  }
1478  } else {
1479  infos += TString::Format("Size: %lld bytes", bsize);
1480  }
1481  }
1482  }
1483  if (it)
1484  it->SetTipText(infos.Data());
1485  }
1486  }
1487  }
1488 }
1489 
1490 ////////////////////////////////////////////////////////////////////////////////
1491 /// Browse object. This, in turn, will trigger the calling of
1492 /// TRootBrowserLite::Add() which will fill the IconBox and the tree.
1493 /// Emits signal "BrowseObj(TObject*)".
1494 
1495 void TRootBrowserLite::BrowseObj(TObject *obj)
1496 {
1497  TGPosition pos = fIconBox->GetPagePosition();
1498  Emit("BrowseObj(TObject*)", (Long_t)obj);
1499 
1500  if (obj != gROOT) {
1501  if (!fLt->FindItemByObj(fLt->GetFirstItem(), obj)) {
1502  fListLevel = 0;
1503  Add(obj);
1504  fListLevel = fLt->FindItemByObj(fLt->GetFirstItem(), obj);
1505  fLt->HighlightItem(fListLevel);
1506  if (obj->IsFolder())
1507  fLt->OpenItem(fListLevel);
1508  fLt->ClearViewPort();
1509  fLt->AdjustPosition(fListLevel);
1510  }
1511  }
1512 
1513  if (obj->IsFolder()) fIconBox->RemoveAll();
1514  obj->Browse(fBrowser);
1515  if ((fListLevel && obj->IsFolder()) || (!fListLevel && (obj == gROOT))) {
1516  fIconBox->Refresh();
1517  }
1518 
1519  if (fBrowser) {
1520  fBrowser->SetRefreshFlag(kFALSE);
1521  }
1522  UpdateDrawOption();
1523 
1524  fIconBox->SetHsbPosition(pos.fX);
1525  fIconBox->SetVsbPosition(pos.fY);
1526 }
1527 
1528 ////////////////////////////////////////////////////////////////////////////////
1529 /// add new draw option to the "history"
1530 
1531 void TRootBrowserLite::UpdateDrawOption()
1532 {
1533  TString opt = GetDrawOption();
1534  TGListBox *lb = fDrawOption->GetListBox();
1535  TGLBContainer *lbc = (TGLBContainer *)lb->GetContainer();
1536 
1537  TIter next(lbc->GetList());
1538  TGFrameElement *el;
1539 
1540  while ((el = (TGFrameElement *)next())) {
1541  TGTextLBEntry *lbe = (TGTextLBEntry *)el->fFrame;
1542  if (lbe->GetText()->GetString() == opt) {
1543  return;
1544  }
1545  }
1546 
1547  Int_t nn = fDrawOption->GetNumberOfEntries() + 1;
1548  fDrawOption->AddEntry(opt.Data(), nn);
1549  fDrawOption->Select(nn);
1550 }
1551 
1552 ////////////////////////////////////////////////////////////////////////////////
1553 /// returns pointer to fIconBox object
1554 
1555 TGFileContainer *TRootBrowserLite::GetIconBox() const
1556 {
1557  return (TGFileContainer*)fIconBox;
1558 }
1559 
1560 ////////////////////////////////////////////////////////////////////////////////
1561 /// Really delete the browser and the this GUI.
1562 
1563 void TRootBrowserLite::ReallyDelete()
1564 {
1565  fBrowser->SetBrowserImp(0);
1566  delete this;
1567 }
1568 
1569 ////////////////////////////////////////////////////////////////////////////////
1570 /// In case window is closed via WM we get here.
1571 
1572 void TRootBrowserLite::CloseWindow()
1573 {
1574  DeleteWindow();
1575 }
1576 
1577 ////////////////////////////////////////////////////////////////////////////////
1578 /// Display in statusbar total number of objects and number of
1579 /// selected objects in IconBox.
1580 
1581 void TRootBrowserLite::DisplayTotal(Int_t total, Int_t selected)
1582 {
1583  char tmp[64];
1584  const char *fmt;
1585 
1586  if (selected)
1587  fmt = "%d Object%s, %d selected.";
1588  else
1589  fmt = "%d Object%s.";
1590 
1591  snprintf(tmp, 64, fmt, total, (total == 1) ? "" : "s", selected);
1592  fStatusBar->SetText(tmp, 0);
1593 }
1594 
1595 ////////////////////////////////////////////////////////////////////////////////
1596 /// Display current directory in second label, fLbl2.
1597 
1598 void TRootBrowserLite::DisplayDirectory()
1599 {
1600  char *p, path[1024];
1601 
1602  fLt->GetPathnameFromItem(fListLevel, path, 12);
1603  p = path;
1604  while (*p && *(p+1) == '/') ++p;
1605  if (!p[0])
1606  fLbl2->SetText(new TGString("Contents of \".\""));
1607  else
1608  fLbl2->SetText(new TGString(Form("Contents of \"%s\"", p)));
1609  fListHdr->Layout();
1610 
1611  // Get full pathname for FS combobox (previously truncated to 12 levels deep)
1612  fLt->GetPathnameFromItem(fListLevel, path);
1613  p = path;
1614  while (*p && *(p+1) == '/') ++p;
1615  fFSComboBox->Update(p);
1616 
1617  if (fListLevel) {
1618  // disable/enable up level navigation
1619  TGButton *btn = fToolBar->GetButton(kOneLevelUp);
1620  const char *dirname = gSystem->DirName(p);
1621  Bool_t disableUp;
1622 
1623  TObject *obj = (TObject*)fListLevel->GetUserData();
1624  disableUp = (strlen(dirname) == 1) && (*dirname == '/');
1625 
1626  // normal file directory
1627  if (disableUp && (obj) && (obj->IsA() == TSystemDirectory::Class())) {
1628  disableUp = strlen(p) == 1;
1629  }
1630  btn->SetState(disableUp ? kButtonDisabled : kButtonUp);
1631  AddToHistory(fListLevel);
1632  }
1633 }
1634 
1635 ////////////////////////////////////////////////////////////////////////////////
1636 /// Execute default action for selected object (action is specified
1637 /// in the $HOME/.root.mimes or $ROOTSYS/etc/root.mimes file.
1638 /// Emits signal "ExecuteDefaultAction(TObject*)".
1639 
1640 void TRootBrowserLite::ExecuteDefaultAction(TObject *obj)
1641 {
1642  TRootBrowserCursorSwitcher cursorSwitcher(fIconBox, fLt);
1643  char action[512];
1644  fBrowser->SetDrawOption(GetDrawOption());
1645  TVirtualPad *wasp = gPad ? (TVirtualPad*)gPad->GetCanvas() : 0;
1646  TFile *wasf = gFile;
1647 
1648  // Special case for file system objects...
1649  if (obj->IsA() == TSystemFile::Class() ||
1650  obj->InheritsFrom("TRemoteObject")) {
1651  TString act;
1652  TString ext = obj->GetName();
1653 
1654  if (fClient->GetMimeTypeList()->GetAction(obj->GetName(), action)) {
1655  act = action;
1656  act.ReplaceAll("%s", obj->GetName());
1657  gInterpreter->SaveGlobalsContext();
1658 
1659  if (act[0] == '!') {
1660  act.Remove(0, 1);
1661  gSystem->Exec(act.Data());
1662  } else {
1663  // special case for remote object: remote process
1664  if (obj->InheritsFrom("TRemoteObject"))
1665  gApplication->SetBit(TApplication::kProcessRemotely);
1666  gApplication->ProcessLine(act.Data());
1667  }
1668  Emit("ExecuteDefaultAction(TObject*)", (Long_t)obj);
1669  }
1670 
1671  // special case for remote object: browse real object
1672  if (obj->InheritsFrom("TRemoteObject") && ext.EndsWith(".root")) {
1673  TRootBrowserCursorSwitcher cursorSwitcher2(fIconBox, fLt);
1674  gApplication->SetBit(TApplication::kProcessRemotely);
1675  gApplication->ProcessLine("((TApplicationServer *)gApplication)->BrowseFile(0);");
1676  Refresh();
1677  }
1678  ////////// new TFile was opened. Add it to the browser /////
1679  if (gFile && (wasf != gFile) && ext.EndsWith(".root")) {
1680  TGListTreeItem *itm = fLt->FindChildByData(0, gROOT->GetListOfFiles());
1681 
1682  if (itm) {
1683  fLt->ClearHighlighted();
1684  fListLevel = itm;
1685  ListTreeHighlight(fListLevel);
1686  fLt->OpenItem(fListLevel);
1687  itm = fLt->AddItem(fListLevel, gFile->GetName());
1688  itm->SetUserData(gFile);
1689  fClient->NeedRedraw(fLt, kTRUE);
1690  return;
1691  }
1692  }
1693 
1694  // only valid for local text files
1695  if (!obj->InheritsFrom("TRemoteObject"))
1696  BrowseTextFile(obj->GetName());
1697 
1698  /////////////// cache and change file's icon ///////////////////////
1699  TVirtualPad *nowp = gPad ? (TVirtualPad*)gPad->GetCanvas() : 0;
1700 
1701  if (fIconBox->fAutoThumbnail && nowp && (nowp != wasp)) {
1702  TSystemFile *sf = (TSystemFile*)obj;
1703  const TGPicture *pic, *spic;
1704 
1705  TIconBoxThumb *thumb = 0;
1706  TString path = gSystem->IsAbsoluteFileName(sf->GetName()) ? sf->GetName() :
1707  gSystem->ConcatFileName(gSystem->WorkingDirectory(), sf->GetName());
1708 
1709  thumb = (TIconBoxThumb*)fIconBox->fThumbnails->FindObject(path);
1710 
1711  if (thumb) {
1712  spic = thumb->fSmall;
1713  pic = thumb->fLarge;
1714  } else {
1715  TImage *img = TImage::Create();
1716  nowp->Modified();
1717  nowp->Update();
1718  img->FromPad(nowp);
1719 
1720  if (!img->IsValid()) {
1721  return;
1722  }
1723 
1724  static const UInt_t sz = 72;
1725  UInt_t w = sz;
1726  UInt_t h = sz;
1727 
1728  if (img->GetWidth() > img->GetHeight()) {
1729  h = (img->GetHeight()*sz)/img->GetWidth();
1730  } else {
1731  w = (img->GetWidth()*sz)/img->GetHeight();
1732  }
1733 
1734  w = w < 54 ? 54 : w;
1735  h = h < 54 ? 54 : h;
1736 
1737  img->Scale(w, h);
1738  img->Merge(img, "tint"); // contrasting
1739  img->DrawBox(0, 0, w, h, "#ffff00", 1); // yellow frame
1740 
1741  pic = fClient->GetPicturePool()->GetPicture(path.Data(), img->GetPixmap(), 0);
1742  img->Scale(w/3, h/3);
1743  spic = fClient->GetPicturePool()->GetPicture(path.Data(), img->GetPixmap(), 0);
1744 
1745  thumb = new TIconBoxThumb(path.Data(), spic, pic);
1746  fIconBox->fThumbnails->Add(thumb);
1747  delete img;
1748  }
1749  }
1750  return;
1751  }
1752 
1753  // For other objects the default action is still hard coded in
1754  // their Browse() member function.
1755 }
1756 
1757 ////////////////////////////////////////////////////////////////////////////////
1758 /// Handle menu and other command generated by the user.
1759 
1760 Bool_t TRootBrowserLite::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
1761 {
1762  TRootHelpDialog *hd;
1763  TRootBrowserCursorSwitcher *cursorSwitcher = 0;
1764  TDirectory *tdir = 0;
1765  TString cmd;
1766 
1767  if (GET_SUBMSG(msg) != kCT_SELCHANGED) {
1768  cursorSwitcher = new TRootBrowserCursorSwitcher(fIconBox, fLt);
1769  }
1770 
1771  TObject *obj;
1772  TGListTreeItem *item = 0;
1773 
1774  gVirtualX->Update();
1775 
1776  switch (GET_MSG(msg)) {
1777 
1778  case kC_COMMAND:
1779 
1780  switch (GET_SUBMSG(msg)) {
1781 
1782  case kCM_BUTTON:
1783  // fallthrough
1784  case kCM_MENU:
1785 
1786  switch ((ERootBrowserCommands)parm1) {
1787  // Handle File menu items...
1788  case kFileNewBrowserLite:
1789  new TBrowser("Browser", "ROOT Object Browser");
1790  break;
1791  case kFileNewBrowser:
1792  gEnv->SetValue("Browser.Name", "TRootBrowser");
1793  new TBrowser();
1794  gEnv->SetValue("Browser.Name", "TRootBrowserLite");
1795  break;
1796  case kFileNewCanvas:
1797  gROOT->MakeDefCanvas();
1798  break;
1799  case kFileNewBuilder:
1800  TGuiBuilder::Instance();
1801  break;
1802  case kFileOpen:
1803  {
1804  static TString dir(".");
1805  TGFileInfo fi;
1806  fi.fFileTypes = gOpenTypes;
1807  fi.fIniDir = StrDup(dir);
1808  new TGFileDialog(fClient->GetDefaultRoot(), this,
1809  kFDOpen,&fi);
1810  dir = fi.fIniDir;
1811  if (fi.fMultipleSelection && fi.fFileNamesList) {
1812  TObjString *el;
1813  TIter next(fi.fFileNamesList);
1814  while ((el = (TObjString *) next())) {
1815  new TFile(el->GetString(), "update");
1816  }
1817  }
1818  else if (fi.fFilename) {
1819  new TFile(fi.fFilename, "update");
1820  }
1821  }
1822  break;
1823  case kFileSave:
1824  case kFileSaveAs:
1825  break;
1826  case kFilePrint:
1827  break;
1828  case kFileCloseBrowser:
1829  SendCloseMessage();
1830  break;
1831  case kFileQuit:
1832  gApplication->Terminate(0);
1833  break;
1834 
1835  // Handle View menu items...
1836  case kViewToolBar:
1837  if (fViewMenu->IsEntryChecked(kViewToolBar))
1838  ShowToolBar(kFALSE);
1839  else
1840  ShowToolBar();
1841  break;
1842  case kViewStatusBar:
1843  if (fViewMenu->IsEntryChecked(kViewStatusBar))
1844  ShowStatusBar(kFALSE);
1845  else
1846  ShowStatusBar();
1847  break;
1848  case kViewLargeIcons:
1849  case kViewSmallIcons:
1850  case kViewList:
1851  case kViewDetails:
1852  SetViewMode((Int_t)parm1);
1853  break;
1854  case kViewHidden:
1855  if (fBrowser->TestBit(TBrowser::kNoHidden)) {
1856  fViewMenu->CheckEntry(kViewHidden);
1857  fBrowser->SetBit(TBrowser::kNoHidden, kFALSE);
1858  } else {
1859  fViewMenu->UnCheckEntry(kViewHidden);
1860  fBrowser->SetBit(TBrowser::kNoHidden, kTRUE);
1861  }
1862  Refresh(kTRUE);
1863  break;
1864  case kViewArrangeByName:
1865  case kViewArrangeByType:
1866  case kViewArrangeBySize:
1867  case kViewArrangeByDate:
1868  SetSortMode((Int_t)parm1);
1869  break;
1870  case kViewLineUp:
1871  break;
1872  case kViewRefresh:
1873  Refresh(kTRUE);
1874  break;
1875  case kViewGroupLV:
1876  if (!fViewMenu->IsEntryChecked(kViewGroupLV)) {
1877  fViewMenu->CheckEntry(kViewGroupLV);
1878  TString gv = gEnv->GetValue("Browser.GroupView", "10000");
1879  Int_t igv = atoi(gv.Data());
1880 
1881  if (igv > 10) {
1882  fIconBox->SetGroupSize(igv);
1883  }
1884  } else {
1885  fViewMenu->UnCheckEntry(kViewGroupLV);
1886  fIconBox->SetGroupSize(10000000); // very large value
1887  }
1888  break;
1889 
1890  // Handle Option menu items...
1891  case kOptionShowCycles:
1892  printf("Currently the browser always shows all cycles\n");
1893  break;
1894 
1895  case kOptionAutoThumbnail:
1896  if (fOptionMenu->IsEntryChecked(kOptionAutoThumbnail)) {
1897  fOptionMenu->UnCheckEntry(kOptionAutoThumbnail);
1898  fIconBox->fThumbnails->Delete();
1899  fIconBox->fAutoThumbnail = kFALSE;
1900  Refresh(kTRUE);
1901  } else {
1902  fOptionMenu->CheckEntry(kOptionAutoThumbnail);
1903  fIconBox->fAutoThumbnail = kTRUE;
1904  }
1905  break;
1906 
1907  // Handle toolbar button...
1908  case kOneLevelUp:
1909  {
1910  if (fBrowseTextFile) {
1911  HideTextEdit();
1912  break;
1913  }
1914  if (!fListLevel || !fListLevel->IsActive()) break;
1915 
1916  if (fListLevel && fIconBox->WasGrouped()) {
1917  if (fListLevel) {
1918  item = fListLevel->GetParent();
1919  if (item) fListLevel = item;
1920  obj = (TObject *) fListLevel->GetUserData();
1921  HighlightListLevel();
1922  if (obj) BrowseObj(obj);
1923  }
1924 
1925  fClient->NeedRedraw(fLt, kTRUE);
1926  break;
1927  }
1928  if (fListLevel) item = fListLevel->GetParent();
1929 
1930 
1931  if (item) {
1932  fListLevel = item;
1933  obj = (TObject *)fListLevel->GetUserData();
1934  HighlightListLevel();
1935  DisplayDirectory();
1936  if (obj) BrowseObj(obj);
1937  fClient->NeedRedraw(fLt, kTRUE);
1938  } else {
1939  obj = (TObject *)fListLevel->GetUserData();
1940  if (obj) ToSystemDirectory(gSystem->DirName(obj->GetTitle()));
1941  }
1942  break;
1943  }
1944 
1945  // toolbar buttons
1946  case kHistoryBack:
1947  HistoryBackward();
1948  break;
1949  case kHistoryForw:
1950  HistoryForward();
1951  break;
1952 
1953  case kViewFind:
1954  Search();
1955  break;
1956 
1957  // Handle Help menu items...
1958  case kHelpAbout:
1959  {
1960 #ifdef R__UNIX
1961  TString rootx = TROOT::GetBinDir() + "/root -a &";
1962  gSystem->Exec(rootx);
1963 #else
1964 #ifdef WIN32
1965  new TWin32SplashThread(kTRUE);
1966 #else
1967  char str[32];
1968  sprintf(str, "About ROOT %s...", gROOT->GetVersion());
1969  hd = new TRootHelpDialog(this, str, 600, 400);
1970  hd->SetText(gHelpAbout);
1971  hd->Popup();
1972 #endif
1973 #endif
1974  }
1975  break;
1976  case kHelpOnCanvas:
1977  hd = new TRootHelpDialog(this, "Help on Canvas...", 600, 400);
1978  hd->SetText(gHelpCanvas);
1979  hd->Popup();
1980  break;
1981  case kHelpOnMenus:
1982  hd = new TRootHelpDialog(this, "Help on Menus...", 600, 400);
1983  hd->SetText(gHelpPullDownMenus);
1984  hd->Popup();
1985  break;
1986  case kHelpOnGraphicsEd:
1987  hd = new TRootHelpDialog(this, "Help on Graphics Editor...", 600, 400);
1988  hd->SetText(gHelpGraphicsEditor);
1989  hd->Popup();
1990  break;
1991  case kHelpOnBrowser:
1992  hd = new TRootHelpDialog(this, "Help on Browser...", 600, 400);
1993  hd->SetText(gHelpBrowserLite);
1994  hd->Popup();
1995  break;
1996  case kHelpOnObjects:
1997  hd = new TRootHelpDialog(this, "Help on Objects...", 600, 400);
1998  hd->SetText(gHelpObjects);
1999  hd->Popup();
2000  break;
2001  case kHelpOnPS:
2002  hd = new TRootHelpDialog(this, "Help on PostScript...", 600, 400);
2003  hd->SetText(gHelpPostscript);
2004  hd->Popup();
2005  break;
2006  case kHelpOnRemote:
2007  hd = new TRootHelpDialog(this, "Help on Browser...", 600, 400);
2008  hd->SetText(gHelpRemote);
2009  hd->Popup();
2010  break;
2011  default:
2012  break;
2013  }
2014  break;
2015  case kCM_COMBOBOX:
2016  if (parm1 == kFSComboBox) {
2017  TGTreeLBEntry *e = (TGTreeLBEntry *) fFSComboBox->GetSelectedEntry();
2018  if (e) {
2019  const char *dirname = e->GetPath()->GetString();
2020  item = fLt->FindItemByPathname(dirname);
2021  if (item) {
2022  fListLevel = item;
2023  HighlightListLevel();
2024  DisplayDirectory();
2025  fClient->NeedRedraw(fLt, kTRUE);
2026  } else {
2027  ToSystemDirectory(dirname);
2028  }
2029  }
2030  }
2031  break;
2032  default:
2033  break;
2034  }
2035 
2036  break;
2037 
2038  case kC_LISTTREE:
2039  switch (GET_SUBMSG(msg)) {
2040 
2041  case kCT_ITEMCLICK:
2042  // tell coverity that parm1 is a Long_t, and not an enum (even
2043  // if we compare it with an enum value) and the meaning of
2044  // parm1 depends on GET_MSG(msg) and GET_SUBMSG(msg)
2045  // coverity[mixed_enums]
2046  if (((EMouseButton)parm1 == kButton1) ||
2047  ((EMouseButton)parm1 == kButton3)) {
2048  HideTextEdit();
2049  TGListTreeItem *item2;
2050  TObject *obj2 = 0;
2051  if ((item2 = fLt->GetSelected()) != 0 ) {
2052  ListTreeHighlight(item2);
2053  fStatusBar->SetText("", 1); // clear
2054  }
2055  if (item2 && parm1 == kButton3) {
2056  Int_t x = (Int_t)(parm2 & 0xffff);
2057  Int_t y = (Int_t)((parm2 >> 16) & 0xffff);
2058  obj2 = (TObject *) item2->GetUserData();
2059  if (obj2) {
2060  if (obj2->InheritsFrom("TTree")) {
2061  // if a tree not attached to any directory (e.g. in a TFolder)
2062  // then attach it to the current directory (gDirectory)
2063  cmd = TString::Format("((TTree *)0x%lx)->GetDirectory();",
2064  (ULong_t)obj2);
2065  tdir = (TDirectory *)gROOT->ProcessLine(cmd.Data());
2066  if (!tdir) {
2067  cmd = TString::Format("((TTree *)0x%lx)->SetDirectory(gDirectory);",
2068  (ULong_t)obj2);
2069  gROOT->ProcessLine(cmd.Data());
2070  }
2071  }
2072  fBrowser->GetContextMenu()->Popup(x, y, obj2, fBrowser);
2073  }
2074  }
2075  fClient->NeedRedraw(fLt);
2076  fListView->LayoutHeader(0);
2077  fListView->Layout();
2078  }
2079  break;
2080 
2081  case kCT_ITEMDBLCLICK:
2082  if (parm1 == kButton1) {
2083  if (fBrowseTextFile) {
2084  HideTextEdit();
2085  }
2086  if (fListLevel && fIconBox->WasGrouped()) {
2087  TObject *obj2;
2088  TGListTreeItem *item2;
2089 
2090  if (fListLevel) {
2091  item2 = fListLevel->GetParent();
2092  if (item2) fListLevel = item2;
2093 
2094  obj2 = (TObject *) fListLevel->GetUserData();
2095  HighlightListLevel();
2096  if (obj2) {
2097  BrowseObj(obj2);
2098  }
2099  }
2100  break;
2101  }
2102  }
2103 
2104  default:
2105  break;
2106  }
2107  break;
2108 
2109  case kC_CONTAINER:
2110  switch (GET_SUBMSG(msg)) {
2111 
2112  case kCT_ITEMCLICK:
2113  if (fIconBox->NumSelected() == 1) {
2114  // display title of selected object
2115  TGFileItem *item2;
2116  void *p = 0;
2117  if ((item2 = (TGFileItem *)fIconBox->GetNextSelected(&p)) != 0) {
2118  TObject *obj2 = (TObject *)item2->GetUserData();
2119 
2120  TGListTreeItem *itm = 0;
2121  if (!fListLevel) itm = fLt->GetFirstItem();
2122  else itm = fListLevel->GetFirstChild();
2123  //Bool_t found = kFALSE;
2124 
2125  while (itm) {
2126  if (itm->GetUserData() == obj2) break;
2127  itm = itm->GetNextSibling();
2128  }
2129 
2130  if (itm) {
2131  if ((fListLevel && fListLevel->IsOpen()) || !fListLevel) {
2132  fLt->ClearHighlighted();
2133  fLt->HighlightItem(itm);
2134  fClient->NeedRedraw(fLt, kTRUE);
2135  }
2136  }
2137 
2138  if (obj2) fStatusBar->SetText(obj2->GetName(), 1);
2139  }
2140  }
2141  if (parm1 == kButton3) {
2142  // show context menu for selected object
2143  if (fIconBox->NumSelected() == 1) {
2144  void *p = 0;
2145  TGFileItem *item2;
2146  if ((item2 = (TGFileItem *) fIconBox->GetNextSelected(&p)) != 0) {
2147  Int_t x = (Int_t)(parm2 & 0xffff);
2148  Int_t y = (Int_t)((parm2 >> 16) & 0xffff);
2149  TObject *obj2 = (TObject *)item2->GetUserData();
2150  if (obj2) {
2151  if (obj2->IsA() == TKey::Class()) {
2152  TKey *key = (TKey*)obj2;
2153  TClass *cl = TClass::GetClass(key->GetClassName());
2154  TString name = key->GetName();
2155  name += ";";
2156  name += key->GetCycle();
2157  //void *add = gROOT->FindObject((char *) name.Data());//key->GetName());
2158  void *add = gDirectory->FindObjectAny((char *) name.Data());
2159  if (cl->IsTObject()) {
2160  obj2 = (TObject*)add; // cl->DynamicCast(TObject::Class(),startadd);
2161  item2->SetUserData(obj2);
2162  } else {
2163  Error("ProcessMessage","do not support non TObject (like %s) yet",
2164  cl->GetName());
2165  break;
2166  }
2167  }
2168  if (obj2 && obj2->InheritsFrom("TTree")) {
2169  // if a tree not attached to any directory (e.g. in a TFolder)
2170  // then attach it to the current directory (gDirectory)
2171  cmd = TString::Format("((TTree *)0x%lx)->GetDirectory();",
2172  (ULong_t)obj2);
2173  tdir = (TDirectory *)gROOT->ProcessLine(cmd.Data());
2174  if (!tdir) {
2175  cmd = TString::Format("((TTree *)0x%lx)->SetDirectory(gDirectory);",
2176  (ULong_t)obj2);
2177  gROOT->ProcessLine(cmd.Data());
2178  }
2179  }
2180  fBrowser->GetContextMenu()->Popup(x, y, obj2, fBrowser);
2181  }
2182  }
2183  }
2184  }
2185  break;
2186  case kCT_ITEMDBLCLICK:
2187  if (parm1 == kButton1) {
2188  if (fIconBox->NumSelected() == 1) {
2189  void *p = 0;
2190  TGFileItem *item2;
2191  if ((item2 = (TGFileItem *) fIconBox->GetNextSelected(&p)) != 0) {
2192  TObject *obj2 = (TObject *)item2->GetUserData();
2193  if (obj2) {
2194  DoubleClicked(obj2);
2195  IconBoxAction(obj2);
2196  }
2197  delete cursorSwitcher;
2198  return kTRUE; //
2199  }
2200  }
2201  }
2202  break;
2203  case kCT_SELCHANGED:
2204  DisplayTotal((Int_t)parm1, (Int_t)parm2);
2205  break;
2206  default:
2207  break;
2208  }
2209 
2210  break;
2211 
2212  default:
2213  break;
2214  }
2215 
2216  delete cursorSwitcher;
2217 
2218  fClient->NeedRedraw(fIconBox);
2219  return kTRUE;
2220 }
2221 
2222 ////////////////////////////////////////////////////////////////////////////////
2223 /// Make object associated with item the current directory.
2224 
2225 void TRootBrowserLite::Chdir(TGListTreeItem *item)
2226 {
2227  if (item) {
2228  TGListTreeItem *i = item;
2229  TString dir;
2230  while (i) {
2231  TObject *obj = (TObject*) i->GetUserData();
2232  if (obj) {
2233  if (obj->IsA() == TDirectoryFile::Class()) {
2234  dir = "/" + dir;
2235  dir = obj->GetName() + dir;
2236  }
2237  if (obj->IsA() == TFile::Class()) {
2238  dir = ":/" + dir;
2239  dir = obj->GetName() + dir;
2240  }
2241  if (obj->IsA() == TKey::Class()) {
2242  if (strcmp(((TKey*)obj)->GetClassName(), "TDirectoryFile") == 0) {
2243  dir = "/" + dir;
2244  dir = obj->GetName() + dir;
2245  }
2246  }
2247  }
2248  i = i->GetParent();
2249  }
2250 
2251  if (gDirectory && dir.Length()) gDirectory->cd(dir.Data());
2252  }
2253 }
2254 
2255 ////////////////////////////////////////////////////////////////////////////////
2256 /// helper method to track history
2257 
2258 void TRootBrowserLite::HighlightListLevel()
2259 {
2260  if (!fListLevel) return;
2261 
2262  fLt->ClearHighlighted();
2263  fLt->HighlightItem(fListLevel);
2264 }
2265 
2266 ////////////////////////////////////////////////////////////////////////////////
2267 /// helper method to track history
2268 
2269 void TRootBrowserLite::AddToHistory(TGListTreeItem *item)
2270 {
2271  TGButton *btn = fToolBar->GetButton(kHistoryBack);
2272 
2273  if (!item || (fHistoryCursor &&
2274  (item == ((TRootBrowserHistoryCursor*)fHistoryCursor)->fItem))) return;
2275 
2276  TRootBrowserHistoryCursor *cur = (TRootBrowserHistoryCursor*)fHistoryCursor;
2277 
2278  while ((cur = (TRootBrowserHistoryCursor*)fHistory->After(fHistoryCursor))) {
2279  fHistory->Remove(cur);
2280  delete cur;
2281  }
2282 
2283  cur = new TRootBrowserHistoryCursor(item);
2284  fHistory->Add(cur);
2285  fHistoryCursor = cur;
2286  btn->SetState(kButtonUp);
2287 }
2288 
2289 ////////////////////////////////////////////////////////////////////////////////
2290 /// clear navigation history
2291 
2292 void TRootBrowserLite::ClearHistory()
2293 {
2294  fHistory->Delete();
2295  TGButton *btn = fToolBar->GetButton(kHistoryBack);
2296  TGButton *btn2 = fToolBar->GetButton(kHistoryForw);
2297  btn->SetState(kButtonDisabled);
2298  btn2->SetState(kButtonDisabled);
2299 }
2300 
2301 ////////////////////////////////////////////////////////////////////////////////
2302 /// go to the past
2303 
2304 Bool_t TRootBrowserLite::HistoryBackward()
2305 {
2306  if (fBrowseTextFile) {
2307  HideTextEdit();
2308  return kFALSE;
2309  }
2310  TRootBrowserHistoryCursor *cur = (TRootBrowserHistoryCursor*)fHistory->Before(fHistoryCursor);
2311  TGButton *btn = fToolBar->GetButton(kHistoryBack);
2312  TGButton *btn2 = fToolBar->GetButton(kHistoryForw);
2313 
2314  if (!cur) {
2315  btn->SetState(kButtonDisabled);
2316  return kFALSE;
2317  }
2318 
2319  fLt->ClearHighlighted();
2320  fHistoryCursor = cur;
2321  fListLevel = cur->fItem;
2322  ListTreeHighlight(fListLevel);
2323  fLt->AdjustPosition();
2324  fClient->NeedRedraw(fLt, kTRUE);
2325 
2326  btn2->SetState(kButtonUp);
2327  cur = (TRootBrowserHistoryCursor*)fHistory->Before(fHistoryCursor);
2328  if (!cur) {
2329  btn->SetState(kButtonDisabled);
2330  return kFALSE;
2331  }
2332 
2333  return kTRUE;
2334 }
2335 
2336 ////////////////////////////////////////////////////////////////////////////////
2337 /// go to the future
2338 
2339 Bool_t TRootBrowserLite::HistoryForward()
2340 {
2341  if (fBrowseTextFile) {
2342  HideTextEdit();
2343  return kFALSE;
2344  }
2345 
2346  TRootBrowserHistoryCursor *cur = (TRootBrowserHistoryCursor*)fHistory->After(fHistoryCursor);
2347  TGButton *btn = fToolBar->GetButton(kHistoryForw);
2348  TGButton *btn2 = fToolBar->GetButton(kHistoryBack);
2349 
2350  if (!cur) {
2351  btn->SetState(kButtonDisabled);
2352  return kFALSE;
2353  }
2354 
2355  fLt->ClearHighlighted();
2356  fHistoryCursor = cur;
2357  fListLevel = cur->fItem;
2358  ListTreeHighlight(fListLevel);
2359  fLt->AdjustPosition();
2360  fClient->NeedRedraw(fLt, kTRUE);
2361 
2362  btn2->SetState(kButtonUp);
2363 
2364  cur = (TRootBrowserHistoryCursor*)fHistory->After(fHistoryCursor);
2365  if (!cur) {
2366  btn->SetState(kButtonDisabled);
2367  return kFALSE;
2368  }
2369 
2370  return kTRUE;
2371 }
2372 
2373 ////////////////////////////////////////////////////////////////////////////////
2374 /// delete list tree item, remove it from history
2375 
2376 void TRootBrowserLite::DeleteListTreeItem(TGListTreeItem *item)
2377 {
2378  ((TRootBrowserHistory*)fHistory)->DeleteItem(item);
2379  fLt->DeleteItem(item);
2380 }
2381 
2382 ////////////////////////////////////////////////////////////////////////////////
2383 /// Open tree item and list in iconbox its contents.
2384 
2385 void TRootBrowserLite::ListTreeHighlight(TGListTreeItem *item)
2386 {
2387  if (item) {
2388  TObject *obj = (TObject *) item->GetUserData();
2389 
2390  if (obj) {
2391  if (obj->IsA() == TKey::Class()) {
2392 
2393  TKey *key = (TKey *)obj;
2394  TString name = obj->GetName();
2395  name += ";";
2396  name += key->GetCycle();
2397  Chdir(item->GetParent());
2398  //TObject *k_obj = gROOT->FindObject(name);
2399  TObject *k_obj = gDirectory->FindObjectAny(name);
2400 
2401  if (k_obj) {
2402  item->SetUserData(k_obj);
2403  obj = k_obj;
2404  }
2405  } else if (obj->InheritsFrom(TDirectoryFile::Class())) {
2406  Chdir(item->GetParent());
2407  }
2408  else if (obj->InheritsFrom("TApplicationRemote")) {
2409  if (!gApplication->GetAppRemote()) {
2410  gROOT->ProcessLine(Form(".R %s", item->GetText()));
2411  if (gApplication->GetAppRemote()) {
2412  Getlinem(kInit, TString::Format("\n%s:root [0]",
2413  gApplication->GetAppRemote()->ApplicationName()));
2414  }
2415  }
2416  }
2417  else if (obj->InheritsFrom("TRemoteObject")) {
2418  // special case for remote object
2419  TRemoteObject *robj = (TRemoteObject *)obj;
2420  // the real object is a TKey
2421  if (!strcmp(robj->GetClassName(), "TKey")) {
2422  TGListTreeItem *parent = item;
2423  TRemoteObject *probj = (TRemoteObject *)parent->GetUserData();
2424  // find the TFile remote object containing the TKey
2425  while ( probj && strcmp(probj->GetClassName(), "TFile")) {
2426  parent = parent->GetParent();
2427  probj = (TRemoteObject *)parent->GetUserData();
2428  }
2429  if (probj) {
2430  // remotely browse file (remotely call TFile::cd())
2431  gApplication->SetBit(TApplication::kProcessRemotely);
2432  gApplication->ProcessLine(
2433  TString::Format("((TApplicationServer *)gApplication)->BrowseFile(\"%s\");",
2434  probj->GetName()));
2435  }
2436  }
2437  }
2438  if (item->GetParent() && item->GetParent()->GetUserData() &&
2439  ((TObject *)item->GetParent()->GetUserData())->InheritsFrom("TApplicationRemote")) {
2440  // switch to remote session
2441  if (!gApplication->GetAppRemote()) {
2442  gROOT->ProcessLine(Form(".R %s", item->GetParent()->GetText()));
2443  if (gApplication->GetAppRemote()) {
2444  Getlinem(kInit, TString::Format("\n%s:root [0]",
2445  gApplication->GetAppRemote()->ApplicationName()));
2446  }
2447  }
2448  else if (!strcmp(item->GetText(), "ROOT Files")) {
2449  // update list of files opened in the remote session
2450  gApplication->SetBit(TApplication::kProcessRemotely);
2451  gApplication->ProcessLine("((TApplicationServer *)gApplication)->BrowseFile(0);");
2452  }
2453  }
2454  else {
2455  // check if the listtree item is from a local session or
2456  // from a remote session, then switch to the session it belongs to
2457  TGListTreeItem *top = item;
2458  while (top->GetParent()) {
2459  top = top->GetParent();
2460  }
2461  TObject *topobj = (TObject *) top->GetUserData();
2462  if (topobj && topobj->InheritsFrom("TApplicationRemote")) {
2463  // it belongs to a remote session
2464  if (!gApplication->GetAppRemote()) {
2465  // switch to remote session if not already in
2466  gROOT->ProcessLine(Form(".R %s", top->GetText()));
2467  if (gApplication->GetAppRemote()) {
2468  Getlinem(kInit, TString::Format("\n%s:root [0]",
2469  gApplication->GetAppRemote()->ApplicationName()));
2470  }
2471  }
2472  }
2473  else if (gApplication->GetAppRemote()) {
2474  // switch back to local session if not already in
2475  gApplication->ProcessLine(".R");
2476  Getlinem(kInit, "\nroot [0]");
2477  }
2478  }
2479 
2480  if (!fListLevel || !fListLevel->IsActive()) {
2481  fListLevel = item;
2482  BrowseObj(obj);
2483  fLt->HighlightItem(fListLevel);
2484  }
2485  }
2486  DisplayDirectory();
2487  }
2488 }
2489 
2490 ////////////////////////////////////////////////////////////////////////////////
2491 /// display directory
2492 
2493 void TRootBrowserLite::ToSystemDirectory(const char *dirname)
2494 {
2495  TString dir = dirname;
2496 
2497  if (fListLevel) {
2498  TObject* obj = (TObject*)fListLevel->GetUserData();
2499 
2500  if (obj && (obj->IsA() == TSystemDirectory::Class())) {
2501  TObject* old = obj;
2502  fListLevel->Rename(dir.Data());
2503  obj = new TSystemDirectory(dir.Data(), dir.Data());
2504  while (fListLevel->GetFirstChild())
2505  fLt->RecursiveDeleteItem(fListLevel->GetFirstChild(),
2506  fListLevel->GetFirstChild()->GetUserData());
2507 
2508  fListLevel->SetUserData(obj);
2509  gROOT->GetListOfBrowsables()->Remove(old);
2510  delete old;
2511  gROOT->GetListOfBrowsables()->Add(obj);
2512  fTreeLock = kTRUE;
2513  BrowseObj(obj);
2514  fTreeLock = kFALSE;
2515 
2516  fClient->NeedRedraw(fLt, kTRUE);
2517  fClient->NeedRedraw(fIconBox);
2518  DisplayDirectory();
2519  //gSystem->ChangeDirectory(dir.Data());
2520  fStatusBar->SetText(dir.Data(), 1);
2521  ClearHistory(); // clear browsing history
2522  }
2523  }
2524  return;
2525 }
2526 
2527 ////////////////////////////////////////////////////////////////////////////////
2528 /// sets drawing option
2529 
2530 void TRootBrowserLite::SetDrawOption(Option_t *option)
2531 {
2532  fDrawOption->GetTextEntry()->SetText(option);
2533 }
2534 
2535 ////////////////////////////////////////////////////////////////////////////////
2536 /// returns drawing option
2537 
2538 Option_t *TRootBrowserLite::GetDrawOption() const
2539 {
2540  return fDrawOption->GetTextEntry()->GetText();
2541 }
2542 ////////////////////////////////////////////////////////////////////////////////
2543 /// Emits signal when double clicking on icon.
2544 
2545 void TRootBrowserLite::DoubleClicked(TObject *obj)
2546 {
2547  Emit("DoubleClicked(TObject*)", (Long_t)obj);
2548 }
2549 
2550 ////////////////////////////////////////////////////////////////////////////////
2551 /// Emits signal when double clicking on icon.
2552 
2553 void TRootBrowserLite::Checked(TObject *obj, Bool_t checked)
2554 {
2555  Long_t args[2];
2556 
2557  args[0] = (Long_t)obj;
2558  args[1] = checked;
2559 
2560  Emit("Checked(TObject*,Bool_t)", args);
2561 }
2562 
2563 ////////////////////////////////////////////////////////////////////////////////
2564 /// Default action when double clicking on icon.
2565 
2566 void TRootBrowserLite::IconBoxAction(TObject *obj)
2567 {
2568  Bool_t browsable = kFALSE;
2569  const char *dirname = 0;
2570  if (obj) {
2571 
2572  TRootBrowserCursorSwitcher cursorSwitcher(fIconBox, fLt);
2573 
2574  Bool_t useLock = kTRUE;
2575 
2576  if (obj->IsA()->GetMethodWithPrototype("Browse", "TBrowser*"))
2577  browsable = kTRUE;
2578 
2579  if (obj->InheritsFrom("TLeaf")) {
2580  TObject *dir = (TObject *)gROOT->ProcessLine(Form("((%s *)0x%lx)->GetBranch()->GetDirectory();",
2581  obj->ClassName(), (ULong_t)obj));
2582  if (!dir) {
2583  browsable = kFALSE;
2584  }
2585  }
2586  if (obj->InheritsFrom("TBranchElement")) {
2587  TObject *dir = (TObject *)gROOT->ProcessLine(Form("((%s *)0x%lx)->GetDirectory();",
2588  obj->ClassName(), (ULong_t)obj));
2589  if (!dir) {
2590  browsable = kFALSE;
2591  }
2592  }
2593 
2594  if (obj->InheritsFrom("TKey")) {
2595  TKey *key = dynamic_cast<TKey*>(obj);
2596  if (key && key->GetClassName() && (!strcmp(key->GetClassName(), "TFormula")))
2597  browsable = kFALSE;
2598  }
2599 
2600  if (obj->IsA() == TSystemDirectory::Class()) {
2601  useLock = kFALSE;
2602 
2603  TString t(obj->GetName());
2604  if (t == ".") goto out;
2605  if (t == "..") {
2606  if (fListLevel && fListLevel->GetParent()) {
2607  fListLevel = fListLevel->GetParent();
2608  obj = (TObject*)fListLevel->GetUserData();
2609  if (fListLevel->GetParent()) {
2610  fListLevel = fListLevel->GetParent();
2611  } else {
2612  obj = (TObject*)fListLevel->GetUserData();
2613  fListLevel = 0;
2614  }
2615  } else {
2616  dirname = gSystem->DirName(gSystem->pwd());
2617  ToSystemDirectory(dirname);
2618  return;
2619  }
2620  }
2621  }
2622 
2623  if (obj && obj->IsFolder()) {
2624  fIconBox->RemoveAll();
2625  TGListTreeItem *itm = 0;
2626 
2627  if (fListLevel) {
2628  fLt->OpenItem(fListLevel);
2629  itm = fListLevel->GetFirstChild();
2630  } else {
2631  itm = fLt->GetFirstItem();
2632  }
2633 
2634  while (itm && (itm->GetUserData() != obj)) {
2635  itm = itm->GetNextSibling();
2636  }
2637 
2638  if (!itm && fListLevel) {
2639  // special case for remote objects
2640  Bool_t isRemote = kFALSE;
2641  if (obj->InheritsFrom("TRemoteObject"))
2642  isRemote = kTRUE;
2643  else if (fListLevel) {
2644  // check also if one of its parents is a remote object
2645  TGListTreeItem *top = fListLevel;
2646  while (top->GetParent()) {
2647  TObject *tobj = (TObject *) top->GetUserData();
2648  if (tobj && (tobj->InheritsFrom("TRemoteObject") ||
2649  tobj->InheritsFrom("TApplicationRemote"))) {
2650  isRemote = kTRUE;
2651  break;
2652  }
2653  top = top->GetParent();
2654  }
2655  }
2656  if (isRemote) {
2657  // add the remote object only if not already in the list
2658  if ((!fLt->FindChildByName(fListLevel, obj->GetName())) &&
2659  (!fLt->FindChildByData(fListLevel, obj))) {
2660  itm = fLt->AddItem(fListLevel, obj->GetName());
2661  if (itm) itm->SetUserData(obj);
2662  }
2663  else {
2664  // set the current item to the one found in the list
2665  itm = fLt->FindChildByData(fListLevel, obj) ?
2666  fLt->FindChildByData(fListLevel, obj) :
2667  fLt->FindChildByName(fListLevel, obj->GetName());
2668  }
2669  }
2670  else {
2671  itm = fLt->AddItem(fListLevel, obj->GetName());
2672  if (itm) itm->SetUserData(obj);
2673  }
2674  }
2675 
2676  if (itm) {
2677  fListLevel = itm;
2678  DisplayDirectory();
2679  TObject *kobj = (TObject *)itm->GetUserData();
2680 
2681  if (kobj && kobj->IsA() == TKey::Class()) {
2682  Chdir(fListLevel->GetParent());
2683  //kobj = gROOT->FindObject(kobj->GetName());
2684  kobj = gDirectory->FindObjectAny(kobj->GetName());
2685 
2686  if (kobj) {
2687  TGListTreeItem *parent = fListLevel->GetParent();
2688  DeleteListTreeItem(fListLevel);
2689  TGListTreeItem *kitem = fLt->AddItem(parent, kobj->GetName(), kobj);
2690  if (kitem) {
2691  obj = kobj;
2692  useLock = kFALSE;
2693  kitem->SetUserData(kobj);
2694  fListLevel = kitem;
2695  } else
2696  fListLevel = parent;
2697  }
2698  }
2699  HighlightListLevel();
2700  }
2701  }
2702 
2703  if (browsable) {
2704  if (useLock) fTreeLock = kTRUE;
2705  Emit("BrowseObj(TObject*)", (Long_t)obj);
2706  if (obj) obj->Browse(fBrowser);
2707  if (useLock) fTreeLock = kFALSE;
2708  }
2709 
2710 out:
2711  if (obj && obj->IsA() != TSystemFile::Class()) {
2712  if (obj->IsFolder()) {
2713  fIconBox->Refresh();
2714  }
2715 
2716  if (fBrowser) {
2717  fBrowser->SetRefreshFlag(kFALSE);
2718  }
2719 
2720  fClient->NeedRedraw(fIconBox);
2721  fClient->NeedRedraw(fLt, kTRUE);
2722  }
2723  }
2724 }
2725 
2726 ////////////////////////////////////////////////////////////////////////////////
2727 /// Recursively remove object from browser.
2728 
2729 void TRootBrowserLite::RecursiveRemove(TObject *obj)
2730 {
2731  // don't delete fIconBox items here (it's status will be updated
2732  // via TBrowser::Refresh() which should be called once all objects have
2733  // been removed.
2734 
2735  TGListTreeItem *item = fLt->FindItemByObj(fLt->GetFirstItem(), obj);
2736  if (item == 0)
2737  return;
2738  if (fListLevel && (item == fListLevel)) {
2739  TGListTreeItem *parent = item->GetParent();
2740  if (parent) {
2741  fListLevel = parent;
2742  fLt->ClearHighlighted();
2743  fLt->HighlightItem(fListLevel);
2744  fLt->OpenItem(fListLevel);
2745  }
2746  else
2747  fListLevel = 0;
2748  }
2749  DeleteListTreeItem(item);
2750 }
2751 
2752 ////////////////////////////////////////////////////////////////////////////////
2753 /// Refresh the browser contents.
2754 
2755 void TRootBrowserLite::Refresh(Bool_t force)
2756 {
2757  Bool_t refresh = fBrowser && fBrowser->GetRefreshFlag();
2758 
2759  if (fTextEdit && !gROOT->IsExecutingMacro() && force) {
2760  fTextEdit->LoadFile(fTextFileName.Data());
2761  fClient->NeedRedraw(fTextEdit);
2762  return;
2763  }
2764 
2765  if ( (refresh || force) && !fIconBox->WasGrouped()
2766  && fIconBox->NumItems()<fIconBox->GetGroupSize() ) {
2767 
2768  TRootBrowserCursorSwitcher cursorSwitcher(fIconBox, fLt);
2769  static UInt_t prev = 0;
2770  UInt_t curr = gROOT->GetListOfBrowsables()->GetSize();
2771  if (!prev) prev = curr;
2772 
2773  if (prev != curr) { // refresh gROOT
2774  TGListTreeItem *sav = fListLevel;
2775  fListLevel = 0;
2776  BrowseObj(gROOT);
2777  fListLevel = sav;
2778  prev = curr;
2779  }
2780 
2781  // Refresh the IconBox
2782  if (fListLevel) {
2783  TObject *obj = (TObject *)fListLevel->GetUserData();
2784  if (obj) {
2785  fTreeLock = kTRUE;
2786  BrowseObj(obj);
2787  fTreeLock = kFALSE;
2788  }
2789  }
2790  }
2791  fClient->NeedRedraw(fLt, kTRUE);
2792 }
2793 
2794 ////////////////////////////////////////////////////////////////////////////////
2795 /// Show or hide toolbar.
2796 
2797 void TRootBrowserLite::ShowToolBar(Bool_t show)
2798 {
2799  if (show) {
2800  ShowFrame(fToolBar);
2801  ShowFrame(fToolBarSep);
2802  fViewMenu->CheckEntry(kViewToolBar);
2803  } else {
2804  HideFrame(fToolBar);
2805  HideFrame(fToolBarSep);
2806  fViewMenu->UnCheckEntry(kViewToolBar);
2807  }
2808 }
2809 
2810 ////////////////////////////////////////////////////////////////////////////////
2811 /// Show or hide statusbar.
2812 
2813 void TRootBrowserLite::ShowStatusBar(Bool_t show)
2814 {
2815  if (show) {
2816  ShowFrame(fStatusBar);
2817  fViewMenu->CheckEntry(kViewStatusBar);
2818  } else {
2819  HideFrame(fStatusBar);
2820  fViewMenu->UnCheckEntry(kViewStatusBar);
2821  }
2822 }
2823 
2824 ////////////////////////////////////////////////////////////////////////////////
2825 /// Set defaults depending on settings in the user's .rootrc.
2826 
2827 void TRootBrowserLite::SetDefaults(const char *iconStyle, const char *sortBy)
2828 {
2829  const char *opt;
2830 
2831  // IconStyle: big, small, list, details
2832  if (iconStyle)
2833  opt = iconStyle;
2834  else
2835  opt = gEnv->GetValue("Browser.IconStyle", "small");
2836  if (!strcasecmp(opt, "big"))
2837  SetViewMode(kViewLargeIcons, kTRUE);
2838  else if (!strcasecmp(opt, "small"))
2839  SetViewMode(kViewSmallIcons, kTRUE);
2840  else if (!strcasecmp(opt, "list"))
2841  SetViewMode(kViewList, kTRUE);
2842  else if (!strcasecmp(opt, "details"))
2843  SetViewMode(kViewDetails, kTRUE);
2844  else
2845  SetViewMode(kViewSmallIcons, kTRUE);
2846 
2847  // SortBy: name, type, size, date
2848  if (sortBy)
2849  opt = sortBy;
2850  else
2851  opt = gEnv->GetValue("Browser.SortBy", "name");
2852  if (!strcasecmp(opt, "name"))
2853  SetSortMode(kViewArrangeByName);
2854  else if (!strcasecmp(opt, "type"))
2855  SetSortMode(kViewArrangeByType);
2856  else if (!strcasecmp(opt, "size"))
2857  SetSortMode(kViewArrangeBySize);
2858  else if (!strcasecmp(opt, "date"))
2859  SetSortMode(kViewArrangeByDate);
2860  else
2861  SetSortMode(kViewArrangeByName);
2862 
2863  fIconBox->Refresh();
2864 }
2865 
2866 ////////////////////////////////////////////////////////////////////////////////
2867 /// Set iconbox's view mode and update menu and toolbar buttons accordingly.
2868 
2869 void TRootBrowserLite::SetViewMode(Int_t new_mode, Bool_t force)
2870 {
2871  int i, bnum;
2872  EListViewMode lv;
2873 
2874  if (force || (fViewMode != new_mode)) {
2875 
2876  switch (new_mode) {
2877  default:
2878  if (!force)
2879  return;
2880  else
2881  new_mode = kViewLargeIcons;
2882  // intentionally no break
2883  case kViewLargeIcons:
2884  bnum = 2;
2885  lv = kLVLargeIcons;
2886  break;
2887  case kViewSmallIcons:
2888  bnum = 3;
2889  lv = kLVSmallIcons;
2890  break;
2891  case kViewList:
2892  bnum = 4;
2893  lv = kLVList;
2894  break;
2895  case kViewDetails:
2896  bnum = 5;
2897  lv = kLVDetails;
2898  break;
2899  }
2900 
2901  fViewMode = new_mode;
2902  fViewMenu->RCheckEntry(fViewMode, kViewLargeIcons, kViewDetails);
2903 
2904  for (i = 2; i <= 5; ++i)
2905  gToolBarData[i].fButton->SetState((i == bnum) ? kButtonEngaged : kButtonUp);
2906 
2907  fListView->SetViewMode(lv);
2908  TGTextButton** buttons = fListView->GetHeaderButtons();
2909  if ((lv == kLVDetails) && (buttons)) {
2910  if (!strcmp(fListView->GetHeader(1), "Attributes")) {
2911  buttons[0]->Connect("Clicked()", "TRootBrowserLite", this,
2912  TString::Format("SetSortMode(=%d)", kViewArrangeByName));
2913  buttons[1]->Connect("Clicked()", "TRootBrowserLite", this,
2914  TString::Format("SetSortMode(=%d)", kViewArrangeByType));
2915  buttons[2]->Connect("Clicked()", "TRootBrowserLite", this,
2916  TString::Format("SetSortMode(=%d)", kViewArrangeBySize));
2917  buttons[5]->Connect("Clicked()", "TRootBrowserLite", this,
2918  TString::Format("SetSortMode(=%d)", kViewArrangeByDate));
2919  }
2920  }
2921  fIconBox->AdjustPosition();
2922  }
2923 }
2924 
2925 ////////////////////////////////////////////////////////////////////////////////
2926 /// Set iconbox's sort mode and update menu radio buttons accordingly.
2927 
2928 void TRootBrowserLite::SetSortMode(Int_t new_mode)
2929 {
2930  EFSSortMode smode;
2931 
2932  switch (new_mode) {
2933  default:
2934  new_mode = kViewArrangeByName;
2935  // intentionally no break
2936  case kViewArrangeByName:
2937  smode = kSortByName;
2938  break;
2939  case kViewArrangeByType:
2940  smode = kSortByType;
2941  break;
2942  case kViewArrangeBySize:
2943  smode = kSortBySize;
2944  break;
2945  case kViewArrangeByDate:
2946  smode = kSortByDate;
2947  break;
2948  }
2949 
2950  fSortMode = new_mode;
2951  fSortMenu->RCheckEntry(fSortMode, kViewArrangeByName, kViewArrangeByDate);
2952 
2953  fIconBox->Sort(smode);
2954 }
2955 
2956 ////////////////////////////////////////////////////////////////////////////////
2957 /// starts serach dialog
2958 
2959 void TRootBrowserLite::Search()
2960 {
2961  if (!fTextEdit) {
2962  fIconBox->Search(kFALSE);
2963  } else {
2964  fTextEdit->Search(kFALSE);
2965  }
2966 }
2967 
2968 ////////////////////////////////////////////////////////////////////////////////
2969 /// test
2970 
2971 static Bool_t isBinary(const char *str, int len)
2972 {
2973  for (int i = 0; i < len; i++) {
2974  char c = str[i];
2975  if (((c < 32) || (c > 126)) && (c != '\t') && (c != '\r') && (c != '\n')) {
2976  return kTRUE;
2977  }
2978  }
2979  return kFALSE;
2980 }
2981 
2982 ////////////////////////////////////////////////////////////////////////////////
2983 /// hide text edit
2984 
2985 void TRootBrowserLite::HideTextEdit()
2986 {
2987  if (!fTextEdit) return;
2988 
2989  ShowMacroButtons(kFALSE);
2990  fTextEdit->UnmapWindow();
2991  fV2->RemoveFrame(fTextEdit);
2992  fV2->AddFrame(fListView, fExpandLayout);
2993  TGButton *savbtn = fToolBar->GetButton(kViewSave);
2994  savbtn->Disconnect();
2995  fTextEdit->DestroyWindow();
2996  delete fTextEdit;
2997  fTextEdit = 0;
2998  fListView->Resize(fV2->GetWidth(), fV2->GetHeight());
2999  fV2->MapSubwindows();
3000  fV2->Layout();
3001  fBrowseTextFile = kFALSE;
3002  fTextFileName = "";
3003 }
3004 
3005 ////////////////////////////////////////////////////////////////////////////////
3006 /// browse text file
3007 
3008 void TRootBrowserLite::BrowseTextFile(const char *file)
3009 {
3010  Bool_t loaded = (fTextEdit != 0);
3011  if (gSystem->AccessPathName(file, kReadPermission)) {
3012  if (loaded) {
3013  HistoryBackward();
3014  }
3015  return;
3016  }
3017  const int bufferSize = 1024;
3018  char buffer[bufferSize];
3019 
3020  FILE *fd = fopen(file, "rb");
3021  if (fd == 0) {
3022  if (loaded) {
3023  HistoryBackward();
3024  }
3025  return;
3026  }
3027  int sz = fread(buffer, 1, bufferSize, fd);
3028  fclose(fd);
3029 
3030  if ((sz > 0) && isBinary(buffer, sz)) {
3031  if (loaded) {
3032  HistoryBackward();
3033  }
3034  return;
3035  }
3036 
3037  if (!fTextEdit) {
3038  fTextEdit = new TGTextEdit(fV2, fV2->GetWidth(), fV2->GetHeight(),
3039  kSunkenFrame | kDoubleBorder);
3040  TColor *col = gROOT->GetColor(19);
3041  if (col)
3042  fTextEdit->SetBackgroundColor(col->GetPixel());
3043  if (TGSearchDialog::SearchDialog()) {
3044  TGSearchDialog::SearchDialog()->Connect("TextEntered(char *)", "TGTextEdit",
3045  fTextEdit, "Search(char *,Bool_t,Bool_t)");
3046  }
3047  fV2->AddFrame(fTextEdit, fExpandLayout);
3048  TGButton *savbtn = fToolBar->GetButton(kViewSave);
3049  savbtn->Connect("Released()", "TGTextEdit", fTextEdit, "SaveFile(=0,kTRUE)");
3050  }
3051  fTextFileName = file;
3052  fTextEdit->LoadFile(file);
3053  if (loaded) return;
3054 
3055  if (fTextFileName.EndsWith(".C")) {
3056  ShowMacroButtons();
3057  } else {
3058  fTextEdit->SetReadOnly();
3059  }
3060  fListView->UnmapWindow();
3061  fV2->RemoveFrame(fListView);
3062  fTextEdit->MapWindow();
3063  fV2->MapSubwindows();
3064  fV2->Layout();
3065  fBrowseTextFile = kTRUE;
3066 
3067  if (fListLevel) {
3068  AddToHistory(fListLevel);
3069  }
3070  TGButton *btn = fToolBar->GetButton(kHistoryForw);
3071 
3072  if (btn) {
3073  btn->SetState(kButtonDisabled);
3074  }
3075 
3076  TGButton *btn2 = fToolBar->GetButton(kHistoryBack);
3077 
3078  if (btn2) {
3079  btn2->SetState(kButtonUp);
3080  }
3081 }
3082 
3083 ////////////////////////////////////////////////////////////////////////////////
3084 /// executed browsed text macro
3085 
3086 void TRootBrowserLite::ExecMacro()
3087 {
3088  char *tmpfile = gSystem->ConcatFileName(gSystem->TempDirectory(),
3089  fTextFileName.Data());
3090 
3091  gROOT->SetExecutingMacro(kTRUE);
3092  fTextEdit->SaveFile(tmpfile, kFALSE);
3093  gROOT->Macro(tmpfile);
3094  gSystem->Unlink(tmpfile);
3095  delete [] tmpfile;
3096  gROOT->SetExecutingMacro(kFALSE);
3097 }
3098 
3099 ////////////////////////////////////////////////////////////////////////////////
3100 /// interrupt browsed macro execution
3101 
3102 void TRootBrowserLite::InterruptMacro()
3103 {
3104  gROOT->SetInterrupt(kTRUE);
3105 }
3106 
3107 ////////////////////////////////////////////////////////////////////////////////
3108 /// show/hide macro buttons
3109 
3110 void TRootBrowserLite::ShowMacroButtons(Bool_t show)
3111 {
3112  TGButton *bt1 = fToolBar->GetButton(kViewExec);
3113  TGButton *bt2 = fToolBar->GetButton(kViewInterrupt);
3114  TGButton *bt3 = fToolBar->GetButton(kViewSave);
3115 
3116  static Bool_t connected = kFALSE;
3117 
3118  if (!show) {
3119  bt1->UnmapWindow();
3120  bt2->UnmapWindow();
3121  bt3->UnmapWindow();
3122  } else {
3123  bt1->MapWindow();
3124  bt2->MapWindow();
3125  bt3->MapWindow();
3126 
3127  if (!connected && fTextEdit) {
3128  bt1->Connect("Pressed()", "TRootBrowserLite", this, "ExecMacro()");
3129  bt2->Connect("Pressed()", "TRootBrowserLite", this, "InterruptMacro()");
3130  connected = kTRUE;
3131  }
3132  }
3133 }
3134 
3135 ////////////////////////////////////////////////////////////////////////////////
3136 /// Set text in column col in status bar.
3137 
3138 void TRootBrowserLite::SetStatusText(const char *txt, Int_t col)
3139 {
3140  ShowStatusBar(kTRUE);
3141  TGStatusBar* status = GetStatusBar();
3142  if (status!=0) {
3143  status->SetText(txt, col);
3144  }
3145 }
3146 
3147 ////////////////////////////////////////////////////////////////////////////////
3148 /// Interface method to the old browser.
3149 
3150 TBrowserImp *TRootBrowserLite::NewBrowser(TBrowser *b, const char *title,
3151  UInt_t width, UInt_t height,
3152  Option_t * /*opt*/)
3153 {
3154  TRootBrowserLite *browser = new TRootBrowserLite(b, title, width, height);
3155  return (TBrowserImp *)browser;
3156 }
3157 
3158 ////////////////////////////////////////////////////////////////////////////////
3159 /// Interface method to the old browser.
3160 
3161 TBrowserImp *TRootBrowserLite::NewBrowser(TBrowser *b, const char *title, Int_t x,
3162  Int_t y, UInt_t width, UInt_t height,
3163  Option_t * /*opt*/)
3164 {
3165  TRootBrowserLite *browser = new TRootBrowserLite(b, title, x, y, width, height);
3166  return (TBrowserImp *)browser;
3167 }