<commit_before>// @(#)root/gui:$Id$
// Author: <NAME>   26/09/2007

/*************************************************************************
 * Copyright (C) 1995-2007, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TROOT.h"
#include "TSystem.h"
#include "TApplication.h"
#include "TGClient.h"
#include "TGListTree.h"
#include "TGLayout.h"
#include "TGComboBox.h"
#include "TContextMenu.h"
#include "TGTextEntry.h"
#include "TGTab.h"
#include "TGLabel.h"
#include "TSystemDirectory.h"
#include "TGMimeTypes.h"
#include "TClass.h"
#include "TQClass.h"
#include "TDataMember.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TRealData.h"
#include "TInterpreter.h"
#include "TRegexp.h"
#include "TEnv.h"
#include "TImage.h"
#include "TBrowser.h"
#include "TRemoteObject.h"
#include "TVirtualPad.h"
#include "Getline.h"
#include <time.h>
#include <string.h>
#include <stdlib.h>

#include "TGFileBrowser.h"
#include "TRootBrowser.h"

#include "TVirtualPadEditor.h"
#include "TGedEditor.h"
#include "TBaseClass.h"

#ifdef WIN32
const char rootdir[] = "\\";
#else
const char rootdir[] = "/";
#endif

const char *filters[] = {
   "",
   "*.*",
   "*.[C|c|h]*",
   "*.root",
   "*.txt"
};

//_____________________________________________________________________________
//
// TCursorSwitcher
//
// Helper class used to change the cursor in a method and restore the
// original one when going out of the method scope.
//_____________________________________________________________________________

///////////////////////////////////////////////////////////////////////////////
class TCursorSwitcher {
private:
   TGWindow *fW1;
   TGWindow *fW2;
public:
   TCursorSwitcher(TGWindow *w1, TGWindow *w2) : fW1(w1), fW2(w2) {
      if (w1) gVirtualX->SetCursor(w1->GetId(), gVirtualX->CreateCursor(kWatch));
      if (w2) gVirtualX->SetCursor(w2->GetId(), gVirtualX->CreateCursor(kWatch));
   }
   ~TCursorSwitcher() {
      if (fW1) gVirtualX->SetCursor(fW1->GetId(), gVirtualX->CreateCursor(kPointer));
      if (fW2) gVirtualX->SetCursor(fW2->GetId(), gVirtualX->CreateCursor(kPointer));
   }
};

//_____________________________________________________________________________
//
// TGFileBrowser
//
// System file browser, used as TRootBrowser plug-in.
// This class is the real core of the ROOT browser.
//_____________________________________________________________________________

ClassImp(TGFileBrowser)

//______________________________________________________________________________
TGFileBrowser::TGFileBrowser(const TGWindow *p, TBrowser* b, UInt_t w, UInt_t h)
   : TGMainFrame(p, w, h), TBrowserImp(b), fNewBrowser(0)
{
   // TGFileBrowser constructor.

   if (p && p != gClient->GetDefaultRoot())
      fNewBrowser = (TRootBrowser *)p->GetMainFrame();
   if (fNewBrowser)
      fNewBrowser->SetActBrowser(this);
   CreateBrowser();
   Resize(w, h);
   if (fBrowser) Show();
}

//______________________________________________________________________________
void TGFileBrowser::CreateBrowser()
{
   // Create the actual file browser.

   fCachedPic  = 0;
   SetCleanup(kDeepCleanup);

   fTopFrame = new TGHorizontalFrame(this, 100, 30);
   fDrawOption = new TGComboBox(fTopFrame, "");
   TGTextEntry *dropt_entry = fDrawOption->GetTextEntry();
   dropt_entry->SetToolTipText("Object Draw Option", 300);
   fDrawOption->Resize(80, 20);
   TGListBox *lb = fDrawOption->GetListBox();
   lb->Resize(lb->GetWidth(), 120);
   Int_t dropt = 1;
   fDrawOption->AddEntry("", dropt++);
   fDrawOption->AddEntry(" box", dropt++);
   fDrawOption->AddEntry(" colz", dropt++);
   fDrawOption->AddEntry(" lego", dropt++);
   fDrawOption->AddEntry(" lego1", dropt++);
   fDrawOption->AddEntry(" lego2", dropt++);
   fDrawOption->AddEntry(" same", dropt++);
   fDrawOption->AddEntry(" surf", dropt++);
   fDrawOption->AddEntry(" surf1", dropt++);
   fDrawOption->AddEntry(" surf2", dropt++);
   fDrawOption->AddEntry(" surf3", dropt++);
   fDrawOption->AddEntry(" surf4", dropt++);
   fDrawOption->AddEntry(" surf5", dropt++);
   fDrawOption->AddEntry(" text", dropt++);
   fTopFrame->AddFrame(fDrawOption, new TGLayoutHints(kLHintsCenterY |
                       kLHintsRight, 2, 2, 2, 2));
   fTopFrame->AddFrame(new TGLabel(fTopFrame, "Draw Option: "),
                       new TGLayoutHints(kLHintsCenterY | kLHintsRight,
                       2, 2, 2, 2));

   fSortButton = new TGPictureButton(fTopFrame, "bld_sortup.png");
   fSortButton->SetToolTipText("Sort Alphabetically\n(Current folder only)");
   fTopFrame->AddFrame(fSortButton, new TGLayoutHints(kLHintsCenterY |
                       kLHintsLeft, 2, 2, 2, 2));
   fSortButton->Connect("Clicked()", "TGFileBrowser", this, "ToggleSort()");

   fRefreshButton = new TGPictureButton(fTopFrame, "tb_refresh.xpm");
   fRefreshButton->SetToolTipText("Refresh Current Folder");
   fTopFrame->AddFrame(fRefreshButton, new TGLayoutHints(kLHintsCenterY |
                       kLHintsLeft, 2, 2, 2, 2));
   fRefreshButton->Connect("Clicked()", "TGFileBrowser", this, "Refresh()");

   AddFrame(fTopFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop |
            kLHintsExpandX, 2, 2, 2, 2));
   fCanvas   = new TGCanvas(this, 100, 100);
   fListTree = new TGListTree(fCanvas, kHorizontalFrame);
   AddFrame(fCanvas, new TGLayoutHints(kLHintsLeft | kLHintsTop |
                kLHintsExpandX | kLHintsExpandY));
   fListTree->Connect("DoubleClicked(TGListTreeItem *, Int_t)",
      "TGFileBrowser", this, "DoubleClicked(TGListTreeItem *, Int_t)");
   fListTree->Connect("Clicked(TGListTreeItem *, Int_t, Int_t, Int_t)",
      "TGFileBrowser", this, "Clicked(TGListTreeItem *, Int_t, Int_t, Int_t)");
   fListTree->Connect("Checked(TObject*, Bool_t)", "TGFileBrowser",
      this, "Checked(TObject*, Bool_t)");

   fRootIcon = gClient->GetPicture("rootdb_t.xpm");
   fFileIcon = gClient->GetPicture("doc_t.xpm");

   fBotFrame = new TGHorizontalFrame(this, 100, 30);
   fBotFrame->AddFrame(new TGLabel(fBotFrame, "Filter: "),
                       new TGLayoutHints(kLHintsCenterY | kLHintsLeft,
                       2, 2, 2, 2));
   fFileType = new TGComboBox(fBotFrame, " All Files (*.*)");
   Int_t ftype = 1;
   fFileType->AddEntry(" All Files (*.*)", ftype++);
   fFileType->AddEntry(" C/C++ Files (*.c;*.cxx;*.h;...)", ftype++);
   fFileType->AddEntry(" ROOT Files (*.root)", ftype++);
   fFileType->AddEntry(" Text Files (*.txt)", ftype++);
   fFileType->Resize(200, 20);
   fBotFrame->AddFrame(fFileType, new TGLayoutHints(kLHintsLeft | kLHintsTop |
                kLHintsExpandX, 2, 2, 2, 2));
   fFileType->Connect("Selected(Int_t)", "TGFileBrowser", this,
                      "ApplyFilter(Int_t)");
   fFileType->GetTextEntry()->Connect("ReturnPressed()", "TGFileBrowser", 
                                      this, "ApplyFilter(Int_t = -1)");
   AddFrame(fBotFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop |
            kLHintsExpandX, 2, 2, 2, 2));

   fContextMenu = new TContextMenu("FileBrowserContextMenu");
   fFilter      = 0;
   fGroupSize   = 1000;
   fListLevel   = 0;
   fCurrentDir  = 0;
   fRootDir     = 0;
   fDir         = 0;
   fFile        = 0;
   fNKeys       = 0;
   fCnt         = 0;

   TString gv = gEnv->GetValue("Browser.GroupView", "1000");
   Int_t igv = atoi(gv.Data());
   if (igv > 10)
      fGroupSize = igv;

   if (gEnv->GetValue("Browser.ShowHidden", 0))
      fShowHidden = kTRUE;
   else
      fShowHidden = kFALSE;

   fDblClick = kFALSE;

   TQObject::Connect("TGHtmlBrowser", "Clicked(char*)",
                     "TGFileBrowser", this, "Selected(char*)");

   TQObject::Connect("TPad", "Modified()",
                     "TGFileBrowser", this, "PadModified()");

   fListLevel = 0;
   MapSubwindows();
   Resize(GetDefaultSize());
   MapWindow();
}

//______________________________________________________________________________
TGFileBrowser::~TGFileBrowser()
{
   // Destructor.

   TQObject::Disconnect("TGHtmlBrowser", "Clicked(char*)");
   TQObject::Disconnect("TPad", "Modified()");

   delete fContextMenu;
   delete fListTree;
   if (fRootIcon) fClient->FreePicture(fRootIcon);
   if (fCachedPic && (fCachedPic != fFileIcon))
      fClient->FreePicture(fCachedPic);
   if (fFileIcon) fClient->FreePicture(fFileIcon);
   Cleanup();
}

//______________________________________________________________________________
static Bool_t IsObjectEditable(TClass *cl)
{
   // Helper function checking if a class has a graphic properties editor.

   TBaseClass *base;
   TList* bcl = cl->GetListOfBases();
   TIter next(bcl);
   while ((base = (TBaseClass*) next())) {
      cl = base->GetClassPointer();
      if (cl && TClass::GetClass(Form("%sEditor", cl->GetName())))
         return kTRUE;
      if (IsObjectEditable(cl))
         return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
static const char *FormatToolTip(TObject *obj, Int_t maxlen=0)
{
   // Format the tooltip information, based on the object passed in argument.

   static TString infos;
   if (!obj) {
      infos.Clear();
      return 0;
   }
   infos = obj->GetName();
   if (obj->GetTitle()) {
      infos += "\n";
      infos += obj->GetTitle();
   }
   if (maxlen > 0 && infos.Length() > maxlen) {
      infos.Remove(maxlen - 3);
      infos += "...";
   }
   TString objinfo = obj->GetObjectInfo(1, 1);
   if (!objinfo.IsNull() && !objinfo.BeginsWith("x=")) {
      Long64_t bsize, fsize, objsize;
      objsize = objinfo.Atoll();
      if (objsize > 0) {
         infos += "\n";
         bsize = fsize = objsize;
         if (fsize > 1024) {
            fsize /= 1024;
            if (fsize > 1024) {
               // 3.7MB is more informative than just 3MB
               infos += TString::Format("Size: %lld.%lldM", fsize/1024,
                                        (fsize%1024)/103);
            } else {
               infos += TString::Format("Size: %lld.%lldK", bsize/1024,
                                        (bsize%1024)/103);
            }
         } else {
            infos += TString::Format("Size: %lld bytes", bsize);
         }
      }
   }
   return infos.Data();
}

/**************************************************************************/
// TBrowserImp virtuals
/**************************************************************************/

