TGFSContainer.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGFSContainer.cxx 36090 2010-10-05 17:32:34Z rdm $
00002 // Author: Fons Rademakers   19/01/98
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, 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 
00013     This source is based on Xclass95, a Win95-looking GUI toolkit.
00014     Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
00015 
00016     Xclass95 is free software; you can redistribute it and/or
00017     modify it under the terms of the GNU Library General Public
00018     License as published by the Free Software Foundation; either
00019     version 2 of the License, or (at your option) any later version.
00020 
00021 **************************************************************************/
00022 
00023 //////////////////////////////////////////////////////////////////////////
00024 //                                                                      //
00025 // TGFileIcon, TGFileEntry, TGFSContainer                               //
00026 //                                                                      //
00027 // Utility classes used by the file selection dialog (TGFSDialog).      //
00028 //                                                                      //
00029 //////////////////////////////////////////////////////////////////////////
00030 
00031 #include "TGFSContainer.h"
00032 #include "TGIcon.h"
00033 #include "TGMsgBox.h"
00034 #include "TGMimeTypes.h"
00035 #include "TRegexp.h"
00036 #include "TList.h"
00037 #include "TSystem.h"
00038 #include "TGDNDManager.h"
00039 #include "TBufferFile.h"
00040 #include "Riostream.h"
00041 #include "TRemoteObject.h"
00042 #include "TImage.h"
00043 #include <time.h>
00044 
00045 ClassImp(TGFileItem)
00046 ClassImp(TGFileContainer)
00047 
00048 class TViewUpdateTimer : public TTimer {
00049 
00050 private:
00051    TGFileContainer   *fContainer;
00052 
00053 public:
00054    TViewUpdateTimer(TGFileContainer *t, Long_t ms) : TTimer(ms, kTRUE) { fContainer = t; }
00055    Bool_t Notify();
00056 };
00057 
00058 
00059 
00060 class TGFileIcon : public TGIcon {
00061 
00062 protected:
00063    const TGPicture *fLpic;   // icon picture
00064 
00065    virtual void DoRedraw();
00066 
00067 public:
00068    TGFileIcon(const TGWindow *p, const TGPicture *pic, const TGPicture *lpic,
00069               UInt_t options = kChildFrame, Pixel_t back = GetWhitePixel()) :
00070       TGIcon(p, pic, 0, 0, options, back) { fLpic = lpic; }
00071 };
00072 
00073 
00074 
00075 //______________________________________________________________________________
00076 class TGFSFrameElement : public TGFrameElement {
00077 public:
00078    TGFileContainer  *fContainer;   // file container
00079 
00080    Bool_t IsSortable() const { return kTRUE; }
00081    Int_t  Compare(const TObject *obj) const;
00082 };
00083 
00084 //______________________________________________________________________________
00085 Int_t TGFSFrameElement::Compare(const TObject *obj) const
00086 {
00087    // Sort frame elements in file selection list view container.
00088 
00089    Int_t type1, type2;
00090 
00091    TGFileItem *f1 = (TGFileItem *) fFrame;
00092    TGFileItem *f2 = (TGFileItem *) ((TGFrameElement *) obj)->fFrame;
00093 
00094    switch (fContainer->fSortType) {
00095       default:
00096       case kSortByName:
00097          //--- this is not exactly what I want...
00098          type1 = f1->GetType();
00099          type2 = f2->GetType();
00100 
00101          //--- use posix macros
00102          if (R_ISDIR(type1)) type1 = 1;
00103          else                type1 = 6;
00104 
00105          if (R_ISDIR(type2)) type2 = 1;
00106          else                type2 = 6;
00107 
00108          if (type1 < type2)  return -1;
00109          if (type1 > type2)  return  1;
00110          return strcmp(f1->GetItemName()->GetString(),
00111                        f2->GetItemName()->GetString());
00112 
00113       case kSortByOwner:
00114          if (f1->GetUid() != f2->GetUid()) {
00115             if (f1->GetUid() < f2->GetUid())
00116                return -1;
00117             else
00118                return +1;
00119          }
00120 
00121          // else sort by name
00122          type1 = f1->GetType();
00123          type2 = f2->GetType();
00124 
00125          //--- use posix macros
00126          if (R_ISDIR(type1)) type1 = 1;
00127          else                type1 = 6;
00128 
00129          if (R_ISDIR(type2)) type2 = 1;
00130          else                type2 = 6;
00131 
00132          if (type1 < type2)  return -1;
00133          if (type1 > type2)  return  1;
00134          return strcmp(f1->GetItemName()->GetString(),
00135                        f2->GetItemName()->GetString());
00136 
00137       case kSortByGroup:
00138          if (f1->GetGid() != f2->GetGid()) {
00139             if (f1->GetGid() < f2->GetGid())
00140                return -1;
00141             else
00142                return +1;
00143          }
00144 
00145          // else sort by name
00146          type1 = f1->GetType();
00147          type2 = f2->GetType();
00148 
00149          //--- use posix macros
00150          if (R_ISDIR(type1)) type1 = 1;
00151          else                type1 = 6;
00152 
00153          if (R_ISDIR(type2)) type2 = 1;
00154          else                type2 = 6;
00155 
00156          if (type1 < type2)  return -1;
00157          if (type1 > type2)  return  1;
00158          return strcmp(f1->GetItemName()->GetString(),
00159                        f2->GetItemName()->GetString());
00160 
00161       case kSortByType:
00162          //--- this is not exactly what I want...
00163 
00164          type1 = f1->GetType();
00165          type2 = f2->GetType();
00166 
00167          //--- use posix macros
00168 
00169          if (R_ISDIR(type1))         type1 = 1;
00170          else if (R_ISLNK(type1))    type1 = 2;
00171          else if (R_ISSOCK(type1))   type1 = 3;
00172          else if (R_ISFIFO(type1))   type1 = 4;
00173          else if (R_ISREG(type1) && (type1 & kS_IXUSR)) type1 = 5;
00174          else                        type1 = 6;
00175 
00176          if (R_ISDIR(type2))         type2 = 1;
00177          else if (R_ISLNK(type2))    type2 = 2;
00178          else if (R_ISSOCK(type2))   type2 = 3;
00179          else if (R_ISFIFO(type2))   type2 = 4;
00180          else if (R_ISREG(type2) && (type2 & kS_IXUSR)) type2 = 5;
00181          else                        type2 = 6;
00182 
00183          if (type1 < type2) return -1;
00184          if (type1 > type2) return 1;
00185          return strcmp(f1->GetItemName()->GetString(),
00186                        f2->GetItemName()->GetString());
00187 
00188       case kSortBySize:
00189          if (f1->GetSize() < f2->GetSize()) return -1;
00190          if (f1->GetSize() > f2->GetSize()) return 1;
00191          return strcmp(f1->GetItemName()->GetString(),
00192                        f2->GetItemName()->GetString());
00193 
00194       case kSortByDate:
00195          time_t loctimeF1 = (time_t) f1->GetModTime();
00196          struct tm tmF1 = *localtime(&loctimeF1);
00197 
00198          time_t loctimeF2 = (time_t) f2->GetModTime();
00199          struct tm tmF2 = *localtime(&loctimeF2);
00200 
00201          if ( tmF1.tm_year != tmF2.tm_year )
00202             return (tmF1.tm_year < tmF2.tm_year) ? +1 : -1;
00203          else if ( tmF1.tm_mon != tmF2.tm_mon )
00204             return (tmF1.tm_mon < tmF2.tm_mon) ? +1 : -1;
00205          else if ( tmF1.tm_mday != tmF2.tm_mday )
00206             return (tmF1.tm_mday < tmF2.tm_mday) ? +1 : -1;
00207          else if ( tmF1.tm_hour != tmF2.tm_hour )
00208             return (tmF1.tm_hour < tmF2.tm_hour) ? +1 : -1;
00209          else if ( tmF1.tm_min != tmF2.tm_min )
00210             return (tmF1.tm_min < tmF2.tm_min) ? +1 : -1;
00211          else if ( tmF1.tm_sec != tmF2.tm_sec )
00212             return (tmF1.tm_sec < tmF2.tm_sec) ? +1 : -1;
00213          else
00214             return 0;
00215    }
00216 }
00217 
00218 
00219 //______________________________________________________________________________
00220 Bool_t TViewUpdateTimer::Notify()
00221 {
00222    // Reset the timer.
00223 
00224    fContainer->HandleTimer(0);
00225    Reset();
00226    return kFALSE;
00227 }
00228 
00229 
00230 //______________________________________________________________________________
00231 void TGFileIcon::DoRedraw()
00232 {
00233    // Draw icon.
00234 
00235    TGIcon::DoRedraw();
00236    if (fLpic) fLpic->Draw(fId, GetBckgndGC()(), 0, 0);
00237 }
00238 
00239 
00240 //______________________________________________________________________________
00241 TGFileItem::TGFileItem(const TGWindow *p,
00242                        const TGPicture *bpic, const TGPicture *blpic,
00243                        const TGPicture *spic, const TGPicture *slpic,
00244                        TGString *name, Int_t type, Long64_t size, Int_t uid,
00245                        Int_t gid, Long_t modtime, EListViewMode viewMode,
00246                        UInt_t options, ULong_t back) :
00247    TGLVEntry(p, bpic, spic, name, 0, viewMode, options, back)
00248 {
00249    // Create a list view item.
00250 
00251    FileStat_t buf;
00252 
00253    buf.fMode   = type;
00254    buf.fSize   = size;
00255    buf.fUid    = uid;
00256    buf.fGid    = gid;
00257    buf.fMtime  = modtime;
00258    buf.fIsLink = (blpic != 0);  // FIXME: hack...
00259 
00260    Init(blpic, slpic, buf, viewMode);
00261 }
00262 
00263 //______________________________________________________________________________
00264 TGFileItem::TGFileItem(const TGWindow *p,
00265                        const TGPicture *bpic, const TGPicture *blpic,
00266                        const TGPicture *spic, const TGPicture *slpic,
00267                        TGString *name, FileStat_t &stat, EListViewMode viewMode,
00268                        UInt_t options, ULong_t back) :
00269    TGLVEntry(p, bpic, spic, name, 0, viewMode, options, back)
00270 {
00271    // Create a list view item.
00272 
00273    Init(blpic, slpic, stat, viewMode);
00274 }
00275 
00276 //______________________________________________________________________________
00277 void TGFileItem::Init(const TGPicture *blpic, const TGPicture *slpic,
00278                       FileStat_t &stat, EListViewMode viewMode)
00279 {
00280    // Common initializer for file list view item.
00281 
00282    char tmp[256];
00283    Long64_t fsize, bsize;
00284 
00285    fBuf = 0;
00286    fDNDData.fData = 0;
00287    fDNDData.fDataLength = 0;
00288    fDNDData.fDataType = 0;
00289    fLcurrent =
00290    fBlpic = blpic;
00291    fSlpic = slpic;
00292 
00293    fViewMode = (EListViewMode) -1;
00294    SetViewMode(viewMode);
00295 
00296    fType    = stat.fMode;
00297    fSize    = stat.fSize;
00298    fUid     = stat.fUid;
00299    fGid     = stat.fGid;
00300    fModTime = stat.fMtime;
00301    fIsLink  = stat.fIsLink;
00302 
00303    fSubnames = new TGString* [6];
00304 
00305    // file type
00306    snprintf(tmp, sizeof(tmp), "%c%c%c%c%c%c%c%c%c%c",
00307             (fIsLink ?
00308              'l' :
00309              R_ISREG(fType) ?
00310              '-' :
00311              (R_ISDIR(fType) ?
00312               'd' :
00313               (R_ISCHR(fType) ?
00314                'c' :
00315                (R_ISBLK(fType) ?
00316                 'b' :
00317                 (R_ISFIFO(fType) ?
00318                  'p' :
00319                  (R_ISSOCK(fType) ?
00320                   's' : '?' )))))),
00321             ((fType & kS_IRUSR) ? 'r' : '-'),
00322             ((fType & kS_IWUSR) ? 'w' : '-'),
00323             ((fType & kS_ISUID) ? 's' : ((fType & kS_IXUSR) ? 'x' : '-')),
00324             ((fType & kS_IRGRP) ? 'r' : '-'),
00325             ((fType & kS_IWGRP) ? 'w' : '-'),
00326             ((fType & kS_ISGID) ? 's' : ((fType & kS_IXGRP) ? 'x' : '-')),
00327             ((fType & kS_IROTH) ? 'r' : '-'),
00328             ((fType & kS_IWOTH) ? 'w' : '-'),
00329             ((fType & kS_ISVTX) ? 't' : ((fType & kS_IXOTH) ? 'x' : '-')));
00330    fSubnames[0] = new TGString(tmp);
00331 
00332    // file size
00333    fsize = bsize = fSize;
00334    if (fsize > 1024) {
00335       fsize /= 1024;
00336       if (fsize > 1024) {
00337          // 3.7MB is more informative than just 3MB
00338          snprintf(tmp, sizeof(tmp), "%lld.%lldM", fsize/1024, (fsize%1024)/103);
00339       } else {
00340          snprintf(tmp, sizeof(tmp), "%lld.%lldK", bsize/1024, (bsize%1024)/103);
00341       }
00342    } else {
00343       snprintf(tmp, sizeof(tmp), "%lld", bsize);
00344    }
00345    fSubnames[1] = new TGString(tmp);
00346 
00347    {
00348       struct UserGroup_t *user_group;
00349 
00350       user_group = gSystem->GetUserInfo(fUid);
00351       if (user_group) {
00352          fSubnames[2] = new TGString(user_group->fUser);
00353          fSubnames[3] = new TGString(user_group->fGroup);
00354          delete user_group;
00355       } else {
00356          fSubnames[2] = new TGString(TString::Format("%d", fUid));
00357          fSubnames[3] = new TGString(TString::Format("%d", fGid));
00358       }
00359    }
00360 
00361    struct tm *newtime;
00362    time_t loctime = (time_t) fModTime;
00363    newtime = localtime(&loctime);
00364    snprintf(tmp, sizeof(tmp), "%d-%02d-%02d %02d:%02d", newtime->tm_year + 1900,
00365             newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour,
00366             newtime->tm_min);
00367    fSubnames[4] = new TGString(tmp);
00368 
00369    fSubnames[5] = 0;
00370 
00371    int i;
00372    for (i = 0; fSubnames[i] != 0; ++i)
00373       ;
00374    fCtw = new int[i+1];
00375    fCtw[i] = 0;
00376    for (i = 0; fSubnames[i] != 0; ++i)
00377       fCtw[i] = gVirtualX->TextWidth(fFontStruct, fSubnames[i]->GetString(),
00378                                      fSubnames[i]->GetLength());
00379 
00380    SetWindowName();
00381 }
00382 
00383 //______________________________________________________________________________
00384 TGFileItem::~TGFileItem()
00385 {
00386    // Destructor.
00387 
00388    delete fBuf;
00389 }
00390 
00391 //______________________________________________________________________________
00392 void TGFileItem::SetViewMode(EListViewMode viewMode)
00393 {
00394    // Set container item view mode.
00395 
00396    TGLVEntry::SetViewMode(viewMode);
00397 
00398    if (viewMode == kLVLargeIcons)
00399       fLcurrent = fBlpic;
00400    else
00401       fLcurrent = fSlpic;
00402 
00403    if (fClient) fClient->NeedRedraw(this);
00404 }
00405 
00406 //______________________________________________________________________________
00407 void TGFileItem::DoRedraw()
00408 {
00409    // Draw list view container item.
00410 
00411    int ix, iy;
00412 
00413    TGLVEntry::DoRedraw();
00414    if (!fLcurrent) return;
00415 
00416    if (fViewMode == kLVLargeIcons) {
00417       ix = (fWidth - fLcurrent->GetWidth()) >> 1;
00418       iy = 0;
00419    } else {
00420       ix = 0;
00421       iy = (fHeight - fLcurrent->GetHeight()) >> 1;
00422    }
00423 
00424    fLcurrent->Draw(fId, fNormGC, ix, iy);
00425 }
00426 
00427 
00428 //______________________________________________________________________________
00429 TGFileContainer::TGFileContainer(const TGWindow *p, UInt_t w, UInt_t h,
00430                                  UInt_t options, ULong_t back) :
00431    TGLVContainer(p, w, h, options, back)
00432 {
00433    // Create a list view container which will hold the contents of
00434    // the current directory.
00435 
00436    fSortType  = kSortByName;
00437    fFilter    = 0;
00438    fDirectory = gSystem->WorkingDirectory();
00439    fRefresh   = new TViewUpdateTimer(this, 1000);
00440    gSystem->AddTimer(fRefresh);
00441    fCachePictures = kTRUE;
00442    fDisplayStat   = kTRUE;
00443    fCleanups  = new TList;
00444 
00445    fFolder_s = fClient->GetPicture("folder_s.xpm");
00446    fFolder_t = fClient->GetPicture("folder_t.xpm");
00447    fApp_s    = fClient->GetPicture("app_s.xpm");
00448    fApp_t    = fClient->GetPicture("app_t.xpm");
00449    fDoc_s    = fClient->GetPicture("doc_s.xpm");
00450    fDoc_t    = fClient->GetPicture("doc_t.xpm");
00451    fSlink_s  = fClient->GetPicture("slink_s.xpm");
00452    fSlink_t  = fClient->GetPicture("slink_t.xpm");
00453 
00454    if (!fFolder_s || !fFolder_t ||
00455        !fApp_s    || !fApp_t    ||
00456        !fDoc_s    || !fDoc_t    ||
00457        !fSlink_s  || !fSlink_t)
00458       Error("TGFileContainer", "required pixmap(s) missing\n");
00459 
00460    SetWindowName();
00461 }
00462 
00463 //______________________________________________________________________________
00464 TGFileContainer::TGFileContainer(TGCanvas *p, UInt_t options, ULong_t back) :
00465    TGLVContainer(p,options, back)
00466 {
00467    // Create a list view container which will hold the contents of
00468    // the current directory.
00469 
00470    fSortType  = kSortByName;
00471    fFilter    = 0;
00472    fDirectory = gSystem->WorkingDirectory();
00473    fRefresh   = new TViewUpdateTimer(this, 1000);
00474    gSystem->AddTimer(fRefresh);
00475    fCachePictures = kTRUE;
00476    fDisplayStat   = kTRUE;
00477    fCleanups  = new TList;
00478 
00479    fFolder_s = fClient->GetPicture("folder_s.xpm");
00480    fFolder_t = fClient->GetPicture("folder_t.xpm");
00481    fApp_s    = fClient->GetPicture("app_s.xpm");
00482    fApp_t    = fClient->GetPicture("app_t.xpm");
00483    fDoc_s    = fClient->GetPicture("doc_s.xpm");
00484    fDoc_t    = fClient->GetPicture("doc_t.xpm");
00485    fSlink_s  = fClient->GetPicture("slink_s.xpm");
00486    fSlink_t  = fClient->GetPicture("slink_t.xpm");
00487 
00488    if (!fFolder_s || !fFolder_t ||
00489        !fApp_s    || !fApp_t    ||
00490        !fDoc_s    || !fDoc_t    ||
00491        !fSlink_s  || !fSlink_t)
00492       Error("TGFileContainer", "required pixmap(s) missing\n");
00493 
00494    SetWindowName();
00495 }
00496 
00497 //______________________________________________________________________________
00498 TGFileContainer::~TGFileContainer()
00499 {
00500    // Delete list view file container.
00501 
00502    if (fRefresh) delete fRefresh;
00503    if (fFilter)  delete fFilter;
00504    fClient->FreePicture(fFolder_s);
00505    fClient->FreePicture(fFolder_t);
00506    fClient->FreePicture(fApp_s);
00507    fClient->FreePicture(fApp_t);
00508    fClient->FreePicture(fDoc_s);
00509    fClient->FreePicture(fDoc_t);
00510    fClient->FreePicture(fSlink_s);
00511    fClient->FreePicture(fSlink_t);
00512    if (fCleanups) {
00513       TGPicture *pic;
00514       TIter nextp(fCleanups);
00515       while ((pic = (TGPicture *)nextp())) {
00516          fClient->GetPicturePool()->FreePicture(pic);
00517       }
00518       fCleanups->Clear();
00519       delete fCleanups;
00520    }
00521 }
00522 
00523 //______________________________________________________________________________
00524 void TGFileContainer::AddFrame(TGFrame *f, TGLayoutHints *l)
00525 {
00526    // Add frame to the composite frame.
00527 
00528    TGFSFrameElement *nw;
00529 
00530    nw = new TGFSFrameElement;
00531    nw->fFrame     = f;
00532    nw->fLayout    = l ? l : fgDefaultHints;
00533    nw->fState     = 1;
00534    nw->fContainer = this;
00535    fList->Add(nw);
00536 }
00537 
00538 //______________________________________________________________________________
00539 Bool_t TGFileContainer::HandleTimer(TTimer *)
00540 {
00541    // Refresh container contents. Check every 5 seconds to see if the
00542    // directory modification date has changed.
00543 
00544    FileStat_t sbuf;
00545 
00546    if (gSystem->GetPathInfo(fDirectory, sbuf) == 0)
00547       if (fMtime != (ULong_t)sbuf.fMtime) DisplayDirectory();
00548 
00549    return kTRUE;
00550 }
00551 
00552 //______________________________________________________________________________
00553 void TGFileContainer::SetFilter(const char *filter)
00554 {
00555    // Set file selection filter.
00556 
00557    if (fFilter) delete fFilter;
00558    fFilter = new TRegexp(filter, kTRUE);
00559 }
00560 
00561 //______________________________________________________________________________
00562 void TGFileContainer::Sort(EFSSortMode sortType)
00563 {
00564    // Sort file system list view container according to sortType.
00565 
00566    fSortType = sortType;
00567 
00568    fList->Sort();
00569 
00570    TGCanvas *canvas = (TGCanvas *) this->GetParent()->GetParent();
00571    canvas->Layout();
00572 }
00573 
00574 //______________________________________________________________________________
00575 void TGFileContainer::GetFilePictures(const TGPicture **pic,
00576              const TGPicture **lpic, Int_t file_type, Bool_t is_link,
00577              const char *name, Bool_t /*small*/)
00578 {
00579    // Determine the file picture for the given file type.
00580 
00581    static TString cached_ext;
00582    static const TGPicture *cached_spic = 0;
00583    static const TGPicture *cached_lpic = 0;
00584    const char *ext = name ? strrchr(name, '.') : 0;
00585    *pic = 0;
00586    *lpic = 0;
00587 
00588    if (fCachePictures && ext && cached_spic && cached_lpic && (cached_ext == ext)) {
00589       *pic = cached_spic;
00590       *lpic = cached_lpic;
00591       if (!is_link) return;
00592    }
00593 
00594    if (R_ISREG(file_type)) {
00595       *pic = fClient->GetMimeTypeList()->GetIcon(name, kTRUE);
00596       *lpic = fClient->GetMimeTypeList()->GetIcon(name, kFALSE);
00597 
00598       if (*pic) {
00599          if (!*lpic) *lpic = *pic;
00600          if (ext) {
00601             cached_ext = ext;
00602             cached_spic = *pic;
00603             cached_lpic = *lpic;
00604             if (!is_link) return;
00605          }
00606       }
00607    } else {
00608       *pic = 0;
00609    }
00610 
00611    if (*pic == 0) {
00612       *pic = fDoc_t;
00613       *lpic = fDoc_s;
00614 
00615       if (R_ISREG(file_type) && (file_type) & kS_IXUSR) {
00616          *pic = fApp_t;
00617          *lpic = fApp_s;
00618       }
00619       if (R_ISDIR(file_type)) {
00620          *pic = fFolder_t;
00621          *lpic = fFolder_s;
00622       }
00623    }
00624    if (is_link) {
00625       TImage *img1, *img2;
00626       if (*pic && *lpic) {
00627          img1 = TImage::Create();
00628          img1->SetImage(((const TGPicture *)*pic)->GetPicture(),
00629                         ((const TGPicture *)*pic)->GetMask());
00630          img2 = TImage::Open("slink_t.xpm");
00631          if (img2) img1->Merge(img2);
00632          TString lnk_name = ((const TGPicture *)*pic)->GetName();
00633          lnk_name.Prepend("lnk_");
00634          *pic = fClient->GetPicturePool()->GetPicture(lnk_name.Data(),
00635                               img1->GetPixmap(), img1->GetMask());
00636          fCleanups->Add(((TObject *)*pic));
00637          if (img2) delete img2; delete img1;
00638          img1 = TImage::Create();
00639          img1->SetImage(((const TGPicture *)*lpic)->GetPicture(),
00640                         ((const TGPicture *)*lpic)->GetMask());
00641          img2 = TImage::Open("slink_s.xpm");
00642          if (img2) img1->Merge(img2);
00643          lnk_name = ((const TGPicture *)*lpic)->GetName();
00644          lnk_name.Prepend("lnk_");
00645          *lpic = fClient->GetPicturePool()->GetPicture(lnk_name.Data(),
00646                               img1->GetPixmap(), img1->GetMask());
00647          fCleanups->Add(((TObject *)*lpic));
00648          if (img2) delete img2; delete img1;
00649       }
00650       else {
00651          *pic = fSlink_t;
00652          *lpic = fSlink_s;
00653       }
00654    }
00655 
00656    cached_lpic = 0;
00657    cached_spic = 0;
00658    cached_ext = "";
00659 }
00660 
00661 //______________________________________________________________________________
00662 void TGFileContainer::ChangeDirectory(const char *path)
00663 {
00664    // Change current directory.
00665 
00666    TString savdir = gSystem->WorkingDirectory();
00667    gSystem->ChangeDirectory(fDirectory.Data());   // so path of ".." will work
00668    if (gSystem->ChangeDirectory(path)) {
00669       fDirectory = gSystem->WorkingDirectory();
00670       gSystem->ChangeDirectory(savdir.Data());
00671       DisplayDirectory();
00672    }
00673 }
00674 
00675 //______________________________________________________________________________
00676 void TGFileContainer::DisplayDirectory()
00677 {
00678    // Display the contents of the current directory in the container.
00679    // This can be used to refresh the contents of the window.
00680 
00681    RemoveAll();
00682    CreateFileList();
00683 
00684    // This automatically calls layout
00685    Sort(fSortType);
00686 
00687    // Make TGExplorerMainFrame display total objects in status bar
00688    SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
00689                fTotal, fSelected);
00690 
00691    MapSubwindows();
00692 }
00693 
00694 //______________________________________________________________________________
00695 void TGFileContainer::CreateFileList()
00696 {
00697    // This function creates the file list from current dir.
00698 
00699    TString savdir = gSystem->WorkingDirectory();
00700    if (!gSystem->ChangeDirectory(fDirectory.Data())) return;
00701 
00702    FileStat_t sbuf;
00703    if (gSystem->GetPathInfo(".", sbuf) == 0)
00704       fMtime = sbuf.fMtime;
00705 
00706    void *dirp;
00707    if ((dirp = gSystem->OpenDirectory(".")) == 0) {
00708       gSystem->ChangeDirectory(savdir.Data());
00709       return;
00710    }
00711 
00712    const char *name;
00713    while ((name = gSystem->GetDirEntry(dirp)) != 0 && fDisplayStat) {
00714       if (strcmp(name, ".") && strcmp(name, ".."))
00715          AddFile(name);
00716       gSystem->ProcessEvents();
00717    }
00718    gSystem->FreeDirectory(dirp);
00719 
00720    gSystem->ChangeDirectory(savdir.Data());
00721 }
00722 
00723 //______________________________________________________________________________
00724 TGFileItem *TGFileContainer::AddFile(const char *name,  const TGPicture *ipic,
00725                                      const TGPicture *ilpic)
00726 {
00727    // Add file in container.
00728 
00729    TString     filename;
00730    TGFileItem *item = 0;
00731    const TGPicture *spic, *slpic;
00732    TGPicture *pic, *lpic;
00733 
00734    FileStat_t sbuf;
00735 
00736    if (gSystem->GetPathInfo(name, sbuf)) {
00737       if (sbuf.fIsLink) {
00738          Info("AddFile", "Broken symlink of %s.", name);
00739       } else {
00740          TString msg;
00741          msg.Form("Can't read file attributes of \"%s\": %s.",
00742                   name, gSystem->GetError());
00743          new TGMsgBox(fClient->GetDefaultRoot(), GetMainFrame(),
00744                       "Error", msg.Data(), kMBIconStop, kMBOk);
00745       }
00746       return item;
00747    }
00748 
00749    filename = name;
00750    if (R_ISDIR(sbuf.fMode) || fFilter == 0 ||
00751        (fFilter && filename.Index(*fFilter) != kNPOS)) {
00752 
00753       if (ipic && ilpic) { // dynamic icons
00754          spic = ipic;
00755          slpic = ilpic;
00756       } else {
00757          GetFilePictures(&spic, &slpic, sbuf.fMode, sbuf.fIsLink, name, kTRUE);
00758       }
00759 
00760       pic = (TGPicture*)spic; pic->AddReference();
00761       lpic = (TGPicture*)slpic; lpic->AddReference();
00762 
00763       item = new TGFileItem(this, lpic, slpic, spic, pic,
00764                             new TGString(gSystem->BaseName(name)),
00765                             sbuf, fViewMode);
00766       AddItem(item);
00767    }
00768 
00769    return item;
00770 }
00771 
00772 //______________________________________________________________________________
00773 TGFileItem *TGFileContainer::AddRemoteFile(TObject *obj, const TGPicture *ipic,
00774                                            const TGPicture *ilpic)
00775 {
00776    // Add remote file in container.
00777 
00778    TString     filename;
00779    TGFileItem *item = 0;
00780    const TGPicture *spic, *slpic;
00781    TGPicture *pic, *lpic;
00782 
00783    FileStat_t sbuf;
00784 
00785    TRemoteObject *robj = (TRemoteObject *)obj;
00786 
00787    robj->GetFileStat(&sbuf);
00788    filename = robj->GetName();
00789 
00790    if (R_ISDIR(sbuf.fMode) || fFilter == 0 ||
00791        (fFilter && filename.Index(*fFilter) != kNPOS)) {
00792 
00793       if (ipic && ilpic) { // dynamic icons
00794          spic = ipic;
00795          slpic = ilpic;
00796       } else {
00797          GetFilePictures(&spic, &slpic, sbuf.fMode, sbuf.fIsLink, filename, kTRUE);
00798       }
00799 
00800       pic = (TGPicture*)spic; pic->AddReference();
00801       lpic = (TGPicture*)slpic; lpic->AddReference();
00802 
00803       item = new TGFileItem(this, lpic, slpic, spic, pic, new TGString(filename),
00804                             sbuf, fViewMode);
00805       AddItem(item);
00806    }
00807    return item;
00808 }
00809 
00810 //______________________________________________________________________________
00811 void TGFileContainer::StopRefreshTimer()
00812 {
00813    // stop refresh  timer
00814 
00815    if (fRefresh) delete fRefresh;
00816    fRefresh = 0;
00817 }
00818 
00819 //______________________________________________________________________________
00820 void TGFileContainer::StartRefreshTimer(ULong_t msec)
00821 {
00822    // start refreshing
00823 
00824    fRefresh = new TViewUpdateTimer(this, msec);
00825    gSystem->AddTimer(fRefresh);
00826 }
00827 
00828 //______________________________________________________________________________
00829 void TGFileContainer::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
00830 {
00831    // Save a file container widget as a C++ statement(s) on output stream out.
00832 
00833    if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
00834 
00835    char quote = '"';
00836    out << endl << "   // container frame" << endl;
00837    out << "   TGFileContainer *";
00838 
00839    if ((fParent->GetParent())->InheritsFrom(TGCanvas::Class())) {
00840       out << GetName() << " = new TGFileContainer(" << GetCanvas()->GetName();
00841    } else {
00842       out << GetName() << " = new TGFileContainer(" << fParent->GetName();
00843       out << "," << GetWidth() << "," << GetHeight();
00844    }
00845 
00846    if (fBackground == GetDefaultFrameBackground()) {
00847       if (GetOptions() == kSunkenFrame) {
00848          out <<");" << endl;
00849       } else {
00850          out << "," << GetOptionString() <<");" << endl;
00851       }
00852    } else {
00853       out << "," << GetOptionString() << ",ucolor);" << endl;
00854    }
00855    if (option && strstr(option, "keep_names"))
00856       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
00857    out << "   " << GetCanvas()->GetName() << "->SetContainer("
00858                 << GetName() << ");" << endl;
00859    out << "   " << GetName() << "->DisplayDirectory();" << endl;
00860    out << "   " << GetName() << "->AddFile("<< quote << ".." << quote << ");" << endl;
00861    out << "   " << GetName() << "->StopRefreshTimer();" << endl;
00862 }

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