]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/TGFileBrowser.cxx
Dummy methods DefineParticle required by the interface added.
[u/mrichter/AliRoot.git] / EVE / Reve / TGFileBrowser.cxx
1
2 #include "TROOT.h"
3 #include "TSystem.h"
4 #include "TApplication.h"
5 #include "TGClient.h"
6 #include "TGListTree.h"
7 #include "TGLayout.h"
8 #include "TGComboBox.h"
9 #include "TContextMenu.h"
10 #include "TGTextEntry.h"
11 #include "TGTab.h"
12 #include "TGLabel.h"
13 #include "TSystemDirectory.h"
14 #include "TGMimeTypes.h"
15 #include "TClass.h"
16 #include "TInterpreter.h"
17 #include "TRegexp.h"
18 #include "TEnv.h"
19 #include "TImage.h"
20 #include "TBrowser.h"
21 #include <time.h>
22 #include <string.h>
23
24 #include "TGFileBrowser.h"
25 #include "TGNewBrowser.h"
26
27 #ifdef WIN32
28 const char rootdir[] = "\\";
29 #else
30 const char rootdir[] = "/";
31 #endif
32
33 const char *filters[] = {
34    "",
35    "*.*",
36    "*.[C|c|h]*",
37    "*.root",
38    "*.txt"
39 };
40
41 ////////////////////////////////////////////////////////////////////////////////////
42 class TCursorSwitcher {
43 private:
44    TGWindow *fW1;
45    TGWindow *fW2;
46 public:
47    TCursorSwitcher(TGWindow *w1, TGWindow *w2) : fW1(w1), fW2(w2) {
48       if (w1) gVirtualX->SetCursor(w1->GetId(), gVirtualX->CreateCursor(kWatch));
49       if (w2) gVirtualX->SetCursor(w2->GetId(), gVirtualX->CreateCursor(kWatch));
50    }
51    ~TCursorSwitcher() {
52       if (fW1) gVirtualX->SetCursor(fW1->GetId(), gVirtualX->CreateCursor(kPointer));
53       if (fW2) gVirtualX->SetCursor(fW2->GetId(), gVirtualX->CreateCursor(kPointer));
54    }
55 };
56
57 ClassImp(TGFileBrowser)
58
59 //______________________________________________________________________________
60 TGFileBrowser::TGFileBrowser(TBrowser* b, const char *name, UInt_t w, UInt_t h) :
61    TGMainFrame(gClient->GetRoot(), w, h), TBrowserImp(b),
62    fNewBrowser(0)
63 {
64    CreateBrowser(name);
65    Resize(w, h);
66    if (fBrowser) Show();
67 }
68
69 //______________________________________________________________________________
70 TGFileBrowser::TGFileBrowser(TBrowser* b, const char *name, Int_t x, Int_t y,
71                              UInt_t w, UInt_t h) :
72    TGMainFrame(gClient->GetRoot(), w, h), TBrowserImp(b),
73    fNewBrowser(0)
74 {
75    CreateBrowser(name);
76    MoveResize(x, y, w, h);
77    SetWMPosition(x, y);
78    if (fBrowser) Show();
79 }
80
81 //______________________________________________________________________________
82 void TGFileBrowser::CreateBrowser(const char *name)
83 {
84    fCachedPic  = 0;
85    SetCleanup(kDeepCleanup);
86
87    /*
88    fNewBrowser = 0;
89    if (p && p != gClient->GetDefaultRoot())
90       fNewBrowser = (TGNewBrowser *)p->GetMainFrame();
91    if (fNewBrowser)
92       fNewBrowser->SetBrowserFrame(this);
93    */
94    fTopFrame = new TGHorizontalFrame(this, 100, 30);
95    fDrawOption = new TGComboBox(fTopFrame, "");
96    TGTextEntry *dropt_entry = fDrawOption->GetTextEntry();
97    dropt_entry->SetToolTipText("Object Draw Option", 300);
98    fDrawOption->Resize(80, 20);
99    TGListBox *lb = fDrawOption->GetListBox();
100    lb->Resize(lb->GetWidth(), 120);
101    Int_t dropt = 1;
102    fDrawOption->AddEntry("", dropt++);
103    fDrawOption->AddEntry(" alp", dropt++);
104    fDrawOption->AddEntry(" box", dropt++);
105    fDrawOption->AddEntry(" colz", dropt++);
106    fDrawOption->AddEntry(" lego", dropt++);
107    fDrawOption->AddEntry(" lego1", dropt++);
108    fDrawOption->AddEntry(" lego2", dropt++);
109    fDrawOption->AddEntry(" same", dropt++);
110    fDrawOption->AddEntry(" surf", dropt++);
111    fDrawOption->AddEntry(" surf1", dropt++);
112    fDrawOption->AddEntry(" surf2", dropt++);
113    fDrawOption->AddEntry(" surf3", dropt++);
114    fDrawOption->AddEntry(" surf4", dropt++);
115    fDrawOption->AddEntry(" surf5", dropt++);
116    fDrawOption->AddEntry(" text", dropt++);
117    fTopFrame->AddFrame(fDrawOption, new TGLayoutHints(kLHintsCenterY | 
118                        kLHintsRight, 2, 2, 2, 2));
119    fTopFrame->AddFrame(new TGLabel(fTopFrame, "Draw Option: "),
120                        new TGLayoutHints(kLHintsCenterY | kLHintsRight, 
121                        2, 2, 2, 2));
122    AddFrame(fTopFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop | 
123             kLHintsExpandX, 2, 2, 2, 2));
124    fCanvas   = new TGCanvas(this, 100, 100);
125    fListTree = new TGListTree(fCanvas, kHorizontalFrame);
126    AddFrame(fCanvas, new TGLayoutHints(kLHintsLeft | kLHintsTop | 
127                 kLHintsExpandX | kLHintsExpandY));
128    fListTree->Connect("DoubleClicked(TGListTreeItem *, Int_t)",
129       "TGFileBrowser", this, "DoubleClicked(TGListTreeItem *, Int_t)");
130    fListTree->Connect("Clicked(TGListTreeItem *, Int_t, Int_t, Int_t)",
131       "TGFileBrowser", this, "Clicked(TGListTreeItem *, Int_t, Int_t, Int_t)");
132
133    fRootIcon = gClient->GetPicture("rootdb_t.xpm");
134    fFileIcon = gClient->GetPicture("doc_t.xpm");
135
136    fBotFrame = new TGHorizontalFrame(this, 100, 30);
137    fBotFrame->AddFrame(new TGLabel(fBotFrame, "Filter: "),
138                        new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 
139                        2, 2, 2, 2));
140    fFileType = new TGComboBox(fBotFrame, " All Files (*.*)");
141    Int_t ftype = 1;
142    fFileType->AddEntry(" All Files (*.*)", ftype++);
143    fFileType->AddEntry(" C/C++ Files (*.c;*.cxx;*.h;...)", ftype++);
144    fFileType->AddEntry(" ROOT Files (*.root)", ftype++);
145    fFileType->AddEntry(" Text Files (*.txt)", ftype++);
146    fFileType->Resize(200, fFileType->GetTextEntry()->GetDefaultHeight());
147    fBotFrame->AddFrame(fFileType, new TGLayoutHints(kLHintsLeft | kLHintsTop | 
148                 kLHintsExpandX, 2, 2, 2, 2));
149    fFileType->Connect("Selected(Int_t)", "TGFileBrowser", this, "ApplyFilter(Int_t)");
150    AddFrame(fBotFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop | 
151             kLHintsExpandX, 2, 2, 2, 2));
152
153    fContextMenu = new TContextMenu("FileBrowserContextMenu") ;
154    fFilter      = 0;
155    fGroupSize   = 1000;
156    fListLevel   = 0;
157    fCurrentDir  = 0;
158    fRootDir     = 0;
159    TString gv = gEnv->GetValue("Browser.GroupView", "10000");
160    Int_t igv = atoi(gv.Data());
161    if (igv > 10)
162       fGroupSize = igv;
163    
164    if (gEnv->GetValue("Browser.ShowHidden", 0))
165       fShowHidden = kTRUE;
166    else
167       fShowHidden = kFALSE;
168
169    MapSubwindows();
170    Resize(GetDefaultSize());
171    SetWindowName(name);
172    SetIconName(name);
173    MapWindow();
174 }
175
176 //______________________________________________________________________________
177 void TGFileBrowser::ReallyDelete()
178 {
179    // Really delete the browser and the this GUI.
180
181    gInterpreter->DeleteGlobal(fBrowser);
182    delete fBrowser;    // will in turn delete this object
183 }
184
185 //______________________________________________________________________________
186 TGFileBrowser::~TGFileBrowser()
187 {
188    // Destructor.
189
190    delete fContextMenu;
191    delete fListTree;
192    Cleanup();
193 }
194
195
196 /**************************************************************************/
197 // TBrowserImp virtuals
198 /**************************************************************************/
199
200 //______________________________________________________________________________
201 void TGFileBrowser::Add(TObject *obj, const char *name, Int_t check)
202 {
203    // Add items to the browser. This function has to be called
204    // by the Browse() member function of objects when they are
205    // called by a browser. If check < 0 (default) no check box is drawn,
206    // if 0 then unchecked checkbox is added, if 1 checked checkbox is added.
207
208    if (obj && obj->InheritsFrom("TSystemDirectory"))
209       return;
210    const TGPicture *pic=0;
211    if (obj && obj->InheritsFrom("TKey"))
212       AddKey(fListLevel, obj, name);
213    else if (obj) {
214       GetObjPicture(&pic, obj);
215       if (!name) name = obj->GetName();
216       if(check > -1) {
217          if (!fListTree->FindChildByName(fListLevel, name)) {
218             TGListTreeItem *item = fListTree->AddItem(fListLevel, name, obj, pic, pic, kTRUE);
219             fListTree->CheckItem(item, (Bool_t)check);
220             TString tip(obj->ClassName());
221             if (obj->GetTitle()) {
222                tip += " ";
223                tip += obj->GetTitle();
224             }
225             fListTree->SetToolTipItem(item, tip.Data());
226          }
227       } 
228       else {
229          if (!fListTree->FindChildByName(fListLevel, name))
230             fListTree->AddItem(fListLevel, name, obj, pic, pic);
231       }
232    }
233    //fListTree->ClearViewPort();
234 }
235
236 //______________________________________________________________________________
237 void TGFileBrowser::BrowseObj(TObject *obj)
238 {
239    // Browse object. This, in turn, will trigger the calling of
240    // TRootBrowser::Add() which will fill the IconBox and the tree.
241    // Emits signal "BrowseObj(TObject*)".
242
243    obj->Browse(fBrowser);
244 }
245
246 //______________________________________________________________________________
247 Option_t *TGFileBrowser::GetDrawOption() const
248 {
249    // returns drawing option
250
251    return fDrawOption->GetTextEntry()->GetText();
252 }
253
254 //______________________________________________________________________________
255 void TGFileBrowser::RecursiveRemove(TObject *obj)
256 {
257
258    TGListTreeItem *itm = 0, *item = 0;
259    if (obj->InheritsFrom("TFile")) {
260       itm = fListTree->FindChildByData(0, gROOT->GetListOfFiles());
261       if (itm)
262          item = fListTree->FindChildByData(itm, obj);
263       if (item)
264          fListTree->DeleteItem(item);
265       itm = fRootDir ? fRootDir->GetFirstChild() : 0;
266       while (itm) {
267          item = fListTree->FindItemByObj(itm, obj);
268          if (item) {
269             fListTree->DeleteChildren(item);
270             item->SetUserData(0);
271          }
272          itm = itm->GetNextSibling();
273       }
274    }
275    if (!obj->InheritsFrom("TFile") && fRootDir)
276       fListTree->RecursiveDeleteItem(fRootDir, obj);
277    fListTree->ClearViewPort();
278 }
279
280 //______________________________________________________________________________
281 void TGFileBrowser::Refresh(Bool_t /*force*/)
282 {
283
284    TCursorSwitcher cursorSwitcher(this, fListTree);
285    static UInt_t prev = 0;
286    UInt_t curr =  gROOT->GetListOfBrowsables()->GetSize();
287    if (!prev) prev = curr;
288
289    if (prev != curr) { // refresh gROOT
290       TGListTreeItem *sav = fListLevel;
291       fListLevel = 0;
292       BrowseObj(gROOT);
293       fListLevel = sav;
294       prev = curr;
295    }
296 }
297
298
299 /**************************************************************************/
300 // Other
301 /**************************************************************************/
302
303 //______________________________________________________________________________
304 void TGFileBrowser::AddFSDirectory(const char* /*entry*/, const char* path)
305 {
306    if (path == 0 && fRootDir == 0) {
307       fRootDir = fListTree->AddItem(0, rootdir);
308    } else {
309       // MT: i give up! wanted to place entries for selected
310       // directories like home, pwd, alice-macros.
311       // TGListTreeItem *lti = fListTree->AddItem(0, entry);
312       //
313    }
314 }
315
316 //______________________________________________________________________________
317 void TGFileBrowser::AddKey(TGListTreeItem *itm, TObject *obj, const char *name)
318 {
319    // display content of ROOT file
320
321    // Int_t from, to;
322    TGListTreeItem *where;
323    static TGListTreeItem *olditem = itm;
324    static TGListTreeItem *item = itm;
325    static const TGPicture *pic  = 0;
326    static const TGPicture *pic2 = gClient->GetPicture("leaf_t.xpm");
327
328    if ((fCnt == 0) || (olditem != itm)) {
329       olditem = item = itm;
330    }
331    if (!name) name = obj->GetName();
332    if (fNKeys > fGroupSize) {
333       where = itm->GetFirstChild();
334       while (where) {
335          if (fListTree->FindItemByObj(where, obj))
336             return;
337          where = where->GetNextSibling();
338       }
339    }
340    if ((fNKeys > fGroupSize) && (fCnt % fGroupSize == 0)) {
341       if (item != itm) {
342          TString newname = Form("%s-%s", item->GetText(), name);
343          item->Rename(newname.Data());
344       }
345       item = fListTree->AddItem(itm, name);
346    }
347    if ((fCnt > fGroupSize) && (fCnt >= fNKeys-1)) {
348       TString newname = Form("%s-%s", item->GetText(), name);
349       item->Rename(newname.Data());
350    }
351    GetObjPicture(&pic, obj);
352    if (!pic) pic = pic2;
353    if (!fListTree->FindChildByName(item, name)) {
354       fListTree->AddItem(item, name, obj, pic, pic);
355    }
356    fCnt++;
357 }
358
359 //______________________________________________________________________________
360 void TGFileBrowser::ApplyFilter(Int_t id)
361 {
362    // Apply filter selected in combo box to the file tree view.
363
364    // Long64_t size;
365    // Long_t fid, flags, modtime;
366
367    if (fFilter) delete fFilter;
368    fFilter = 0;
369    if (id > 1)
370       fFilter = new TRegexp(filters[id], kTRUE);
371    TGListTreeItem *item = fCurrentDir;
372    if (!item)
373       item = fRootDir;
374    fListTree->DeleteChildren(item);
375    DoubleClicked(item, 1);
376    //fListTree->AdjustPosition(item);
377    fListTree->ClearViewPort();
378 }
379
380 //______________________________________________________________________________
381 void TGFileBrowser::Chdir(TGListTreeItem *item)
382 {
383    // Make object associated with item the current directory.
384
385    if (item) {
386       TGListTreeItem *i = item;
387       while (i) {
388          TObject *obj = (TObject*) i->GetUserData();
389          if ((obj) && obj->InheritsFrom("TFile")) {
390             gROOT->ProcessLine(Form("((TFile *)0x%lx)->cd()", obj));
391             break;
392          }
393          i = i->GetParent();
394       }
395    }
396 }
397
398 //______________________________________________________________________________
399 void TGFileBrowser::Clicked(TGListTreeItem *item, Int_t btn, Int_t x, Int_t y)
400 {
401
402    char path[1024];
403    Long64_t size = 0;
404    Long_t id = 0, flags = 0, modtime = 0;
405    fListLevel = item;
406    if (item && btn == kButton3) {
407       TObject *obj = (TObject *) item->GetUserData();
408       if (obj) {
409          if (obj->InheritsFrom("TKey")) {
410             Chdir(item);
411             const char *clname = (const char *)gROOT->ProcessLine(Form("((TKey *)0x%lx)->GetClassName();", obj));
412             if (clname) {
413                TClass *cl = TClass::GetClass(clname);
414                void *add = gROOT->FindObject((char *) obj->GetName());
415                if (add && cl->IsTObject()) {
416                   obj = (TObject*)add;
417                   item->SetUserData(obj);
418                }
419             }
420          }
421          fContextMenu->Popup(x, y, obj);
422       }
423       else {
424          fListTree->GetPathnameFromItem(item, path);
425          if (strlen(path) > 3) {
426             TString dirname = DirName(item);
427             gSystem->GetPathInfo(dirname.Data(), &id, &size, &flags, &modtime);
428             if (flags & 2) {
429                fCurrentDir = item;
430                TSystemDirectory d(item->GetText(), dirname.Data());
431                fContextMenu->Popup(x, y, &d);
432             }
433             else {
434                fCurrentDir = item->GetParent();
435                TSystemFile f(item->GetText(), dirname.Data());
436                fContextMenu->Popup(x, y, &f);
437             }
438          }
439       }
440       fListTree->ClearViewPort();
441    }
442    else {
443       if (!item->GetUserData()) {
444          fListTree->GetPathnameFromItem(item, path);
445          if (strlen(path) > 1) {
446             TString dirname = DirName(item);
447             gSystem->GetPathInfo(dirname.Data(), &id, &size, &flags, &modtime);
448             if (flags & 2)
449                fCurrentDir = item;
450             else
451                fCurrentDir = item->GetParent();
452          }
453       }
454    }
455 }
456
457 //______________________________________________________________________________
458 TString TGFileBrowser::DirName(TGListTreeItem* item)
459 {
460    // returns an absolute path
461
462    TGListTreeItem* parent;
463    TString dirname = item->GetText();
464
465    while ((parent=item->GetParent())) {
466       dirname = gSystem->ConcatFileName(parent->GetText(),dirname);
467       item = parent;
468    }
469
470    return dirname;
471 }
472
473 //______________________________________________________________________________
474 static Bool_t IsTextFile(const char *candidate)
475 {
476    // Returns true if given a text file
477    // Uses the specification given on p86 of the Camel book
478    // - Text files have no NULLs in the first block
479    // - and less than 30% of characters with high bit set
480
481    Int_t i;
482    Int_t nchars;
483    Int_t weirdcount = 0;
484    char buffer[512];
485    FILE *infile;
486    FileStat_t buf;
487
488    gSystem->GetPathInfo(candidate, buf);
489    if (!(buf.fMode & kS_IFREG))
490       return kFALSE;
491
492    infile = fopen(candidate, "r");
493    if (infile) {
494       // Read a block
495       nchars = fread(buffer, 1, 512, infile);
496       fclose (infile);
497       // Examine the block
498       for (i = 0; i < nchars; i++) {
499          if (buffer[i] & 128)
500             weirdcount++;
501          if (buffer[i] == '\0')
502             // No NULLs in text files
503             return kFALSE;
504       }
505       if ((nchars > 0) && ((weirdcount * 100 / nchars) > 30))
506          return kFALSE;
507    } else {
508       // Couldn't open it. Not a text file then
509       return kFALSE;
510    }
511    return kTRUE;
512 }
513
514 //______________________________________________________________________________
515 void TGFileBrowser::DoubleClicked(TGListTreeItem *item, Int_t /*btn*/)
516 {
517    // Process double clicks in TGListTree.
518
519    const TGPicture *pic=0;
520    TString dirname = DirName(item);
521    TGListTreeItem *itm;
522    FileStat_t sbuf;
523    Long64_t size;
524    Long_t id, flags, modtime;
525
526    TCursorSwitcher switcher(this, fListTree);
527    fListLevel = item;
528    TObject *obj = (TObject *) item->GetUserData();
529    if (obj && !obj->InheritsFrom("TSystemFile")) {
530       if (obj->InheritsFrom("TFile")) {
531          fNKeys = gROOT->ProcessLine(Form("((TFile *)0x%lx)->GetListOfKeys()->GetEntries();", obj));
532       }
533       if (obj->InheritsFrom("TKey")) {
534          Chdir(item);
535          const char *clname = (const char *)gROOT->ProcessLine(Form("((TKey *)0x%lx)->GetClassName();", obj));
536          if (clname) {
537             TClass *cl = TClass::GetClass(clname);
538             void *add = gROOT->FindObject((char *) obj->GetName());
539             if (add && cl->IsTObject()) {
540                obj = (TObject*)add;
541                item->SetUserData(obj);
542             }
543          }
544       }
545       obj->Browse(fBrowser);
546       fNKeys = 0;
547       fCnt = 0;
548       fListTree->ClearViewPort();
549       return;
550    }
551    flags = id = size = modtime = 0;
552    gSystem->GetPathInfo(dirname.Data(), &id, &size, &flags, &modtime);
553    Int_t isdir = (Int_t)flags & 2;
554
555    TString savdir = gSystem->WorkingDirectory();
556    if (isdir) {
557       fCurrentDir = item;
558       TSystemDirectory dir(item->GetText(),DirName(item));
559       TList *files = dir.GetListOfFiles();
560       if (files) {
561          files->Sort();
562          TIter next(files);
563          TSystemFile *file;
564          TString fname;
565          // directories first 
566          while ((file=(TSystemFile*)next())) {
567             fname = file->GetName();
568             if (file->IsDirectory()) {
569                if (!fShowHidden && fname.BeginsWith("."))
570                   continue;
571                if ((fname!="..") && (fname!=".")) { // skip it
572                   if (!fListTree->FindChildByName(item, fname)) {
573                      itm = fListTree->AddItem(item, fname);
574                   }
575                }
576             }
577          }
578          // then files... 
579          TIter nextf(files);
580          while ((file=(TSystemFile*)nextf())) {
581             fname = file->GetName();
582             if (!file->IsDirectory() && (fFilter == 0 ||
583                (fFilter && fname.Index(*fFilter) != kNPOS))) {
584                if (!fShowHidden && fname.BeginsWith("."))
585                   continue;
586                size = modtime = 0;
587                if (gSystem->GetPathInfo(fname, sbuf) == 0) {
588                   size    = sbuf.fSize;
589                   modtime = sbuf.fMtime;
590                }
591                pic = gClient->GetMimeTypeList()->GetIcon(fname, kTRUE);
592                if (!pic)
593                   pic = fFileIcon;
594                if (!fListTree->FindChildByName(item, fname)) {
595                   itm = fListTree->AddItem(item,fname,pic,pic);
596                   if (size && modtime) {
597                      char *tiptext = FormatFileInfo(fname.Data(), size, modtime);
598                      itm->SetTipText(tiptext);
599                      delete [] tiptext;
600                   }
601                }
602             }
603          }
604          delete files;
605       }
606    }
607    else {
608       fCurrentDir = item->GetParent();
609       TSystemFile f(item->GetText(), dirname.Data());
610       TString fname = f.GetName();
611       if (fname.EndsWith(".root")) {
612          TObject *rfile = 0;
613          gSystem->ChangeDirectory(gSystem->DirName(dirname.Data()));
614          rfile = gROOT->GetListOfFiles()->FindObject(obj);
615          if (!rfile) {
616             rfile = (TObject *)gROOT->ProcessLine(Form("new TFile(\"%s\")",fname.Data()));
617             item->SetUserData(rfile);
618          }
619          if (rfile) {
620             fNKeys = gROOT->ProcessLine(Form("((TFile *)0x%lx)->GetListOfKeys()->GetEntries();", rfile));
621             fCnt = 0;
622             gROOT->ProcessLine(Form("((TFile *)0x%lx)->Browse((TBrowser *)0x%lx)", rfile, fBrowser));
623             fNKeys = 0;
624             fCnt = 0;
625          }
626       }
627       else if (fname.EndsWith(".png")) {
628          gSystem->ChangeDirectory(gSystem->DirName(dirname.Data()));
629          XXExecuteDefaultAction(&f);
630       }
631       else if (IsTextFile(dirname.Data())) {
632          gSystem->ChangeDirectory(gSystem->DirName(dirname.Data()));
633          if (fNewBrowser) {
634             TGTab *tabRight = fNewBrowser->GetTabRight();
635             TGCompositeFrame *frame = tabRight->GetCurrentContainer();
636             TGFrameElement *fe = (TGFrameElement *)frame->GetList()->First();
637             if (fe) {
638                TGCompositeFrame *embed = (TGCompositeFrame *)fe->fFrame;
639                if (embed->InheritsFrom("TGTextEditor")) {
640                   gROOT->ProcessLine(Form("((TGTextEditor *)0x%lx)->LoadFile(\"%s\");", 
641                                      embed, f.GetName()));
642                }
643                else if (embed->InheritsFrom("TGTextEdit")) {
644                   gROOT->ProcessLine(Form("((TGTextEdit *)0x%lx)->LoadFile(\"%s\");", 
645                                      embed, f.GetName()));
646                }
647                else {
648                   XXExecuteDefaultAction(&f);
649                }
650             }
651          }
652       }
653       else {
654          gSystem->ChangeDirectory(gSystem->DirName(dirname.Data()));
655          XXExecuteDefaultAction(&f);
656       }
657    }
658    gSystem->ChangeDirectory(savdir.Data());
659    fListTree->ClearViewPort();
660 }
661
662 //____________________________________________________________________________
663 Long_t TGFileBrowser::XXExecuteDefaultAction(TObject *obj)
664 {
665    // Execute default action for selected object (action is specified
666    // in the $HOME/.root.mimes or $ROOTSYS/etc/root.mimes file.
667
668    char action[512];
669    TString act;
670    TString ext = obj->GetName();
671    fBrowser->SetDrawOption(GetDrawOption());
672
673    if (gClient->GetMimeTypeList()->GetAction(obj->GetName(), action)) {
674       act = action;
675       act.ReplaceAll("%s", obj->GetName());
676       gInterpreter->SaveGlobalsContext();
677
678       if (act[0] == '!') {
679          act.Remove(0, 1);
680          gSystem->Exec(act.Data());
681          return 0;
682       } else {
683          return gApplication->ProcessLine(act.Data());
684       }
685    }
686    return 0;
687 }
688
689 //______________________________________________________________________________
690 char *TGFileBrowser::FormatFileInfo(const char *fname, Long64_t size, Long_t modtime)
691 {
692
693    Long64_t fsize, bsize;
694    TString infos = fname;
695    infos += "\n";
696
697    fsize = bsize = size;
698    if (fsize > 1024) {
699       fsize /= 1024;
700       if (fsize > 1024) {
701          // 3.7MB is more informative than just 3MB
702          infos += Form("Size: %lld.%lldM", fsize/1024, (fsize%1024)/103);
703       } else {
704          infos += Form("Size: %lld.%lldK", bsize/1024, (bsize%1024)/103);
705       }
706    } else {
707       infos += Form("Size: %lld", bsize);
708    }
709    struct tm *newtime;
710    time_t loctime = (time_t) modtime;
711    newtime = localtime(&loctime);
712    infos += "\n";
713    infos += Form("%d-%02d-%02d %02d:%02d", newtime->tm_year + 1900,
714            newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour,
715            newtime->tm_min);
716    return StrDup(infos.Data());
717 }
718
719 //______________________________________________________________________________
720 void TGFileBrowser::GetObjPicture(const TGPicture **pic, TObject *obj)
721 {
722    // Retrieve icons associated with class "name". Association is made
723    // via the user's ~/.root.mimes file or via $ROOTSYS/etc/root.mimes.
724
725    TClass *objClass = 0;
726    static TImage *im = 0;
727    if (!im) {
728       im = TImage::Create();
729    }
730
731    if (obj->InheritsFrom("TKey")) {
732       const char *clname = (const char *)gROOT->ProcessLine(Form("((TKey *)0x%lx)->GetClassName();", obj));
733       if (clname)
734          objClass = TClass::GetClass(clname);
735    }
736    else if (obj->InheritsFrom("TKeyMapFile")) {
737       const char *title = (const char *)gROOT->ProcessLine(Form("((TKeyMapFile *)0x%lx)->GetTitle();", obj));
738       if (title)
739          objClass = TClass::GetClass(title);
740    }
741    else
742       objClass = obj->IsA();
743    const char *name = obj->GetIconName() ? obj->GetIconName() : objClass->GetName();
744    TString xpm_magic(name, 3);
745    Bool_t xpm = xpm_magic == "/* ";
746    const char *iconname = xpm ? obj->GetName() : name;
747
748    if (obj->IsA()->InheritsFrom("TGeoVolume")) {
749       iconname = obj->GetIconName() ? obj->GetIconName() : obj->IsA()->GetName();
750    }
751
752    if (fCachedPicName == iconname) {
753       *pic = fCachedPic;
754       return;
755    }
756    *pic = gClient->GetMimeTypeList()->GetIcon(iconname, kTRUE);
757    if (!(*pic) && xpm) {
758       if (im && im->SetImageBuffer((char**)&name, TImage::kXpm)) {
759          im->Scale(im->GetWidth()/4, im->GetHeight()/4);
760          *pic = gClient->GetPicturePool()->GetPicture(iconname, im->GetPixmap(),
761                                                       im->GetMask());
762       }
763       gClient->GetMimeTypeList()->AddType("[thumbnail]", iconname, iconname, iconname, "->Browse()");
764       return;
765    }
766    if (*pic == 0) {
767       if (!obj->IsFolder())
768          *pic = fFileIcon;
769    }
770    fCachedPic = *pic;
771    fCachedPicName = iconname;
772 }
773
774 //______________________________________________________________________________
775 void TGFileBrowser::GotoDir(const char *path)
776 {
777
778    TGListTreeItem *item, *itm;
779    char *token;
780    static const char seps[] = "/\\";
781    // Establish string and get the first token:
782    token = strtok(strdup(path), seps);
783    // Note: strtok is deprecated; consider using strtok_s instead
784    item = fRootDir;
785    if (item == 0) return;
786    fListTree->HighlightItem(item);
787    fListTree->OpenItem(item);
788    DoubleClicked(item, 1);
789    while (token) {
790       // while there are tokens in path
791       itm = fListTree->FindChildByName(item, token);
792       if (itm) {
793          item = itm;
794          fListTree->HighlightItem(item);
795          fListTree->OpenItem(item);
796          DoubleClicked(item, 1);
797       }
798       // get next token:
799       token = strtok( NULL, seps );
800    }
801    fListTree->ClearViewPort();
802    fListTree->AdjustPosition(item);
803 }
804
805