//______________________________________________________________________________
void TGFileBrowser::Add(TObject *obj, const char *name, Int_t check)
{
   // Add items to the browser. This function has to be called
   // by the Browse() member function of objects when they are
   // called by a browser. If check < 0 (default) no check box is drawn,
   // if 0 then unchecked checkbox is added, if 1 checked checkbox is added.

   if (fListLevel && !strcmp(fListLevel->GetText(), "Classes") &&
      fListLevel->GetParent() &&
      !strcmp(fListLevel->GetParent()->GetText(), "root")) {
      // Browsing list of root classes...
   }
   else {
      if (obj && obj->InheritsFrom("TApplication"))
         fListLevel = 0;
      if (obj && obj->InheritsFrom("TSystemDirectory"))
         return;
   }
   const TGPicture *pic=0;
   if (obj && obj->InheritsFrom("TKey") && (obj->IsA() != TClass::Class()))
      AddKey(fListLevel, obj, name);
   else if (obj) {
      GetObjPicture(&pic, obj);
      if (!name) name = obj->GetName();
      if (check > -1) {
         if (!fListTree->FindChildByName(fListLevel, name)) {
            TGListTreeItem *item = fListTree->AddItem(fListLevel, name, obj,
                                                      pic, pic, kTRUE);
            if ((pic != fFileIcon) && (pic != fCachedPic))
               fClient->FreePicture(pic);
            if (item) fListTree->CheckItem(item, (Bool_t)check);
            fListTree->SetToolTipItem(item, FormatToolTip(obj, 32));
         }
      }
      else {
         // special case for remote object
         Bool_t isRemote = kFALSE;
         if (obj->InheritsFrom("TRemoteObject"))
            isRemote = kTRUE;
         else if (fListLevel) {
            // check also if one of its parents is a remote object
            TGListTreeItem *top = fListLevel;
            while (top->GetParent()) {
               TObject *tobj = (TObject *) top->GetUserData();
               if (tobj && (tobj->InheritsFrom("TRemoteObject") ||
                  tobj->InheritsFrom("TApplicationRemote"))) {
                  isRemote = kTRUE;
                  break;
               }
               top = top->GetParent();
            }
         }
         if (isRemote) {
            TRemoteObject *robj = (TRemoteObject *)obj;
            if (!strcmp(robj->GetClassName(), "TKey")) {
               AddKey(fListLevel, obj, name);
            }
            else {
               TString fname = name;
               // add the remote object only if not already in the list
               if (!fShowHidden && fname.BeginsWith("."))
                  return;
               AddRemoteFile(obj);
            }
         }
         else {
            if (!fListTree->FindChildByName(fListLevel, name)) {
               TGListTreeItem *item = fListTree->AddItem(fListLevel, name, obj, pic, pic);
               if ((pic != fFileIcon) && (pic != fCachedPic))
                  fClient->FreePicture(pic);
               if (item && obj && obj->InheritsFrom("TObject"))
                  item->SetDNDSource(kTRUE);
               fListTree->SetToolTipItem(item, FormatToolTip(obj, 32));
            }
         }
      }
   }
}

