1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxDialog class 
   8 // Copyright:   (c) AUTHOR 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "dialog.h" 
  16 #include "wx/dialog.h" 
  20 #include "wx/settings.h" 
  22 #include "wx/mac/uma.h" 
  24 // Lists to keep track of windows, so we can disable/enable them 
  26 wxList wxModalDialogs
; 
  27 //wxList wxModelessWindows;  // Frames and modeless dialogs 
  28 extern wxList wxPendingDelete
; 
  30 #if !USE_SHARED_LIBRARY 
  31 IMPLEMENT_DYNAMIC_CLASS(wxDialog
, wxTopLevelWindow
) 
  33 BEGIN_EVENT_TABLE(wxDialog
, wxDialogBase
) 
  34   EVT_BUTTON(wxID_OK
, wxDialog::OnOK
) 
  35   EVT_BUTTON(wxID_APPLY
, wxDialog::OnApply
) 
  36   EVT_BUTTON(wxID_CANCEL
, wxDialog::OnCancel
) 
  38   EVT_CHAR_HOOK(wxDialog::OnCharHook
) 
  40   EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged
) 
  42   EVT_CLOSE(wxDialog::OnCloseWindow
) 
  50     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
  53 bool wxDialog::Create(wxWindow 
*parent
, wxWindowID id
, 
  54            const wxString
& title
, 
  61   SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
  64   if ( !wxTopLevelWindow::Create(parent
, id
, title
, pos
, size
, style
, name
) ) 
  67         MacCreateRealWindow( title 
, pos 
, size 
, MacRemoveBordersFromStyle(style
)  , name 
) ; 
  69         m_macWindowBackgroundTheme 
= kThemeBrushDialogBackgroundActive 
; 
  70         SetThemeWindowBackground( (WindowRef
) m_macWindow 
, m_macWindowBackgroundTheme 
, false ) ; 
  74 void wxDialog::SetModal(bool flag
) 
  78         m_windowStyle 
|= wxDIALOG_MODAL
; 
  80         wxModelessWindows
.DeleteObject(this); 
  84         m_windowStyle 
&= ~wxDIALOG_MODAL
; 
  86         wxModelessWindows
.Append(this); 
  92         m_isBeingDeleted 
= TRUE 
; 
  96 // By default, pressing escape cancels the dialog , on mac command-stop does the same thing 
  97 void wxDialog::OnCharHook(wxKeyEvent
& event
) 
 100     ( event
.m_keyCode 
== WXK_ESCAPE 
||  
 101       ( event
.m_keyCode 
== '.' && event
.MetaDown() ) ) 
 102      && FindWindow(wxID_CANCEL
) ) 
 104                 // Behaviour changed in 2.0: we'll send a Cancel message 
 105                 // to the dialog instead of Close. 
 106                 wxCommandEvent 
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
); 
 107                 cancelEvent
.SetEventObject( this ); 
 108                 GetEventHandler()->ProcessEvent(cancelEvent
); 
 112   // We didn't process this event. 
 116 bool wxDialog::IsModal() const 
 118     return (GetWindowStyleFlag() & wxDIALOG_MODAL
) != 0; 
 122 bool wxDialog::IsModalShowing() const 
 124     return wxModalDialogs
.Find((wxDialog 
*)this) != NULL
; // const_cast 
 127 extern bool s_macIsInModalLoop 
; 
 129 bool wxDialog::Show(bool show
) 
 131     if ( !wxDialogBase::Show(show
) ) 
 139         // usually will result in TransferDataToWindow() being called 
 149         else // end of modal dialog 
 151             // this will cause IsModalShowing() return FALSE and our local 
 152             // message loop will terminate 
 153             wxModalDialogs
.DeleteObject(this); 
 160 void wxDialog::DoShowModal() 
 162     wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") ); 
 164     wxModalDialogs
.Append(this); 
 166         wxWindow 
*parent 
= GetParent(); 
 168     // remember where the focus was 
 169     wxWindow 
*winFocus 
= FindFocus(); 
 176         winFocus 
= wxTheApp
->GetTopWindow(); 
 178         // TODO : test whether parent gets disabled 
 180         bool formerModal 
= s_macIsInModalLoop 
; 
 181         s_macIsInModalLoop 
= true ; 
 183         while ( IsModalShowing() ) 
 185                 while ( !wxTheApp
->Pending() && wxTheApp
->ProcessIdle() ) 
 188                 wxTheApp
->MacDoOneEvent() ; 
 191         s_macIsInModalLoop 
= formerModal 
; 
 193     // TODO probably reenable the parent window if any 
 198         winFocus
->SetFocus(); 
 203 // Replacement for Show(TRUE) for modal dialogs - returns return code 
 204 int wxDialog::ShowModal() 
 206   m_windowStyle 
|= wxDIALOG_MODAL
; 
 208   return GetReturnCode(); 
 211 // NB: this function (surprizingly) may be called for both modal and modeless 
 212 //     dialogs and should work for both of them 
 213 void wxDialog::EndModal(int retCode
) 
 215   SetReturnCode(retCode
); 
 220 void wxDialog::OnOK(wxCommandEvent
& event
) 
 222   if ( Validate() && TransferDataFromWindow() ) 
 228 void wxDialog::OnApply(wxCommandEvent
& event
) 
 231     TransferDataFromWindow(); 
 232   // TODO probably need to disable the Apply button until things change again 
 235 void wxDialog::OnCancel(wxCommandEvent
& event
) 
 237         EndModal(wxID_CANCEL
); 
 240 void wxDialog::OnCloseWindow(wxCloseEvent
& event
) 
 242     // We'll send a Cancel message by default, 
 243     // which may close the dialog. 
 244     // Check for looping if the Cancel event handler calls Close(). 
 246     // Note that if a cancel button and handler aren't present in the dialog, 
 247     // nothing will happen when you close the dialog via the window manager, or 
 249     // We wouldn't want to destroy the dialog by default, since the dialog may have been 
 250     // created on the stack. 
 251     // However, this does mean that calling dialog->Close() won't delete the dialog 
 252     // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be 
 253     // sure to destroy the dialog. 
 254     // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog. 
 256     static wxList closing
; 
 258     if ( closing
.Member(this) ) 
 261     closing
.Append(this); 
 263     wxCommandEvent 
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
); 
 264     cancelEvent
.SetEventObject( this ); 
 265     GetEventHandler()->ProcessEvent(cancelEvent
); // This may close the dialog 
 267     closing
.DeleteObject(this); 
 270 void wxDialog::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 272   SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
));