57 static const char *gDefTypes[] = {
"All files",
"*",
58 "ROOT files",
"*.root",
62 static TGFileInfo gInfo;
65 ClassImp(TGFileDialog);
70 TGFileInfo::~TGFileInfo()
74 if ( fFileNamesList != 0 ) {
75 fFileNamesList->Delete();
76 delete fFileNamesList;
83 void TGFileInfo::SetMultipleSelection(Bool_t option)
85 if ( fMultipleSelection != option ) {
86 fMultipleSelection = option;
87 if ( fMultipleSelection == kTRUE )
88 fFileNamesList =
new TList();
90 fFileNamesList->Delete();
91 delete fFileNamesList;
105 TGFileDialog::TGFileDialog(
const TGWindow *p,
const TGWindow *main,
106 EFileDialogMode dlg_type, TGFileInfo *file_info) :
107 TGTransientFrame(p, main, 10, 10, kVerticalFrame), fTbfname(0), fName(0),
108 fTypes(0), fTreeLB(0), fCdup(0), fNewf(0), fList(0), fDetails(0), fCheckB(0),
109 fPcdup(0), fPnewf(0), fPlist(0), fPdetails(0), fOk(0), fCancel(0), fFv(0),
112 SetCleanup(kDeepCleanup);
113 Connect(
"CloseWindow()",
"TGFileDialog",
this,
"CloseWindow()");
123 Error(
"TGFileDialog",
"file_info argument not set");
125 if (fFileInfo->fIniDir) {
126 delete [] fFileInfo->fIniDir;
127 fFileInfo->fIniDir = 0;
129 if (fFileInfo->fFilename) {
130 delete [] fFileInfo->fFilename;
131 fFileInfo->fFilename = 0;
133 fFileInfo->fFileTypeIdx = 0;
135 fFileInfo = file_info;
137 if (!fFileInfo->fFileTypes)
138 fFileInfo->fFileTypes = gDefTypes;
140 if (!fFileInfo->fIniDir)
141 fFileInfo->fIniDir = StrDup(
".");
143 TGHorizontalFrame *fHtop =
new TGHorizontalFrame(
this, 10, 10);
146 TGLabel *fLookin =
new TGLabel(fHtop,
new TGHotString((dlg_type == kFDSave)
147 ?
"S&ave in:" :
"&Look in:"));
148 fTreeLB =
new TGFSComboBox(fHtop, kIDF_FSLB);
149 fTreeLB->Associate(
this);
151 fPcdup = fClient->GetPicture(
"tb_uplevel.xpm");
152 fPnewf = fClient->GetPicture(
"tb_newfolder.xpm");
153 fPlist = fClient->GetPicture(
"tb_list.xpm");
154 fPdetails = fClient->GetPicture(
"tb_details.xpm");
156 if (!(fPcdup && fPnewf && fPlist && fPdetails))
157 Error(
"TGFileDialog",
"missing toolbar pixmap(s).\n");
159 fCdup =
new TGPictureButton(fHtop, fPcdup, kIDF_CDUP);
160 fNewf =
new TGPictureButton(fHtop, fPnewf, kIDF_NEW_FOLDER);
161 fList =
new TGPictureButton(fHtop, fPlist, kIDF_LIST);
162 fDetails =
new TGPictureButton(fHtop, fPdetails, kIDF_DETAILS);
164 fCdup->SetStyle(gClient->GetStyle());
165 fNewf->SetStyle(gClient->GetStyle());
166 fList->SetStyle(gClient->GetStyle());
167 fDetails->SetStyle(gClient->GetStyle());
169 fCdup->SetToolTipText(
"Up One Level");
170 fNewf->SetToolTipText(
"Create New Folder");
171 fList->SetToolTipText(
"List");
172 fDetails->SetToolTipText(
"Details");
174 fCdup->Associate(
this);
175 fNewf->Associate(
this);
176 fList->Associate(
this);
177 fDetails->Associate(
this);
179 fList->AllowStayDown(kTRUE);
180 fDetails->AllowStayDown(kTRUE);
182 fTreeLB->Resize(200, fTreeLB->GetDefaultHeight());
184 fHtop->AddFrame(fLookin,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2));
185 fHtop->AddFrame(fTreeLB,
new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 3, 0, 2, 2));
186 fHtop->AddFrame(fCdup,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 2, 2));
187 fHtop->AddFrame(fNewf,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 2, 2));
188 fHtop->AddFrame(fList,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 2, 2));
189 fHtop->AddFrame(fDetails,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 0, 8, 2, 2));
191 if (dlg_type == kFDSave) {
192 fCheckB =
new TGCheckButton(fHtop,
"&Overwrite", kIDF_CHECKB);
193 fCheckB->SetToolTipText(
"Overwrite a file without displaying a message if selected");
195 fCheckB =
new TGCheckButton(fHtop,
"&Multiple files", kIDF_CHECKB);
196 fCheckB->SetToolTipText(
"Allows multiple file selection when SHIFT is pressed");
197 fCheckB->Connect(
"Toggled(Bool_t)",
"TGFileInfo",fFileInfo,
"SetMultipleSelection(Bool_t)");
199 fHtop->AddFrame(fCheckB,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY));
200 fCheckB->SetOn(fFileInfo->fMultipleSelection);
201 AddFrame(fHtop,
new TGLayoutHints(kLHintsTop | kLHintsExpandX, 4, 4, 3, 1));
205 fFv =
new TGListView(
this, 400, 161);
207 fFc =
new TGFileContainer(fFv->GetViewPort(),
208 10, 10, kHorizontalFrame, fgWhitePixel);
209 fFc->Associate(
this);
211 fFv->GetViewPort()->SetBackgroundColor(fgWhitePixel);
212 fFv->SetContainer(fFc);
213 fFv->SetViewMode(kLVList);
214 fFv->SetIncrements(1, 19);
216 TGTextButton** buttons = fFv->GetHeaderButtons();
218 buttons[0]->Connect(
"Clicked()",
"TGFileContainer", fFc,
"Sort(=kSortByName)");
219 buttons[1]->Connect(
"Clicked()",
"TGFileContainer", fFc,
"Sort(=kSortByType)");
220 buttons[2]->Connect(
"Clicked()",
"TGFileContainer", fFc,
"Sort(=kSortBySize)");
221 buttons[3]->Connect(
"Clicked()",
"TGFileContainer", fFc,
"Sort(=kSortByOwner)");
222 buttons[4]->Connect(
"Clicked()",
"TGFileContainer", fFc,
"Sort(=kSortByGroup)");
223 buttons[5]->Connect(
"Clicked()",
"TGFileContainer", fFc,
"Sort(=kSortByDate)");
226 fFc->SetFilter(fFileInfo->fFileTypes[fFileInfo->fFileTypeIdx+1]);
227 fFc->Sort(kSortByName);
228 fFc->ChangeDirectory(fFileInfo->fIniDir);
229 fFc->SetMultipleSelection(fFileInfo->fMultipleSelection);
230 fTreeLB->Update(fFc->GetDirectory());
232 fList->SetState(kButtonEngaged);
234 AddFrame(fFv,
new TGLayoutHints(kLHintsTop | kLHintsExpandX | kLHintsExpandY, 4, 4, 3, 1));
236 if (dlg_type == kFDOpen) {
237 fCheckB->Connect(
"Toggled(Bool_t)",
"TGFileContainer",fFc,
"SetMultipleSelection(Bool_t)");
238 fCheckB->Connect(
"Toggled(Bool_t)",
"TGFileContainer",fFc,
"UnSelectAll()");
243 TGHorizontalFrame *fHf =
new TGHorizontalFrame(
this, 10, 10);
245 TGVerticalFrame *fVf =
new TGVerticalFrame(fHf, 10, 10);
247 TGHorizontalFrame *fHfname =
new TGHorizontalFrame(fVf, 10, 10);
249 TGLabel *fLfname =
new TGLabel(fHfname,
new TGHotString(
"File &name:"));
250 fTbfname =
new TGTextBuffer(1034);
251 fName =
new TGTextEntry(fHfname, fTbfname);
252 fName->Resize(230, fName->GetDefaultHeight());
253 fName->Associate(
this);
255 fHfname->AddFrame(fLfname,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2));
256 fHfname->AddFrame(fName,
new TGLayoutHints(kLHintsRight | kLHintsCenterY, 0, 20, 2, 2));
258 fVf->AddFrame(fHfname,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY | kLHintsExpandX));
260 TGHorizontalFrame *fHftype =
new TGHorizontalFrame(fVf, 10, 10);
262 TGLabel *fLftypes =
new TGLabel(fHftype,
new TGHotString(
"Files of &type:"));
263 fTypes =
new TGComboBox(fHftype, kIDF_FTYPESLB);
264 fTypes->Associate(
this);
265 fTypes->Resize(230, fName->GetDefaultHeight());
268 for (i = 0; fFileInfo->fFileTypes[i] != 0; i += 2) {
269 s.Form(
"%s (%s)", fFileInfo->fFileTypes[i], fFileInfo->fFileTypes[i+1]);
270 fTypes->AddEntry(s.Data(), i);
272 fTypes->Select(fFileInfo->fFileTypeIdx);
278 if (fFileInfo->fFilename && fFileInfo->fFilename[0])
279 fTbfname->AddText(0, fFileInfo->fFilename);
282 if (dlg_type == kFDSave) {
283 fTbfname->AddText(0,
"unnamed");
285 if (fFileInfo->fFileTypes[fFileInfo->fFileTypeIdx+1] &&
286 strstr(fFileInfo->fFileTypes[fFileInfo->fFileTypeIdx+1],
"*.")) {
287 TString ext = fFileInfo->fFileTypes[fFileInfo->fFileTypeIdx+1];
288 ext.ReplaceAll(
"*.",
".");
289 fTbfname->AddText(7, ext.Data());
295 fTypes->GetListBox()->Resize(230, 120);
296 fHftype->AddFrame(fLftypes,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 5, 2, 2));
297 fHftype->AddFrame(fTypes,
new TGLayoutHints(kLHintsRight | kLHintsCenterY, 0, 20, 2, 2));
299 fVf->AddFrame(fHftype,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY | kLHintsExpandX));
301 fHf->AddFrame(fVf,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY | kLHintsExpandX));
305 TGVerticalFrame *fVbf =
new TGVerticalFrame(fHf, 10, 10, kFixedWidth);
307 fOk =
new TGTextButton(fVbf,
new TGHotString((dlg_type == kFDSave)
308 ?
"&Save" :
"&Open"), kIDF_OK);
309 fCancel =
new TGTextButton(fVbf,
new TGHotString(
"Cancel"), kIDF_CANCEL);
311 fOk->Associate(
this);
312 fCancel->Associate(
this);
314 fVbf->AddFrame(fOk,
new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 2, 2));
315 fVbf->AddFrame(fCancel,
new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 2, 2));
317 UInt_t width = TMath::Max(fOk->GetDefaultWidth(), fCancel->GetDefaultWidth()) + 20;
318 fVbf->Resize(width + 20, fVbf->GetDefaultHeight());
320 fHf->AddFrame(fVbf,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY));
322 AddFrame(fHf,
new TGLayoutHints(kLHintsTop | kLHintsExpandX, 4, 4, 3, 1));
323 SetEditDisabled(kEditDisable);
327 TGDimension size = GetDefaultSize();
337 SetWMSize(size.fWidth, size.fHeight);
338 SetWMSizeHints(size.fWidth, size.fHeight, 10000, 10000, 1, 1);
340 const char *wname = (dlg_type == kFDSave) ?
"Save As..." :
"Open";
341 SetWindowName(wname);
343 SetClassHints(
"ROOT",
"FileDialog");
345 SetMWMHints(kMWMDecorAll | kMWMDecorResizeH | kMWMDecorMaximize |
346 kMWMDecorMinimize | kMWMDecorMenu,
347 kMWMFuncAll | kMWMFuncResize | kMWMFuncMaximize |
352 fFc->DisplayDirectory();
353 if (dlg_type == kFDSave)
355 fClient->WaitFor(
this);
361 TGFileDialog::~TGFileDialog()
363 if (IsZombie())
return;
364 TString str = fCheckB->GetString();
365 if (str.Contains(
"Multiple"))
366 fCheckB->Disconnect(
"Toggled(Bool_t)");
367 fClient->FreePicture(fPcdup);
368 fClient->FreePicture(fPnewf);
369 fClient->FreePicture(fPlist);
370 fClient->FreePicture(fPdetails);
377 void TGFileDialog::CloseWindow()
379 if (fFileInfo->fFilename)
380 delete [] fFileInfo->fFilename;
381 fFileInfo->fFilename = 0;
382 if (fFileInfo->fFileNamesList != 0) {
383 fFileInfo->fFileNamesList->Delete();
384 fFileInfo->fFileNamesList = 0;
394 static inline void pExpandUnixPathName(TGFileInfo &file_info) {
395 char *tmpPath = gSystem->ExpandPathName(file_info.fFilename);
396 delete [] file_info.fFilename;
397 file_info.fFilename = StrDup(gSystem->UnixPathName(tmpPath));
405 Bool_t TGFileDialog::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
407 if (!fFc->GetDisplayStat())
return kTRUE;
414 TString sdir = gSystem->WorkingDirectory();
416 switch (GET_MSG(msg)) {
418 switch (GET_SUBMSG(msg)) {
423 if (fTbfname->GetTextLength() == 0) {
424 txt =
"Please provide file name or use \"Cancel\"";
425 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
426 "Missing File Name", txt, kMBIconExclamation,
429 }
else if (!gSystem->AccessPathName(fTbfname->GetString(), kFileExists) &&
430 !strcmp(fOk->GetTitle(),
"Save") &&
431 (!(fCheckB->GetState() == kButtonDown))) {
433 txt = TString::Format(
"File name %s already exists, OK to overwrite it?",
434 fTbfname->GetString());
435 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
436 "File Name Exist", txt.Data(), kMBIconExclamation,
437 kMBYes | kMBNo, &ret);
441 if (fFileInfo->fMultipleSelection) {
442 if (fFileInfo->fFilename)
443 delete [] fFileInfo->fFilename;
444 fFileInfo->fFilename = 0;
447 if (fFileInfo->fFilename)
448 delete [] fFileInfo->fFilename;
449 if (gSystem->IsAbsoluteFileName(fTbfname->GetString()))
450 fFileInfo->fFilename = StrDup(fTbfname->GetString());
452 fFileInfo->fFilename = gSystem->ConcatFileName(fFc->GetDirectory(),
453 fTbfname->GetString());
454 pExpandUnixPathName(*fFileInfo);
456 if (fCheckB && (fCheckB->GetState() == kButtonDown))
457 fFileInfo->fOverwrite = kTRUE;
459 fFileInfo->fOverwrite = kFALSE;
464 if (fFileInfo->fFilename)
465 delete [] fFileInfo->fFilename;
466 fFileInfo->fFilename = 0;
467 if (fFc->GetDisplayStat())
468 fFc->SetDisplayStat(kFALSE);
469 if (fFileInfo->fFileNamesList != 0) {
470 fFileInfo->fFileNamesList->Delete();
471 fFileInfo->fFileNamesList = 0;
478 fFc->ChangeDirectory(
"..");
479 fTreeLB->Update(fFc->GetDirectory());
480 if (fFileInfo->fIniDir)
delete [] fFileInfo->fIniDir;
481 fFileInfo->fIniDir = StrDup(fFc->GetDirectory());
482 if (strcmp(gSystem->WorkingDirectory(),fFc->GetDirectory())) {
483 gSystem->cd(fFc->GetDirectory());
487 case kIDF_NEW_FOLDER: {
489 strlcpy(answer,
"(empty)",
sizeof(answer));
490 new TGInputDialog(gClient->GetRoot(), GetMainFrame(),
491 "Enter directory name:",
494 while ( strcmp(answer,
"(empty)") == 0 ) {
495 new TGMsgBox(gClient->GetRoot(), GetMainFrame(),
"Error",
496 "Please enter a valid directory name.",
498 new TGInputDialog(gClient->GetRoot(), GetMainFrame(),
499 "Enter directory name:",
502 if ( strcmp(answer,
"") == 0 )
505 if (strcmp(gSystem->WorkingDirectory(),fFc->GetDirectory())) {
506 gSystem->cd(fFc->GetDirectory());
508 if ( gSystem->MakeDirectory(answer) != 0 )
509 new TGMsgBox(gClient->GetRoot(), GetMainFrame(),
"Error",
510 TString::Format(
"Directory name \'%s\' already exists!", answer),
513 fFc->DisplayDirectory();
515 gSystem->ChangeDirectory(sdir.Data());
520 fFv->SetViewMode(kLVList);
521 fDetails->SetState(kButtonUp);
525 fFv->SetViewMode(kLVDetails);
526 fList->SetState(kButtonUp);
534 e = (TGTreeLBEntry *) fTreeLB->GetSelectedEntry();
536 fFc->ChangeDirectory(e->GetPath()->GetString());
537 fTreeLB->Update(fFc->GetDirectory());
538 if (fFileInfo->fIniDir)
delete [] fFileInfo->fIniDir;
539 fFileInfo->fIniDir = StrDup(fFc->GetDirectory());
540 if (strcmp(gSystem->WorkingDirectory(),fFc->GetDirectory())) {
541 gSystem->cd(fFc->GetDirectory());
547 te = (TGTextLBEntry *) fTypes->GetSelectedEntry();
551 fFileInfo->fFileTypeIdx = te->EntryId();
552 fFc->SetFilter(fFileInfo->fFileTypes[fFileInfo->fFileTypeIdx+1]);
553 fFc->DisplayDirectory();
554 fClient->NeedRedraw(fName);
566 switch (GET_SUBMSG(msg)) {
568 if (parm1 == kButton1) {
569 if (fFc->NumSelected() > 0) {
570 if ( fFileInfo->fMultipleSelection == kFALSE ) {
571 TGLVEntry *e2 = (TGLVEntry *) fFc->GetNextSelected(&p);
572 if ((e2) && !R_ISDIR(((TGFileItem *)e2)->GetType())) {
574 if (e2->GetItemName())
575 fTbfname->AddText(0, e2->GetItemName()->GetString());
576 fClient->NeedRedraw(fName);
581 TList *tmp = fFc->GetSelectedItems();
584 if ( fFileInfo->fFileNamesList != 0 ) {
585 fFileInfo->fFileNamesList->Delete();
588 fFileInfo->fFileNamesList =
new TList();
590 while ((el = (TObjString *) next())) {
591 char *s = gSystem->ConcatFileName(fFc->GetDirectory(),
593 tmpString +=
"\"" + el->GetString() +
"\" ";
594 fFileInfo->fFileNamesList->Add(
new TObjString(s));
598 fTbfname->AddText(0, tmpString);
599 fClient->NeedRedraw(fName);
605 case kCT_ITEMDBLCLICK:
607 if (parm1 == kButton1) {
608 if (fFc->NumSelected() == 1) {
609 f = (TGFileItem *) fFc->GetNextSelected(&p);
610 if (f && R_ISDIR(f->GetType())) {
611 fFc->ChangeDirectory(f->GetItemName()->GetString());
612 fTreeLB->Update(fFc->GetDirectory());
613 if (fFileInfo->fIniDir)
delete [] fFileInfo->fIniDir;
614 fFileInfo->fIniDir = StrDup(fFc->GetDirectory());
615 if (strcmp(gSystem->WorkingDirectory(),fFc->GetDirectory())) {
616 gSystem->cd(fFc->GetDirectory());
619 if (!strcmp(fOk->GetTitle(),
"Save") &&
620 (!(fCheckB->GetState() == kButtonDown))) {
623 txt = TString::Format(
"File name %s already exists, OK to overwrite it?",
624 fTbfname->GetString());
625 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
626 "File Name Exist", txt.Data(), kMBIconExclamation,
627 kMBYes | kMBNo, &ret);
631 if (fFileInfo->fFilename)
632 delete [] fFileInfo->fFilename;
633 if (gSystem->IsAbsoluteFileName(fTbfname->GetString()))
634 fFileInfo->fFilename = StrDup(fTbfname->GetString());
636 fFileInfo->fFilename = gSystem->ConcatFileName(fFc->GetDirectory(),
637 fTbfname->GetString());
638 pExpandUnixPathName(*fFileInfo);
639 if (fCheckB && (fCheckB->GetState() == kButtonDown))
640 fFileInfo->fOverwrite = kTRUE;
642 fFileInfo->fOverwrite = kFALSE;
658 switch (GET_SUBMSG(msg)) {
661 if (fTbfname->GetTextLength() == 0) {
662 const char *txt2 =
"Please provide file name or use \"Cancel\"";
663 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
664 "Missing File Name", txt2, kMBIconExclamation,
667 }
else if (!gSystem->AccessPathName(fTbfname->GetString(), kFileExists)) {
669 if (!gSystem->GetPathInfo(fTbfname->GetString(), buf) &&
670 R_ISDIR(buf.fMode)) {
671 fFc->ChangeDirectory(fTbfname->GetString());
672 fTreeLB->Update(fFc->GetDirectory());
673 if (strcmp(gSystem->WorkingDirectory(), fFc->GetDirectory())) {
674 gSystem->cd(fFc->GetDirectory());
676 fName->SetText(
"", kFALSE);
679 else if (!strcmp(fOk->GetTitle(),
"Save") &&
680 (!(fCheckB->GetState() == kButtonDown))) {
682 txt = TString::Format(
"File name %s already exists, OK to overwrite it?",
683 fTbfname->GetString());
684 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
685 "File Name Exist", txt.Data(), kMBIconExclamation,
686 kMBYes | kMBNo, &ret);
691 if (fFileInfo->fFilename)
692 delete [] fFileInfo->fFilename;
693 fFileInfo->fFilename = gSystem->ConcatFileName(fFc->GetDirectory(),
694 fTbfname->GetString());
695 pExpandUnixPathName(*fFileInfo);
696 if (fCheckB && (fCheckB->GetState() == kButtonDown))
697 fFileInfo->fOverwrite = kTRUE;
699 fFileInfo->fOverwrite = kFALSE;
713 fClient->NeedRedraw(fFc);