//______________________________________________________________________________
void TGFileBrowser::AddRemoteFile(TObject *obj)
{
   // Add remote file in list tree.

   Bool_t      is_link;
   Int_t       type, uid, gid;
   Long_t      modtime;
   Long64_t    size;
   TString     filename;
   const TGPicture *spic;
   TGPicture *pic;

   FileStat_t sbuf;

   type    = 0;
   size    = 0;
   uid     = 0;
   gid     = 0;
   modtime = 0;
   is_link = kFALSE;

   TRemoteObject *robj = (TRemoteObject *)obj;

   robj->GetFileStat(&sbuf);
   is_link = sbuf.fIsLink;
   type    = sbuf.fMode;
   size    = sbuf.fSize;
   uid     = sbuf.fUid;
   gid     = sbuf.fGid;
   modtime = sbuf.fMtime;
   filename = robj->GetName();
   if (R_ISDIR(type) || fFilter == 0 ||
       (fFilter && filename.Index(*fFilter) != kNPOS)) {

      GetFilePictures(&spic, type, is_link, filename);

      pic = (TGPicture*)spic; pic->AddReference();

      if ((!fListTree->FindChildByName(fListLevel, filename)) &&
         (!fListTree->FindChildByData(fListLevel, obj)))
         fListTree->AddItem(fListLevel, filename, obj, pic, pic);
   }
}

