From 3cbc65cca297adf2a275196252d34e567bae93fa Mon Sep 17 00:00:00 2001
From: Rene Brun <Rene.Brun@cern.ch>
Date: Tue, 8 Jul 2003 19:42:07 +0000
Subject: [PATCH] From Valery Onuchin - I added new example to guitest which
 demonstrates    how to use TGFileContainer/TGContainer classes.

   This example along with TestListDir example added previously
   reproduces general functionality of TRootBrowser

- added new simplified constructor to TGLVEntry class

- add new method

TGMenuBar::AddPopup(const TString &s, Int_t padleft, Int_t padright,
                   Int_t padtop, Int_t padbottom)

which also simplifies adding of popup-menus

- mods in TGFSContainer.h which allow to make #include <TGFSContainer.h>
  during ROOT session


git-svn-id: http://root.cern.ch/svn/root/trunk@6863 27541ba8-7e3a-0410-8455-c3a389f83636
---
 gui/inc/TGFSContainer.h   |  40 ++------
 gui/inc/TGListView.h      |   8 +-
 gui/inc/TGMenu.h          |   8 +-
 gui/src/TGFSContainer.cxx |  46 ++++++++-
 gui/src/TGListView.cxx    |  55 ++++++++++-
 gui/src/TGMenu.cxx        |  28 +++++-
 gui/src/TRootBrowser.cxx  |   4 +-
 test/guitest.cxx          | 199 +++++++++++++++++++++++++++++++++++++-
 tutorials/guitest.C       | 175 ++++++++++++++++++++++++++++++++-
 9 files changed, 515 insertions(+), 48 deletions(-)

