TGFileBrowser.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGFileBrowser.cxx 36426 2010-10-26 18:03:52Z bellenot $
00002 // Author: Bertrand Bellenot   26/09/2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "TROOT.h"
00013 #include "TSystem.h"
00014 #include "TApplication.h"
00015 #include "TGClient.h"
00016 #include "TGListTree.h"
00017 #include "TGLayout.h"
00018 #include "TGComboBox.h"
00019 #include "TContextMenu.h"
00020 #include "TGTextEntry.h"
00021 #include "TGTab.h"
00022 #include "TGLabel.h"
00023 #include "TSystemDirectory.h"
00024 #include "TGMimeTypes.h"
00025 #include "TClass.h"
00026 #include "TQClass.h"
00027 #include "TDataMember.h"
00028 #include "TMethod.h"
00029 #include "TMethodArg.h"
00030 #include "TRealData.h"
00031 #include "TInterpreter.h"
00032 #include "TRegexp.h"
00033 #include "TEnv.h"
00034 #include "TImage.h"
00035 #include "TBrowser.h"
00036 #include "TRemoteObject.h"
00037 #include "TVirtualPad.h"
00038 #include "Getline.h"
00039 #include <time.h>
00040 #include <string.h>
00041 #include <stdlib.h>
00042 
00043 #include "TGFileBrowser.h"
00044 #include "TRootBrowser.h"
00045 
00046 #include "TVirtualPadEditor.h"
00047 #include "TGedEditor.h"
00048 #include "TBaseClass.h"
00049 
00050 #ifdef WIN32
00051 const char rootdir[] = "\\";
00052 #else
00053 const char rootdir[] = "/";
00054 #endif
00055 
00056 const char *filters[] = {
00057    "",
00058    "*.*",
00059    "*.[C|c|h]*",
00060    "*.root",
00061    "*.txt"
00062 };
00063 
00064 //_____________________________________________________________________________
00065 //
00066 // TCursorSwitcher
00067 //
00068 // Helper class used to change the cursor in a method and restore the
00069 // original one when going out of the method scope.
00070 //_____________________________________________________________________________
00071 
00072 ///////////////////////////////////////////////////////////////////////////////
00073 class TCursorSwitcher {
00074 private:
00075    TGWindow *fW1;
00076    TGWindow *fW2;
00077 public:
00078    TCursorSwitcher(TGWindow *w1, TGWindow *w2) : fW1(w1), fW2(w2) {
00079       if (w1) gVirtualX->SetCursor(w1->GetId(), gVirtualX->CreateCursor(kWatch));
00080       if (w2) gVirtualX->SetCursor(w2->GetId(), gVirtualX->CreateCursor(kWatch));
00081    }
00082    ~TCursorSwitcher() {
00083       if (fW1) gVirtualX->SetCursor(fW1->GetId(), gVirtualX->CreateCursor(kPointer));
00084       if (fW2) gVirtualX->SetCursor(fW2->GetId(), gVirtualX->CreateCursor(kPointer));
00085    }
00086 };
00087 
00088 //_____________________________________________________________________________
00089 //
00090 // TGFileBrowser
00091 //
00092 // System file browser, used as TRootBrowser plug-in.
00093 // This class is the real core of the ROOT browser.
00094 //_____________________________________________________________________________
00095 
00096 ClassImp(TGFileBrowser)
00097 
00098 //______________________________________________________________________________
00099 TGFileBrowser::TGFileBrowser(const TGWindow *p, TBrowser* b, UInt_t w, UInt_t h)
00100    : TGMainFrame(p, w, h), TBrowserImp(b), fNewBrowser(0)
00101 {
00102    // TGFileBrowser constructor.
00103 
00104    if (p && p != gClient->GetDefaultRoot())
00105       fNewBrowser = (TRootBrowser *)p->GetMainFrame();
00106    if (fNewBrowser)
00107       fNewBrowser->SetActBrowser(this);
00108    CreateBrowser();
00109    Resize(w, h);
00110    if (fBrowser) Show();
00111 }
00112 
00113 //______________________________________________________________________________
00114 void TGFileBrowser::CreateBrowser()
00115 {
00116    // Create the actual file browser.
00117 
00118    fCachedPic  = 0;
00119    SetCleanup(kDeepCleanup);
00120 
00121    fTopFrame = new TGHorizontalFrame(this, 100, 30);
00122    fDrawOption = new TGComboBox(fTopFrame, "");
00123    TGTextEntry *dropt_entry = fDrawOption->GetTextEntry();
00124    dropt_entry->SetToolTipText("Object Draw Option", 300);
00125    fDrawOption->Resize(80, 20);
00126    TGListBox *lb = fDrawOption->GetListBox();
00127    lb->Resize(lb->GetWidth(), 120);
00128    Int_t dropt = 1;
00129    fDrawOption->AddEntry("", dropt++);
00130    fDrawOption->AddEntry(" alp", dropt++);
00131    fDrawOption->AddEntry(" box", dropt++);
00132    fDrawOption->AddEntry(" colz", dropt++);
00133    fDrawOption->AddEntry(" lego", dropt++);
00134    fDrawOption->AddEntry(" lego1", dropt++);
00135    fDrawOption->AddEntry(" lego2", dropt++);
00136    fDrawOption->AddEntry(" same", dropt++);
00137    fDrawOption->AddEntry(" surf", dropt++);
00138    fDrawOption->AddEntry(" surf1", dropt++);
00139    fDrawOption->AddEntry(" surf2", dropt++);
00140    fDrawOption->AddEntry(" surf3", dropt++);
00141    fDrawOption->AddEntry(" surf4", dropt++);
00142    fDrawOption->AddEntry(" surf5", dropt++);
00143    fDrawOption->AddEntry(" text", dropt++);
00144    fTopFrame->AddFrame(fDrawOption, new TGLayoutHints(kLHintsCenterY |
00145                        kLHintsRight, 2, 2, 2, 2));
00146    fTopFrame->AddFrame(new TGLabel(fTopFrame, "Draw Option: "),
00147                        new TGLayoutHints(kLHintsCenterY | kLHintsRight,
00148                        2, 2, 2, 2));
00149 
00150    fSortButton = new TGPictureButton(fTopFrame, "bld_sortup.png");
00151    fSortButton->SetToolTipText("Sort Alphabetically\n(Current folder only)");
00152    fTopFrame->AddFrame(fSortButton, new TGLayoutHints(kLHintsCenterY |
00153                        kLHintsLeft, 2, 2, 2, 2));
00154    fSortButton->Connect("Clicked()", "TGFileBrowser", this, "ToggleSort()");
00155 
00156    fRefreshButton = new TGPictureButton(fTopFrame, "tb_refresh.xpm");
00157    fRefreshButton->SetToolTipText("Refresh Current Folder");
00158    fTopFrame->AddFrame(fRefreshButton, new TGLayoutHints(kLHintsCenterY |
00159                        kLHintsLeft, 2, 2, 2, 2));
00160    fRefreshButton->Connect("Clicked()", "TGFileBrowser", this, "Refresh()");
00161 
00162    AddFrame(fTopFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop |
00163             kLHintsExpandX, 2, 2, 2, 2));
00164    fCanvas   = new TGCanvas(this, 100, 100);
00165    fListTree = new TGListTree(fCanvas, kHorizontalFrame);
00166    AddFrame(fCanvas, new TGLayoutHints(kLHintsLeft | kLHintsTop |
00167                 kLHintsExpandX | kLHintsExpandY));
00168    fListTree->Connect("DoubleClicked(TGListTreeItem *, Int_t)",
00169       "TGFileBrowser", this, "DoubleClicked(TGListTreeItem *, Int_t)");
00170    fListTree->Connect("Clicked(TGListTreeItem *, Int_t, Int_t, Int_t)",
00171       "TGFileBrowser", this, "Clicked(TGListTreeItem *, Int_t, Int_t, Int_t)");
00172    fListTree->Connect("Checked(TObject*, Bool_t)", "TGFileBrowser",
00173       this, "Checked(TObject*, Bool_t)");
00174 
00175    fRootIcon = gClient->GetPicture("rootdb_t.xpm");
00176    fFileIcon = gClient->GetPicture("doc_t.xpm");
00177 
00178    fBotFrame = new TGHorizontalFrame(this, 100, 30);
00179    fBotFrame->AddFrame(new TGLabel(fBotFrame, "Filter: "),
00180                        new TGLayoutHints(kLHintsCenterY | kLHintsLeft,
00181                        2, 2, 2, 2));
00182    fFileType = new TGComboBox(fBotFrame, " All Files (*.*)");
00183    Int_t ftype = 1;
00184    fFileType->AddEntry(" All Files (*.*)", ftype++);
00185    fFileType->AddEntry(" C/C++ Files (*.c;*.cxx;*.h;...)", ftype++);
00186    fFileType->AddEntry(" ROOT Files (*.root)", ftype++);
00187    fFileType->AddEntry(" Text Files (*.txt)", ftype++);
00188    fFileType->Resize(200, 20);
00189    fBotFrame->AddFrame(fFileType, new TGLayoutHints(kLHintsLeft | kLHintsTop |
00190                 kLHintsExpandX, 2, 2, 2, 2));
00191    fFileType->Connect("Selected(Int_t)", "TGFileBrowser", this, "ApplyFilter(Int_t)");
00192    AddFrame(fBotFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop |
00193             kLHintsExpandX, 2, 2, 2, 2));
00194 
00195    fContextMenu = new TContextMenu("FileBrowserContextMenu");
00196    fFilter      = 0;
00197    fGroupSize   = 1000;
00198    fListLevel   = 0;
00199    fCurrentDir  = 0;
00200    fRootDir     = 0;
00201    fDir         = 0;
00202    fFile        = 0;
00203    fNKeys       = 0;
00204    fCnt         = 0;
00205 
00206    TString gv = gEnv->GetValue("Browser.GroupView", "1000");
00207    Int_t igv = atoi(gv.Data());
00208    if (igv > 10)
00209       fGroupSize = igv;
00210 
00211    if (gEnv->GetValue("Browser.ShowHidden", 0))
00212       fShowHidden = kTRUE;
00213    else
00214       fShowHidden = kFALSE;
00215 
00216    fDblClick = kFALSE;
00217 
00218    TQObject::Connect("TGHtmlBrowser", "Clicked(char*)",
00219                      "TGFileBrowser", this, "Selected(char*)");
00220 
00221    TQObject::Connect("TPad", "Modified()",
00222                      "TGFileBrowser", this, "PadModified()");
00223 
00224    fListLevel = 0;
00225    MapSubwindows();
00226    Resize(GetDefaultSize());
00227    MapWindow();
00228 }
00229 
00230 //______________________________________________________________________________
00231 TGFileBrowser::~TGFileBrowser()
00232 {
00233    // Destructor.
00234 
00235    TQObject::Disconnect("TGHtmlBrowser", "Clicked(char*)");
00236    TQObject::Disconnect("TPad", "Modified()");
00237 
00238    delete fContextMenu;
00239    delete fListTree;
00240    if (fRootIcon) fClient->FreePicture(fRootIcon);
00241    if (fCachedPic && (fCachedPic != fFileIcon))
00242       fClient->FreePicture(fCachedPic);
00243    if (fFileIcon) fClient->FreePicture(fFileIcon);
00244    Cleanup();
00245 }
00246 
00247 //______________________________________________________________________________
00248 static Bool_t IsObjectEditable(TClass *cl)
00249 {
00250    // Helper function checking if a class has a graphic properties editor.
00251 
00252    TBaseClass *base;
00253    TList* bcl = cl->GetListOfBases();
00254    TIter next(bcl);
00255    while ((base = (TBaseClass*) next())) {
00256       cl = base->GetClassPointer();
00257       if (cl && TClass::GetClass(Form("%sEditor", cl->GetName())))
00258          return kTRUE;
00259       if (IsObjectEditable(cl))
00260          return kTRUE;
00261    }
00262    return kFALSE;
00263 }
00264 
00265 //______________________________________________________________________________
00266 static const char *FormatToolTip(TObject *obj, Int_t maxlen=0)
00267 {
00268    // Format the tooltip information, based on the object passed in argument.
00269 
00270    static TString infos;
00271    if (!obj) {
00272       infos.Clear();
00273       return 0;
00274    }
00275    infos = obj->GetName();
00276    if (obj->GetTitle()) {
00277       infos += "\n";
00278       infos += obj->GetTitle();
00279    }
00280    if (maxlen > 0 && infos.Length() > maxlen) {
00281       infos.Remove(maxlen - 3);
00282       infos += "...";
00283    }
00284    TString objinfo = obj->GetObjectInfo(1, 1);
00285    if (!objinfo.IsNull() && !objinfo.BeginsWith("x=")) {
00286       Long64_t bsize, fsize, objsize;
00287       objsize = objinfo.Atoll();
00288       if (objsize > 0) {
00289          infos += "\n";
00290          bsize = fsize = objsize;
00291          if (fsize > 1024) {
00292             fsize /= 1024;
00293             if (fsize > 1024) {
00294                // 3.7MB is more informative than just 3MB
00295                infos += TString::Format("Size: %lld.%lldM", fsize/1024,
00296                                         (fsize%1024)/103);
00297             } else {
00298                infos += TString::Format("Size: %lld.%lldK", bsize/1024,
00299                                         (bsize%1024)/103);
00300             }
00301          } else {
00302             infos += TString::Format("Size: %lld bytes", bsize);
00303          }
00304       }
00305    }
00306    return infos.Data();
00307 }
00308 
00309 /**************************************************************************/
00310 // TBrowserImp virtuals
00311 /**************************************************************************/
00312 
00313 //______________________________________________________________________________
00314 void TGFileBrowser::Add(TObject *obj, const char *name, Int_t check)
00315 {
00316    // Add items to the browser. This function has to be called
00317    // by the Browse() member function of objects when they are
00318    // called by a browser. If check < 0 (default) no check box is drawn,
00319    // if 0 then unchecked checkbox is added, if 1 checked checkbox is added.
00320 
00321    if (fListLevel && !strcmp(fListLevel->GetText(), "Classes") &&
00322       fListLevel->GetParent() &&
00323       !strcmp(fListLevel->GetParent()->GetText(), "root")) {
00324       // Browsing list of root classes...
00325    }
00326    else {
00327       if (obj && obj->InheritsFrom("TApplication"))
00328          fListLevel = 0;
00329       if (obj && obj->InheritsFrom("TSystemDirectory"))
00330          return;
00331    }
00332    const TGPicture *pic=0;
00333    if (obj && obj->InheritsFrom("TKey") && (obj->IsA() != TClass::Class()))
00334       AddKey(fListLevel, obj, name);
00335    else if (obj) {
00336       GetObjPicture(&pic, obj);
00337       if (!name) name = obj->GetName();
00338       if (check > -1) {
00339          if (!fListTree->FindChildByName(fListLevel, name)) {
00340             TGListTreeItem *item = fListTree->AddItem(fListLevel, name, obj,
00341                                                       pic, pic, kTRUE);
00342             if ((pic != fFileIcon) && (pic != fCachedPic))
00343                fClient->FreePicture(pic);
00344             if (item) fListTree->CheckItem(item, (Bool_t)check);
00345             fListTree->SetToolTipItem(item, FormatToolTip(obj, 32));
00346          }
00347       }
00348       else {
00349          // special case for remote object
00350          Bool_t isRemote = kFALSE;
00351          if (obj->InheritsFrom("TRemoteObject"))
00352             isRemote = kTRUE;
00353          else if (fListLevel) {
00354             // check also if one of its parents is a remote object
00355             TGListTreeItem *top = fListLevel;
00356             while (top->GetParent()) {
00357                TObject *tobj = (TObject *) top->GetUserData();
00358                if (tobj && (tobj->InheritsFrom("TRemoteObject") ||
00359                   tobj->InheritsFrom("TApplicationRemote"))) {
00360                   isRemote = kTRUE;
00361                   break;
00362                }
00363                top = top->GetParent();
00364             }
00365          }
00366          if (isRemote) {
00367             TRemoteObject *robj = (TRemoteObject *)obj;
00368             if (!strcmp(robj->GetClassName(), "TKey")) {
00369                AddKey(fListLevel, obj, name);
00370             }
00371             else {
00372                TString fname = name;
00373                // add the remote object only if not already in the list
00374                if (!fShowHidden && fname.BeginsWith("."))
00375                   return;
00376                AddRemoteFile(obj);
00377             }
00378          }
00379          else {
00380             if (!fListTree->FindChildByName(fListLevel, name)) {
00381                TGListTreeItem *item = fListTree->AddItem(fListLevel, name, obj, pic, pic);
00382                if ((pic != fFileIcon) && (pic != fCachedPic))
00383                   fClient->FreePicture(pic);
00384                if (item && obj && obj->InheritsFrom("TObject"))
00385                   item->SetDNDSource(kTRUE);
00386                fListTree->SetToolTipItem(item, FormatToolTip(obj, 32));
00387             }
00388          }
00389       }
00390    }
00391 }
00392 
00393 //______________________________________________________________________________
00394 void TGFileBrowser::AddRemoteFile(TObject *obj)
00395 {
00396    // Add remote file in list tree.
00397 
00398    Bool_t      is_link;
00399    Int_t       type, uid, gid;
00400    Long_t      modtime;
00401    Long64_t    size;
00402    TString     filename;
00403    const TGPicture *spic;
00404    TGPicture *pic;
00405 
00406    FileStat_t sbuf;
00407 
00408    type    = 0;
00409    size    = 0;
00410    uid     = 0;
00411    gid     = 0;
00412    modtime = 0;
00413    is_link = kFALSE;
00414 
00415    TRemoteObject *robj = (TRemoteObject *)obj;
00416 
00417    robj->GetFileStat(&sbuf);
00418    is_link = sbuf.fIsLink;
00419    type    = sbuf.fMode;
00420    size    = sbuf.fSize;
00421    uid     = sbuf.fUid;
00422    gid     = sbuf.fGid;
00423    modtime = sbuf.fMtime;
00424    filename = robj->GetName();
00425    if (R_ISDIR(type) || fFilter == 0 ||
00426        (fFilter && filename.Index(*fFilter) != kNPOS)) {
00427 
00428       GetFilePictures(&spic, type, is_link, filename);
00429 
00430       pic = (TGPicture*)spic; pic->AddReference();
00431 
00432       if ((!fListTree->FindChildByName(fListLevel, filename)) &&
00433          (!fListTree->FindChildByData(fListLevel, obj)))
00434          fListTree->AddItem(fListLevel, filename, obj, pic, pic);
00435    }
00436 }
00437 
00438 //______________________________________________________________________________
00439 void TGFileBrowser::BrowseObj(TObject *obj)
00440 {
00441    // Browse object. This, in turn, will trigger the calling of
00442    // TBrowser::Add() which will fill the IconBox and the tree.
00443    // Emits signal "BrowseObj(TObject*)".
00444 
00445    if (fNewBrowser)
00446       fNewBrowser->SetActBrowser(this);
00447    if (obj != gROOT) {
00448       if (!fListTree->FindItemByObj(fListTree->GetFirstItem(), obj)) {
00449          fListLevel = 0;
00450          Add(obj);
00451          fListLevel = fListTree->FindItemByObj(fListTree->GetFirstItem(), obj);
00452          fListTree->HighlightItem(fListLevel);
00453          if (obj->IsFolder())
00454             fListTree->OpenItem(fListLevel);
00455          fListTree->ClearViewPort();
00456          fListTree->AdjustPosition(fListLevel);
00457       }
00458    }
00459    obj->Browse(fBrowser);
00460    if (obj == gROOT) {
00461       TList *volumes = gSystem->GetVolumes("all");
00462       TList *curvol  = gSystem->GetVolumes("cur");
00463       if (volumes && curvol) {
00464          const char *curdrive;
00465          TNamed *named = (TNamed *)curvol->At(0);
00466          if (named)
00467             curdrive = named->GetName();
00468          else
00469             curdrive = "C:";
00470          TIter next(volumes);
00471          TNamed *drive;
00472          while ((drive = (TNamed *)next())) {
00473             AddFSDirectory(TString::Format("%s\\", drive->GetName()), drive->GetTitle(),
00474                            (strcmp(drive->GetName(), curdrive) == 0) ?
00475                            "SetRootDir" : "Add");
00476          }
00477          delete volumes;
00478          delete curvol;
00479       }
00480       else {
00481          AddFSDirectory("/");
00482       }
00483       GotoDir(gSystem->WorkingDirectory());
00484       if (gROOT->GetListOfFiles() && !gROOT->GetListOfFiles()->IsEmpty())
00485          Selected(0);
00486    }
00487 }
00488 
00489 //______________________________________________________________________________
00490 void TGFileBrowser::Checked(TObject *obj, Bool_t checked)
00491 {
00492    // Emits signal when double clicking on icon.
00493 
00494    if (fNewBrowser)
00495       fNewBrowser->Checked(obj, checked);
00496 }
00497 
00498 //______________________________________________________________________________
00499 Option_t *TGFileBrowser::GetDrawOption() const
00500 {
00501    // returns drawing option
00502 
00503    return fDrawOption->GetTextEntry()->GetText();
00504 }
00505 
00506 //______________________________________________________________________________
00507 void TGFileBrowser::GetFilePictures(const TGPicture **pic, Int_t file_type,
00508                                     Bool_t is_link, const char *name)
00509 {
00510    // Determine the file picture for the given file type.
00511 
00512    static TString cached_ext;
00513    static const TGPicture *cached_spic = 0;
00514    const char *ext = name ? strrchr(name, '.') : 0;
00515    TString sname = name ? name : " ";
00516    *pic = 0;
00517 
00518    if (ext && cached_spic && (cached_ext == ext)) {
00519       *pic = cached_spic;
00520       return;
00521    }
00522 
00523    if (R_ISREG(file_type)) {
00524       *pic = gClient->GetMimeTypeList()->GetIcon(name, kTRUE);
00525 
00526       if (*pic) {
00527          if (ext) {
00528             cached_ext = ext;
00529             cached_spic = *pic;
00530             return;
00531          }
00532       }
00533    } else {
00534       *pic = 0;
00535    }
00536 
00537    if (*pic == 0) {
00538       *pic = gClient->GetPicture("doc_t.xpm");
00539 
00540       if (R_ISREG(file_type) && (file_type) & kS_IXUSR) {
00541          *pic = gClient->GetPicture("app_t.xpm");
00542       }
00543       if (R_ISDIR(file_type)) {
00544          *pic = gClient->GetPicture("folder_t.xpm");
00545       }
00546       if(sname.EndsWith(".root")) {
00547          *pic = gClient->GetPicture("rootdb_t.xpm");
00548       }
00549 
00550    }
00551    if (is_link) {
00552       *pic = gClient->GetPicture("slink_t.xpm");
00553    }
00554 
00555    cached_spic = 0;
00556    cached_ext = "";
00557 }
00558 
00559 //______________________________________________________________________________
00560 void TGFileBrowser::RecursiveRemove(TObject *obj)
00561 {
00562    // Recursively remove object.
00563 
00564    TGListTreeItem *itm = 0, *item = 0;
00565    if (obj->InheritsFrom("TFile")) {
00566       itm = fListTree->FindChildByData(0, gROOT->GetListOfFiles());
00567       if (itm)
00568          item = fListTree->FindChildByData(itm, obj);
00569       if (item)
00570          fListTree->DeleteItem(item);
00571       itm = fRootDir ? fRootDir->GetFirstChild() : 0;
00572       while (itm) {
00573          item = fListTree->FindItemByObj(itm, obj);
00574          if (item) {
00575             fListTree->DeleteChildren(item);
00576             item->SetUserData(0);
00577          }
00578          itm = itm->GetNextSibling();
00579       }
00580    }
00581    if (!obj->InheritsFrom("TFile") && fRootDir)
00582       fListTree->RecursiveDeleteItem(fRootDir, obj);
00583    //fListTree->ClearViewPort();
00584 }
00585 
00586 //______________________________________________________________________________
00587 void TGFileBrowser::Refresh(Bool_t /*force*/)
00588 {
00589    // Refresh content of the list tree.
00590 
00591    TTimer::SingleShot(200, "TGFileBrowser", this, "Update()");
00592    return; // disable refresh for the time being...
00593    TCursorSwitcher cursorSwitcher(this, fListTree);
00594    static UInt_t prev = 0;
00595    UInt_t curr =  gROOT->GetListOfBrowsables()->GetSize();
00596    if (!prev) prev = curr;
00597 
00598    if (prev != curr) { // refresh gROOT
00599       TGListTreeItem *sav = fListLevel;
00600       fListLevel = 0;
00601       BrowseObj(gROOT);
00602       fListLevel = sav;
00603       prev = curr;
00604    }
00605 }
00606 
00607 //______________________________________________________________________________
00608 void TGFileBrowser::Update()
00609 {
00610    // Update content of the list tree.
00611 
00612    Long64_t size = 0;
00613    Long_t id = 0, flags = 0, modtime = 0;
00614    char path[1024];
00615    TGListTreeItem *item = fCurrentDir;
00616    TObject *selected = 0;
00617    if (!item) item = fRootDir;
00618    if (!item) return;
00619    //fListTree->DeleteChildren(item);
00620    TGListTreeItem *curr = fListTree->GetSelected(); // GetCurrent() ??
00621    if (curr) {
00622       TObject *obj = (TObject *) curr->GetUserData();
00623       if (obj && !obj->TestBit(kNotDeleted)) {
00624          fListTree->DeleteItem(curr);
00625          curr = 0;
00626          obj = 0;
00627       }
00628       else if (obj && obj->TestBit(kNotDeleted) &&
00629                obj->InheritsFrom("TObjString") && curr->GetParent()) {
00630          fListTree->GetPathnameFromItem(curr->GetParent(), path);
00631          if (strlen(path) > 1) {
00632             TString dirpath = FullPathName(curr->GetParent());
00633             Int_t res = gSystem->GetPathInfo(dirpath.Data(), &id, &size,
00634                                              &flags, &modtime);
00635             if ((res == 0) && (flags & 2)) {
00636                TString fullpath = FullPathName(curr);
00637                if (gSystem->AccessPathName(fullpath.Data())) {
00638                   fListTree->DeleteItem(curr);
00639                   curr = 0;
00640                   obj = 0;
00641                }
00642             }
00643          }
00644       }
00645       selected = obj;
00646       if (selected && selected->InheritsFrom("TLeaf"))
00647          selected = (TObject *)gROOT->ProcessLine(TString::Format("((TLeaf *)0x%lx)->GetBranch()->GetTree();", (ULong_t)selected));
00648       if (selected && selected->InheritsFrom("TBranch"))
00649          selected = (TObject *)gROOT->ProcessLine(TString::Format("((TBranch *)0x%lx)->GetTree();", (ULong_t)selected));
00650    }
00651    TString actpath = FullPathName(item);
00652    flags = id = size = modtime = 0;
00653    if (gSystem->GetPathInfo(actpath.Data(), &id, &size, &flags, &modtime) == 0) {
00654       Int_t isdir = (Int_t)flags & 2;
00655 
00656       TString savdir = gSystem->WorkingDirectory();
00657       if (isdir) {
00658          TGListTreeItem *del = 0, *itm = item->GetFirstChild();
00659          while (itm) {
00660             fListTree->GetPathnameFromItem(itm, path);
00661             if (strlen(path) > 1) {
00662                TString recpath = FullPathName(itm);
00663                if (gSystem->AccessPathName(recpath.Data())) {
00664                   del = itm;
00665                   itm = itm->GetNextSibling();
00666                   fListTree->DeleteItem(del);
00667                }
00668             }
00669             if (del)
00670                del = 0;
00671             else
00672                itm = itm->GetNextSibling();
00673          }
00674       }
00675    }
00676    DoubleClicked(item, 1);
00677 
00678    if (selected && gPad && IsObjectEditable(selected->IsA())) {
00679       TVirtualPadEditor *ved = TVirtualPadEditor::GetPadEditor(kFALSE);
00680       if (ved) {
00681          TGedEditor *ged = (TGedEditor *)ved;
00682          ged->SetModel(gPad, selected, kButton1Down);
00683       }
00684    }
00685 }
00686 
00687 /**************************************************************************/
00688 // Other
00689 /**************************************************************************/
00690 
00691 //______________________________________________________________________________
00692 void TGFileBrowser::AddFSDirectory(const char *entry, const char *path,
00693                                    Option_t *opt)
00694 {
00695    // Add file system directory in the list tree.
00696 
00697    TGListTreeItem *item = 0;
00698    if ((opt == 0) || (strlen(opt) == 0)) {
00699       if (fRootDir == 0 && !fListTree->FindChildByName(0, rootdir))
00700          item = fRootDir = fListTree->AddItem(0, rootdir);
00701       return;
00702    }
00703    if (strstr(opt, "SetRootDir")) {
00704       if (!fListTree->FindChildByName(0, entry))
00705          item = fRootDir = fListTree->AddItem(0, entry);
00706    }
00707    else if (strstr(opt, "Add")) {
00708       // MT: i give up! wanted to place entries for selected
00709       // directories like home, pwd, alice-macros.
00710       // TGListTreeItem *lti = fListTree->AddItem(0, entry);
00711       //
00712       if (!fListTree->FindChildByName(0, entry))
00713          item = fListTree->AddItem(0, entry);
00714    }
00715    if (item && path) {
00716       TString infos = path;
00717       item->SetTipText(path);
00718       TGPicture *pic = 0;
00719       if (infos.Contains("Removable"))
00720          pic = (TGPicture *)gClient->GetPicture("fdisk_t.xpm");
00721       else if (infos.Contains("Local"))
00722          pic = (TGPicture *)gClient->GetPicture("hdisk_t.xpm");
00723       else if (infos.Contains("CD"))
00724          pic = (TGPicture *)gClient->GetPicture("cdrom_t.xpm");
00725       else if (infos.Contains("Network"))
00726          pic = (TGPicture *)gClient->GetPicture("netdisk_t.xpm");
00727       if (pic)
00728          item->SetPictures(pic, pic);
00729    }
00730 }
00731 
00732 //______________________________________________________________________________
00733 void TGFileBrowser::AddKey(TGListTreeItem *itm, TObject *obj, const char *name)
00734 {
00735    // display content of ROOT file
00736 
00737    // Int_t from, to;
00738    TGListTreeItem *where;
00739    static TGListTreeItem *olditem = itm;
00740    static TGListTreeItem *item = itm;
00741    const TGPicture *pic;
00742 
00743    if (itm == 0) return;
00744 
00745    if ((fCnt == 0) || (olditem != itm)) {
00746       olditem = item = itm;
00747    }
00748    if (!name) name = obj->GetName();
00749    if (fNKeys > fGroupSize) {
00750       where = itm->GetFirstChild();
00751       while (where) {
00752          if (fListTree->FindItemByObj(where, obj))
00753             return;
00754          where = where->GetNextSibling();
00755       }
00756    }
00757    if ((fNKeys > fGroupSize) && (fCnt % fGroupSize == 0)) {
00758       if (item != itm) {
00759          TString newname = TString::Format("%s-%s", item->GetText(), name);
00760          item->Rename(newname.Data());
00761       }
00762       item = fListTree->AddItem(itm, name);
00763       item->SetDNDSource(kTRUE);
00764    }
00765    if ((fCnt > fGroupSize) && (fCnt >= fNKeys-1)) {
00766       TString newname = TString::Format("%s-%s", item->GetText(), name);
00767       item->Rename(newname.Data());
00768    }
00769    GetObjPicture(&pic, obj);
00770    if (!fListTree->FindChildByName(item, name)) {
00771       TGListTreeItem *it = fListTree->AddItem(item, name, obj, pic, pic);
00772       if (pic && (pic != fFileIcon) && (pic != fCachedPic))
00773          fClient->FreePicture(pic);
00774       it->SetDNDSource(kTRUE);
00775       it->SetTipText(FormatToolTip(obj, 32));
00776    }
00777    fCnt++;
00778 }
00779 
00780 //______________________________________________________________________________
00781 void TGFileBrowser::ApplyFilter(Int_t id)
00782 {
00783    // Apply filter selected in combo box to the file tree view.
00784 
00785    // Long64_t size;
00786    // Long_t fid, flags, modtime;
00787 
00788    if (fFilter) delete fFilter;
00789    fFilter = 0;
00790    if (id > 1)
00791       fFilter = new TRegexp(filters[id], kTRUE);
00792    TGListTreeItem *item = fCurrentDir;
00793    if (!item)
00794       item = fRootDir;
00795    if (!item) return;
00796    fListTree->DeleteChildren(item);
00797    DoubleClicked(item, 1);
00798    //fListTree->AdjustPosition(item);
00799    fListTree->ClearViewPort();
00800 }
00801 
00802 //______________________________________________________________________________
00803 void TGFileBrowser::Chdir(TGListTreeItem *item)
00804 {
00805    // Make object associated with item the current directory.
00806 
00807    if (item) {
00808       TGListTreeItem *i = item;
00809       while (i) {
00810          TObject *obj = (TObject*) i->GetUserData();
00811          if ((obj) && obj->InheritsFrom("TDirectory")) {
00812             ((TDirectory *)obj)->cd();
00813             break;
00814          }
00815          i = i->GetParent();
00816       }
00817    }
00818 }
00819 
00820 //______________________________________________________________________________
00821 void TGFileBrowser::CheckRemote(TGListTreeItem *item)
00822 {
00823    // Check if the current list tree item points to a remote object.
00824 
00825    if (!item) return;
00826    TObject *obj = (TObject *) item->GetUserData();
00827    if (obj) {
00828       if (obj->InheritsFrom("TApplicationRemote")) {
00829          if (!gApplication->GetAppRemote()) {
00830             gROOT->ProcessLine(TString::Format(".R %s", item->GetText()));
00831             if (gApplication->GetAppRemote()) {
00832                Getlinem(kInit, TString::Format("\n%s:root [0]",
00833                         gApplication->GetAppRemote()->ApplicationName()));
00834             }
00835          }
00836       }
00837       if (item->GetParent() && item->GetParent()->GetUserData() &&
00838          ((TObject *)item->GetParent()->GetUserData())->InheritsFrom("TApplicationRemote")) {
00839          // switch to remote session
00840          if (!gApplication->GetAppRemote()) {
00841             gROOT->ProcessLine(TString::Format(".R %s", item->GetParent()->GetText()));
00842             if (gApplication->GetAppRemote()) {
00843                Getlinem(kInit, TString::Format("\n%s:root [0]",
00844                         gApplication->GetAppRemote()->ApplicationName()));
00845             }
00846          }
00847          else if (!strcmp(item->GetText(), "ROOT Files")) {
00848             // update list of files opened in the remote session
00849             gApplication->SetBit(TApplication::kProcessRemotely);
00850             gApplication->ProcessLine("((TApplicationServer *)gApplication)->BrowseFile(0);");
00851          }
00852       }
00853       else {
00854          // check if the listtree item is from a local session or
00855          // from a remote session, then switch to the session it belongs to
00856          TGListTreeItem *top = item;
00857          while (top->GetParent()) {
00858             top = top->GetParent();
00859          }
00860          TObject *topobj = (TObject *) top->GetUserData();
00861          if (topobj && topobj->InheritsFrom("TApplicationRemote")) {
00862             // it belongs to a remote session
00863             if (!gApplication->GetAppRemote()) {
00864                // switch to remote session if not already in
00865                gROOT->ProcessLine(TString::Format(".R %s", top->GetText()));
00866                if (gApplication->GetAppRemote()) {
00867                   Getlinem(kInit, TString::Format("\n%s:root [0]",
00868                            gApplication->GetAppRemote()->ApplicationName()));
00869                }
00870             }
00871          }
00872          else if (gApplication->GetAppRemote()) {
00873             // switch back to local session if not already in
00874             gApplication->ProcessLine(".R");
00875             Getlinem(kInit, "\nroot [0]");
00876          }
00877       }
00878    }
00879    else if (gApplication->GetAppRemote()) {
00880       // switch back to local session if not already in
00881       gApplication->ProcessLine(".R");
00882       Getlinem(kInit, "\nroot [0]");
00883    }
00884 }
00885 
00886 //______________________________________________________________________________
00887 Bool_t TGFileBrowser::CheckSorted(TGListTreeItem *item, Bool_t but)
00888 {
00889    // Check if the list tree item children are alphabetically sorted.
00890    // If the but argument is true, the "sort" button state is set accordingly.
00891 
00892    Bool_t found = kFALSE;
00893    TGListTreeItem *i, *itm;
00894    if (item->GetFirstChild())
00895       itm = item;
00896    else
00897       itm = item->GetParent();
00898    for (sLTI_i p=fSortedItems.begin(); p!=fSortedItems.end(); ++p) {
00899       i = (TGListTreeItem *)(*p);
00900       if (itm == i) {
00901          found = kTRUE;
00902          break;
00903       }
00904    }
00905    if (but) fSortButton->SetState(found ? kButtonEngaged : kButtonUp);
00906    return found;
00907 }
00908 
00909 //______________________________________________________________________________
00910 void TGFileBrowser::Clicked(TGListTreeItem *item, Int_t btn, Int_t x, Int_t y)
00911 {
00912    // Process mouse clicks in TGListTree.
00913 
00914    char path[1024];
00915    Long64_t size = 0;
00916    Long_t id = 0, flags = 0, modtime = 0;
00917    fListLevel = item;
00918    if (!item) return;
00919    CheckSorted(item, kTRUE);
00920    CheckRemote(item);
00921    TObject *selected = 0;
00922    TString fullpath = FullPathName(item);
00923    TObject *obj = (TObject *) item->GetUserData();
00924    if (obj && (!obj->InheritsFrom("TObjString") ||
00925        gSystem->AccessPathName(fullpath.Data()))) {
00926       if (obj->InheritsFrom("TKey") && (obj->IsA() != TClass::Class())) {
00927          Chdir(item);
00928          const char *clname = (const char *)gROOT->ProcessLine(TString::Format("((TKey *)0x%lx)->GetClassName();", (ULong_t)obj));
00929          if (clname) {
00930             TClass *cl = TClass::GetClass(clname);
00931             TString name = (const char *)gROOT->ProcessLine(TString::Format("((TKey *)0x%lx)->GetName();", (ULong_t)obj));
00932             name += ";";
00933             name += (Short_t)gROOT->ProcessLine(TString::Format("((TKey *)0x%lx)->GetCycle();", (ULong_t)obj));
00934             void *add = gDirectory->FindObjectAny((char *) name.Data());
00935             if (add && cl->IsTObject()) {
00936                obj = (TObject*)add;
00937                // don't change the user data, to avoid deletion of the 
00938                // list tree item by RecursiveRemove()
00939                // it is better to read the object each time anyway, 
00940                // as it may have changed in the file
00941                if (obj->InheritsFrom("TDirectory"))
00942                   item->SetUserData(obj);
00943             }
00944          }
00945       }
00946       if (obj->InheritsFrom("TLeaf") ||
00947           obj->InheritsFrom("TBranch")) {
00948          Chdir(item);
00949       }
00950       if (btn == kButton3)
00951         fContextMenu->Popup(x, y, obj, fBrowser);
00952       selected = obj;
00953    }
00954    else {
00955       fListTree->GetPathnameFromItem(item, path);
00956       if (strlen(path) > 3) {
00957          if (gSystem->GetPathInfo(fullpath.Data(), &id, &size, &flags, &modtime) == 0) {
00958             if (flags & 2) {
00959                fCurrentDir = item;
00960                if (btn == kButton3) {
00961                   if (fDir) delete fDir;
00962                   fDir = new TSystemDirectory(item->GetText(), fullpath.Data());
00963                   fContextMenu->Popup(x, y, fDir, fBrowser);
00964                }
00965             }
00966             else {
00967                fCurrentDir = item->GetParent();
00968                if (btn == kButton3) {
00969                   if (fFile) delete fFile;
00970                   fFile = new TSystemFile(item->GetText(), fullpath.Data());
00971                   fContextMenu->Popup(x, y, fFile, fBrowser);
00972                }
00973             }
00974          }
00975       }
00976    }
00977    fListTree->ClearViewPort();
00978    if (selected && selected->InheritsFrom("TLeaf"))
00979       selected = (TObject *)gROOT->ProcessLine(TString::Format("((TLeaf *)0x%lx)->GetBranch()->GetTree();", (ULong_t)selected));
00980    if (selected && selected->InheritsFrom("TBranch"))
00981       selected = (TObject *)gROOT->ProcessLine(TString::Format("((TBranch *)0x%lx)->GetTree();", (ULong_t)selected));
00982    if (selected && selected->InheritsFrom("TTree")) {
00983       // if a tree not attached to any directory (e.g. in a TFolder)
00984       // then attach it to the current directory (gDirectory)
00985       TDirectory *tdir = (TDirectory *)gROOT->ProcessLine(TString::Format("((TTree *)0x%lx)->GetDirectory();", (ULong_t)selected));
00986       if (!tdir) {
00987          gROOT->ProcessLine(TString::Format("((TTree *)0x%lx)->SetDirectory(gDirectory);", (ULong_t)selected));
00988       }
00989    }
00990    if (selected && gPad && IsObjectEditable(selected->IsA())) {
00991       TVirtualPadEditor *ved = TVirtualPadEditor::GetPadEditor(kFALSE);
00992       if (ved) {
00993          TGedEditor *ged = (TGedEditor *)ved;
00994          ged->SetModel(gPad, selected, kButton1Down);
00995       }
00996    }
00997 }
00998 
00999 //______________________________________________________________________________
01000 TString TGFileBrowser::FullPathName(TGListTreeItem* item)
01001 {
01002    // returns an absolute path
01003 
01004    TGListTreeItem *parent, *itm = item;
01005    TString dirname = itm->GetText();
01006 
01007    while ((parent=itm->GetParent())) {
01008       dirname = gSystem->ConcatFileName(parent->GetText(),dirname);
01009       itm = parent;
01010    }
01011 
01012    return dirname;
01013 }
01014 
01015 //______________________________________________________________________________
01016 TString TGFileBrowser::DirName(TGListTreeItem* item)
01017 {
01018    // returns the directory path
01019 
01020    TString dirname;
01021    TString fullpath = FullPathName(item);
01022 
01023 #ifdef WIN32
01024    char   winDrive[256];
01025    char   winDir[256];
01026    char   winName[256];
01027    char   winExt[256];
01028    _splitpath(fullpath.Data(), winDrive, winDir, winName, winExt);
01029    dirname = TString::Format("%s%s", winDrive, winDir);
01030 #else
01031    dirname = gSystem->DirName(fullpath);
01032 #endif
01033    return dirname;
01034 }
01035 
01036 //______________________________________________________________________________
01037 static Bool_t IsTextFile(const char *candidate)
01038 {
01039    // Returns true if given a text file
01040    // Uses the specification given on p86 of the Camel book
01041    // - Text files have no NULLs in the first block
01042    // - and less than 30% of characters with high bit set
01043 
01044    Int_t i;
01045    Int_t nchars;
01046    Int_t weirdcount = 0;
01047    char buffer[512];
01048    FILE *infile;
01049    FileStat_t buf;
01050 
01051    gSystem->GetPathInfo(candidate, buf);
01052    if (!(buf.fMode & kS_IFREG))
01053       return kFALSE;
01054 
01055    infile = fopen(candidate, "r");
01056    if (infile) {
01057       // Read a block
01058       nchars = fread(buffer, 1, 512, infile);
01059       fclose (infile);
01060       // Examine the block
01061       for (i = 0; i < nchars; i++) {
01062          if (buffer[i] & 128)
01063             weirdcount++;
01064          if (buffer[i] == '\0')
01065             // No NULLs in text files
01066             return kFALSE;
01067       }
01068       if ((nchars > 0) && ((weirdcount * 100 / nchars) > 30))
01069          return kFALSE;
01070    } else {
01071       // Couldn't open it. Not a text file then
01072       return kFALSE;
01073    }
01074    return kTRUE;
01075 }
01076 
01077 //______________________________________________________________________________
01078 void TGFileBrowser::DoubleClicked(TGListTreeItem *item, Int_t /*btn*/)
01079 {
01080    // Process double clicks in TGListTree.
01081 
01082    const TGPicture *pic=0;
01083    TString dirname = DirName(item);
01084    TString fullpath = FullPathName(item);
01085    TGListTreeItem *itm;
01086    FileStat_t sbuf;
01087    Long64_t size;
01088    Long_t id, flags, modtime;
01089    char action[512];
01090    TString act;
01091 
01092    if (fNewBrowser)
01093       fNewBrowser->SetActBrowser(this);
01094    TCursorSwitcher switcher(this, fListTree);
01095    fListLevel = item;
01096    CheckSorted(item, kTRUE);
01097    CheckRemote(item);
01098    TGListTreeItem *pitem = item->GetParent();
01099    TObject *obj = (TObject *) item->GetUserData();
01100    if (obj && !obj->InheritsFrom("TSystemFile")) {
01101       TString ext = obj->GetName();
01102       if (obj->InheritsFrom("TFile")) {
01103          fNKeys = ((TDirectory *)obj)->GetListOfKeys()->GetEntries();
01104       }
01105       else if (obj->InheritsFrom("TKey") && (obj->IsA() != TClass::Class())) {
01106          Chdir(item);
01107          const char *clname = (const char *)gROOT->ProcessLine(TString::Format("((TKey *)0x%lx)->GetClassName();", (ULong_t)obj));
01108          if (clname) {
01109             TClass *cl = TClass::GetClass(clname);
01110             TString name = (const char *)gROOT->ProcessLine(TString::Format("((TKey *)0x%lx)->GetName();", (ULong_t)obj));
01111             name += ";";
01112             name += (Short_t)gROOT->ProcessLine(TString::Format("((TKey *)0x%lx)->GetCycle();", (ULong_t)obj));
01113             void *add = gDirectory->FindObjectAny((char *) name.Data());
01114             if (add && cl->IsTObject()) {
01115                obj = (TObject*)add;
01116                // don't change the user data, to avoid deletion of the 
01117                // list tree item by RecursiveRemove()
01118                // it is better to read the object each time anyway, 
01119                // as it may have changed in the file
01120                if (obj->InheritsFrom("TDirectory"))
01121                   item->SetUserData(obj);
01122             }
01123          }
01124       }
01125       else if (obj->InheritsFrom("TLeaf") ||
01126           obj->InheritsFrom("TBranch")) {
01127          Chdir(item);
01128       }
01129       else if (obj->InheritsFrom("TRemoteObject")) {
01130          // the real object is a TKey
01131          TRemoteObject *robj = (TRemoteObject *)obj;
01132          if (!strcmp(robj->GetClassName(), "TKey")) {
01133             TGListTreeItem *parent = item;
01134             TRemoteObject *probj = (TRemoteObject *)parent->GetUserData();
01135             // find the TFile remote object containing the TKey
01136             while ( probj && strcmp(probj->GetClassName(), "TFile")) {
01137                parent = parent->GetParent();
01138                probj = (TRemoteObject *)parent->GetUserData();
01139             }
01140             if (probj && !strcmp(probj->GetClassName(), "TFile")) {
01141                // remotely browse file (remotely call TFile::cd())
01142                gApplication->SetBit(TApplication::kProcessRemotely);
01143                gApplication->ProcessLine(
01144                   TString::Format("((TApplicationServer *)gApplication)->BrowseFile(\"%s\");",
01145                        probj->GetName()));
01146                gSystem->Sleep(250);
01147             }
01148          }
01149          if (gClient->GetMimeTypeList()->GetAction(obj->GetName(), action)) {
01150             act = action;
01151             act.ReplaceAll("%s", obj->GetName());
01152             if ((act[0] != '!') && (strcmp(pitem->GetText(), "ROOT Files"))) {
01153                // special case for remote object: remote process
01154                gApplication->SetBit(TApplication::kProcessRemotely);
01155                gApplication->ProcessLine(act.Data());
01156             }
01157          }
01158          if ((ext.EndsWith(".root")) && (strcmp(pitem->GetText(), "ROOT Files"))) {
01159             gApplication->SetBit(TApplication::kProcessRemotely);
01160             gApplication->ProcessLine("((TApplicationServer *)gApplication)->BrowseFile(0);");
01161          }
01162       }
01163       if (!obj->InheritsFrom("TObjString") ||
01164           gSystem->AccessPathName(fullpath.Data())) {
01165          fDblClick = kTRUE;
01166          obj->Browse(fBrowser);
01167          fDblClick = kFALSE;
01168          fNKeys = 0;
01169          fCnt = 0;
01170          fListTree->ClearViewPort();
01171          return;
01172       }
01173    }
01174    flags = id = size = modtime = 0;
01175    if (gSystem->GetPathInfo(fullpath.Data(), &id, &size, &flags, &modtime) != 0)
01176       return;
01177    Int_t isdir = (Int_t)flags & 2;
01178 
01179    TString savdir = gSystem->WorkingDirectory();
01180    if (isdir) {
01181       fCurrentDir = item;
01182       //fListTree->DeleteChildren(item);
01183       TSystemDirectory dir(item->GetText(),FullPathName(item));
01184       TList *files = dir.GetListOfFiles();
01185       if (files) {
01186          files->Sort();
01187          TIter next(files);
01188          TSystemFile *file;
01189          TString fname;
01190          // directories first
01191          //fListTree->DeleteChildren(item);
01192          while ((file=(TSystemFile*)next())) {
01193             fname = file->GetName();
01194             if (file->IsDirectory()) {
01195                if (!fShowHidden && fname.BeginsWith("."))
01196                   continue;
01197                if ((fname!="..") && (fname!=".")) { // skip it
01198                   if (!fListTree->FindChildByName(item, fname)) {
01199                      itm = fListTree->AddItem(item, fname);
01200                      // uncomment line below to set directories as
01201                      // DND targets
01202                      //itm->SetDNDTarget(kTRUE);
01203                      itm->SetUserData(0);
01204                   }
01205                }
01206             }
01207          }
01208          // then files...
01209          TIter nextf(files);
01210          while ((file=(TSystemFile*)nextf())) {
01211             fname = file->GetName();
01212             if (!file->IsDirectory() && (fFilter == 0 ||
01213                (fFilter && fname.Index(*fFilter) != kNPOS))) {
01214                if (!fShowHidden && fname.BeginsWith("."))
01215                   continue;
01216                size = modtime = 0;
01217                if (gSystem->GetPathInfo(fname, sbuf) == 0) {
01218                   size    = sbuf.fSize;
01219                   modtime = sbuf.fMtime;
01220                }
01221                pic = gClient->GetMimeTypeList()->GetIcon(fname, kTRUE);
01222                if (!pic)
01223                   pic = fFileIcon;
01224                if (!fListTree->FindChildByName(item, fname)) {
01225                   itm = fListTree->AddItem(item,fname,pic,pic);
01226                   if (pic != fFileIcon)
01227                      fClient->FreePicture(pic);
01228                   itm->SetUserData(new TObjString(TString::Format("file://%s/%s\r\n",
01229                                    gSystem->UnixPathName(file->GetTitle()),
01230                                    file->GetName())), kTRUE);
01231                   itm->SetDNDSource(kTRUE);
01232                   if (size && modtime) {
01233                      char *tiptext = FormatFileInfo(fname.Data(), size, modtime);
01234                      itm->SetTipText(tiptext);
01235                      delete [] tiptext;
01236                   }
01237                }
01238             }
01239          }
01240          files->Delete();
01241          delete files;
01242       }
01243    }
01244    else {
01245       fCurrentDir = item->GetParent();
01246       TSystemFile f(item->GetText(), fullpath.Data());
01247       TString fname = f.GetName();
01248       if (fname.EndsWith(".root")) {
01249          TDirectory *rfile = 0;
01250          gSystem->ChangeDirectory(dirname.Data());
01251          rfile = (TDirectory *)gROOT->GetListOfFiles()->FindObject(obj);
01252          if (!rfile) {
01253             rfile = (TDirectory *)gROOT->ProcessLine(TString::Format("new TFile(\"%s\")",fname.Data()));
01254          }
01255          if (rfile) {
01256             // replace actual user data (TObjString) by the TDirectory...
01257             if (item->GetUserData()) {
01258                // first delete the data to avoid memory leaks
01259                TObject *obj2 = static_cast<TObject *>(item->GetUserData());
01260                // only delete TObjString as they are the only objects
01261                // created who have to be deleted
01262                delete dynamic_cast<TObjString *>(obj2);
01263             }
01264             item->SetUserData(rfile);
01265             fNKeys = rfile->GetListOfKeys()->GetEntries();
01266             fCnt = 0;
01267             rfile->Browse(fBrowser);
01268             fNKeys = 0;
01269             fCnt = 0;
01270          }
01271       }
01272       else if (fname.EndsWith(".png")) {
01273          gSystem->ChangeDirectory(dirname.Data());
01274          XXExecuteDefaultAction(&f);
01275          gSystem->ChangeDirectory(savdir.Data());
01276       }
01277       else if (IsTextFile(fullpath.Data())) {
01278          gSystem->ChangeDirectory(dirname.Data());
01279          if (fNewBrowser) {
01280             TGFrameElement *fe = 0;
01281             TGTab *tabRight = fNewBrowser->GetTabRight();
01282             TGCompositeFrame *frame = tabRight->GetCurrentContainer();
01283             if (frame)
01284                fe = (TGFrameElement *)frame->GetList()->First();
01285             if (fe) {
01286                TGCompositeFrame *embed = (TGCompositeFrame *)fe->fFrame;
01287                TString fullname = f.GetTitle();
01288                fullname.ReplaceAll("\\", "\\\\");
01289                if (embed->InheritsFrom("TGTextEditor")) {
01290                   gROOT->ProcessLine(TString::Format("((TGTextEditor *)0x%lx)->LoadFile(\"%s\");",
01291                                      (ULong_t)embed, fullname.Data()));
01292                }
01293                else if (embed->InheritsFrom("TGTextEdit")) {
01294                   gROOT->ProcessLine(TString::Format("((TGTextEdit *)0x%lx)->LoadFile(\"%s\");",
01295                                      (ULong_t)embed, fullname.Data()));
01296                }
01297                else {
01298                   XXExecuteDefaultAction(&f);
01299                }
01300             }
01301             else {
01302                XXExecuteDefaultAction(&f);
01303             }
01304          }
01305          gSystem->ChangeDirectory(savdir.Data());
01306       }
01307       else {
01308          gSystem->ChangeDirectory(dirname.Data());
01309          XXExecuteDefaultAction(&f);
01310          gSystem->ChangeDirectory(savdir.Data());
01311       }
01312    }
01313    //gSystem->ChangeDirectory(savdir.Data());
01314    fListTree->ClearViewPort();
01315 }
01316 
01317 //____________________________________________________________________________
01318 Long_t TGFileBrowser::XXExecuteDefaultAction(TObject *obj)
01319 {
01320    // Execute default action for selected object (action is specified
01321    // in the $HOME/.root.mimes or $ROOTSYS/etc/root.mimes file.
01322 
01323    char action[512];
01324    TString act;
01325    TString ext = obj->GetName();
01326    fBrowser->SetDrawOption(GetDrawOption());
01327 
01328    if (gClient->GetMimeTypeList()->GetAction(obj->GetName(), action)) {
01329       act = action;
01330       act.ReplaceAll("%s", obj->GetName());
01331       gInterpreter->SaveGlobalsContext();
01332 
01333       if (act[0] == '!') {
01334          act.Remove(0, 1);
01335          gSystem->Exec(act.Data());
01336          return 0;
01337       } else {
01338          // special case for remote object: remote process
01339          if (obj->InheritsFrom("TRemoteObject"))
01340             gApplication->SetBit(TApplication::kProcessRemotely);
01341          return gApplication->ProcessLine(act.Data());
01342       }
01343    }
01344    return 0;
01345 }
01346 
01347 //______________________________________________________________________________
01348 char *TGFileBrowser::FormatFileInfo(const char *fname, Long64_t size, Long_t modtime)
01349 {
01350    // Format file information to be displayed in the tooltip.
01351 
01352    Long64_t fsize, bsize;
01353    TString infos = fname;
01354    infos += "\n";
01355 
01356    fsize = bsize = size;
01357    if (fsize > 1024) {
01358       fsize /= 1024;
01359       if (fsize > 1024) {
01360          // 3.7MB is more informative than just 3MB
01361          infos += TString::Format("Size: %lld.%lldM", fsize/1024, (fsize%1024)/103);
01362       } else {
01363          infos += TString::Format("Size: %lld.%lldK", bsize/1024, (bsize%1024)/103);
01364       }
01365    } else {
01366       infos += TString::Format("Size: %lld", bsize);
01367    }
01368    struct tm *newtime;
01369    time_t loctime = (time_t) modtime;
01370    newtime = localtime(&loctime);
01371    infos += "\n";
01372    infos += TString::Format("%d-%02d-%02d %02d:%02d", newtime->tm_year + 1900,
01373            newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour,
01374            newtime->tm_min);
01375    return StrDup(infos.Data());
01376 }
01377 
01378 //______________________________________________________________________________
01379 void TGFileBrowser::GetObjPicture(const TGPicture **pic, TObject *obj)
01380 {
01381    // Retrieve icons associated with class "name". Association is made
01382    // via the user's ~/.root.mimes file or via $ROOTSYS/etc/root.mimes.
01383 
01384    const char *clname = 0;
01385    TClass *objClass = 0;
01386    static TImage *im = 0;
01387    if (!im) {
01388       im = TImage::Create();
01389    }
01390 
01391    if (obj->IsA() == TClass::Class()) {
01392       objClass = obj->IsA();
01393       if (objClass)
01394          clname = objClass->GetName();
01395    }
01396    else if (obj->InheritsFrom("TKey")) {
01397       clname = (char *)gROOT->ProcessLine(TString::Format("((TKey *)0x%lx)->GetClassName();", (ULong_t)obj));
01398    }
01399    else if (obj->InheritsFrom("TKeyMapFile")) {
01400       clname = (char *)gROOT->ProcessLine(TString::Format("((TKeyMapFile *)0x%lx)->GetTitle();", (ULong_t)obj));
01401    }
01402    else if (obj->InheritsFrom("TRemoteObject")) {
01403       // special case for remote object: get real object class
01404       TRemoteObject *robj = (TRemoteObject *)obj;
01405       if (!strcmp(robj->GetClassName(), "TKey"))
01406          clname = robj->GetKeyClassName();
01407       else
01408          clname = robj->GetClassName();
01409    }
01410    else {
01411       objClass = obj->IsA();
01412       if (objClass)
01413          clname = objClass->GetName();
01414    }
01415    if (!clname) {
01416       clname = "Unknown";
01417    }
01418    const char *name = obj->GetIconName() ? obj->GetIconName() : clname;
01419    TString xpm_magic(name, 3);
01420    Bool_t xpm = xpm_magic == "/* ";
01421    const char *iconname = xpm ? obj->GetName() : name;
01422 
01423    if (obj->IsA()->InheritsFrom("TGeoVolume")) {
01424       iconname = obj->GetIconName() ? obj->GetIconName() : obj->IsA()->GetName();
01425    }
01426 
01427    if (fCachedPicName == iconname) {
01428       *pic = fCachedPic;
01429       return;
01430    }
01431    *pic = gClient->GetMimeTypeList()->GetIcon(iconname, kTRUE);
01432    if (!(*pic) && xpm) {
01433       if (im && im->SetImageBuffer((char**)&name, TImage::kXpm)) {
01434          im->Scale(im->GetWidth()/4, im->GetHeight()/4);
01435          *pic = gClient->GetPicturePool()->GetPicture(iconname, im->GetPixmap(),
01436                                                       im->GetMask());
01437       }
01438       gClient->GetMimeTypeList()->AddType("[thumbnail]", iconname, iconname, iconname, "->Browse()");
01439       return;
01440    }
01441    if (fCachedPic && (fCachedPic != fFileIcon))
01442       fClient->FreePicture(fCachedPic);
01443    if (*pic == 0) {
01444       if (!obj->IsFolder())
01445          *pic = fFileIcon;
01446    }
01447    fCachedPic = *pic;
01448    fCachedPicName = iconname;
01449 }
01450 
01451 //______________________________________________________________________________
01452 void TGFileBrowser::GotoDir(const char *path)
01453 {
01454    // Go to the directory "path" and open all the parent list tree items.
01455 
01456    TGListTreeItem *item, *itm;
01457    Bool_t expand = kTRUE;
01458    TString sPath(gSystem->UnixPathName(path));
01459    item = fRootDir;
01460    if (item == 0) return;
01461    fListTree->OpenItem(item);
01462    TObjArray *tokens = sPath.Tokenize("/");
01463    if (tokens->IsEmpty()) {
01464       fListTree->HighlightItem(item);
01465       DoubleClicked(item, 1);
01466       delete tokens;
01467       fListTree->ClearViewPort();
01468       fListTree->AdjustPosition(item);
01469       return;
01470    }
01471    TString first = ((TObjString*)tokens->At(0))->GetName();
01472    if (first == "afs")
01473       expand = kFALSE;
01474    if (first.Length() == 2 && first.EndsWith(":")) {
01475       TList *curvol  = gSystem->GetVolumes("cur");
01476       if (curvol) {
01477          TNamed *drive = (TNamed *)curvol->At(0);
01478          if (first == drive->GetName()) {
01479             TString infos = drive->GetTitle();
01480             if (infos.Contains("Network"))
01481                expand = kFALSE;
01482          }
01483          delete curvol;
01484       }
01485    }
01486    for (Int_t i = 0; i < tokens->GetEntriesFast(); ++i) {
01487       TString token = ((TObjString*)tokens->At(i))->GetName();
01488       if (token.Length() == 2 && token.EndsWith(":")) {
01489          token.Append("\\");
01490          itm = fListTree->FindChildByName(0, token);
01491          if (itm) {
01492             item = itm;
01493             fListTree->OpenItem(item);
01494             if (expand)
01495                DoubleClicked(item, 1);
01496          }
01497          continue;
01498       }
01499       itm = fListTree->FindChildByName(item, token);
01500       if (itm) {
01501          item = itm;
01502          fListTree->OpenItem(item);
01503          if (expand)
01504             DoubleClicked(item, 1);
01505       }
01506       else {
01507          itm = fListTree->AddItem(item, token);
01508          item = itm;
01509          fListTree->OpenItem(item);
01510          if (expand)
01511             DoubleClicked(item, 1);
01512       }
01513    }
01514    fListTree->HighlightItem(item);
01515    DoubleClicked(item, 1);
01516    delete tokens;
01517    fListTree->ClearViewPort();
01518    fListTree->AdjustPosition(item);
01519 }
01520 
01521 //______________________________________________________________________________
01522 void TGFileBrowser::PadModified()
01523 {
01524    // Slot used to switch to the tab containing the current pad/canvas (gPad)
01525    // used e.g. when drawing a histogram by double-clicking on its list tree
01526    // item in a root file.
01527 
01528    if (fDblClick && fNewBrowser) {
01529       Int_t i;
01530       TGTab *tabRight = fNewBrowser->GetTabRight();
01531       for (i=0;i<tabRight->GetNumberOfTabs();++i) {
01532          TGFrameElement *fe = 0;
01533          TGCompositeFrame *embed = 0;
01534          TGCompositeFrame *frame = tabRight->GetTabContainer(i);
01535          if (frame)
01536             fe = (TGFrameElement *)frame->GetList()->First();
01537          if (fe)
01538             embed = (TGCompositeFrame *)fe->fFrame;
01539          if (embed && embed->InheritsFrom("TRootCanvas")) {
01540             ULong_t canvas = gROOT->ProcessLine(TString::Format("((TRootCanvas *)0x%lx)->Canvas();",
01541                                                 (ULong_t)embed));
01542             if ((canvas) && (canvas == (ULong_t)gPad ||
01543                 canvas == (ULong_t)gPad->GetCanvas())) {
01544                tabRight->SetTab(i, kTRUE);
01545                break;
01546             }
01547          }
01548       }
01549    }
01550 }
01551 
01552 //______________________________________________________________________________
01553 void TGFileBrowser::Selected(char *)
01554 {
01555    // A ROOT File has been selected in TGHtmlBrowser.
01556 
01557    TGListTreeItem *itm = fListTree->FindChildByData(0, gROOT->GetListOfFiles());
01558    if (itm) {
01559       fListTree->ClearHighlighted();
01560       fListLevel = itm;
01561       fListTree->HighlightItem(fListLevel);
01562       fListTree->OpenItem(fListLevel);
01563       BrowseObj(gROOT->GetListOfFiles());
01564       fListTree->ClearViewPort();
01565       fListTree->AdjustPosition(fListLevel);
01566    }
01567 }
01568 
01569 //______________________________________________________________________________
01570 void TGFileBrowser::ToggleSort()
01571 {
01572    // Toggle the sort mode and set the "sort button" state accordingly.
01573 
01574    if (!fListLevel) return;
01575    char *itemname = 0;
01576    TGListTreeItem *item = fListLevel;
01577    if (!fListLevel->GetFirstChild()) {
01578       item = fListLevel->GetParent();
01579       itemname = StrDup(fListLevel->GetText());
01580    }
01581    if (!item) {
01582       if (itemname)
01583          delete [] itemname;
01584       return;
01585    }
01586    Bool_t is_sorted = CheckSorted(item);
01587    if (!is_sorted) {
01588       //alphabetical sorting
01589       fListTree->SortChildren(item);
01590       fSortedItems.push_back(item);
01591       fSortButton->SetState(kButtonEngaged);
01592    }
01593    else {
01594       fListTree->DeleteChildren(item);
01595       DoubleClicked(item, 1);
01596       fSortedItems.remove(item);
01597       fSortButton->SetState(kButtonUp);
01598       gClient->NeedRedraw(fListTree, kTRUE);
01599       gClient->HandleInput();
01600       if (itemname) {
01601          TGListTreeItem *itm = fListTree->FindChildByName(item, itemname);
01602          if (itm) {
01603             fListTree->ClearHighlighted();
01604             Clicked(itm, 1, 0, 0);
01605             itm->SetActive(kTRUE);
01606             fListTree->SetSelected(itm);
01607             fListTree->HighlightItem(itm, kTRUE, kTRUE);
01608          }
01609       }
01610    }
01611    if (itemname)
01612       delete [] itemname;
01613    fListTree->ClearViewPort();
01614    fListTree->AdjustPosition(fListLevel);
01615 }

Generated on Tue Jul 5 14:21:58 2011 for ROOT_528-00b_version by  doxygen 1.5.1