TGFSComboBox.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGFSComboBox.cxx 37379 2010-12-07 18:37:12Z bellenot $
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 // TGFSComboBox, TGTreeLBEntry                                          //
00026 //                                                                      //
00027 // This is a combo box that is used in the File Selection dialog box.   //
00028 // It will allow the file path selection.                               //
00029 //                                                                      //
00030 //////////////////////////////////////////////////////////////////////////
00031 
00032 #include "RConfigure.h"
00033 
00034 #include "TGFSComboBox.h"
00035 #include "TGResourcePool.h"
00036 #include "TGPicture.h"
00037 #include "TSystem.h"
00038 #include "Riostream.h"
00039 
00040 const TGFont *TGTreeLBEntry::fgDefaultFont = 0;
00041 TGGC         *TGTreeLBEntry::fgDefaultGC = 0;
00042 
00043 //--- this is temp here...
00044 
00045 struct Lbc_t {
00046    const char *fName;   // root prefix name
00047    const char *fPath;   // path
00048    const char *fPixmap; // picture file
00049    Int_t       fId;     // widget id
00050    Int_t       fIndent; // identification level
00051    Int_t       fFlags;  // flag
00052 };
00053 
00054 static struct Lbc_t gLbc[32];
00055 
00056 ClassImp(TGTreeLBEntry)
00057 ClassImp(TGFSComboBox)
00058 
00059 //______________________________________________________________________________
00060 TGTreeLBEntry::TGTreeLBEntry(const TGWindow *p, TGString *text,
00061                              const TGPicture *pic, Int_t id, TGString *path,
00062                              GContext_t norm, FontStruct_t font, UInt_t options,
00063                              ULong_t back) :
00064    TGLBEntry(p, id, options, back)
00065 {
00066    // Create a tree (i.e. entry can be indented) listbox entry.
00067    // The strings text and path are adopted by the entry.
00068 
00069    if (text && !pic)
00070       Error("TGTreeLBEntry", "icon not found for entry %s", text->GetString());
00071 
00072    fPic    = pic;
00073    fSelPic = 0;
00074    fText   = text;
00075    fPath   = path;
00076 
00077    fNormGC     = norm;
00078    fFontStruct = font;
00079 
00080    fActive = kFALSE;
00081 
00082    int max_ascent, max_descent;
00083    if (fText)
00084       fTWidth = gVirtualX->TextWidth(fFontStruct, fText->GetString(), fText->GetLength());
00085    gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
00086    fTHeight = max_ascent + max_descent;
00087    SetWindowName();
00088 }
00089 
00090 //______________________________________________________________________________
00091 TGTreeLBEntry::~TGTreeLBEntry()
00092 {
00093    // Delete tree listbox entry.
00094 
00095    delete fText;
00096    delete fPath;
00097    delete fSelPic;
00098 }
00099 
00100 //______________________________________________________________________________
00101 void TGTreeLBEntry::Activate(Bool_t a)
00102 {
00103    // Make entry active (highlight picture).
00104 
00105    if (fActive == a) return;
00106    fActive = a;
00107 
00108    if (fActive) {
00109       fSelPic = new TGSelectedPicture(fClient, fPic);
00110    } else {
00111       if (fSelPic) delete fSelPic;
00112       fSelPic = 0;
00113    }
00114    DoRedraw();
00115 }
00116 
00117 //______________________________________________________________________________
00118 void TGTreeLBEntry::DrawCopy(Handle_t id, Int_t x, Int_t y)
00119 {
00120    // Redraw the tree listbox entry on pixmap/window.
00121 
00122    int ix, iy, lx, ly;
00123 
00124    ix = x;
00125    iy = y + ((fHeight - fPic->GetHeight()) >> 1);
00126    lx = x + (int)(fPic->GetWidth() + 4);
00127    ly = y + (int)((fHeight - (fTHeight+1)) >> 1);
00128 
00129    if (fActive) {
00130       if (fSelPic) fSelPic->Draw(id, fNormGC, ix, iy);
00131       gVirtualX->SetForeground(fNormGC, fgDefaultSelectedBackground);
00132       gVirtualX->FillRectangle(id, fNormGC, lx, ly, fTWidth, fTHeight+1);
00133       gVirtualX->SetForeground(fNormGC, fClient->GetResourcePool()->GetSelectedFgndColor());
00134    } else {
00135       fPic->Draw(id, fNormGC, ix, iy);
00136       gVirtualX->SetForeground(fNormGC, fgWhitePixel);
00137       gVirtualX->FillRectangle(id, fNormGC, lx, ly, fTWidth, fTHeight+1);
00138       gVirtualX->SetForeground(fNormGC, fgBlackPixel);
00139    }
00140 
00141    int max_ascent, max_descent;
00142    gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
00143 
00144    fText->Draw(id, fNormGC, lx, ly + max_ascent);
00145 }
00146 
00147 //______________________________________________________________________________
00148 void TGTreeLBEntry::DoRedraw()
00149 {
00150    // Redraw the tree listbox entry.
00151 
00152    DrawCopy(fId, 0, 0);
00153 }
00154 
00155 //______________________________________________________________________________
00156 TGDimension TGTreeLBEntry::GetDefaultSize() const
00157 {
00158    // Return default size of tree listbox entry.
00159 
00160    TGDimension isize(fPic->GetWidth(), fPic->GetHeight());
00161    TGDimension lsize(fTWidth, fTHeight+1);
00162 
00163    return TGDimension(isize.fWidth + lsize.fWidth + 4,
00164                       TMath::Max(isize.fHeight, lsize.fHeight) + 2);
00165 }
00166 
00167 //______________________________________________________________________________
00168 void TGTreeLBEntry::Update(TGLBEntry *e)
00169 {
00170    // Update text and picture of a listbox entry.
00171 
00172    TGTreeLBEntry *te = (TGTreeLBEntry *) e;
00173 
00174    if (fText) delete fText;
00175    fText = new TGString(te->GetText());
00176    fPic = te->GetPicture();
00177    fTWidth = gVirtualX->TextWidth(fFontStruct, fText->GetString(), fText->GetLength());
00178    gVirtualX->ClearWindow(fId);
00179    fClient->NeedRedraw(this);
00180 }
00181 
00182 //______________________________________________________________________________
00183 FontStruct_t TGTreeLBEntry::GetDefaultFontStruct()
00184 {
00185    // Return default font structure.
00186 
00187    if (!fgDefaultFont)
00188       fgDefaultFont = gClient->GetResourcePool()->GetDefaultFont();
00189    return fgDefaultFont->GetFontStruct();
00190 }
00191 
00192 //______________________________________________________________________________
00193 const TGGC &TGTreeLBEntry::GetDefaultGC()
00194 {
00195    // Return default graphics context.
00196 
00197    if (!fgDefaultGC)
00198       fgDefaultGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
00199    return *fgDefaultGC;
00200 }
00201 
00202 
00203 //______________________________________________________________________________
00204 TGFSComboBox::TGFSComboBox(const TGWindow *parent, Int_t id, UInt_t options,
00205                            ULong_t back) :
00206    TGComboBox(parent, id, options | kOwnBackground, back)
00207 {
00208    // Create a file system combobox showing system directories.
00209 
00210    int   i, indent;
00211    const TGPicture *pic;
00212    char  *p;
00213 
00214    SetTopEntry(new TGTreeLBEntry(this, new TGString("Current dir"),
00215                fClient->GetPicture("folder_t.xpm"), 0),
00216                new TGLayoutHints(kLHintsLeft | kLHintsExpandX |
00217                                  kLHintsExpandY, 4, 0, 0, 0));
00218 
00219    fListBox->GetContainer()->AddInput(kButtonPressMask | kButtonReleaseMask |
00220                                       kPointerMotionMask);
00221 
00222    //--- first check for the existence of some directories...
00223 
00224    const char *homeDir = gSystem->HomeDirectory();
00225 #ifndef ROOTPREFIX
00226    const char *rootSys = gSystem->Getenv("ROOTSYS");
00227 #else
00228    // const char *rootSys = ROOTPREFIX;
00229 #endif
00230 
00231    Int_t idx = 0;
00232    TList *volumes = gSystem->GetVolumes("all");
00233    TList *curvol  = gSystem->GetVolumes("cur");
00234    TString infos;
00235    const char *curdrive = "";
00236    if (volumes && curvol) {
00237       TNamed *named = (TNamed *)curvol->At(0);
00238       if (named) {
00239          curdrive = named->GetName();
00240          infos = named->GetTitle();
00241          gLbc[idx].fName = StrDup(infos.Data());
00242          gLbc[idx].fPath = StrDup(Form("%s\\", curdrive));
00243          if (infos.Contains("Removable"))
00244             gLbc[idx].fPixmap = StrDup("fdisk_t.xpm");
00245          else if (infos.Contains("Local"))
00246             gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
00247          else if (infos.Contains("CD"))
00248             gLbc[idx].fPixmap = StrDup("cdrom_t.xpm");
00249          else if (infos.Contains("Network"))
00250             gLbc[idx].fPixmap = StrDup("netdisk_t.xpm");
00251          else
00252             gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
00253          gLbc[idx].fId     = 1000;
00254          gLbc[idx].fIndent = 0; 
00255          gLbc[idx].fFlags  = 0;
00256          ++idx;
00257       }
00258       else {
00259          gLbc[idx].fName = StrDup("Root");
00260          gLbc[idx].fPath = StrDup("/");
00261          gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
00262          gLbc[idx].fId     = 1000;
00263          gLbc[idx].fIndent = 1; 
00264          gLbc[idx].fFlags  = 0;
00265          ++idx;
00266       }
00267    }
00268    else {
00269       gLbc[idx].fName = StrDup("Root");
00270       gLbc[idx].fPath = StrDup("/");
00271       gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
00272       gLbc[idx].fId     = 1000;
00273       gLbc[idx].fIndent = 1; 
00274       gLbc[idx].fFlags  = 0;
00275       ++idx;
00276       gLbc[idx].fName = StrDup("Floppy");
00277       gLbc[idx].fPath = StrDup("/floppy");
00278       gLbc[idx].fPixmap = StrDup("fdisk_t.xpm");
00279       gLbc[idx].fId     = 2000;
00280       gLbc[idx].fIndent = 1; 
00281       gLbc[idx].fFlags  = 0;
00282       ++idx;
00283       gLbc[idx].fName = StrDup("CD-ROM");
00284       gLbc[idx].fPath = StrDup("/cdrom");
00285       gLbc[idx].fPixmap = StrDup("cdrom_t.xpm");
00286       gLbc[idx].fId     = 3000;
00287       gLbc[idx].fIndent = 1; 
00288       gLbc[idx].fFlags  = 0;
00289       ++idx;
00290    }
00291    gLbc[idx].fName   = StrDup("Home");
00292    gLbc[idx].fPath   = StrDup("$HOME");
00293    gLbc[idx].fPixmap = StrDup("home_t.xpm");
00294    gLbc[idx].fId     = (idx+1) * 1000;
00295    gLbc[idx].fIndent = 1; 
00296    gLbc[idx].fFlags  = 0;
00297    ++idx;
00298 #ifndef ROOTPREFIX
00299    gLbc[idx].fName   = StrDup("RootSys");
00300    gLbc[idx].fPath   = StrDup("$ROOTSYS");
00301 #else
00302    gLbc[idx].fName   = StrDup(ROOTPREFIX);
00303    gLbc[idx].fPath   = StrDup(ROOTPREFIX);
00304 #endif
00305    gLbc[idx].fPixmap = StrDup("root_t.xpm");
00306    gLbc[idx].fId     = (idx+1) * 1000;
00307    gLbc[idx].fIndent = 1; 
00308    gLbc[idx].fFlags  = 0;
00309    ++idx;
00310 
00311    if (volumes && curvol) {
00312       TIter next(volumes);
00313       TNamed *drive;
00314       while ((drive = (TNamed *)next())) {
00315          if (!strcmp(drive->GetName(), curdrive))
00316             continue;
00317          infos = drive->GetTitle();
00318          gLbc[idx].fName   = StrDup(drive->GetTitle());
00319          gLbc[idx].fPath   = StrDup(Form("%s\\", drive->GetName()));
00320          if (infos.Contains("Removable"))
00321             gLbc[idx].fPixmap = StrDup("fdisk_t.xpm");
00322          else if (infos.Contains("Local"))
00323             gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
00324          else if (infos.Contains("CD"))
00325             gLbc[idx].fPixmap = StrDup("cdrom_t.xpm");
00326          else if (infos.Contains("Network"))
00327             gLbc[idx].fPixmap = StrDup("netdisk_t.xpm");
00328          else
00329             gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
00330          gLbc[idx].fId     = (idx+1) * 1000;
00331          gLbc[idx].fIndent = 0;
00332          gLbc[idx].fFlags  = 0;
00333          ++idx;
00334       }
00335       delete volumes;
00336       delete curvol;
00337    }
00338    gLbc[idx].fName   = 0;
00339    gLbc[idx].fPath   = 0;
00340    gLbc[idx].fPixmap = 0;
00341    gLbc[idx].fId     = (idx+1) * 1000;
00342    gLbc[idx].fIndent = 0;
00343    gLbc[idx].fFlags  = 0;
00344 
00345    for (i = 0; gLbc[i].fPath != 0; ++i) {
00346       if (strstr(gLbc[i].fPath, "$HOME") != 0) {
00347          if (homeDir) {
00348             int hlen = strlen(homeDir);
00349             int blen = hlen + strlen(gLbc[i].fPath) - 3;
00350             p = new char[blen];
00351             strlcpy(p, homeDir, blen);
00352             strlcat(p, &gLbc[i].fPath[5], blen-strlen(&gLbc[i].fPath[5]));
00353             gLbc[i].fPath = p;
00354          } else {
00355             gLbc[i].fFlags = 0;
00356          }
00357       }
00358 #ifndef ROOTPREFIX
00359       // Below should _only_ be called if the prefix isn't set at build
00360       // time. The code below expands the occurance of `$ROOTSYS' in
00361       // the table above.  However, in the case of prefix being set at
00362       // build time, we do not need to expand the prefix, as it is
00363       // already known, so the entries in the table above are actually
00364       // fully expanded.
00365       if (strstr(gLbc[i].fPath, "$ROOTSYS") != 0) {
00366          // Get the size of the prefix template
00367          const int plen = 8;
00368          if (rootSys) {
00369             int hlen = strlen(rootSys);
00370             // Allocate enough memory to hold prefix (hlen), and
00371             // what's in the path (strlen(gLbc[i].fPath)) minus the
00372             // prefix template size, and one character for terminating
00373             // null.
00374             int blen = hlen + strlen(gLbc[i].fPath) - plen + 1;
00375             p = new char[blen];
00376             strlcpy(p, rootSys, blen);
00377             strlcat(p, &(gLbc[i].fPath[plen]), blen-strlen(&gLbc[i].fPath[plen]));
00378             // Figure out where to put the terminating NULL
00379             int npos = hlen + strlen(&(gLbc[i].fPath[plen]));
00380             p[npos] = '\0';
00381             gLbc[i].fPath = p;
00382          } else {
00383             gLbc[i].fFlags = 0;
00384          }
00385       }
00386 #endif
00387       if (gSystem->AccessPathName(gLbc[i].fPath, kFileExists) == 0)
00388          gLbc[i].fFlags = 1;
00389    }
00390 
00391    //--- then init the contents...
00392 
00393    for (i = 0; gLbc[i].fName != 0; ++i) {
00394       if (gLbc[i].fFlags) {
00395          indent = 4 + (gLbc[i].fIndent * 10);
00396          pic = fClient->GetPicture(gLbc[i].fPixmap);
00397          if (!pic) Error("TGFSComboBox", "pixmap not found: %s", gLbc[i].fPixmap);
00398          AddEntry(new TGTreeLBEntry(fListBox->GetContainer(),
00399                   new TGString(gLbc[i].fName), pic, gLbc[i].fId,
00400                   new TGString(gLbc[i].fPath)),
00401                   new TGLayoutHints(kLHintsLeft | kLHintsTop, indent, 0, 0, 0));
00402       }
00403    }
00404    SetWindowName();
00405 }
00406 
00407 //______________________________________________________________________________
00408 void TGFSComboBox::Update(const char *path)
00409 {
00410    // Update file system combo box.
00411 
00412    char dirname[1024], mpath[1024];
00413    const char *tailpath = 0;
00414    int  i, indent_lvl = 0, afterID = -1, sel = -1;
00415 
00416    if (!path) return;
00417 
00418    for (i = 0; gLbc[i].fPath != 0; ++i)
00419       RemoveEntries(gLbc[i].fId+1, gLbc[i+1].fId-1);
00420 
00421    int len = 0;
00422    for (i = 0; gLbc[i].fName != 0; ++i) {
00423       if (gLbc[i].fFlags) {
00424          int slen = strlen(gLbc[i].fPath);
00425          if (strncmp(path, gLbc[i].fPath, slen) == 0) {
00426             if (slen > len) {
00427                sel = afterID = gLbc[i].fId;
00428                indent_lvl = gLbc[i].fIndent + 1;
00429                tailpath = path + slen;
00430                strlcpy(mpath, gLbc[i].fPath, 1024);
00431                len = slen;
00432             }
00433          }
00434       }
00435    }
00436 
00437    if (tailpath && *tailpath) {
00438       if (*tailpath == '/') ++tailpath;
00439       if (*tailpath)
00440          while (1) {
00441             const char *picname;
00442             const char *semi = strchr(tailpath, '/');
00443             if (semi == 0) {
00444                strlcpy(dirname, tailpath, 1024);
00445                picname = "ofolder_t.xpm";
00446             } else {
00447                strlcpy(dirname, tailpath, (semi-tailpath)+1);
00448                picname = "folder_t.xpm";
00449             }
00450             if (mpath[strlen(mpath)-1] != '/') 
00451                strlcat(mpath, "/", 1024-strlen(mpath));
00452             strlcat(mpath, dirname, 1024-strlen(mpath));
00453             int indent = 4 + (indent_lvl * 10);
00454             const TGPicture *pic = fClient->GetPicture(picname);
00455             if (!pic) Error("Update", "pixmap not found: %s", picname);
00456             InsertEntry(new TGTreeLBEntry(fListBox->GetContainer(),
00457                         new TGString(dirname), pic, afterID+1,
00458                         new TGString(mpath)),
00459                         new TGLayoutHints(kLHintsLeft | kLHintsTop,
00460                                           indent, 0, 0, 0),
00461                         afterID);
00462             sel = ++afterID;
00463             ++indent_lvl;
00464             if (semi == 0) break;
00465             tailpath = ++semi;
00466          }
00467    }
00468    if (sel > 0) Select(sel);
00469 }
00470 
00471 //______________________________________________________________________________
00472 void TGFSComboBox::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
00473 {
00474    // Save a file system combo box as a C++ statement(s) on output stream out.
00475 
00476    if (fBackground != GetWhitePixel()) SaveUserColor(out, option);
00477 
00478    out << endl << "   // file system combo box" << endl;
00479    out << "   TGFSComboBox *";
00480    out << GetName() << " = new TGFSComboBox(" << fParent->GetName()
00481                                           << "," << fWidgetId;
00482    if (fBackground == GetWhitePixel()) {
00483       if (GetOptions() == (kHorizontalFrame | kSunkenFrame | kDoubleBorder)) {
00484          out <<");" << endl;
00485       } else {
00486          out << "," << GetOptionString() <<");" << endl;
00487       }
00488    } else {
00489       out << "," << GetOptionString() << ",ucolor);" << endl;
00490    }
00491    if (option && strstr(option, "keep_names"))
00492       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
00493 
00494    out << "   " << GetName() << "->Resize(" << GetWidth()  << ","
00495        << GetHeight() << ");" << endl;
00496    out << "   " << GetName() << "->Select(" << GetSelected() << ");" << endl;
00497 
00498 }

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