diff --git a/gui/inc/TGFSContainer.h b/gui/inc/TGFSContainer.h
index 7d14dd15587..7dbfc97c6d9 100644
--- a/gui/inc/TGFSContainer.h
+++ b/gui/inc/TGFSContainer.h
@@ -1,4 +1,4 @@
-// @(#)root/gui:$Name:  $:$Id: TGFSContainer.h,v 1.6 2002/11/15 13:24:59 brun Exp $
+// @(#)root/gui:$Name:  $:$Id: TGFSContainer.h,v 1.7 2003/05/28 11:55:31 rdm Exp $
 // Author: Fons Rademakers   19/01/98
 
 /*************************************************************************
@@ -47,36 +47,11 @@ enum EFSSortMode {
 class TRegexp;
 class TGPicture;
 class TGFileContainer;
+class TViewUpdateTimer;
+class TGFileIcon;
+class TGFileItem;
 
-
-
-class TViewUpdateTimer : public TTimer {
-
-private:
-   TGFileContainer   *fContainer;
-
-public:
-   TViewUpdateTimer(TGFileContainer *t, Long_t ms) : TTimer(ms, kTRUE) { fContainer = t; }
-   Bool_t Notify();
-};
-
-
-
-class TGFileIcon : public TGIcon {
-
-protected:
-   const TGPicture *fLpic;
-
-   virtual void DoRedraw();
-
-public:
-   TGFileIcon(const TGWindow *p, const TGPicture *pic, const TGPicture *lpic,
-              UInt_t options = kChildFrame, Pixel_t back = GetWhitePixel()) :
-      TGIcon(p, pic, 0, 0, options, back) { fLpic = lpic; }
-};
-
-
-
+#ifndef __CINT__
 class TGFileItem : public TGLVEntry {
 
 protected:
@@ -105,8 +80,7 @@ public:
    Int_t   GetType() const { return fType; }
    ULong_t GetSize() const { return fSize; }
 };
-
-
+#endif
 
 class TGFileContainer : public TGLVContainer {
 
@@ -139,6 +113,8 @@ public:
    virtual ~TGFileContainer();
 
    virtual Bool_t HandleTimer(TTimer *t);
+   void StopRefreshTimer();
+   void StartRefreshTimer(ULong_t msec=1000);
 
    virtual TGFileItem *AddFile(const char *name);
    virtual void AddFrame(TGFrame *f, TGLayoutHints *l = 0);
diff --git a/gui/inc/TGListView.h b/gui/inc/TGListView.h
index 2beed881c37..d4b729b379e 100644
--- a/gui/inc/TGListView.h
+++ b/gui/inc/TGListView.h
@@ -1,4 +1,4 @@
-// @(#)root/gui:$Name:  $:$Id: TGListView.h,v 1.14 2002/11/15 13:24:59 brun Exp $
+// @(#)root/gui:$Name:  $:$Id: TGListView.h,v 1.15 2003/05/28 11:55:31 rdm Exp $
 // Author: Fons Rademakers   17/01/98
 
 /*************************************************************************
@@ -50,6 +50,7 @@ enum EListViewMode {
 class TGSelectedPicture;
 class TGTextButton;
 class TGListView;
+class TGLVContainer;
 
 
 class TGLVEntry : public TGFrame {
@@ -86,6 +87,11 @@ public:
              TGString *name, TGString **subnames, EListViewMode ViewMode,
              UInt_t options = kChildFrame,
              Pixel_t back = GetWhitePixel());
+
+   TGLVEntry(const TGLVContainer *p,
+             const TString& name, const TString& cname, TGString **subnames = 0,
+             UInt_t options = kChildFrame, Pixel_t back = GetWhitePixel());
+
    virtual ~TGLVEntry();
 
    virtual void SetViewMode(EListViewMode ViewMode);
diff --git a/gui/inc/TGMenu.h b/gui/inc/TGMenu.h
index c765ac46228..a6d0f86aadb 100644
--- a/gui/inc/TGMenu.h
+++ b/gui/inc/TGMenu.h
@@ -1,4 +1,4 @@
-// @(#)root/gui:$Name:  $:$Id: TGMenu.h,v 1.14 2003/03/15 14:19:38 rdm Exp $
+// @(#)root/gui:$Name:  $:$Id: TGMenu.h,v 1.15 2003/05/28 11:55:31 rdm Exp $
 // Author: Fons Rademakers   09/01/98
 
 /*************************************************************************
@@ -270,12 +270,13 @@ protected:
    TList        *fTitles;        // list of menu titles
    Cursor_t      fDefaultCursor; // right pointing cursor
    Bool_t        fStick;         // stick mode (popup menu stays sticked on screen)
+   TList        *fTrash;         // garabge 
 
    virtual void AddFrameBefore(TGFrame *f, TGLayoutHints *l = 0,
                                TGPopupMenu *before = 0);
 
 public:
-   TGMenuBar(const TGWindow *p, UInt_t w, UInt_t h,
+   TGMenuBar(const TGWindow *p, UInt_t w = 60, UInt_t h = 20,
              UInt_t options = kHorizontalFrame | kRaisedFrame);
    virtual ~TGMenuBar();
 
@@ -283,6 +284,9 @@ public:
                          TGPopupMenu *before = 0);
    virtual void AddPopup(const char *s, TGPopupMenu *menu, TGLayoutHints *l,
                          TGPopupMenu *before = 0);
+   virtual TGPopupMenu *AddPopup(const TString &s, Int_t padleft = 0, Int_t padright = 4,
+                                 Int_t padtop = 0, Int_t padbottom = 0);
+
    virtual TGPopupMenu *GetPopup(const char *s);
    virtual TGPopupMenu *RemovePopup(const char *s);
 
diff --git a/gui/src/TGFSContainer.cxx b/gui/src/TGFSContainer.cxx
index 043acf53795..5c4e94f93f9 100644
--- a/gui/src/TGFSContainer.cxx
+++ b/gui/src/TGFSContainer.cxx
@@ -1,4 +1,4 @@
-// @(#)root/gui:$Name:  $:$Id: TGFSContainer.cxx,v 1.10 2002/11/15 13:24:59 brun Exp $
+// @(#)root/gui:$Name:  $:$Id: TGFSContainer.cxx,v 1.11 2003/05/28 11:55:31 rdm Exp $
 // Author: Fons Rademakers   19/01/98
 
 /*************************************************************************
@@ -53,6 +53,32 @@
 
 ClassImp(TGFileContainer)
 
+class TViewUpdateTimer : public TTimer {
+
+private:
+   TGFileContainer   *fContainer;
+
+public:
+   TViewUpdateTimer(TGFileContainer *t, Long_t ms) : TTimer(ms, kTRUE) { fContainer = t; }
+   Bool_t Notify();
+};
+
+
+
+class TGFileIcon : public TGIcon {
+
+protected:
+   const TGPicture *fLpic;
+
+   virtual void DoRedraw();
+
+public:
+   TGFileIcon(const TGWindow *p, const TGPicture *pic, const TGPicture *lpic,
+              UInt_t options = kChildFrame, Pixel_t back = GetWhitePixel()) :
+      TGIcon(p, pic, 0, 0, options, back) { fLpic = lpic; }
+};
+
+
 
 //______________________________________________________________________________
 class TGFSFrameElement : public TGFrameElement {
@@ -689,3 +715,21 @@ TGFileItem *TGFileContainer::AddFile(const char *name)
 #endif
    return item;
 }
+
+//______________________________________________________________________________
+void TGFileContainer::StopRefreshTimer()
+{
+   // stop refresh  timer
+
+   if (fRefresh) delete fRefresh;
+   fRefresh = 0;
+}
+
+//______________________________________________________________________________
+void TGFileContainer::StartRefreshTimer(ULong_t msec)
+{
+   // start refreshing 
+
+   fRefresh = new TViewUpdateTimer(this, msec);
+   gSystem->AddTimer(fRefresh);
+}
diff --git a/gui/src/TGListView.cxx b/gui/src/TGListView.cxx
index e89c4042e03..bbf62b54803 100644
--- a/gui/src/TGListView.cxx
+++ b/gui/src/TGListView.cxx
@@ -1,4 +1,4 @@
-// @(#)root/gui:$Name:  $:$Id: TGListView.cxx,v 1.14 2002/11/15 13:24:59 brun Exp $
+// @(#)root/gui:$Name:  $:$Id: TGListView.cxx,v 1.15 2003/05/28 11:55:31 rdm Exp $
 // Author: Fons Rademakers   17/01/98
 
 /*************************************************************************
@@ -46,7 +46,7 @@
 #include "TList.h"
 #include "TMath.h"
 #include "TSystem.h"
-
+#include "TGMimeTypes.h"
 
 const TGFont *TGLVEntry::fgDefaultFont = 0;
 TGGC         *TGLVEntry::fgDefaultGC = 0;
@@ -114,6 +114,57 @@ TGLVEntry::TGLVEntry(const TGWindow *p, const TGPicture *bigpic,
    }
 }
 
+//______________________________________________________________________________
+TGLVEntry::TGLVEntry(const TGLVContainer *p, const TString& name, 
+                     const TString& cname, TGString **subnames,
+                     UInt_t options, Pixel_t back) :
+   TGFrame(p, 10, 10, options, back)
+{
+   // Create a list view item.
+
+   fSelPic = 0;
+
+   fCurrent  =
+   fBigPic   = fClient->GetMimeTypeList()->GetIcon(cname, kFALSE);
+   fSmallPic = fClient->GetMimeTypeList()->GetIcon(cname, kTRUE);
+
+   fName = new TGString(name);
+   fSubnames = subnames;
+   fUserData = 0;
+
+   fCpos  =
+   fJmode = 0;
+
+   fActive = kFALSE;
+
+   fFontStruct = GetDefaultFontStruct();
+   fNormGC     = GetDefaultGC()();
+
+   Int_t max_ascent, max_descent;
+   fTWidth = gVirtualX->TextWidth(fFontStruct, fName->GetString(), fName->GetLength());
+   gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
+   fTHeight = max_ascent + max_descent;
+
+   if (fSubnames) {
+      Int_t i;
+      for (i = 0; fSubnames[i] != 0; ++i)
+         ;
+      fCtw = new int[i];
+      for (i = 0; fSubnames[i] != 0; ++i)
+         fCtw[i] = gVirtualX->TextWidth(fFontStruct, fSubnames[i]->GetString(),
+                                        fSubnames[i]->GetLength());
+   } else {
+      fCtw = 0;
+   }
+
+   fViewMode = (EListViewMode)-1;
+   SetViewMode((EListViewMode)p->GetViewMode());
+
+   if (!p->IsMapSubwindows()) {
+      fClient->UnregisterWindow(this);
+   }
+}
+
 //______________________________________________________________________________
 TGLVEntry::~TGLVEntry()
 {
diff --git a/gui/src/TGMenu.cxx b/gui/src/TGMenu.cxx
index a574c67fe3e..c1a4dc9f516 100644
--- a/gui/src/TGMenu.cxx
+++ b/gui/src/TGMenu.cxx
@@ -1,4 +1,4 @@
-// @(#)root/gui:$Name:  $:$Id: TGMenu.cxx,v 1.12 2003/04/26 07:48:37 rdm Exp $
+// @(#)root/gui:$Name:  $:$Id: TGMenu.cxx,v 1.13 2003/05/28 11:55:31 rdm Exp $
 // Author: Fons Rademakers   09/01/98
 
 /*************************************************************************
@@ -89,6 +89,7 @@ TGMenuBar::TGMenuBar(const TGWindow *p, UInt_t w, UInt_t h, UInt_t options)
    fTitles        = new TList;
    fStick         = kTRUE;
    fDefaultCursor = fClient->GetResourcePool()->GetGrabCursor();
+   fTrash         = new TList();
 
    gVirtualX->GrabButton(fId, kButton1, kAnyModifier,
                        kButtonPressMask | kButtonReleaseMask | kEnterWindowMask,
@@ -105,6 +106,9 @@ TGMenuBar::~TGMenuBar()
    TGMenuTitle    *t;
    Int_t           keycode;
 
+   fTrash->Delete();
+   delete fTrash;
+
    const TGMainFrame *main = (TGMainFrame *) GetMainFrame();
 
    TIter next(fList);
@@ -149,6 +153,28 @@ void TGMenuBar::AddPopup(const char *s, TGPopupMenu *menu, TGLayoutHints *l,
    AddPopup(new TGHotString(s), menu, l, before);
 }
 
+//______________________________________________________________________________
+TGPopupMenu *TGMenuBar::AddPopup(const TString &s, Int_t padleft, Int_t padright,
+                                 Int_t padtop, Int_t padbottom)
+{
+   // Add popup menu to menu bar. Do not delete returned popup-menu 
+
+   ULong_t hints = kLHintsTop;
+
+   if (padleft)   hints |= kLHintsRight;
+   if (padright)  hints |= kLHintsLeft;
+   if (padtop)    hints |= kLHintsBottom;
+   if (padbottom) hints |= kLHintsTop;
+
+   TGLayoutHints *l = new TGLayoutHints(hints,padleft,padright,0,0);
+   fTrash->Add(l);
+
+   TGPopupMenu *menu = new TGPopupMenu(fClient->GetRoot());
+   AddPopup(new TGHotString(s), menu, l, 0);
+   fTrash->Add(menu);
+   return menu;
+}
+
 //______________________________________________________________________________
 void TGMenuBar::AddFrameBefore(TGFrame *f, TGLayoutHints *l,
                                TGPopupMenu *before)
diff --git a/gui/src/TRootBrowser.cxx b/gui/src/TRootBrowser.cxx
index 6a68c2ade1e..447238821ed 100644
--- a/gui/src/TRootBrowser.cxx
+++ b/gui/src/TRootBrowser.cxx
@@ -1,4 +1,4 @@
-// @(#)root/gui:$Name:  $:$Id: TRootBrowser.cxx,v 1.41 2003/05/23 16:20:24 rdm Exp $
+// @(#)root/gui:$Name:  $:$Id: TRootBrowser.cxx,v 1.42 2003/05/28 11:55:32 rdm Exp $
 // Author: Fons Rademakers   27/02/98
 
 /*************************************************************************
@@ -284,7 +284,7 @@ TRootIconBox::TRootIconBox(TGListView *lv, UInt_t options, ULong_t back) :
    fActiveObject = 0;
 
    // Don't use timer HERE (timer is set in TBrowser).
-   delete fRefresh;
+   StopRefreshTimer();
    fRefresh = 0;
 }
 
diff --git a/test/guitest.cxx b/test/guitest.cxx
index e29e1182ff0..1b5b3985bcf 100644
--- a/test/guitest.cxx
+++ b/test/guitest.cxx
@@ -1,4 +1,4 @@
-// @(#)root/test:$Name:  $:$Id: guitest.cxx,v 1.30 2003/07/02 11:40:06 rdm Exp $
+// @(#)root/test:$Name:  $:$Id: guitest.cxx,v 1.31 2003/07/03 11:41:02 rdm Exp $
 // Author: Fons Rademakers   07/03/98
 
 // guitest.cxx: test program for ROOT native GUI classes.
@@ -15,6 +15,7 @@
 #include <TGResourcePool.h>
 #include <TGListBox.h>
 #include <TGListTree.h>
+#include <TGFSContainer.h>
 #include <TGClient.h>
 #include <TGFrame.h>
 #include <TGIcon.h>
@@ -42,6 +43,9 @@
 #include <TSystem.h>
 #include <TSystemDirectory.h>
 #include <TEnv.h>
+#include <TFile.h>
+#include <TKey.h>
+
 
 
 enum ETestCommandIdentifiers {
@@ -57,6 +61,7 @@ enum ETestCommandIdentifiers {
    M_TEST_SLIDER,
    M_TEST_SHUTTER,
    M_TEST_DIRLIST,
+   M_TEST_FILELIST,
    M_TEST_PROGRESS,
    M_TEST_NUMBERENTRY,
    M_TEST_NEWMENU,
@@ -337,6 +342,27 @@ public:
 };
 
 
+
+class TestFileList  : public TGTransientFrame {
+
+protected:
+   TGFileContainer  *fContents;
+   TList            *fTrash;
+
+   virtual void DisplayFile(const TString &fname);
+   virtual void DisplayDirectory(const TString &fname);
+   virtual void DisplayObject(const TString& fname,const TString& name);
+   virtual void OnDoubleClick(TGLVEntry*,Int_t);
+   virtual void DoMenu(Int_t);
+
+public:
+   TestFileList(const TGWindow *p, const TGWindow *main, UInt_t w, UInt_t h);
+   virtual ~TestFileList();
+
+   virtual Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2);
+};
+
+
 class TestProgress : public TGTransientFrame {
 
 private:
@@ -526,6 +552,7 @@ TestMainFrame::TestMainFrame(const TGWindow *p, UInt_t w, UInt_t h)
    fMenuTest->AddEntry("&Sliders...", M_TEST_SLIDER);
    fMenuTest->AddEntry("Sh&utter...", M_TEST_SHUTTER);
    fMenuTest->AddEntry("&List Directory...", M_TEST_DIRLIST);
+   fMenuTest->AddEntry("&File List...", M_TEST_FILELIST);
    fMenuTest->AddEntry("&Progress...", M_TEST_PROGRESS);
    fMenuTest->AddEntry("&Number Entry...", M_TEST_NUMBERENTRY);
    fMenuTest->AddSeparator();
@@ -730,6 +757,10 @@ Bool_t TestMainFrame::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
                      new TestDirList(gClient->GetRoot(), this, 400, 200);
                      break;
 
+                  case M_TEST_FILELIST:
+                     new TestFileList(gClient->GetRoot(), this, 400, 200);
+                     break;
+
                   case M_TEST_PROGRESS:
                      new TestProgress(fClient->GetRoot(), this, 600, 300);
                      break;
@@ -1669,7 +1700,7 @@ TestDirList::TestDirList(const TGWindow *p, const TGWindow *main,
    TGLayoutHints *lo;
    fIcon = gClient->GetPicture("rootdb_t.xpm");
 
-   TGCanvas* canvas = new TGCanvas(this, 500, 300);
+   TGCanvas* canvas = new TGCanvas(this, w, h);
    fTrash->Add(canvas);
    fContents = new TGListTree(canvas, kHorizontalFrame);
    fContents->Associate(this);
@@ -1703,10 +1734,8 @@ TestDirList::~TestDirList()
    // dtor.
 
    delete fContents;
-
    fTrash->Delete();
    delete fTrash;
-   delete fMain;
 }
 
 TString TestDirList::DirName(TGListTreeItem* item)
@@ -1764,6 +1793,168 @@ Bool_t TestDirList::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
    return kTRUE;
 }
 
+
+
+TestFileList::TestFileList(const TGWindow *p, const TGWindow *main, UInt_t w, UInt_t h) :
+              TGTransientFrame(p, main, w, h)
+{
+   // Create transient frame containing a filelist widget.
+   
+   fTrash = new TList();
+   TGLayoutHints *lo;
+
+   TGMenuBar* mb = new TGMenuBar(this);
+   lo = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1);
+   AddFrame(mb, lo);
+   fTrash->Add(mb);
+   fTrash->Add(lo);
+
+   TGPopupMenu *menu = mb->AddPopup("&View");
+   menu->AddEntry("Lar&ge Icons",kLVLargeIcons);
+   menu->AddEntry("S&mall Icons",kLVSmallIcons);
+   menu->AddEntry("&List",       kLVList);
+   menu->AddEntry("&Details",    kLVDetails);
+   menu->AddEntry("&Close",      10);
+   menu->Associate(this);
+
+   TGListView* lv = new TGListView(this, w, h);
+   lo = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
+   AddFrame(lv,lo);
+   fTrash->Add(lv);
+   fTrash->Add(lo);
+
+   Pixel_t white;
+   gClient->GetColorByName("white",white);
+   fContents = new TGFileContainer(lv,kSunkenFrame,white);
+   fContents->Associate(this);
+
+   // position relative to the parent's window
+   Window_t wdum;
+   int ax, ay;
+   gVirtualX->TranslateCoordinates(main->GetId(), GetParent()->GetId(),
+             (Int_t)(((TGFrame *) main)->GetWidth() - GetWidth()) >> 1,
+             (Int_t)(((TGFrame *) main)->GetHeight() - GetHeight()) >> 1,
+             ax, ay, wdum);
+   Move(ax, ay);
+   SetWindowName("File List Test");
+   Resize(GetDefaultSize());
+   MapSubwindows();
+   MapWindow();
+   fContents->DisplayDirectory();
+   fContents->AddFile("..");  // up level directory
+   fContents->Layout();
+}
+
+TestFileList::~TestFileList()
+{
+   // dtor.
+
+   delete fContents;
+   fTrash->Delete();
+   delete fTrash;
+}
+
+void TestFileList::DisplayFile(const TString &fname)
+{
+   // display content of ROOT file
+
+   TFile file(fname);
+   fContents->RemoveAll();
+   fContents->AddFile(".");
+   fContents->SetPagePosition(0,0);
+
+   TIter next(file.GetListOfKeys());
+   TKey *key;
+
+   while ((key=(TKey*)next())) {
+      TString cname = key->GetClassName();
+      TString name = key->GetName();
+      TGLVEntry *entry = new TGLVEntry(fContents,name,cname);
+      fContents->AddItem(entry);
+
+      // user data is a filename
+      entry->SetUserData((void*)strdup(fname.Data()));
+   }
+   fContents->Layout();
+}
+
+void TestFileList::DisplayDirectory(const TString &fname)
+{
+   // display content of directory
+
+   gSystem->ChangeDirectory(fname);
+   fContents->ChangeDirectory(fname);
+   fContents->DisplayDirectory();
+   fContents->AddFile("..");  // up level directory
+   fContents->Layout();
+}
+
+void TestFileList::DisplayObject(const TString& fname,const TString& name)
+{
+   // browse object located in file
+
+   TDirectory *sav = gDirectory;
+   TFile f(fname);
+   TObject* obj = f.Get(name);
+   if (obj) obj->Browse(0);
+   gDirectory = sav;
+}
+
+
+void TestFileList::DoMenu(Int_t mode)
+{
+   // switch view mode
+
+   if (mode<10) {
+      fContents->SetViewMode((EListViewMode)mode);
+   } else {
+      delete this;
+   }
+}
+
+void TestFileList::OnDoubleClick(TGLVEntry* f, Int_t btn)
+{
+   // handle double click
+
+   if (btn!=kButton1) return;
+ 
+   TString name(f->GetName());
+   const char* fname = (const char*)f->GetUserData();
+
+   if (fname) {
+      DisplayObject(fname,name); 
+   } else if (name.EndsWith(".root")) {
+      DisplayFile(name);
+   } else {
+      DisplayDirectory(name);
+   }
+}
+
+Bool_t TestFileList::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
+{
+   // process message sent to this widget.
+
+   switch (GET_MSG(msg)) {
+
+      case kC_CONTAINER:
+         switch (GET_SUBMSG(msg)) {
+            case kCT_ITEMDBLCLICK:
+               OnDoubleClick((TGLVEntry*)fContents->GetLastActive(), parm1);
+               break;
+         }
+         break;
+      case kC_COMMAND:
+         switch (GET_SUBMSG(msg)) {
+            case kCM_MENU:
+               DoMenu(parm1);
+               break;
+         }
+         break;
+   }
+   return kTRUE;
+}
+
+
 TestProgress::TestProgress(const TGWindow *p, const TGWindow *main,
                            UInt_t w, UInt_t h) :
     TGTransientFrame(p, main, w, h)
diff --git a/tutorials/guitest.C b/tutorials/guitest.C
index 2141e8f3287..795168ee1c3 100644
--- a/tutorials/guitest.C
+++ b/tutorials/guitest.C
@@ -1,4 +1,4 @@
-// @(#)root/tutorials:$Name:  $:$Id: guitest.C,v 1.25 2003/07/02 11:40:07 rdm Exp $
+// @(#)root/tutorials:$Name:  $:$Id: guitest.C,v 1.26 2003/07/03 11:41:02 rdm Exp $
 // Author: Fons Rademakers   22/10/2000
 
 // guitest.C: test program for ROOT native GUI classes exactly like
@@ -16,6 +16,7 @@
 #include <TGResourcePool.h>
 #include <TGListBox.h>
 #include <TGListTree.h>
+#include <TGFSContainer.h>
 #include <TGClient.h>
 #include <TGFrame.h>
 #include <TGIcon.h>
@@ -44,7 +45,8 @@
 #include <TSystem.h>
 #include <TSystemDirectory.h>
 #include <TEnv.h>
-
+#include <TFile.h>
+#include <TKey.h>
 
 enum ETestCommandIdentifiers {
    M_FILE_OPEN,
@@ -59,6 +61,7 @@ enum ETestCommandIdentifiers {
    M_TEST_SLIDER,
    M_TEST_SHUTTER,
    M_TEST_DIRLIST,
+   M_TEST_FILELIST,
    M_TEST_PROGRESS,
    M_TEST_NUMBERENTRY,
    M_TEST_NEWMENU,
@@ -385,6 +388,28 @@ public:
 };
 
 
+class TestFileList {
+
+RQ_OBJECT("TestFileList")
+
+protected:
+   TGMainFrame      *fMain;
+   TGFileContainer  *fContents;
+   TList            *fTrash;
+
+   virtual void DisplayFile(const TString &fname);
+   virtual void DisplayDirectory(const TString &fname);
+   virtual void DisplayObject(const TString& fname,const TString& name);
+
+public:
+   TestFileList(const TGWindow *p, const TGWindow *main, UInt_t w, UInt_t h);
+   virtual ~TestFileList();
+
+   // slots
+   virtual void OnDoubleClick(TGLVEntry*,Int_t);
+   virtual void DoMenu(Int_t);
+};
+
 class TestProgress {
 
 private:
@@ -594,6 +619,7 @@ TestMainFrame::TestMainFrame(const TGWindow *p, UInt_t w, UInt_t h)
    fMenuTest->AddEntry("&Sliders...", M_TEST_SLIDER);
    fMenuTest->AddEntry("Sh&utter...", M_TEST_SHUTTER);
    fMenuTest->AddEntry("&List Directory...", M_TEST_DIRLIST);
+   fMenuTest->AddEntry("&File List...", M_TEST_FILELIST);
    fMenuTest->AddEntry("&Progress...", M_TEST_PROGRESS);
    fMenuTest->AddEntry("&Number Entry...", M_TEST_NUMBERENTRY);
    fMenuTest->AddSeparator();
@@ -805,6 +831,10 @@ void TestMainFrame::HandleMenu(Int_t id)
          new TestDirList(gClient->GetRoot(), fMain, 400, 200);
          break;
 
+     case M_TEST_FILELIST:
+         new TestFileList(gClient->GetRoot(), fMain, 400, 200);
+         break;
+
       case M_TEST_PROGRESS:
          new TestProgress(gClient->GetRoot(), fMain, 600, 300);
          break;
@@ -1151,7 +1181,7 @@ void TestDialog::DoOK()
 
    // The same effect can be obtained by using a singleshot timer:
    //TTimer::SingleShot(50, "TestDialog", this, "CloseWindow()");
-}Contents->AddItem(0,"/");  // browse the upper directory
+}
 
 
 void TestDialog::DoCancel()
@@ -1856,6 +1886,145 @@ void TestDirList::OnDoubleClick(TGListTreeItem* item, Int_t btn)
 }
 
 
+TestFileList::TestFileList(const TGWindow *p, const TGWindow *main, UInt_t w, UInt_t h)
+{
+   // Create transient frame containing a filelist widget.
+   
+   fTrash = new TList();
+   TGLayoutHints *lo;
+
+   fMain = new TGTransientFrame(p, main, w, h);
+
+   TGMenuBar* mb = new TGMenuBar(fMain);
+   lo = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1);
+   fMain->AddFrame(mb, lo);
+   fTrash->Add(mb);
+   fTrash->Add(lo);
+
+   TGPopupMenu *menu = mb->AddPopup("&View");
+   menu->AddEntry("Lar&ge Icons",kLVLargeIcons);
+   menu->AddEntry("S&mall Icons",kLVSmallIcons);
+   menu->AddEntry("&List",       kLVList);
+   menu->AddEntry("&Details",    kLVDetails);
+   menu->AddEntry("&Close",      10);
+   menu->Connect("Activated(Int_t)","TestFileList",this,"DoMenu(Int_t)");
+
+   TGListView* lv = new TGListView(fMain, w, h);
+   lo = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
+   fMain->AddFrame(lv,lo);
+   fTrash->Add(lv);
+   fTrash->Add(lo);
+
+   Pixel_t white;
+   gClient->GetColorByName("white",white);
+   fContents = new TGFileContainer(lv,kSunkenFrame,white);
+   fContents->Connect("DoubleClicked(TGFrame*,Int_t)","TestFileList",this,
+                      "OnDoubleClick(TGLVEntry*,Int_t)");
+
+   // position relative to the parent's window
+   Window_t wdum;
+   int ax, ay;
+   gVirtualX->TranslateCoordinates(main->GetId(), fMain->GetParent()->GetId(),
+             (Int_t)(((TGFrame *) main)->GetWidth() - fMain->GetWidth()) >> 1,
+             (Int_t)(((TGFrame *) main)->GetHeight() - fMain->GetHeight()) >> 1,
+             ax, ay, wdum);
+   fMain->Move(ax, ay);
+
+   fMain->SetWindowName("File List Test");
+   fMain->Resize(fMain->GetDefaultSize());
+   fMain->MapSubwindows();
+   fMain->MapWindow();
+   fContents->DisplayDirectory();
+   fContents->AddFile("..");  // up level directory
+   fContents->Layout();
+}
+
+TestFileList::~TestFileList()
+{
+   // dtor.
+
+   delete fContents;
+   fTrash->Delete();
+   delete fTrash;
+   delete fMain;
+}
+
+void TestFileList::DoMenu(Int_t mode)
+{
+   // switch view mode
+
+   if (mode<10) {
+      fContents->SetViewMode((EListViewMode)mode);
+   } else {
+      delete this;
+   }
+}
+
+void TestFileList::DisplayFile(const TString &fname)
+{
+   // display content of ROOT file
+
+   TFile file(fname);
+   fContents->RemoveAll();
+   fContents->AddFile(".");
+   fContents->SetPagePosition(0,0);
+
+   TIter next(file.GetListOfKeys());
+   TKey *key;
+
+   while ((key=(TKey*)next())) {
+      TString cname = key->GetClassName();
+      TString name = key->GetName();
+      TGLVEntry *entry = new TGLVEntry(fContents,name,cname);
+      fContents->AddItem(entry);
+
+      // user data is a filename
+      entry->SetUserData((void*)strdup(fname.Data()));
+   }
+   fContents->Layout();
+}
+
+void TestFileList::DisplayDirectory(const TString &fname)
+{
+   // display content of directory
+
+   gSystem->ChangeDirectory(fname);
+   fContents->ChangeDirectory(fname);
+   fContents->DisplayDirectory();
+   fContents->AddFile("..");  // up level directory
+   fContents->Layout();
+}
+
+void TestFileList::DisplayObject(const TString& fname,const TString& name)
+{
+   // browse object located in file
+
+   TDirectory *sav = gDirectory;
+   TFile f(fname);
+   TObject* obj = f.Get(name);
+   if (obj) obj->Browse(0);
+   gDirectory = sav;
+}
+
+void TestFileList::OnDoubleClick(TGLVEntry* f, Int_t btn)
+{
+   // handle double click
+
+   if (btn!=kButton1) return;
+ 
+   TString name(f->GetName());
+   const char* fname = (const char*)f->GetUserData();
+
+   if (fname) {
+      DisplayObject(fname,name); 
+   } else if (name.EndsWith(".root")) {
+      DisplayFile(name);
+   } else {
+      DisplayDirectory(name);
+   }
+}
+
+
 TestProgress::TestProgress(const TGWindow *p, const TGWindow *main,
                            UInt_t w, UInt_t h)
 {
-- 
GitLab