Signal-based TGFileDialog?

Hi,

I’m wondering whether someone has already written an alternative to TGFileDialog, that is based on ROOT’s signalling mechanism.

I’d imagine it to emit something like OnClickedSave() / OnClickedClose(). The former potentially with the output TGFileInfo* as argument?

Why I’m asking is, that I think I’ll need to implement something like this, as the available TGFileDialog forces the rest of my application to wait for it to being closed:

[quote][…], and main is the main (TGMainFrame) application
window (the one opening the dialog), onto which the dialog is
usually centered, and which is waiting for it to close.[/quote]

This is not usable in my case. I just recently switched from a ugly self-made filename input box to TGFileDialog, only to notice that it halts my program until it is closed …

Thanks in advance!
Sven

Hi Sven,

Well, this is the usual behavior of the file dialog in many applications (they are modal)
The other option is to create your own file selection frame (or widget) matching your needs.
See for example the “List Directory…” and “File List…” examples in the “Test” menu of the $ROOTSYS/tutorials/gui/guitest.C tutorial.

Cheers, Bertrand.

Hi Bertrand,

thanks for the fast reply!

Certainly, you are right. Its just not what I need …

We have a DAQ-System driven by the same program, I can’t allow it to not record anymore, just because someone clicked “new file” and can’t decide for the file name :wink:

I’m asking, because I can’t be the first to have such a problem, right?
There’s hope that someone has looked into the TGFileDialog code already, and made it modeless and emitting signals.

This is exactly what we had before, albeit not really worked out nicely, I admit.
I thought TGFileDialog would be great as it functions as such a dialog should (so, there are no surprises for the user).

Best!
Sven

Hi Sven,

Well, and what about using a separate thread for the DAQ? (so it will never wait on the GUI, or anything else that could disturb it…)

Cheers, Bertrand.

Oh yes!

ATM, I’m working on a threaded re-write of the code. But that will need time and work.

However, I had replaced our dialog with the built-in one some time ago, and now we noticed this had this “side effect”. If there was some simple solution or if adapting the class is straight forward enough, I’d simple drop that into the code, and then continue with re-writing. I’d like to maintain the old code as long as the new code is not in shape …

Sven

I’m not sure there is an easy solution to this, but I’ll check.

Cheers, Bertrand.

From how I understand the code, it does not look impossible to implement it:

1.) Get rid of:

fClient->WaitFor(this);

2.) Wherever

DeleteWindow();

is called, one should add the Emit() of the respective Signal.

3.) Add the signals: OnClickedOK, OnClickedSave, OnClickedCancel
Maybe the first two can be implemented as one …

However, I see no way to do it without copying large parts of the original class. Almost all the work is done in the constructor and the ProcessMessage method.

Maybe some clever inheriting and overwriting DeleteWindow (i.e., adding the emitting to it) could be an option to re-use ProcessMessage, but the constructor would still have to be copied as one would only like to get rid of its last line.

I already implemented a possible solution to be used like this:

TGFileDialog *dlg = new TGFileDialog(gClient->GetRoot(), fMain, kFDOpen, &fi, kFALSE); dlg->Connect("Selected(TGFileInfo *)", "TestMainFrame", this, "DoOK(TGFileInfo *)");
But then one has to be careful when using a non-modal dialog. For example, the TGFileInfo passed as argument of TGFileDialog has to be somehow global (or member of the class calling TGFileDialog), to make sure it is still accessible when going out of scope.
To illustrate this, the following example will not work:

case M_FILE_OPEN: { TGFileInfo fi; fi.fFileTypes = filetypes; fi.fIniDir = StrDup(dir); printf("fIniDir = %s\n", fi.fIniDir); TGFileDialog *dlg = new TGFileDialog(gClient->GetRoot(), fMain, kFDOpen, &fi, kFALSE); dlg->Connect("Selected(TGFileInfo *)", "TestMainFrame", this, "DoOK(TGFileInfo *)"); } break; Since the TGFileInfo fi will be deleted when going out of scope… So this is error prone and I don’t really like it…
If you want, I can send you a diff and you can try it with your application

Cheers, Bertrand.

Ah, I see. This might indeed become problematic, when used wrongly…

Yes, please, do so.
I’d very much like to have a look at what you’ve done!

In the end, I want to implement the functionality of the dialog anyway.
So, I suppose I will face the same problem, even if I implement my own modeless dialog, right?

Or could this be mitigated in a newly written dialog somehow?

[quote=“augustin”]Yes, please, do so.
I’d very much like to have a look at what you’ve done!
[/quote]So here it is. Against ROOT v5-34-00-patches, but easy to apply on any version… TGFileDialog-non-modal.diff (3.37 KB)

[quote=“augustin”]In the end, I want to implement the functionality of the dialog anyway.
So, I suppose I will face the same problem, even if I implement my own modeless dialog, right?
[/quote]Yes, you have to use it the right way

[quote=“augustin”]Or could this be mitigated in a newly written dialog somehow?[/quote]Yes, sure, everything is possible… Up to you :wink:

Cheers, Bertrand.

[quote=“bellenot”][quote=“augustin”]Yes, please, do so.
I’d very much like to have a look at what you’ve done!
[/quote]So here it is. Against ROOT v5-34-00-patches, but easy to apply on any version… [attachment=0]TGFileDialog-non-modal.diff[/attachment][/quote]

Great! Thanks! I’ll test it right away…

And it looks like my analysis above of what needs to be done was right :slight_smile:
You did exactly the same…

Sure. What I meant was: Is it even possible to mitigate it, as in: If the TGFileInfo is created on the spot (as in your negative example) it will be gone once we leave the scope. So, TGFileInfo has to exist on the calling class level. There’s no way around it that I can think of …

Well, one could make a copy of the TGFileInfo inside TGFileDialog and returned by the signal. But then it has to be deleted by the slot.

Well, one could make a copy of the TGFileInfo inside TGFileDialog and returned by the signal. But then it has to be deleted by the slot.[/quote]

Ah, right. But that would also give the responsibility for the TGFileInfo object to the caller, which is identical to the other solution in the end: In the one case it is the responsibility to provide the TGFileInfo for filling, in the other it is the responsibility to take care of the copied TGFileInfo afterwards …

Anyway: Your patch works perfectly! Thanks a lot!!

Any chance of getting it into the ROOT release, too?
Even if I’m the first to look for this functionality, I might not be the last …
And it would spare me applying the patch everywhere :wink:

Best!
Sven

This has to be discussed. BTW, which version of ROOT are you using?

Cheers, Bertrand.

Very good!

Usually the latest 5.x production release.
I try to follow those, but haven’t come around to try ROOT 6…

However, just now, I simply used the 5.34.00-patches git branch, as I didn’t want to fiddle with the patch …

Then be warned that if the patch has to be applied, it will only be in ROOT 6, since only critical bug fixes are going into ROOT 5…

Cheers, Bertrand.

[quote=“bellenot”]Then be warned that if the patch has to be applied, it will only be in ROOT 6, since only critical bug fixes are going into ROOT 5…
[/quote]

I see …

I shall go and test whether I can build my code against ROOT 6, then :smiley: