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
, wxTopLevelWindow
) 
  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::GetSystemColour(wxSYS_COLOUR_3DFACE
)); 
  53 bool wxDialog::Create(wxWindow 
*parent
, wxWindowID id
, 
  54            const wxString
& title
, 
  61   SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
)); 
  64   if ( !wxTopLevelWindow::Create(parent
, id
, title
, pos
, size
, style
, name
) ) 
  67         MacCreateRealWindow( title 
, pos 
, size 
, MacRemoveBordersFromStyle(style
)  , name 
) ; 
  69         m_macWindowData
->m_macWindowBackgroundTheme 
= kThemeBrushDialogBackgroundActive 
; 
  73 void wxDialog::SetModal(bool flag
) 
  77         m_windowStyle 
|= wxDIALOG_MODAL
; 
  79         wxModelessWindows
.DeleteObject(this); 
  83         m_windowStyle 
&= ~wxDIALOG_MODAL
; 
  85         wxModelessWindows
.Append(this); 
  91         m_isBeingDeleted 
= TRUE 
; 
  95 // By default, pressing escape cancels the dialog , on mac command-stop does the same thing 
  96 void wxDialog::OnCharHook(wxKeyEvent
& event
) 
  99     ( event
.m_keyCode 
== WXK_ESCAPE 
||  
 100       ( event
.m_keyCode 
== '.' && event
.MetaDown() ) ) 
 101      && FindWindow(wxID_CANCEL
) ) 
 103                 // Behaviour changed in 2.0: we'll send a Cancel message 
 104                 // to the dialog instead of Close. 
 105                 wxCommandEvent 
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
); 
 106                 cancelEvent
.SetEventObject( this ); 
 107                 GetEventHandler()->ProcessEvent(cancelEvent
); 
 111   // We didn't process this event. 
 115 bool wxDialog::IsModal() const 
 117     return (GetWindowStyleFlag() & wxDIALOG_MODAL
) != 0; 
 121 bool wxDialog::IsModalShowing() const 
 123     return wxModalDialogs
.Find((wxDialog 
*)this) != NULL
; // const_cast 
 126 extern bool s_macIsInModalLoop 
; 
 128 bool wxDialog::Show(bool show
) 
 130     if ( !wxDialogBase::Show(show
) ) 
 138         // usually will result in TransferDataToWindow() being called 
 148         else // end of modal dialog 
 150             // this will cause IsModalShowing() return FALSE and our local 
 151             // message loop will terminate 
 152             wxModalDialogs
.DeleteObject(this); 
 159 void wxDialog::DoShowModal() 
 161     wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") ); 
 163     wxModalDialogs
.Append(this); 
 165         wxWindow 
*parent 
= GetParent(); 
 167     // remember where the focus was 
 168     wxWindow 
*winFocus 
= FindFocus(); 
 175         winFocus 
= wxTheApp
->GetTopWindow(); 
 177         // TODO : test whether parent gets disabled 
 179         bool formerModal 
= s_macIsInModalLoop 
; 
 180         s_macIsInModalLoop 
= true ; 
 182         while ( IsModalShowing() ) 
 184                 while ( !wxTheApp
->Pending() && wxTheApp
->ProcessIdle() ) 
 187                 wxTheApp
->MacDoOneEvent() ; 
 190         s_macIsInModalLoop 
= formerModal 
; 
 192     // TODO probably reenable the parent window if any 
 197         winFocus
->SetFocus(); 
 202 // Replacement for Show(TRUE) for modal dialogs - returns return code 
 203 int wxDialog::ShowModal() 
 205   m_windowStyle 
|= wxDIALOG_MODAL
; 
 207   return GetReturnCode(); 
 210 // NB: this function (surprizingly) may be called for both modal and modeless 
 211 //     dialogs and should work for both of them 
 212 void wxDialog::EndModal(int retCode
) 
 214   SetReturnCode(retCode
); 
 219 void wxDialog::OnOK(wxCommandEvent
& event
) 
 221   if ( Validate() && TransferDataFromWindow() ) 
 227 void wxDialog::OnApply(wxCommandEvent
& event
) 
 230     TransferDataFromWindow(); 
 231   // TODO probably need to disable the Apply button until things change again 
 234 void wxDialog::OnCancel(wxCommandEvent
& event
) 
 236         EndModal(wxID_CANCEL
); 
 239 void wxDialog::OnCloseWindow(wxCloseEvent
& event
) 
 241     // We'll send a Cancel message by default, 
 242     // which may close the dialog. 
 243     // Check for looping if the Cancel event handler calls Close(). 
 245     // Note that if a cancel button and handler aren't present in the dialog, 
 246     // nothing will happen when you close the dialog via the window manager, or 
 248     // We wouldn't want to destroy the dialog by default, since the dialog may have been 
 249     // created on the stack. 
 250     // However, this does mean that calling dialog->Close() won't delete the dialog 
 251     // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be 
 252     // sure to destroy the dialog. 
 253     // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog. 
 255     static wxList closing
; 
 257     if ( closing
.Member(this) ) 
 260     closing
.Append(this); 
 262     wxCommandEvent 
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
); 
 263     cancelEvent
.SetEventObject( this ); 
 264     GetEventHandler()->ProcessEvent(cancelEvent
); // This may close the dialog 
 266     closing
.DeleteObject(this); 
 269 void wxDialog::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 271   SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));