00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00044
00045 struct Lbc_t {
00046 const char *fName;
00047 const char *fPath;
00048 const char *fPixmap;
00049 Int_t fId;
00050 Int_t fIndent;
00051 Int_t fFlags;
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
00067
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
00094
00095 delete fText;
00096 delete fPath;
00097 delete fSelPic;
00098 }
00099
00100
00101 void TGTreeLBEntry::Activate(Bool_t a)
00102 {
00103
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
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
00151
00152 DrawCopy(fId, 0, 0);
00153 }
00154
00155
00156 TGDimension TGTreeLBEntry::GetDefaultSize() const
00157 {
00158
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
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
00186
00187 if (!fgDefaultFont)
00188 fgDefaultFont = gClient->GetResourcePool()->GetDefaultFont();
00189 return fgDefaultFont->GetFontStruct();
00190 }
00191
00192
00193 const TGGC &TGTreeLBEntry::GetDefaultGC()
00194 {
00195
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
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
00223
00224 const char *homeDir = gSystem->HomeDirectory();
00225 #ifndef ROOTPREFIX
00226 const char *rootSys = gSystem->Getenv("ROOTSYS");
00227 #else
00228
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
00360
00361
00362
00363
00364
00365 if (strstr(gLbc[i].fPath, "$ROOTSYS") != 0) {
00366
00367 const int plen = 8;
00368 if (rootSys) {
00369 int hlen = strlen(rootSys);
00370
00371
00372
00373
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
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
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
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
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 }