wxFileDialog::SetExtraControlCreator question

202 views
Skip to first unread message

Carl Godkin

unread,
May 21, 2013, 5:25:35 PM5/21/13
to wx-u...@googlegroups.com

Hi again,

Earlier I asked about using the generic file dialog in wxGTK 2.9.4.

One of the reasons for this is that we like to add some extra controls to the file dialog which is of course supported now in wx 2.9 using SetExtraControlCreator.

Is it possible to determine the currently selected file in a native file dialog (before the user presses "OK," that is) ?

I ask because I am able to query the contents of the various controls in the generic file dialog to (say) enable or disable some of the extra controls based on the current selection.  For example, a "Plot" button might be enabled if an image file is selected and disabled if another file type is selected.  (I hope I am explaining this clearly!)

Thanks for any pointers using this new functionality.  

carl

Vadim Zeitlin

unread,
May 22, 2013, 10:03:55 AM5/22/13
to wx-u...@googlegroups.com
On Tue, 21 May 2013 14:25:35 -0700 Carl Godkin wrote:

CG> Is it possible to determine the currently selected file in a native file
CG> dialog (before the user presses "OK," that is) ?

Not currently. However I believe others had requested this in the past
(although I can't find any ticket for it right now) and the good news is
that it should be possible and even relatively simple to implement for both
MSW and GTK (as usual, I have no idea about OS X).

Under MSW we just need to add another case to the existing
wxFileDialogHookFunction and generate an event when we get CDN_SELCHANGE.
Under GTK we need to connection to "selection-changed" signal in
wxFileDialog. And, of course, it would be pretty simple to implement this
in the generic version too.

So if you need this functionality, please consider adding it to wxWidgets.
It shouldn't be very difficult and would definitely be useful.

TIA,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

Carl Godkin

unread,
May 22, 2013, 10:08:00 AM5/22/13
to wx-u...@googlegroups.com
On Wed, May 22, 2013 at 7:03 AM, Vadim Zeitlin <va...@wxwidgets.org> wrote:
On Tue, 21 May 2013 14:25:35 -0700 Carl Godkin wrote:

CG> Is it possible to determine the currently selected file in a native file
CG> dialog (before the user presses "OK," that is) ?

 Not currently. However I believe others had requested this in the past
(although I can't find any ticket for it right now) and the good news is
that it should be possible and even relatively simple to implement for both
MSW and GTK (as usual, I have no idea about OS X).

 Under MSW we just need to add another case to the existing
wxFileDialogHookFunction and generate an event when we get CDN_SELCHANGE.
Under GTK we need to connection to "selection-changed" signal in
wxFileDialog. And, of course, it would be pretty simple to implement this
in the generic version too.



I have indeed done this already for the wxMSW native file dialog and it works well.  I will
see what I can do about the wxGTK file dialog.  (And, as you probably concluded, this
was the main reason I was asking the generic file dialog where implementing this behavior is simple.)

Thanks for both replies.  I'll try to figure this out for wxGTK and contribute both back
if possible.

Thanks again,

carl
 

Carl Godkin

unread,
May 24, 2013, 10:04:18 AM5/24/13
to wx-u...@googlegroups.com
On Wed, May 22, 2013 at 7:03 AM, Vadim Zeitlin <va...@wxwidgets.org> wrote:
On Tue, 21 May 2013 14:25:35 -0700 Carl Godkin wrote:

CG> Is it possible to determine the currently selected file in a native file
CG> dialog (before the user presses "OK," that is) ?

 Not currently. However I believe others had requested this in the past
(although I can't find any ticket for it right now) and the good news is
that it should be possible and even relatively simple to implement for both
MSW and GTK (as usual, I have no idea about OS X).

 Under MSW we just need to add another case to the existing
wxFileDialogHookFunction and generate an event when we get CDN_SELCHANGE.
Under GTK we need to connection to "selection-changed" signal in
wxFileDialog. And, of course, it would be pretty simple to implement this
in the generic version too.

 So if you need this functionality, please consider adding it to wxWidgets.
It shouldn't be very difficult and would definitely be useful.


Thanks for the implementation tips.  I've started working on this and have a question:

I don't think that UpdateUIEvents appear to work for the extra controls added to the wxMSW native file dialog.  Is this expected?  I can't find any prior discussion of this in the archives.

FWIW, I had been using UpdateUIEvents happily enough with the generic file dialog on wxGTK, but I imagine that's not really relevant.

Thanks,

carl
 

Vadim Zeitlin

unread,
May 24, 2013, 12:26:32 PM5/24/13
to wx-u...@googlegroups.com
On Fri, 24 May 2013 07:04:18 -0700 Carl Godkin wrote:

CG> I don't think that UpdateUIEvents appear to work for the extra controls
CG> added to the wxMSW native file dialog. Is this expected?

Not really expected but not that surprising neither: update UI events are
generated from idle handler in the application itself which sends them to
all the top level windows which, in turn, send them to their children and
so on. As the file dialog is not a wxWindow, it doesn't get these events
naturally and so something specific would need to be done to get them for
these controls. I don't have any really good ideas about what to do here
though, I can think of several things that would work but none of them is
really satisfactory. The least bad one is probably to have a list of
windows that have foreign parents and send idle and update UI events to
them separately in wxApp. Of course, care should be taken to not only add
custom controls to this list but also to remove them from it when they're
about to be destroyed.

Regards,

Carl Godkin

unread,
May 24, 2013, 3:14:26 PM5/24/13
to wx-u...@googlegroups.com
The idea of changing how updateUI events are dispatched is quite daunting
to me since I've never worked anywhere near that code before.

I came up another idea and have implemented it for both native wxMSW
and native wxGTK wxFileDialogs.  See what you think.

When the current file dialog selection is changed (on a CDN_SELCHANGE message
for wxMSW, or on a selection-changed signal in wxGTK), I create a wxUpdateUIEvent 
with the extra control's ID,  add the selected filename to the event with event.SetString(),
and call HandleWindowEvent().

In my client code, I connected an event handler to the extra control that gets notified
when the current selection changes.  (I admit that I'm abusing wxUpdateUIEvent a little
here and should maybe make it a generic wxCommandEvent since all I need
is the m_commandString member.)

Anyway, my event handler just updates the extra control UI as necessary and it all works well.

I could try to package this up as a proposed patch if you don't think this approach
is too ugly.

Thanks for the help so far!

carl

 

Vadim Zeitlin

unread,
May 24, 2013, 8:35:17 PM5/24/13
to wx-u...@googlegroups.com
On Fri, 24 May 2013 12:14:26 -0700 Carl Godkin wrote:

CG> I came up another idea and have implemented it for both native wxMSW
CG> and native wxGTK wxFileDialogs. See what you think.
CG>
CG> When the current file dialog selection is changed (on a CDN_SELCHANGE
CG> message for wxMSW, or on a selection-changed signal in wxGTK), I create
CG> a wxUpdateUIEvent with the extra control's ID, add the selected
CG> filename to the event with event.SetString(), and call
CG> HandleWindowEvent().

Using wxUpdateUIEvent::SetString() for the filename is definitely an
abuse, it's not supposed to be used for this. How would it be different
from the wxCommandEvent that you're working on adding then?

But sending wxUpdateUIEvent to the extra controls in the usual way, i.e.
by just calling UpdateWindowUI(), only when the selection changes, before
and/or after (probably "and" rather than "or") sending this wxCommandEvent
could be enough in practice. This wouldn't allow these controls to be
updated to reflect the state of something external to the dialog but as
they're meant to be used only for something filename-related, it probably
wouldn't be a big limitation.

Carl Godkin

unread,
May 28, 2013, 10:19:07 AM5/28/13
to wx-u...@googlegroups.com
I didn't know about wxWindow::UpdateWindowUI() before reading your reply.  That definitely makes things simpler.  I now have the selection changed handler in the file dialog code for both wxMSW and wxGTK just call 
   m_extraControl->UpdateWindowUI (wxUPDATE_UI_RECURSE) 
which works well.

However, I'm not sure what the best way to pass the name of the currently selected file to the extra controls would be.  What I've done for now in my implementation is simply to use the extra control's client data hook:
   m_extraControl->SetClientObject (new wxStringClientData (filename));

before calling UpdateWindowUI.

Is there a better way you'd recommend? 

Thanks,

carl

Vadim Zeitlin

unread,
May 28, 2013, 2:11:08 PM5/28/13
to wx-u...@googlegroups.com
On Tue, 28 May 2013 07:19:07 -0700 Carl Godkin wrote:

CG> I didn't know about wxWindow::UpdateWindowUI() before reading your reply.
CG> That definitely makes things simpler. I now have the selection changed
CG> handler in the file dialog code for both wxMSW and wxGTK just call
CG> m_extraControl->UpdateWindowUI (wxUPDATE_UI_RECURSE)
CG> which works well.

Great, thanks.

CG> However, I'm not sure what the best way to pass the name of the currently
CG> selected file to the extra controls would be. What I've done for now in my
CG> implementation is simply to use the extra control's client data hook:
CG> m_extraControl->SetClientObject (new wxStringClientData (filename));
CG>
CG> before calling UpdateWindowUI.
CG>
CG> Is there a better way you'd recommend?

It's not totally clear to me what are we trying to do here. I thought we
started from the idea that an event should be generated when the selection
in the dialog changes. With this approach, the code handling this event
would also update any custom controls in the dialog and it would already
have the name of the selected file.

However you seem to have switched to a completely different approach since
then, and now the controls are supposed to update themselves from their
idle or update UI event handlers. In this case, the best would seem to be
to provide wxFileDialog::GetCurrentlySelectedFileName() or something
similar so that they could retrieve the selected item from the dialog
itself.

Carl Godkin

unread,
May 28, 2013, 2:42:55 PM5/28/13
to wx-u...@googlegroups.com
On Tue, May 28, 2013 at 11:11 AM, Vadim Zeitlin <va...@wxwidgets.org> wrote:


CG> However, I'm not sure what the best way to pass the name of the currently
CG> selected file to the extra controls would be.  What I've done for now in my
CG> implementation is simply to use the extra control's client data hook:
CG>    m_extraControl->SetClientObject (new wxStringClientData (filename));
CG>
CG> before calling UpdateWindowUI.
CG>
CG> Is there a better way you'd recommend?

 It's not totally clear to me what are we trying to do here. I thought we
started from the idea that an event should be generated when the selection
in the dialog changes. With this approach, the code handling this event
would also update any custom controls in the dialog and it would already
have the name of the selected file.

 However you seem to have switched to a completely different approach since
then, and now the controls are supposed to update themselves from their
idle or update UI event handlers. In this case, the best would seem to be
to provide wxFileDialog::GetCurrentlySelectedFileName() or something
similar so that they could retrieve the selected item from the dialog
itself.


Yes, an event is generated when the current selection in the dialog changes.  This event, however, is internal to the wxFileDialog code specific to each port.  

In other words, the wxGTK port connects "selection-changed" signal to a GTK callback which calls UpdateWindowUI().   And the wxMSW port handles CDN_SELCHANGE by calling a Windows event handler which then calls UpdateWindowUI().  I think you're okay with this scheme already.

So where I guess we're disconnected is how the extra control's client code that handles the wxUpdateUIEvents can learn the currently selected file name since there's no generic way for the control to discover it that I can see.

I could write a wxFileDialog::GetCurrentlySelectedFileName() if you think that's best. 

Sorry if I'm being dense,

carl

Vadim Zeitlin

unread,
May 28, 2013, 2:49:57 PM5/28/13
to wx-u...@googlegroups.com
On Tue, 28 May 2013 11:42:55 -0700 Carl Godkin wrote:

CG> Yes, an event is generated when the current selection in the dialog
CG> changes. This event, however, is internal to the wxFileDialog code
CG> specific to each port.

I think the confusion is related to the use of the word "event". For me,
an event was a wxWidgets event, e.g. wxEVT_FILEDIALOG_SELECTION_CHANGED or
something like this.

CG> In other words, the wxGTK port connects "selection-changed" signal to a GTK
CG> callback which calls UpdateWindowUI(). And the wxMSW port handles
CG> CDN_SELCHANGE by calling a Windows event handler which then calls
CG> UpdateWindowUI(). I think you're okay with this scheme already.

This is fine for sending wxEVT_IDLE events, yes. If we don't have the
"direct" event like the one from above, this means that using wxEVT_IDLE or
wxEVT_UPDATE_UI handlers is the *only* way to update the custom controls
which is a bit strange but why not, it's definitely better than nothing.

CG> I could write a wxFileDialog::GetCurrentlySelectedFileName() if you think
CG> that's best.

This would be useful anyhow and if you already have code reacting to its
changes, it should be simple to do and should solve the problem, I think.

Thanks,

Carl Godkin

unread,
May 28, 2013, 3:04:35 PM5/28/13
to wx-u...@googlegroups.com
On Tue, May 28, 2013 at 11:49 AM, Vadim Zeitlin <va...@wxwidgets.org> wrote:
On Tue, 28 May 2013 11:42:55 -0700 Carl Godkin wrote:

CG> Yes, an event is generated when the current selection in the dialog
CG> changes.  This event, however, is internal to the wxFileDialog code
CG> specific to each port.

 I think the confusion is related to the use of the word "event". For me,
an event was a wxWidgets event, e.g. wxEVT_FILEDIALOG_SELECTION_CHANGED or
something like this.


I could go either way.  I hadn't thought of an entirely new event, but that would be pretty doable even for me.

Since what I've already done already works for me, I'm mostly continuing work to try to provide a generally useful feature for others to use.  So I'll rework what I have in the next few days to introduce a  wxEVT_FILEDIALOG_SELECTION_CHANGED event.

Thanks for all the advice,

carl

Vadim Zeitlin

unread,
May 28, 2013, 3:52:49 PM5/28/13
to wx-u...@googlegroups.com
On Tue, 28 May 2013 12:04:35 -0700 Carl Godkin wrote:

CG> Since what I've already done already works for me, I'm mostly continuing
CG> work to try to provide a generally useful feature for others to use. So
CG> I'll rework what I have in the next few days to introduce a
CG> wxEVT_FILEDIALOG_SELECTION_CHANGED event.

Notice that having GetCurrentlySelectedFileName() accessor could still be
useful, even so, so I think you could just add it and submit the patch with
your changes so far to get it applied quickly (as I still do hope to make
2.9.5 soonish). And add wxEVT_FILEDIALOG_SELECTION_CHANGED later if/when
you have time.

CG> Thanks for all the advice,

Thanks for working on this!
Reply all
Reply to author
Forward
0 new messages