Use the same logic for closing dialogs as for handling Escape key.

Pressing "Esc" key closed the dialog with only wxID_OK button (but no
wxID_CANCEL one) by default but pressing the "close window" button only closed
it if wxID_CANCEL was present.

Fix this by using the same code in OnCloseWindow() as in OnCharHook(), after
extracting it into the new SendCloseButtonClickEvent() method.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65488 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2010-09-09 20:53:26 +00:00
parent 0b94182cdc
commit 83a7613b71
2 changed files with 47 additions and 37 deletions

View File

@@ -249,6 +249,13 @@ private:
// can be used as our parent or NULL if it can't
wxWindow *CheckIfCanBeUsedAsParent(wxWindow *parent) const;
// Helper of OnCharHook() and OnCloseWindow(): find the appropriate button
// for closing the dialog and send a click event for it.
//
// Return true if we found a button to close the dialog and "clicked" it or
// false otherwise.
bool SendCloseButtonClickEvent();
// handle Esc key presses
void OnCharHook(wxKeyEvent& event);

View File

@@ -377,6 +377,32 @@ bool wxDialogBase::EmulateButtonClickIfPresent(int id)
#endif // wxUSE_BUTTON/!wxUSE_BUTTON
}
bool wxDialogBase::SendCloseButtonClickEvent()
{
int idCancel = GetEscapeId();
switch ( idCancel )
{
case wxID_NONE:
// The user doesn't want this dialog to close "implicitly".
break;
case wxID_ANY:
// this value is special: it means translate Esc to wxID_CANCEL
// but if there is no such button, then fall back to wxID_OK
if ( EmulateButtonClickIfPresent(wxID_CANCEL) )
return true;
idCancel = GetAffirmativeId();
// fall through
default:
// translate Esc to button press for the button with given id
if ( EmulateButtonClickIfPresent(idCancel) )
return true;
}
return false;
}
bool wxDialogBase::IsEscapeKey(const wxKeyEvent& event)
{
// for most platforms, Esc key is used to close the dialogs
@@ -388,25 +414,10 @@ void wxDialogBase::OnCharHook(wxKeyEvent& event)
{
if ( event.GetKeyCode() == WXK_ESCAPE )
{
int idCancel = GetEscapeId();
switch ( idCancel )
if ( SendCloseButtonClickEvent() )
{
case wxID_NONE:
// don't handle Esc specially at all
break;
case wxID_ANY:
// this value is special: it means translate Esc to wxID_CANCEL
// but if there is no such button, then fall back to wxID_OK
if ( EmulateButtonClickIfPresent(wxID_CANCEL) )
return;
idCancel = GetAffirmativeId();
// fall through
default:
// translate Esc to button press for the button with given id
if ( EmulateButtonClickIfPresent(idCancel) )
return;
// Skip the call to event.Skip() below, we did handle this key.
return;
}
}
@@ -480,23 +491,9 @@ wxDialogModality wxDialogBase::GetModality() const
void wxDialogBase::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
{
// We'll send a Cancel message by default, which may close the dialog.
// Check for looping if the Cancel event handler calls Close().
// Note that if a cancel button and handler aren't present in the dialog,
// nothing will happen when you close the dialog via the window manager, or
// via Close(). We wouldn't want to destroy the dialog by default, since
// the dialog may have been created on the stack. However, this does mean
// that calling dialog->Close() won't delete the dialog unless the handler
// for wxID_CANCEL does so. So use Destroy() if you want to be sure to
// destroy the dialog. The default OnCancel (above) simply ends a modal
// dialog, and hides a modeless dialog.
int idCancel = GetEscapeId();
if ( idCancel == wxID_NONE )
return;
if ( idCancel == wxID_ANY )
idCancel = wxID_CANCEL;
//
// VZ: this is horrible and MT-unsafe. Can't we reuse some of these global
// lists here? don't dare to change it now, but should be done later!
static wxList closing;
@@ -506,9 +503,15 @@ void wxDialogBase::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
closing.Append(this);
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, idCancel);
cancelEvent.SetEventObject( this );
GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
// Note that if a cancel button and handler aren't present in the dialog,
// nothing will happen when you close the dialog via the window manager, or
// via Close(). We wouldn't want to destroy the dialog by default, since
// the dialog may have been created on the stack. However, this does mean
// that calling dialog->Close() won't delete the dialog unless the handler
// for wxID_CANCEL does so. So use Destroy() if you want to be sure to
// destroy the dialog. The default OnCancel (above) simply ends a modal
// dialog, and hides a modeless dialog.
SendCloseButtonClickEvent();
closing.DeleteObject(this);
}