Fix data transfer to wxFileDialogCustomizeHook in non-wxMSW ports
Calling TransferDataFromCustomControls() in custom panel destructor suffered from two fatal flaws: 1. It happened whether the dialog was accepted or cancelled, while we're only supposed to call this function when it's accepted. 2. It was done too late, when the customization hook itself could have been already destroyed, as it only has to live until ShowModal() returns but doesn't have (and typically doesn't) survive wxFileDialog itself. Fix this by adding TransferDataFromExtraControl() and calling it explicitly when, and only if, the dialog is accepted. This fixes accessing invalid stack memory (thanks ASAN!) under GTK and Mac and allows to remove the ugly workaround from wxMSW code, which can now also just call TransferDataFromExtraControl().
This commit is contained in:
parent
a68f8653d9
commit
a0ea9ba631
7 changed files with 21 additions and 29 deletions
|
|
@ -206,6 +206,9 @@ protected:
|
|||
// Helper function for native file dialog usage where no wx events
|
||||
// are processed.
|
||||
void UpdateExtraControlUI();
|
||||
// Helper function simply transferring data from custom controls if they
|
||||
// are used -- must be called if the dialog was accepted.
|
||||
void TransferDataFromExtraControl();
|
||||
|
||||
private:
|
||||
ExtraControlCreatorFunction m_extraControlCreator;
|
||||
|
|
|
|||
|
|
@ -617,7 +617,6 @@ public:
|
|||
Panel(wxWindow* parent, wxFileDialogCustomizeHook& customizeHook)
|
||||
: wxPanel(parent),
|
||||
wxFileDialogCustomize(this),
|
||||
m_customizeHook(customizeHook),
|
||||
m_lastWasRadio(false)
|
||||
{
|
||||
// Use a simple horizontal sizer to layout all the controls for now.
|
||||
|
|
@ -628,18 +627,13 @@ public:
|
|||
sizer->AddSpacer(wxSizerFlags::GetDefaultBorder());
|
||||
|
||||
// This will call our own AddXXX().
|
||||
m_customizeHook.AddCustomControls(*this);
|
||||
customizeHook.AddCustomControls(*this);
|
||||
|
||||
// Now that everything was created, resize and layout.
|
||||
SetClientSize(sizer->ComputeFittingClientSize(this));
|
||||
sizer->Layout();
|
||||
}
|
||||
|
||||
virtual ~Panel()
|
||||
{
|
||||
m_customizeHook.TransferDataFromCustomControls();
|
||||
}
|
||||
|
||||
|
||||
// Implement wxFileDialogCustomizeImpl pure virtual methods.
|
||||
wxFileDialogButtonImpl* AddButton(const wxString& label) wxOVERRIDE
|
||||
|
|
@ -720,8 +714,6 @@ private:
|
|||
}
|
||||
|
||||
|
||||
wxFileDialogCustomizeHook& m_customizeHook;
|
||||
|
||||
bool m_lastWasRadio;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(Panel);
|
||||
|
|
@ -921,6 +913,12 @@ void wxFileDialogBase::UpdateExtraControlUI()
|
|||
m_extraControl->UpdateWindowUI(wxUPDATE_UI_RECURSE);
|
||||
}
|
||||
|
||||
void wxFileDialogBase::TransferDataFromExtraControl()
|
||||
{
|
||||
if ( m_customizeHook )
|
||||
m_customizeHook->TransferDataFromCustomControls();
|
||||
}
|
||||
|
||||
void wxFileDialogBase::SetPath(const wxString& path)
|
||||
{
|
||||
wxString ext;
|
||||
|
|
|
|||
|
|
@ -366,6 +366,8 @@ void wxGenericFileDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
|
|||
return;
|
||||
}
|
||||
|
||||
TransferDataFromExtraControl();
|
||||
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -370,6 +370,8 @@ void wxFileDialog::OnFakeOk(wxCommandEvent& WXUNUSED(event))
|
|||
str(gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(m_widget)));
|
||||
m_dir = wxString::FromUTF8(str);
|
||||
|
||||
TransferDataFromExtraControl();
|
||||
|
||||
EndDialog(wxID_OK);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -333,6 +333,8 @@ int wxFileDialog::ShowModal()
|
|||
|
||||
if (m_fileName.empty())
|
||||
return wxID_CANCEL;
|
||||
else
|
||||
return wxID_OK;
|
||||
|
||||
TransferDataFromExtraControl();
|
||||
|
||||
return wxID_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1144,24 +1144,7 @@ void wxFileDialog::MSWOnTypeChange(int nFilterIndex)
|
|||
|
||||
void wxFileDialog::MSWOnFileOK()
|
||||
{
|
||||
if ( m_customizeHook )
|
||||
{
|
||||
if ( m_extraControl )
|
||||
{
|
||||
// If we've created the old style extra controls even though we're
|
||||
// using the customize hook, we must delete them now, to ensure
|
||||
// that TransferDataFromCustomControls() called from the extra
|
||||
// controls panel destructor is called while the controls still
|
||||
// exist.
|
||||
DestroyExtraControl();
|
||||
}
|
||||
else // This is the normal case, when using IFileDialog.
|
||||
{
|
||||
// Just call TransferDataFromCustomControls() directly, it won't be
|
||||
// called from anywhere else.
|
||||
m_customizeHook->TransferDataFromCustomControls();
|
||||
}
|
||||
}
|
||||
TransferDataFromExtraControl();
|
||||
}
|
||||
|
||||
// helper used below in ShowCommFileDialog(): style is used to determine
|
||||
|
|
|
|||
|
|
@ -675,6 +675,8 @@ void wxFileDialog::ModalFinishedCallback(void* panel, int returnCode)
|
|||
m_filterIndex = m_filterChoice->GetSelection();
|
||||
else
|
||||
m_filterIndex = GetMatchingFilterExtension(m_fileName);
|
||||
|
||||
TransferDataFromExtraControl();
|
||||
}
|
||||
|
||||
SetReturnCode(wasAccepted ? wxID_OK : wxID_CANCEL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue