Can I do this with wx.FileDialog?

What I’m trying to accomplish:

I have a couple of different file types which may be saved
from the application.

When the user changes the “save as type:” popup
field I’d like to be able to

automatically change the extension of the string in the
“filename:” field to reflect

the filtering extension. wx.FileDialog has a number of
methods which seems useful for this.

However I’m having problems getting some kind of callback
invoked when the user

modifies the “save as type:” popup field.

e.g.

Save as dialog invoked users sees

filename:    usersfile.a3s

Save As Type: field changed to “.zip”

After changing the save sas type, I’d like the user to see

filename:    usersfile.zip

But currently it still says

filename:  usersfile.a3s

Some approaches I’ve tried:

I tried using a Validator approach (see sample code
below), thinking

I’d modify the field when the Validate() method gets
invoked.

With that approach the init() and the Clone() method
would get invoked

but not the Validate(), TransferToWindow(),
TransferFromWindow() methods.

Although wx.FileDialog derives from wx.Window (which has
the SetValidator() method)

it doesn’t seem to get invoked. From looking at examples
and the wxPython in Action book

is seems that only wx.Control (which also derives from
wx.Window)

derived objects might actually make use of the validator.

I also tried deriving a subclass from wx.FileDialog (no
sample code)

so that I could override some methods but they didn’t get
called either.

And I’ve seen some posts which suggest that wouldn’t work.

Suggestions on how this can be done? Or is this currently
not possible?

Or have I misunderstood the wx way of doing things?

---------Sample code below----------------

SaveSceneDialog::saveFromDialog() pops up a dialog and

prompting the user

for a filename to save to. Returns the filename, or None

if the user has

cancelled.

···

class TestValidator(wx.PyValidator):

        def __init__(self):

                    wx.PyValidator.__init__(self)

                    print "TestValidator.__init__

called"; import sys; sys.stdout.flush()

        def Clone(self):

                    print "Clone called";

import sys; sys.stdout.flush()

                    return TestValidator()

        def Validate(self, win):

                    print "Validate called";

import sys; sys.stdout.flush()

                    return True

        def TransferToWindow(self):

                    print "TransferToWindow

called"; import sys; sys.stdout.flush()

                    return True

        def TransferFromWindow(self):

                    print "TransferFromWindow

called"; import sys; sys.stdout.flush()

                    return True

class SaveSceneDialog:

        @staticmethod

        def saveFromDialog(window, filenameHint):

                    if filenameHint:

                                filenameHint =

os.path.basename(filenameHint)

                    else:

                                filenameHint = ''

                    dlg = wx.FileDialog(window,

_(“Save Scene As”))

                    dlg.SetDirectory(GetOptionPrefsDirectory(kPrefsLastScenePath))

                    dlg.SetFilename(filenameHint)

                    dlg.SetStyle(wx.SAVE|wx.OVERWRITE_PROMPT)

                    dlg.SetWildcard("Application

File (.a3s)|.a3s|Compressed Archive (.zip)|.zip")

                    dlg.SetValidator(TestValidator())

                    filename = None

                    if dlg.ShowModal() == wx.ID_OK:

                                try:

                                            OptionPrefs.instance().set(kPrefsLastScenePath,

dlg.GetDirectory())

                                            filename =

dlg.GetPath()

                                            print

“SAVE AS FILENAME”, filename; import sys; sys.stdout.flush()

                                except:

                                            filename =

None

                                            printException()

                    dlg.Destroy()

                    return filename

Dave Blosdale wrote:

What I'm trying to accomplish:

  I have a couple of different file types which may be saved from the application.
  When the user changes the "save as type:" popup field I'd like to be able to
  automatically change the extension of the string in the "filename:" field to reflect
  the filtering extension. wx.FileDialog has a number of methods which seems useful for this.
  However I'm having problems getting some kind of callback invoked when the user
  modifies the "save as type:" popup field.

Some approaches I've tried:

  I tried using a Validator approach (see sample code below), thinking
  I'd modify the field when the Validate() method gets invoked.
  With that approach the __init__() and the Clone() method would get invoked
  but not the Validate(), TransferToWindow(), TransferFromWindow() methods.

  Although wx.FileDialog derives from wx.Window (which has the SetValidator() method)
  it doesn't seem to get invoked. From looking at examples and the wxPython in Action book
  is seems that only wx.Control (which also derives from wx.Window)
  derived objects might actually make use of the validator.

In general this is true although there are ways around it. But the real problem in this case is that the wx.FileDialog is not really a wx.Dialog, or a wx.Window. wx.FileDialog is just a facade in front of the native platform's file dialog APIs and so the vast majority of the wx.Window functionality has no effect on the dialog. When you call ShowModal it just takes some of the info you've provided and calls a platform API that does the work. This is unfortunately not extendable in any way from wx.

To answer your specific question, if the user has already typed or selected "foo.ext1" and changes the save as type to "*.ext2" the dialog code doesn't really know if the user wants "foo.ext2" or "foo.ext1.ext2". Since the filename is not restricted to having a single '.' like it was in old days either name is valid. Each platform has a default way to deal with that and to decide what is correct, and wx honors that. This way the users who are used to how the file dialog works in other apps will be familiar with how it works in your app too.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!