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
, wxPanel
)
33 BEGIN_EVENT_TABLE(wxDialog
, wxPanel
)
34 EVT_SIZE(wxDialog::OnSize
)
35 EVT_BUTTON(wxID_OK
, wxDialog::OnOK
)
36 EVT_BUTTON(wxID_APPLY
, wxDialog::OnApply
)
37 EVT_BUTTON(wxID_CANCEL
, wxDialog::OnCancel
)
38 EVT_CHAR_HOOK(wxDialog::OnCharHook
)
39 EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged
)
40 EVT_CLOSE(wxDialog::OnCloseWindow
)
47 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));
50 bool wxDialog::Create(wxWindow
*parent
, wxWindowID id
,
51 const wxString
& title
,
57 m_windowStyle
= style
;
59 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));
63 wxTopLevelWindows
.Append(this);
65 if (parent
) parent
->AddChild(this);
68 m_windowId
= (int)NewControlId();
88 ::SetRect(&theBoundsRect
, m_x
, m_y
, m_x
+ m_width
, m_y
+ m_height
);
89 m_macWindowData
= new MacWindowData() ;
91 WindowClass wclass
= kMovableModalWindowClass
;
92 WindowAttributes attr
= kWindowNoAttributes
;
94 if ( ( m_windowStyle
& wxMINIMIZE_BOX
) || ( m_windowStyle
& wxMAXIMIZE_BOX
) )
96 attr
|= kWindowFullZoomAttribute
;
97 attr
|= kWindowResizableAttribute
;
100 UMACreateNewWindow( wclass
, attr
, &theBoundsRect
, &m_macWindowData
->m_macWindow
) ;
101 wxAssociateWinWithMacWindow( m_macWindowData
->m_macWindow
, this ) ;
103 if( wxApp::s_macDefaultEncodingIsPC
)
104 label
= wxMacMakeMacStringFromPC( title
) ;
107 UMASetWTitleC( m_macWindowData
->m_macWindow
, label
) ;
108 m_macWindowData
->m_macWindowBackgroundTheme
= kThemeBrushDialogBackgroundActive
;
109 UMACreateRootControl( m_macWindowData
->m_macWindow
, &m_macWindowData
->m_macRootControl
) ;
110 m_macWindowData
->m_macFocus
= NULL
;
115 void wxDialog::SetModal(bool flag
)
118 m_windowStyle
|= wxDIALOG_MODAL
;
120 if ( m_windowStyle
& wxDIALOG_MODAL
)
121 m_windowStyle
-= wxDIALOG_MODAL
;
123 wxModelessWindows
.DeleteObject(this);
125 wxModelessWindows
.Append(this);
128 wxDialog::~wxDialog()
130 wxTopLevelWindows
.DeleteObject(this);
132 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL
) != wxDIALOG_MODAL
)
133 wxModelessWindows
.DeleteObject(this);
135 // If this is the last top-level window, exit.
136 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
138 wxTheApp
->SetTopWindow(NULL
);
140 if (wxTheApp
->GetExitOnFrameDelete())
142 wxTheApp
->ExitMainLoop() ;
147 // By default, pressing escape cancels the dialog
148 void wxDialog::OnCharHook(wxKeyEvent
& event
)
150 if (event
.m_keyCode
== WXK_ESCAPE
)
152 // Behaviour changed in 2.0: we'll send a Cancel message
153 // to the dialog instead of Close.
154 wxCommandEvent
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
);
155 cancelEvent
.SetEventObject( this );
156 GetEventHandler()->ProcessEvent(cancelEvent
);
160 // We didn't process this event.
164 void wxDialog::Iconize(bool WXUNUSED(iconize
))
169 bool wxDialog::IsIconized() const
175 extern bool s_macIsInModalLoop
;
177 bool wxDialog::Show(bool show
)
179 if ( m_macShown
== show
)
184 bool modal
= ((GetWindowStyleFlag() & wxDIALOG_MODAL
) == wxDIALOG_MODAL
) ;
188 s_macIsInModalLoop
= true ;
191 // if we don't do it, some window might be deleted while we have pointers
192 // to them in our disabledWindows list and the program will crash when it
193 // will try to reenable them after the modal dialog end
194 wxTheApp
->DeletePendingObjects();
196 UMAShowWindow( m_macWindowData
->m_macWindow
) ;
197 UMASelectWindow( m_macWindowData
->m_macWindow
) ;
199 if (!wxModalDialogs
.Member(this))
200 wxModalDialogs
.Append(this);
202 while (wxModalDialogs
.Member(this) )
204 wxTheApp
->MacDoOneEvent() ;
209 wxModalDialogs
.DeleteObject(this);
210 UMAHideWindow( m_macWindowData
->m_macWindow
) ;
212 s_macIsInModalLoop
= false ;
218 UMAShowWindow( m_macWindowData
->m_macWindow
) ;
219 UMASelectWindow( m_macWindowData
->m_macWindow
) ;
223 UMAHideWindow( m_macWindowData
->m_macWindow
) ;
230 // Replacement for Show(TRUE) for modal dialogs - returns return code
231 int wxDialog::ShowModal()
233 m_windowStyle
|= wxDIALOG_MODAL
;
235 return GetReturnCode();
238 void wxDialog::EndModal(int retCode
)
240 SetReturnCode(retCode
);
241 // TODO modal un-showing
246 void wxDialog::OnOK(wxCommandEvent
& event
)
248 if ( Validate() && TransferDataFromWindow() )
254 SetReturnCode(wxID_OK
);
260 void wxDialog::OnApply(wxCommandEvent
& event
)
263 TransferDataFromWindow();
264 // TODO probably need to disable the Apply button until things change again
267 void wxDialog::OnCancel(wxCommandEvent
& event
)
270 EndModal(wxID_CANCEL
);
273 SetReturnCode(wxID_CANCEL
);
278 void wxDialog::OnCloseWindow(wxCloseEvent
& event
)
280 // We'll send a Cancel message by default,
281 // which may close the dialog.
282 // Check for looping if the Cancel event handler calls Close().
284 // Note that if a cancel button and handler aren't present in the dialog,
285 // nothing will happen when you close the dialog via the window manager, or
287 // We wouldn't want to destroy the dialog by default, since the dialog may have been
288 // created on the stack.
289 // However, this does mean that calling dialog->Close() won't delete the dialog
290 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
291 // sure to destroy the dialog.
292 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
294 static wxList closing
;
296 if ( closing
.Member(this) )
299 closing
.Append(this);
301 wxCommandEvent
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
);
302 cancelEvent
.SetEventObject( this );
303 GetEventHandler()->ProcessEvent(cancelEvent
); // This may close the dialog
305 closing
.DeleteObject(this);
308 // Destroy the window (delayed, if a managed window)
309 bool wxDialog::Destroy()
311 if (!wxPendingDelete
.Member(this))
312 wxPendingDelete
.Append(this);
316 void wxDialog::OnSize(wxSizeEvent
& WXUNUSED(event
))
318 // if we're using constraints - do use them
319 #if wxUSE_CONSTRAINTS
320 if ( GetAutoLayout() ) {
326 void wxDialog::OnSysColourChanged(wxSysColourChangedEvent
& event
)
328 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));
337 wxSizer
*wxDialog::CreateTextSizer( const wxString
&message
)
339 wxBoxSizer
*box
= new wxBoxSizer( wxVERTICAL
);
341 // get line height for empty lines
343 wxFont
new_font( GetFont() );
344 if (!new_font
.Ok()) new_font
= *wxSWISS_FONT
;
345 GetTextExtent( "H", (int*)NULL
, &y
, (int*)NULL
, (int*)NULL
, &new_font
);
348 for (size_t pos
= 0; pos
< message
.Len(); pos
++)
350 if (message
[pos
] == _T('\n'))
354 wxStaticText
*s1
= new wxStaticText( this, -1, line
);
365 line
+= message
[pos
];
369 // remaining text behind last '\n'
372 wxStaticText
*s2
= new wxStaticText( this, -1, line
);
379 wxSizer
*wxDialog::CreateButtonSizer( long flags
)
381 wxBoxSizer
*box
= new wxBoxSizer( wxHORIZONTAL
);
383 #if defined(__WXMSW__) || defined(__WXMAC__)
389 wxButton
*ok
= (wxButton
*) NULL
;
390 wxButton
*cancel
= (wxButton
*) NULL
;
391 wxButton
*yes
= (wxButton
*) NULL
;
392 wxButton
*no
= (wxButton
*) NULL
;
394 // always show an OK button, unless only YES_NO is given
395 if ((flags
& wxYES_NO
) == 0) flags
= flags
| wxOK
;
397 if (flags
& wxYES_NO
)
399 yes
= new wxButton( this, wxID_YES
, _("Yes") );
400 box
->Add( yes
, 0, wxLEFT
|wxRIGHT
, margin
);
401 no
= new wxButton( this, wxID_NO
, _("No") );
402 box
->Add( no
, 0, wxLEFT
|wxRIGHT
, margin
);
406 yes
= new wxButton( this, wxID_YES
, _("Yes") );
407 box
->Add( yes
, 0, wxLEFT
|wxRIGHT
, margin
);
411 no
= new wxButton( this, wxID_NO
, _("No") );
412 box
->Add( no
, 0, wxLEFT
|wxRIGHT
, margin
);
417 ok
= new wxButton( this, wxID_OK
, _("OK") );
418 box
->Add( ok
, 0, wxLEFT
|wxRIGHT
, margin
);
421 if (flags
& wxFORWARD
)
422 box
->Add( new wxButton( this, wxID_FORWARD
, _("Forward") ), 0, wxLEFT
|wxRIGHT
, margin
);
424 if (flags
& wxBACKWARD
)
425 box
->Add( new wxButton( this, wxID_BACKWARD
, _("Backward") ), 0, wxLEFT
|wxRIGHT
, margin
);
428 box
->Add( new wxButton( this, wxID_SETUP
, _("Setup") ), 0, wxLEFT
|wxRIGHT
, margin
);
431 box
->Add( new wxButton( this, wxID_MORE
, _("More...") ), 0, wxLEFT
|wxRIGHT
, margin
);
434 box
->Add( new wxButton( this, wxID_HELP
, _("Help") ), 0, wxLEFT
|wxRIGHT
, margin
);
436 if (flags
& wxCANCEL
)
438 cancel
= new wxButton( this, wxID_CANCEL
, _("Cancel") );
439 box
->Add( cancel
, 0, wxLEFT
|wxRIGHT
, margin
);
442 if ((flags
& wxNO_DEFAULT
) == 0)