1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxDialog class 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:       wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  14 #include "wx/dialog.h" 
  18 #include "wx/settings.h" 
  20 #include "wx/mac/uma.h" 
  22 // Lists to keep track of windows, so we can disable/enable them 
  24 wxList wxModalDialogs
; 
  25 //wxList wxModelessWindows;  // Frames and modeless dialogs 
  26 extern wxList wxPendingDelete
; 
  28 IMPLEMENT_DYNAMIC_CLASS(wxDialog
, wxTopLevelWindow
) 
  30 BEGIN_EVENT_TABLE(wxDialog
, wxDialogBase
) 
  31   EVT_BUTTON(wxID_OK
, wxDialog::OnOK
) 
  32   EVT_BUTTON(wxID_APPLY
, wxDialog::OnApply
) 
  33   EVT_BUTTON(wxID_CANCEL
, wxDialog::OnCancel
) 
  35   EVT_CHAR_HOOK(wxDialog::OnCharHook
) 
  37   EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged
) 
  39   EVT_CLOSE(wxDialog::OnCloseWindow
) 
  44     m_isModalStyle 
= false; 
  47 bool wxDialog::Create(wxWindow 
*parent
, wxWindowID id
, 
  48            const wxString
& title
, 
  54     SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG
); 
  56     // All dialogs should really have this style 
  57     style 
|= wxTAB_TRAVERSAL
; 
  59     if ( !wxTopLevelWindow::Create(parent
, id
, title
, pos
, size
, style 
& ~(wxYES
|wxOK
|wxNO 
/*|wxCANCEL*/) , name
) ) 
  65 void wxDialog::SetModal(bool flag
) 
  69         m_isModalStyle 
= true; 
  71         wxModelessWindows
.DeleteObject(this); 
  73         SetWindowModality( (WindowRef
) MacGetWindowRef() , kWindowModalityAppModal 
, NULL 
) ; 
  78         m_isModalStyle 
= false; 
  80         wxModelessWindows
.Append(this); 
  86     m_isBeingDeleted 
= true; 
  90 // By default, pressing escape cancels the dialog; on mac command-stop does the same thing 
  91 void wxDialog::OnCharHook(wxKeyEvent
& event
) 
  93     if (( event
.m_keyCode 
== WXK_ESCAPE 
|| 
  94         ( event
.m_keyCode 
== '.' && event
.MetaDown() ) ) 
  95         && FindWindow(wxID_CANCEL
) ) 
  97         // Behaviour changed in 2.0: we'll send a Cancel message 
  98         // to the dialog instead of Close. 
  99         wxCommandEvent 
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
); 
 100         cancelEvent
.SetEventObject( this ); 
 101         GetEventHandler()->ProcessEvent(cancelEvent
); 
 105     // We didn't process this event. 
 109 bool wxDialog::IsModal() const 
 111     return wxModalDialogs
.Find((wxDialog 
*)this) != NULL
; // const_cast 
 112     //    return m_isModalStyle; 
 116 bool wxDialog::IsModalShowing() const 
 118     return wxModalDialogs
.Find((wxDialog 
*)this) != NULL
; // const_cast 
 121 bool wxDialog::Show(bool show
) 
 123     if ( !wxDialogBase::Show(show
) ) 
 131         // usually will result in TransferDataToWindow() being called 
 135     if ( m_isModalStyle 
) 
 141         else // end of modal dialog 
 143             // this will cause IsModalShowing() return false and our local 
 144             // message loop will terminate 
 145             wxModalDialogs
.DeleteObject(this); 
 153 extern bool s_macIsInModalLoop 
; 
 156 void wxDialog::DoShowModal() 
 158     wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") ); 
 160     wxModalDialogs
.Append(this); 
 165     BeginAppModalStateForWindow(  (WindowRef
) MacGetWindowRef()) ; 
 167     // TODO : test whether parent gets disabled 
 168     bool formerModal 
= s_macIsInModalLoop 
; 
 169     s_macIsInModalLoop 
= true ; 
 171     while ( IsModalShowing() ) 
 173         wxTheApp
->MacDoOneEvent() ; 
 174         // calls process idle itself 
 178     EndAppModalStateForWindow( (WindowRef
) MacGetWindowRef() ) ; 
 180     // TODO probably reenable the parent window if any 
 181     s_macIsInModalLoop 
= formerModal 
; 
 186 // Replacement for Show(true) for modal dialogs - returns return code 
 187 int wxDialog::ShowModal() 
 189     if ( !m_isModalStyle 
) 
 193     return GetReturnCode(); 
 196 // NB: this function (surprizingly) may be called for both modal and modeless 
 197 //     dialogs and should work for both of them 
 198 void wxDialog::EndModal(int retCode
) 
 200     SetReturnCode(retCode
); 
 206 void wxDialog::OnOK(wxCommandEvent
& WXUNUSED(event
)) 
 208   if ( Validate() && TransferDataFromWindow() ) 
 212 void wxDialog::OnApply(wxCommandEvent
& WXUNUSED(event
)) 
 215       TransferDataFromWindow(); 
 217   // TODO probably need to disable the Apply button until things change again 
 220 void wxDialog::OnCancel(wxCommandEvent
& WXUNUSED(event
)) 
 222     EndModal(wxID_CANCEL
); 
 225 void wxDialog::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
)) 
 227     // We'll send a Cancel message by default, 
 228     // which may close the dialog. 
 229     // Check for looping if the Cancel event handler calls Close(). 
 231     // Note that if a cancel button and handler aren't present in the dialog, 
 232     // nothing will happen when you close the dialog via the window manager, or 
 234     // We wouldn't want to destroy the dialog by default, since the dialog may have been 
 235     // created on the stack. 
 236     // However, this does mean that calling dialog->Close() won't delete the dialog 
 237     // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be 
 238     // sure to destroy the dialog. 
 239     // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog. 
 241     static wxList closing
; 
 243     if ( closing
.Member(this) ) 
 246     closing
.Append(this); 
 248     wxCommandEvent 
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
); 
 249     cancelEvent
.SetEventObject( this ); 
 250     GetEventHandler()->ProcessEvent(cancelEvent
); // This may close the dialog 
 252     closing
.DeleteObject(this); 
 255 void wxDialog::OnSysColourChanged(wxSysColourChangedEvent
& WXUNUSED(event
)) 
 257   SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
));