//______________________________________________________________________________
void TGFileBrowser::BrowseObj(TObject *obj)
{
   // Browse object. This, in turn, will trigger the calling of
   // TBrowser::Add() which will fill the IconBox and the tree.
   // Emits signal "BrowseObj(TObject*)".

   if (fNewBrowser)
      fNewBrowser->SetActBrowser(this);
   if (obj != gROOT) {
      if (!fListTree->FindItemByObj(fListTree->GetFirstItem(), obj)) {
         fListLevel = 0;
         Add(obj);
         fListLevel = fListTree->FindItemByObj(fListTree->GetFirstItem(), obj);
         fListTree->HighlightItem(fListLevel);
         if (obj->IsFolder())
            fListTree->OpenItem(fListLevel);
         fListTree->ClearViewPort();
         fListTree->AdjustPosition(fListLevel);
      }
   }
   obj->Browse(fBrowser);
   if (obj == gROOT) {
      TList *volumes = gSystem->GetVolumes("all");
      TList *curvol  = gSystem->GetVolumes("cur");
      if (volumes && curvol) {
         const char *curdrive;
         TNamed *named = (TNamed *)curvol->At(0);
         if (named)
            curdrive = named->GetName();
         else
            curdrive = "C:";
         TIter next(volumes);
         TNamed *drive;
         while ((drive = (TNamed *)next())) {
            AddFSDirectory(TString::Format("%s\\", drive->GetName()), drive->GetTitle(),
                           (strcmp(drive->GetName(), curdrive) == 0) ?
                           "SetRootDir" : "Add");
         }
         delete volumes;
         delete curvol;
      }
      else {
         AddFSDirectory("/");
      }
      GotoDir(gSystem->WorkingDirectory());
      if (gROOT->GetListOfFiles() && !gROOT->GetListOfFiles()->IsEmpty())
         Selected(0);
   }
}

//______________________________________________________________________________
void TGFileBrowser::Checked(TObject *obj, Bool_t checked)
{
   // Emits signal when double clicking on icon.

   if (fNewBrowser)
      fNewBrowser->Checked(obj, checked);
}

//______________________________________________________________________________
Option_t *TGFileBrowser::GetDrawOption() const
{
   // returns drawing option

   return fDrawOption->GetTextEntry()->GetText();
}

//______________________________________________________________________________
void TGFileBrowser::GetFilePictures(const TGPicture **pic, Int_t file_type,
                                    Bool_t is_link, const char *name)
{
   // Determine the file picture for the given file type.

   static TString cached_ext;
   static const TGPicture *cached_spic = 0;
   const char *ext = name ? strrchr(name, '.') : 0;
   TString sname = name ? name : " ";
   *pic = 0;

   if (ext && cached_spic && (cached_ext == ext)) {
      *pic = cached_spic;
      return;
   }

   if (R_ISREG(file_type)) {
      *pic = gClient->GetMimeTypeList()->GetIcon(name, kTRUE);

      if (*pic) {
         if (ext) {
            cached_ext = ext;
            cached_spic = *pic;
            return;
         }
      }
   } else {
      *pic = 0;
   }

   if (*pic == 0) {
      *pic = gClient->GetPicture("doc_t.xpm");

      if (R_ISREG(file_type) && (file_type) & kS_IXUSR) {
         *pic = gClient->GetPicture("app_t.xpm");
      }
      if (R_ISDIR(file_type)) {
         *pic = gClient->GetPicture("folder_t.xpm");
      }
      if(sname.EndsWith(".root")) {
         *pic = gClient->GetPicture("rootdb_t.xpm");
      }

   }
   if (is_link) {
      *pic = gClient->GetPicture("slink_t.xpm");
   }

   cached_spic = 0;
   cached_ext = "";
}

//______________________________________________________________________________
void TGFileBrowser::RecursiveRemove(TObject *obj)
{
   // Recursively remove object.

   TGListTreeItem *itm = 0, *item = 0;
   if (obj->InheritsFrom("TFile")) {
      itm = fListTree->FindChildByData(0, gROOT->GetListOfFiles());
      if (itm)
         item = fListTree->FindChildByData(itm, obj);
      if (item)
         fListTree->DeleteItem(item);
      itm = fRootDir ? fRootDir->GetFirstChild() : 0;
      while (itm) {
         item = fListTree->FindItemByObj(itm, obj);
         if (item) {
            fListTree->DeleteChildren(item);
            item->SetUserData(0);
         }
         itm = itm->GetNextSibling();
      }
   }
   if (!obj->InheritsFrom("TFile") && fRootDir)
      fListTree->RecursiveDeleteItem(fRootDir, obj);
   //fListTree->ClearViewPort();
}

