wxFileDialog SetDirectory and SetFilename Seem to be ignored Topic is solved
I would say, try to reproduce this in a minimal compilable sample.
Then we can try it; then we can gather information about it. If it turns out no one else has a solution, then you can post this small example to a bug report and get the most attention.
PS: you can print wxString to std::cout/std::cerr with a small call to .mb_str()
Then we can try it; then we can gather information about it. If it turns out no one else has a solution, then you can post this small example to a bug report and get the most attention.
PS: you can print wxString to std::cout/std::cerr with a small call to .mb_str()
"Keyboard not detected. Press F1 to continue"
-- Windows
-- Windows
-
- Knows some wx things
- Posts: 30
- Joined: Sun Feb 01, 2009 12:38 am
OK I have trimmed this down to a single source file and single header file with no external inputs. This generates the following output which indicates that the values of the wxString parameters are ignored while the const wchar * parameters are honored.Auria wrote:I would say, try to reproduce this in a minimal compilable sample.
Code: Select all
std::getenv("HOME")="/home/jcobban"
start: GetDirectory()="", GetFilename()="0xb7701a58"
start: GetWildcard()="GEDCOM files (*.ged)|*.ged;*.GED
SetDirectory("/home/jcobban")
lastFn="/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree/Cobban.GED"
endDir=71, length=82
SetDirectory("/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree")
SetFilename("Cobban.GED")
last: GetDirectory()="", GetFilename()=""
return: GetDirectory()="", GetFilename()=""
Code: Select all
#ifndef OPEN_FILE_DIALOG_H_
#define OPEN_FILE_DIALOG_H_
#include <wx/wx.h>
class OpenFileDialog : public wxFileDialog
{
public:
OpenFileDialog( wxFrame * parent);
virtual ~OpenFileDialog();
void onQuit(wxCommandEvent& event);
}; // class OpenFileDialog
class GenFrame : public wxFrame
{
public:
GenFrame();
virtual ~GenFrame();
static int main();
}; // GenFrame
class GenTool : public wxApp
{
public:
virtual bool OnInit();
};
#endif /*OPEN_FILE_DIALOG_H_*/
Code: Select all
#include <cstdlib>
#include <cstring>
#include <iostream>
#include "OpenFileDialog.h"
OpenFileDialog::OpenFileDialog( wxFrame * parent)
: wxFileDialog( parent,
L"Choose a file",
::wxGetHomeDir(), // home directory
L"", // initial file name
L"GEDCOM files (*.ged)|*.ged;*.GED",
wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR)
{
wxString dftDir = ::wxGetHomeDir();
std::wcerr << "std::getenv("HOME")="" << dftDir.c_str() << ""\n";
std::wcerr << "start: GetDirectory()="" << GetDirectory().c_str()
<< "", GetFilename()="" << GetFilename() << ""\n";
std::wcerr << "start: GetWildcard()="" << GetWildcard().c_str() << "\n";
std::wcerr << "SetDirectory("" << dftDir.c_str() << "")\n";
SetDirectory(dftDir);
// get configuration for dialog
wxString lastFn = L"/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree/Cobban.GED";
std::wcerr << "lastFn="" << lastFn.c_str() << ""\n";
size_t endDir = lastFn.find_last_of('/', lastFn.length() - 1);
std::wcerr << "endDir=" << endDir << ", length=" << lastFn.length() << "\n";
if (endDir == std::string::npos)
{ // no directory separator
std::wcerr << "SetFilename("" << lastFn.c_str() << "")\n";
SetFilename(lastFn);
} // no directory separator
else
{ // directory separator present
wxString directory, filename;
directory = lastFn.substr(0, endDir);
filename = lastFn.substr(endDir + 1);
std::wcerr << "SetDirectory("" << directory.c_str() << "")\n";
SetDirectory(directory);
std::wcerr << "SetFilename("" << filename.c_str() << "")\n";
SetFilename(filename);
std::wcerr << "last: GetDirectory()="" << GetDirectory().c_str()
<< "", GetFilename()="" << GetFilename().c_str() << ""\n";
} // directory separator present
std::wcerr << "return: GetDirectory()="" << GetDirectory().c_str()
<< "", GetFilename()="" << GetFilename().c_str() << ""\n";
} // OpenFileDialog::OpenFileDialog
//****************************************
//
// OpenFileDialog::~OpenFileDialog
//
// Destructor. Release child resources.
//
//****************************************
OpenFileDialog::~OpenFileDialog()
{
} // OpenFileDialog::~OpenFileDialog
GenFrame::GenFrame( )
: wxFrame( (wxFrame*) NULL,
-1,
L"Test Driver",
wxPoint(50, 50),
wxSize(500, 500) )
{
// allocate and initialize the open file dialog
OpenFileDialog * openFileDialog = new OpenFileDialog(this);
if (openFileDialog->ShowModal() == wxID_OK){
wxString fileName = openFileDialog->GetPath();
}
} // GenFrame::GenFrame
GenFrame::~GenFrame()
{
} // GenFrame::~GenFrame
IMPLEMENT_APP(GenTool)
//****************************************
//
// GenTool::OnInit
//
// Method called when GUI initialization complete.
//
//****************************************
bool GenTool::OnInit()
{
// create an instance of the main window
GenFrame *frame = new GenFrame();
// display the window as the top window for this application
std::cerr << "frame->Show(TRUE);\n";
frame->Show(TRUE);
SetTopWindow(frame);
// continue in the event loop
return TRUE;
}
GetFilename() and SetFilename() are simple getters and setters, i just can't think of anything going wrong there.
I noticed that the "correct" output is given when you print a string directly, but not when you use the return value from a method.
I suspect it's just a display problem with std::
Could you test this code please:
BTW: When you use the wxT() macro around string literals, your code will work on Unicode and ANSI and you don't have to put the "L" in front (that's all that macro actually does)
I noticed that the "correct" output is given when you print a string directly, but not when you use the return value from a method.
I suspect it's just a display problem with std::
Could you test this code please:
Code: Select all
wxString dftDir = ::wxGetHomeDir();
std::wcerr << "dftDir="" << dftDir.c_str() << ""\n";
std::wcerr << "wxGetHomeDir()="" << ::wxGetHomeDir().c_str() << ""\n";
// and now we try wxLogMessage for the same
wxLogMessage(wxT("dftDir='%s'"), dftDir.c_str());
wxLogMessage(wxT("wxGetHomeDir()='%s'"), ::wxGetHomeDir().c_str());
Use the source, Luke!
Hmm not sure what's up with your quotes ("), they're all messed up
Anyhow, I ran the following code :
And got the following output :
Which I believe is the expected output?
Anyhow, I ran the following code :
Code: Select all
#ifndef OPEN_FILE_DIALOG_H_
#define OPEN_FILE_DIALOG_H_
#include <wx/wx.h>
class OpenFileDialog : public wxFileDialog
{
public:
OpenFileDialog( wxFrame * parent);
virtual ~OpenFileDialog();
void onQuit(wxCommandEvent& event);
}; // class OpenFileDialog
class GenFrame : public wxFrame
{
public:
GenFrame();
virtual ~GenFrame();
static int main();
}; // GenFrame
class GenTool : public wxApp
{
public:
virtual bool OnInit();
};
#endif /*OPEN_FILE_DIALOG_H_*/
#include <cstdlib>
#include <cstring>
#include <iostream>
//
//#include "OpenFileDialog.h"
OpenFileDialog::OpenFileDialog( wxFrame * parent)
: wxFileDialog( parent,
L"Choose a file",
::wxGetHomeDir(), // home directory
L"", // initial file name
L"GEDCOM files (*.ged)|*.ged;*.GED",
wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR)
{
wxString dftDir = ::wxGetHomeDir();
std::wcerr << "std::getenv(\"HOME\")=" << dftDir.c_str() << "\n";
std::wcerr << "start: GetDirectory()=" << GetDirectory().c_str()
<< ", GetFilename()=" << GetFilename() << "\n";
std::wcerr << "start: GetWildcard()=" << GetWildcard().c_str() << "\n";
std::wcerr << "SetDirectory(" << dftDir.c_str() << ")\n";
SetDirectory(dftDir);
// get configuration for dialog
wxString lastFn = L"/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree/Cobban.GED";
std::wcerr << "lastFn=" << lastFn.c_str() << "\n";
size_t endDir = lastFn.find_last_of('/', lastFn.length() - 1);
std::wcerr << "endDir=" << endDir << ", length=" << lastFn.length() << "\n";
if (endDir == std::string::npos)
{ // no directory separator
std::wcerr << "SetFilename(" << lastFn.c_str() << ")\n";
SetFilename(lastFn);
} // no directory separator
else
{ // directory separator present
wxString directory, filename;
directory = lastFn.substr(0, endDir);
filename = lastFn.substr(endDir + 1);
std::wcerr << "SetDirectory(" << directory.c_str() << ")\n";
SetDirectory(directory);
std::wcerr << "SetFilename(" << filename.c_str() << ")\n";
SetFilename(filename);
std::wcerr << "last: GetDirectory()=" << GetDirectory().c_str()
<< ", GetFilename()=" << GetFilename().c_str() << "\n";
} // directory separator present
std::wcerr << "return: GetDirectory()=" << GetDirectory().c_str()
<< ", GetFilename()=" << GetFilename().c_str() << "\n";
} // OpenFileDialog::OpenFileDialog
//****************************************
//
// OpenFileDialog::~OpenFileDialog
//
// Destructor. Release child resources.
//
//****************************************
OpenFileDialog::~OpenFileDialog()
{
} // OpenFileDialog::~OpenFileDialog
GenFrame::GenFrame( )
: wxFrame( (wxFrame*) NULL,
-1,
L"Test Driver",
wxPoint(50, 50),
wxSize(500, 500) )
{
// allocate and initialize the open file dialog
OpenFileDialog * openFileDialog = new OpenFileDialog(this);
if (openFileDialog->ShowModal() == wxID_OK){
wxString fileName = openFileDialog->GetPath();
}
} // GenFrame::GenFrame
GenFrame::~GenFrame()
{
} // GenFrame::~GenFrame
IMPLEMENT_APP(GenTool)
//****************************************
//
// GenTool::OnInit
//
// Method called when GUI initialization complete.
//
//****************************************
bool GenTool::OnInit()
{
// create an instance of the main window
GenFrame *frame = new GenFrame();
// display the window as the top window for this application
std::cerr << "frame->Show(TRUE);\n";
frame->Show(TRUE);
SetTopWindow(frame);
// continue in the event loop
return TRUE;
}
Code: Select all
[Session started at 2009-06-17 20:31:25 -0400.]
std::getenv("HOME")=/Users/mmg
start: GetDirectory()=/Users/mmg, GetFilename()=0x152a9c
start: GetWildcard()=GEDCOM files (*.ged)|*.ged;*.GED
SetDirectory(/Users/mmg)
lastFn=/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree/Cobban.GED
endDir=71, length=82
SetDirectory(/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree)
SetFilename(Cobban.GED)
last: GetDirectory()=/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree, GetFilename()=Cobban.GED
return: GetDirectory()=/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree, GetFilename()=Cobban.GED
frame->Show(TRUE);
The Debugger has exited with status 0.
"Keyboard not detected. Press F1 to continue"
-- Windows
-- Windows
-
- Knows some wx things
- Posts: 30
- Joined: Sun Feb 01, 2009 12:38 am
I apologize. I should have attached the two files rather than trying to imbed them in the posting. The functionality of theAuria wrote:Hmm not sure what's up with your quotes ("), they're all messed up
Code: Select all
tag seems to unescape escaped quotes when it displays the code.
[quote="Auria"]
And got the following output :
[code]
[Session started at 2009-06-17 20:31:25 -0400.]
std::getenv("HOME")=/Users/mmg
start: GetDirectory()=/Users/mmg, GetFilename()=0x152a9c
start: GetWildcard()=GEDCOM files (*.ged)|*.ged;*.GED
SetDirectory(/Users/mmg)
lastFn=/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree/Cobban.GED
endDir=71, length=82
SetDirectory(/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree)
SetFilename(Cobban.GED)
last: GetDirectory()=/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree, GetFilename()=Cobban.GED
return: GetDirectory()=/media/disk-1/Documents and Settings/Jim Cobban/My Documents/FamilyTree, GetFilename()=Cobban.GED
frame->Show(TRUE);
The Debugger has exited with status 0.
So if it works on your system, why doesn't it work on mine? I have the latest stable version of wxWidgets, I just downloaded it last week. I am running Ubuntu 9.04 with Gtk 2.
-
- Knows some wx things
- Posts: 30
- Joined: Sun Feb 01, 2009 12:38 am
doublemax wrote:GetFilename() and SetFilename() are simple getters and setters, i just can't think of anything going wrong there.
I noticed that the "correct" output is given when you print a string directly, but not when you use the return value from a method.
I suspect it's just a display problem with std::
Could you test this code please:Code: Select all
wxString dftDir = ::wxGetHomeDir(); std::wcerr << "dftDir="" << dftDir.c_str() << ""\n"; std::wcerr << "wxGetHomeDir()="" << ::wxGetHomeDir().c_str() << ""\n"; [/quote] I don't understand your point. I believe that the fact that stream insertion is not well supported by wxWidgets is irrelevant. In my example code some attributes of wxFileDialog are initialized using string literals, and when I print the result of calling the GetXxx method for those attributes I get the value which I specified when I issued SetXxx. But if I call the SetXxx method with an instance of wxString, and then print the result of GetXxxx I get the default value for the attribute, and the behavior of the dialog is consistent with the values of the attributes as displayed by GetXxxx. I don't want to use the wxLog methods because they are not type safe. That is why the stream inserters were added to C++ in the first place. I consider it a bug that in the Unicode version of wxWidgets inserting a wxString into an output stream displays an address in hex, whereas in the Ansi version the string value of the wxString is displayed. That is I only have to call the c_str() method before inserting into a stream in the Unicode version (although it is safe to call it in both cases).
Hi,
Auria's code failed for me, using wxGTK-2.8.10. That's because of what seems to be a bug in (the wxGTK) wxFileDialog::SetFilename, which asserts if you pass it a filepath; but gtk requires one, and if you pass a filename gtk asserts and doesn't properly create the dialog. I'll look into this.
If I pass a valid filepath (and ignore the assert), std::wcerr << "return: GetDirectory()=" gives the correct output, though the GetFilename() doesn't, of course. However for you, neither works. Are you getting a gtk assert? (Are you using a wx debug build?)
I wonder if some of the problem is going to be a version of the transient buffer problem described in http://wiki.wxwidgets.org/WxString#Conv ... mal_String. The race condition that this causes would explain why the code works for other people.
Regards,
David
Auria's code failed for me, using wxGTK-2.8.10. That's because of what seems to be a bug in (the wxGTK) wxFileDialog::SetFilename, which asserts if you pass it a filepath; but gtk requires one, and if you pass a filename gtk asserts and doesn't properly create the dialog. I'll look into this.
If I pass a valid filepath (and ignore the assert), std::wcerr << "return: GetDirectory()=" gives the correct output, though the GetFilename() doesn't, of course. However for you, neither works. Are you getting a gtk assert? (Are you using a wx debug build?)
I wonder if some of the problem is going to be a version of the transient buffer problem described in http://wiki.wxwidgets.org/WxString#Conv ... mal_String. The race condition that this causes would explain why the code works for other people.
Regards,
David
-
- Knows some wx things
- Posts: 30
- Joined: Sun Feb 01, 2009 12:38 am
I figured I would need to get around to this, so I just rebuilt wxWidgets with ../configure --with-gtk --enable-unicode --enable-debug --enable-debug_gdb.DavidHart wrote:Hi,
Auria's code failed for me, using wxGTK-2.8.10. That's because of what seems to be a bug in (the wxGTK) wxFileDialog::SetFilename, which asserts if you pass it a filepath; but gtk requires one, and if you pass a filename gtk asserts and doesn't properly create the dialog. I'll look into this.
If I pass a valid filepath (and ignore the assert), std::wcerr << "return: GetDirectory()=" gives the correct output, though the GetFilename() doesn't, of course. However for you, neither works. Are you getting a gtk assert? (Are you using a wx debug build?)
Regards,
David
I recompiled and rebuilt my programs. Now when I try to run (or gdb) the program I get "/home/jcobban/workspace/DebugWxFileDialog/Debug/DebugWxFileDialog: error while loading shared libraries: libwx_gtk2ud_richtext-2.8.so.0: cannot open shared object file: No such file or directory"
I haven't even put a richtext widget in the app (although I will once I get past this problem with the file dialog).
It's a *buntu speciality. See http://forums.wxwidgets.org/viewtopic.php?t=11734 (and, if you want a thorough explanation, http://www.dwheeler.com/program-library ... O/x36.html).
It seems to be random which lib gets mentioned in the error message.I haven't even put a richtext widget in the app
-
- Knows some wx things
- Posts: 30
- Joined: Sun Feb 01, 2009 12:38 am
Silly me, I forgot to run ldconfig after make install.DavidHart wrote:It's a *buntu speciality. See http://forums.wxwidgets.org/viewtopic.php?t=11734 (and, if you want a thorough explanation, http://www.dwheeler.com/program-library ... O/x36.html).
-
- Knows some wx things
- Posts: 30
- Joined: Sun Feb 01, 2009 12:38 am
I have rebuilt wxWindows with debug and tried running the program. Tracing the logic I cannot see what is going wrong. It seems to be calling the right methods in Gtk, but it just isn't working. I don't see any asserts.DavidHart wrote:Hi,
If I pass a valid filepath (and ignore the assert), std::wcerr << "return: GetDirectory()=" gives the correct output, though the GetFilename() doesn't, of course. However for you, neither works. Are you getting a gtk assert? (Are you using a wx debug build?)
For example the constructor wxFileDialog::wxFileDialog follows the execution path that I would expect because I have put a non-empty string for the default directory and an empty string for the file name in the constructor. I see the constructor execute the following statements:
Code: Select all
wxFileName fn;
fn.AssignDir(defaultDir);
const wxString dir = fn.GetPath();
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(m_widget),
dir.fn_str());
Coming back with an old comment I made that you didn't seem to appreciate
What if you test with a path that is not outside the linux filesystem? It may well be that gtk_file_chooser_set_current_folder doesn't like foreign filesystems.
In any case, GTK+ docs (http://library.gnome.org/devel/gtk/unst ... ent-folder) mention that this method returns a boolean, maybe check it

In any case, GTK+ docs (http://library.gnome.org/devel/gtk/unst ... ent-folder) mention that this method returns a boolean, maybe check it
"Keyboard not detected. Press F1 to continue"
-- Windows
-- Windows
OK, see http://trac.wxwidgets.org/ticket/10917
James, as you can see, the wxGTK wxFileDialog getters/setters are buggy; so it wasn't an output problem, just that the getters were returning "".
wxMSW and wxMac use the generic dialog, which doesn't have this problem.
James, as you can see, the wxGTK wxFileDialog getters/setters are buggy; so it wasn't an output problem, just that the getters were returning "".
wxMSW and wxMac use the generic dialog, which doesn't have this problem.
-
- Knows some wx things
- Posts: 30
- Joined: Sun Feb 01, 2009 12:38 am
Thanks for investigating this. I have only just started on using wxWidgets, so what is the procedure for applying your fix to my copy of the source?DavidHart wrote:OK, see http://trac.wxwidgets.org/ticket/10917
James, as you can see, the wxGTK wxFileDialog getters/setters are buggy; so it wasn't an output problem, just that the getters were returning "".
wxMSW and wxMac use the generic dialog, which doesn't have this problem.
Take a look at 'man patch', or google for how to apply a patch
e.g. http://www.linuxhq.com/patch-howto.html

"Keyboard not detected. Press F1 to continue"
-- Windows
-- Windows