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 // can be used as our parent or NULL if it can't
wxWindow *CheckIfCanBeUsedAsParent(wxWindow *parent) const; 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 // handle Esc key presses
void OnCharHook(wxKeyEvent& event); void OnCharHook(wxKeyEvent& event);

View File

@@ -377,6 +377,32 @@ bool wxDialogBase::EmulateButtonClickIfPresent(int id)
#endif // wxUSE_BUTTON/!wxUSE_BUTTON #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) bool wxDialogBase::IsEscapeKey(const wxKeyEvent& event)
{ {
// for most platforms, Esc key is used to close the dialogs // 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 ) if ( event.GetKeyCode() == WXK_ESCAPE )
{ {
int idCancel = GetEscapeId(); if ( SendCloseButtonClickEvent() )
switch ( idCancel )
{ {
case wxID_NONE: // Skip the call to event.Skip() below, we did handle this key.
// don't handle Esc specially at all return;
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;
} }
} }
@@ -480,23 +491,9 @@ wxDialogModality wxDialogBase::GetModality() const
void wxDialogBase::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) void wxDialogBase::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
{ {
// We'll send a Cancel message by default, which may close the dialog. // We'll send a Cancel message by default, which may close the dialog.
// Check for looping if the Cancel event handler calls Close(). // 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 // 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! // lists here? don't dare to change it now, but should be done later!
static wxList closing; static wxList closing;
@@ -506,9 +503,15 @@ void wxDialogBase::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
closing.Append(this); closing.Append(this);
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, idCancel); // Note that if a cancel button and handler aren't present in the dialog,
cancelEvent.SetEventObject( this ); // nothing will happen when you close the dialog via the window manager, or
GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog // 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); closing.DeleteObject(this);
} }