//______________________________________________________________________________
void TGFileBrowser::Refresh(Bool_t /*force*/)
{
   // Refresh content of the list tree.

   TTimer::SingleShot(200, "TGFileBrowser", this, "Update()");
   return; // disable refresh for the time being...
   TCursorSwitcher cursorSwitcher(this, fListTree);
   static UInt_t prev = 0;
   UInt_t curr =  gROOT->GetListOfBrowsables()->GetSize();
   if (!prev) prev = curr;

   if (prev != curr) { // refresh gROOT
      TGListTreeItem *sav = fListLevel;<commit_msg>Ignore unreachable (dead) code report (coverity)<commit_after>// @(#)root/gui:$Id$
// Author: <NAME>   26/09/2007

/*************************************************************************
 * Copyright (C) 1995-2007, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TROOT.h"
#include "TSystem.h"
#include "TApplication.h"
#include "TGClient.h"
#include "TGListTree.h"
#include "TGLayout.h"
#include "TGComboBox.h"
#include "TContextMenu.h"
#include "TGTextEntry.h"
#include "TGTab.h"
#include "TGLabel.h"
#include "TSystemDirectory.h"
#include "TGMimeTypes.h"
#include "TClass.h"
#include "TQClass.h"
#include "TDataMember.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TRealData.h"
#include "TInterpreter.h"
#include "TRegexp.h"
#include "TEnv.h"
#include "TImage.h"
#include "TBrowser.h"
#include "TRemoteObject.h"
#include "TVirtualPad.h"
#include "Getline.h"
#include <time.h>
#include <string.h>
#include <stdlib.h>

#include "TGFileBrowser.h"
#include "TRootBrowser.h"

#include "TVirtualPadEditor.h"
#include "TGedEditor.h"
#include "TBaseClass.h"

#ifdef WIN32
const char rootdir[] = "\\";
#else
const char rootdir[] = "/";
#endif

const char *filters[] = {
   "",
   "*.*",
   "*.[C|c|h]*",
   "*.root",
   "*.txt"
};

//_____________________________________________________________________________
//
// TCursorSwitcher
//
// Helper class used to change the cursor in a method and restore the
// original one when going out of the method scope.
//_____________________________________________________________________________

///////////////////////////////////////////////////////////////////////////////
class TCursorSwitcher {
private:
   TGWindow *fW1;
   TGWindow *fW2;
public:
   TCursorSwitcher(TGWindow *w1, TGWindow *w2) : fW1(w1), fW2(w2) {
      if (w1) gVirtualX->SetCursor(w1->GetId(), gVirtualX->CreateCursor(kWatch));
      if (w2) gVirtualX->SetCursor(w2->GetId(), gVirtualX->CreateCursor(kWatch));
   }
   ~TCursorSwitcher() {
      if (fW1) gVirtualX->SetCursor(fW1->GetId(), gVirtualX->CreateCursor(kPointer));
      if (fW2) gVirtualX->SetCursor(fW2->GetId(), gVirtualX->CreateCursor(kPointer));
   }
};

//_____________________________________________________________________________
//
// TGFileBrowser
//
// System file browser, used as TRootBrowser plug-in.
// This class is the real core of the ROOT browser.
//_____________________________________________________________________________

ClassImp(TGFileBrowser)

//______________________________________________________________________________
TGFileBrowser::TGFileBrowser(const TGWindow *p, TBrowser* b, UInt_t w, UInt_t h)
   : TGMainFrame(p, w, h), TBrowserImp(b), fNewBrowser(0)
{
   // TGFileBrowser constructor.

   if (p && p != gClient->GetDefaultRoot())
      fNewBrowser = (TRootBrowser *)p->GetMainFrame();
   if (fNewBrowser)
      fNewBrowser->SetActBrowser(this);
   CreateBrowser();
   Resize(w, h);
   if (fBrowser) Show();
}

//______________________________________________________________________________
void TGFileBrowser::CreateBrowser()
{
   // Create the actual file browser.

   fCachedPic  = 0;
   SetCleanup(kDeepCleanup);

   fTopFrame = new TGHorizontalFrame(this, 100, 30);
   fDrawOption = new TGComboBox(fTopFrame, "");
   TGTextEntry *dropt_entry = fDrawOption->GetTextEntry();
   dropt_entry->SetToolTipText("Object Draw Option", 300);
   fDrawOption->Resize(80, 20);
   TGListBox *lb = fDrawOption->GetListBox();
   lb->Resize(lb->GetWidth(), 120);
   Int_t dropt = 1;
   fDrawOption->AddEntry("", dropt++);
   fDrawOption->AddEntry(" box", dropt++);
   fDrawOption->AddEntry(" colz", dropt++);
   fDrawOption->AddEntry(" lego", dropt++);
   fDrawOption->AddEntry(" lego1", dropt++);
   fDrawOption->AddEntry(" lego2", dropt++);
   fDrawOption->AddEntry(" same", dropt++);
   fDrawOption->AddEntry(" surf", dropt++);
   fDrawOption->AddEntry(" surf1", dropt++);
   fDrawOption->AddEntry(" surf2", dropt++);
   fDrawOption->AddEntry(" surf3", dropt++);
   fDrawOption->AddEntry(" surf4", dropt++);
   fDrawOption->AddEntry(" surf5", dropt++);
   fDrawOption->AddEntry(" text", dropt++);
   fTopFrame->AddFrame(fDrawOption, new TGLayoutHints(kLHintsCenterY |
                       kLHintsRight, 2, 2, 2, 2));
   fTopFrame->AddFrame(new TGLabel(fTopFrame, "Draw Option: "),
                       new TGLayoutHints(kLHintsCenterY | kLHintsRight,
                       2, 2, 2, 2));

   fSortButton = new TGPictureButton(fTopFrame, "bld_sortup.png");
   fSortButton->SetToolTipText("Sort Alphabetically\n(Current folder only)");
   fTopFrame->AddFrame(fSortButton, new TGLayoutHints(kLHintsCenterY |
                       kLHintsLeft, 2, 2, 2, 2));
   fSortButton->Connect("Clicked()", "TGFileBrowser", this, "ToggleSort()");

   fRefreshButton = new TGPictureButton(fTopFrame, "tb_refresh.xpm");
   fRefreshButton->SetToolTipText("Refresh Current Folder");
   fTopFrame->AddFrame(fRefreshButton, new TGLayoutHints(kLHintsCenterY |
                       kLHintsLeft, 2, 2, 2, 2));
   fRefreshButton->Connect("Clicked()", "TGFileBrowser", this, "Refresh()");

   AddFrame(fTopFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop |
            kLHintsExpandX, 2, 2, 2, 2));
   fCanvas   = new TGCanvas(this, 100, 100);
   fListTree = new TGListTree(fCanvas, kHorizontalFrame);
   AddFrame(fCanvas, new TGLayoutHints(kLHintsLeft | kLHintsTop |
                kLHintsExpandX | kLHintsExpandY));
   fListTree->Connect("DoubleClicked(TGListTreeItem *, Int_t)",
      "TGFileBrowser", this, "DoubleClicked(TGListTreeItem *, Int_t)");
   fListTree->Connect("Clicked(TGListTreeItem *, Int_t, Int_t, Int_t)",
      "TGFileBrowser", this, "Clicked(TGListTreeItem *, Int_t, Int_t, Int_t)");
   fListTree->Connect("Checked(TObject*, Bool_t)", "TGFileBrowser",
      this, "Checked(TObject*, Bool_t)");

   fRootIcon = gClient->GetPicture("rootdb_t.xpm");
   fFileIcon = gClient->GetPicture("doc_t.xpm");

   fBotFrame = new TGHorizontalFrame(this, 100, 30);
   fBotFrame->AddFrame(new TGLabel(fBotFrame, "Filter: "),
                       new TGLayoutHints(kLHintsCenterY | kLHintsLeft,
                       2, 2, 2, 2));
   fFileType = new TGComboBox(fBotFrame, " All Files (*.*)");
   Int_t ftype = 1;
   fFileType->AddEntry(" All Files (*.*)", ftype++);
   fFileType->AddEntry(" C/C++ Files (*.c;*.cxx;*.h;...)", ftype++);
   fFileType->AddEntry(" ROOT Files (*.root)", ftype++);
   fFileType->AddEntry(" Text Files (*.txt)", ftype++);
   fFileType->Resize(200, 20);
   fBotFrame->AddFrame(fFileType, new TGLayoutHints(kLHintsLeft | kLHintsTop |
                kLHintsExpandX, 2, 2, 2, 2));
   fFileType->Connect("Selected(Int_t)", "TGFileBrowser", this,
                      "ApplyFilter(Int_t)");
   fFileType->GetTextEntry()->Connect("ReturnPressed()", "TGFileBrowser", 
                                      this, "ApplyFilter(Int_t = -1)");
   AddFrame(fBotFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop |
            kLHintsExpandX, 2, 2, 2, 2));

   fContextMenu = new TContextMenu("FileBrowserContextMenu");
   fFilter      = 0;
   fGroupSize   = 1000;
   fListLevel   = 0;
   fCurrentDir  = 0;
   fRootDir     = 0;
   fDir         = 0;
   fFile        = 0;
   fNKeys       = 0;
   fCnt         = 0;

   TString gv = gEnv->GetValue("Browser.GroupView", "1000");
   Int_t igv = atoi(gv.Data());
   if (igv > 10)
      fGroupSize = igv;

   if (gEnv->GetValue("Browser.ShowHidden", 0))
      fShowHidden = kTRUE;
   else
      fShowHidden = kFALSE;

   fDblClick = kFALSE;

   TQObject::Connect("TGHtmlBrowser", "Clicked(char*)",
                     "TGFileBrowser", this, "Selected(char*)");

   TQObject::Connect("TPad", "Modified()",
                     "TGFileBrowser", this, "PadModified()");

   fListLevel = 0;
   MapSubwindows();
   Resize(GetDefaultSize());
   MapWindow();
}

//______________________________________________________________________________
TGFileBrowser::~TGFileBrowser()
{
   // Destructor.

   TQObject::Disconnect("TGHtmlBrowser", "Clicked(char*)");
   TQObject::Disconnect("TPad", "Modified()");

   delete fContextMenu;
   delete fListTree;
   if (fRootIcon) fClient->FreePicture(fRootIcon);
   if (fCachedPic && (fCachedPic != fFileIcon))
      fClient->FreePicture(fCachedPic);
   if (fFileIcon) fClient->FreePicture(fFileIcon);
   Cleanup();
}

//______________________________________________________________________________
static Bool_t IsObjectEditable(TClass *cl)
{
   // Helper function checking if a class has a graphic properties editor.

   TBaseClass *base;
   TList* bcl = cl->GetListOfBases();
   TIter next(bcl);
   while ((base = (TBaseClass*) next())) {
      cl = base->GetClassPointer();
      if (cl && TClass::GetClass(Form("%sEditor", cl->GetName())))
         return kTRUE;
      if (IsObjectEditable(cl))
         return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
static const char *FormatToolTip(TObject *obj, Int_t maxlen=0)
{
   // Format the tooltip information, based on the object passed in argument.

   static TString infos;
   if (!obj) {
      infos.Clear();
      return 0;
   }
   infos = obj->GetName();
   if (obj->GetTitle()) {
      infos += "\n";
      infos += obj->GetTitle();
   }
   if (maxlen > 0 && infos.Length() > maxlen) {
      infos.Remove(maxlen - 3);
      infos += "...";
   }
   TString objinfo = obj->GetObjectInfo(1, 1);
   if (!objinfo.IsNull() && !objinfo.BeginsWith("x=")) {
      Long64_t bsize, fsize, objsize;
      objsize = objinfo.Atoll();
      if (objsize > 0) {
         infos += "\n";
         bsize = fsize = objsize;
         if (fsize > 1024) {
            fsize /= 1024;
            if (fsize > 1024) {
               // 3.7MB is more informative than just 3MB
               infos += TString::Format("Size: %lld.%lldM", fsize/1024,
                                        (fsize%1024)/103);
            } else {
               infos += TString::Format("Size: %lld.%lldK", bsize/1024,
                                        (bsize%1024)/103);
            }
         } else {
            infos += TString::Format("Size: %lld bytes", bsize);
         }
      }
   }
   return infos.Data();
}

/**************************************************************************/
// TBrowserImp virtuals
/**************************************************************************/

//______________________________________________________________________________
void TGFileBrowser::Add(TObject *obj, const char *name, Int_t check)
{
   // Add items to the browser. This function has to be called
   // by the Browse() member function of objects when they are
   // called by a browser. If check < 0 (default) no check box is drawn,
   // if 0 then unchecked checkbox is added, if 1 checked checkbox is added.

   if (fListLevel && !strcmp(fListLevel->GetText(), "Classes") &&
      fListLevel->GetParent() &&
      !strcmp(fListLevel->GetParent()->GetText(), "root")) {
      // Browsing list of root classes...
   }
   else {
      if (obj && obj->InheritsFrom("TApplication"))
         fListLevel = 0;
      if (obj && obj->InheritsFrom("TSystemDirectory"))
         return;
   }
   const TGPicture *pic=0;
   if (obj && obj->InheritsFrom("TKey") && (obj->IsA() != TClass::Class()))
      AddKey(fListLevel, obj, name);
   else if (obj) {
      GetObjPicture(&pic, obj);
      if (!name) name = obj->GetName();
      if (check > -1) {
         if (!fListTree->FindChildByName(fListLevel, name)) {
            TGListTreeItem *item = fListTree->AddItem(fListLevel, name, obj,
                                                      pic, pic, kTRUE);
            if ((pic != fFileIcon) && (pic != fCachedPic))
               fClient->FreePicture(pic);
            if (item) fListTree->CheckItem(item, (Bool_t)check);
            fListTree->SetToolTipItem(item, FormatToolTip(obj, 32));
         }
      }
      else {
         // special case for remote object
         Bool_t isRemote = kFALSE;
         if (obj->InheritsFrom("TRemoteObject"))
            isRemote = kTRUE;
         else if (fListLevel) {
            // check also if one of its parents is a remote object
            TGListTreeItem *top = fListLevel;
            while (top->GetParent()) {
               TObject *tobj = (TObject *) top->GetUserData();
               if (tobj && (tobj->InheritsFrom("TRemoteObject") ||
                  tobj->InheritsFrom("TApplicationRemote"))) {
                  isRemote = kTRUE;
                  break;
               }
               top = top->GetParent();
            }
         }
         if (isRemote) {
            TRemoteObject *robj = (TRemoteObject *)obj;
            if (!strcmp(robj->GetClassName(), "TKey")) {
               AddKey(fListLevel, obj, name);
            }
            else {
               TString fname = name;
               // add the remote object only if not already in the list
               if (!fShowHidden && fname.BeginsWith("."))
                  return;
               AddRemoteFile(obj);
            }
         }
         else {
            if (!fListTree->FindChildByName(fListLevel, name)) {
               TGListTreeItem *item = fListTree->AddItem(fListLevel, name, obj, pic, pic);
               if ((pic != fFileIcon) && (pic != fCachedPic))
                  fClient->FreePicture(pic);
               if (item && obj && obj->InheritsFrom("TObject"))
                  item->SetDNDSource(kTRUE);
               fListTree->SetToolTipItem(item, FormatToolTip(obj, 32));
            }
         }
      }
   }
}

//______________________________________________________________________________
void TGFileBrowser::AddRemoteFile(TObject *obj)
{
   // Add remote file in list tree.

   Bool_t      is_link;
   Int_t       type, uid, gid;
   Long_t      modtime;
   Long64_t    size;
   TString     filename;
   const TGPicture *spic;
   TGPicture *pic;

   FileStat_t sbuf;

   type    = 0;
   size    = 0;
   uid     = 0;
   gid     = 0;
   modtime = 0;
   is_link = kFALSE;

   TRemoteObject *robj = (TRemoteObject *)obj;

   robj->GetFileStat(&sbuf);
   is_link = sbuf.fIsLink;
   type    = sbuf.fMode;
   size    = sbuf.fSize;
   uid     = sbuf.fUid;
   gid     = sbuf.fGid;
   modtime = sbuf.fMtime;
   filename = robj->GetName();
   if (R_ISDIR(type) || fFilter == 0 ||
       (fFilter && filename.Index(*fFilter) != kNPOS)) {

      GetFilePictures(&spic, type, is_link, filename);

      pic = (TGPicture*)spic; pic->AddReference();

      if ((!fListTree->FindChildByName(fListLevel, filename)) &&
         (!fListTree->FindChildByData(fListLevel, obj)))
         fListTree->AddItem(fListLevel, filename, obj, pic, pic);
   }
}

//______________________________________________________________________________
void TGFileBrowser::BrowseObj(TObject *obj)
{
   // Browse object. This, in turn, will trigger the calling of
   // TBrowser::Add() which will fill the IconBox and the tree.
   // Emits signal "BrowseObj(TObject*)".

   if (fNewBrowser)
      fNewBrowser->SetActBrowser(this);
   if (obj != gROOT) {
      if (!fListTree->FindItemByObj(fListTree->GetFirstItem(), obj)) {
         fListLevel = 0;
         Add(obj);
         fListLevel = fListTree->FindItemByObj(fListTree->GetFirstItem(), obj);
         fListTree->HighlightItem(fListLevel);
         if (obj->IsFolder())
            fListTree->OpenItem(fListLevel);
         fListTree->ClearViewPort();
         fListTree->AdjustPosition(fListLevel);
      }
   }
   obj->Browse(fBrowser);
   if (obj == gROOT) {
      TList *volumes = gSystem->GetVolumes("all");
      TList *curvol  = gSystem->GetVolumes("cur");
      if (volumes && curvol) {
         const char *curdrive;
         TNamed *named = (TNamed *)curvol->At(0);
         if (named)
            curdrive = named->GetName();
         else
            curdrive = "C:";
         TIter next(volumes);
         TNamed *drive;
         while ((drive = (TNamed *)next())) {
            AddFSDirectory(TString::Format("%s\\", drive->GetName()), drive->GetTitle(),
                           (strcmp(drive->GetName(), curdrive) == 0) ?
                           "SetRootDir" : "Add");
         }
         delete volumes;
         delete curvol;
      }
      else {
         AddFSDirectory("/");
      }
      GotoDir(gSystem->WorkingDirectory());
      if (gROOT->GetListOfFiles() && !gROOT->GetListOfFiles()->IsEmpty())
         Selected(0);
   }
}

//______________________________________________________________________________
void TGFileBrowser::Checked(TObject *obj, Bool_t checked)
{
   // Emits signal when double clicking on icon.

   if (fNewBrowser)
      fNewBrowser->Checked(obj, checked);
}

//______________________________________________________________________________
Option_t *TGFileBrowser::GetDrawOption() const
{
   // returns drawing option

   return fDrawOption->GetTextEntry()->GetText();
}

//______________________________________________________________________________
void TGFileBrowser::GetFilePictures(const TGPicture **pic, Int_t file_type,
                                    Bool_t is_link, const char *name)
{
   // Determine the file picture for the given file type.

   static TString cached_ext;
   static const TGPicture *cached_spic = 0;
   const char *ext = name ? strrchr(name, '.') : 0;
   TString sname = name ? name : " ";
   *pic = 0;

   if (ext && cached_spic && (cached_ext == ext)) {
      *pic = cached_spic;
      return;
   }

   if (R_ISREG(file_type)) {
      *pic = gClient->GetMimeTypeList()->GetIcon(name, kTRUE);

      if (*pic) {
         if (ext) {
            cached_ext = ext;
            cached_spic = *pic;
            return;
         }
      }
   } else {
      *pic = 0;
   }

   if (*pic == 0) {
      *pic = gClient->GetPicture("doc_t.xpm");

      if (R_ISREG(file_type) && (file_type) & kS_IXUSR) {
         *pic = gClient->GetPicture("app_t.xpm");
      }
      if (R_ISDIR(file_type)) {
         *pic = gClient->GetPicture("folder_t.xpm");
      }
      if(sname.EndsWith(".root")) {
         *pic = gClient->GetPicture("rootdb_t.xpm");
      }

   }
   if (is_link) {
      *pic = gClient->GetPicture("slink_t.xpm");
   }

   cached_spic = 0;
   cached_ext = "";
}

//______________________________________________________________________________
void TGFileBrowser::RecursiveRemove(TObject *obj)
{
   // Recursively remove object.

   TGListTreeItem *itm = 0, *item = 0;
   if (obj->InheritsFrom("TFile")) {
      itm = fListTree->FindChildByData(0, gROOT->GetListOfFiles());
      if (itm)
         item = fListTree->FindChildByData(itm, obj);
      if (item)
         fListTree->DeleteItem(item);
      itm = fRootDir ? fRootDir->GetFirstChild() : 0;
      while (itm) {
         item = fListTree->FindItemByObj(itm, obj);
         if (item) {
            fListTree->DeleteChildren(item);
            item->SetUserData(0);
         }
         itm = itm->GetNextSibling();
      }
   }
   if (!obj->InheritsFrom("TFile") && fRootDir)
      fListTree->RecursiveDeleteItem(fRootDir, obj);
   //fListTree->ClearViewPort();
}

//______________________________________________________________________________
void TGFileBrowser::Refresh(Bool_t /*force*/)
{
   // Refresh content of the list tree.

   TTimer::SingleShot(200, "TGFileBrowser", this, "Update()");
   return; // disable refresh for the time being...
   // coverity[unreachable]
   TCursorSwitcher cursorSwitcher(this, fListTree);
   static UInt_t prev = 0;
   UInt_t curr =  gROOT->GetListOfBrowsables()->GetSize();
   if (!prev) prev = curr;

   if (prev != curr) { // refresh gROOT
      TGListTreeItem *sav = fListLevel;
{'fraction_non_alphanumeric': 0.15586300067548972, 'fraction_numerical': 0.010607690575667359, 'mean_word_length': 2.729079205149734, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 329, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2619624', 'n_tokens_mistral': 13001, 'n_tokens_neox': 12348, 'n_words': 2609}