wxTOPLEVEL_EX_DIALOG is a better name than wxTLW_EX_DIALOG
[wxWidgets.git] / src / univ / dialog.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/dialog.cpp
3 // Author: Robert Roebling, Vaclav Slavik
4 // Id: $Id$
5 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 #ifdef __GNUG__
10 #pragma implementation "univdialog.h"
11 #endif
12
13 #include "wx/dialog.h"
14 #include "wx/utils.h"
15 #include "wx/evtloop.h"
16 #include "wx/app.h"
17
18 //-----------------------------------------------------------------------------
19 // wxDialog
20 //-----------------------------------------------------------------------------
21
22 BEGIN_EVENT_TABLE(wxDialog,wxDialogBase)
23 EVT_BUTTON (wxID_OK, wxDialog::OnOK)
24 EVT_BUTTON (wxID_CANCEL, wxDialog::OnCancel)
25 EVT_BUTTON (wxID_APPLY, wxDialog::OnApply)
26 EVT_CLOSE (wxDialog::OnCloseWindow)
27 END_EVENT_TABLE()
28
29 IMPLEMENT_DYNAMIC_CLASS(wxDialog,wxTopLevelWindow)
30
31 void wxDialog::Init()
32 {
33 m_returnCode = 0;
34 m_windowDisabler = NULL;
35 m_eventLoop = NULL;
36 m_isShowingModal = FALSE;
37 }
38
39 wxDialog::~wxDialog()
40 {
41 delete m_eventLoop;
42 }
43
44 bool wxDialog::Create(wxWindow *parent,
45 wxWindowID id, const wxString &title,
46 const wxPoint &pos, const wxSize &size,
47 long style, const wxString &name)
48 {
49 SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG);
50
51 // all dialogs should have tab traversal enabled
52 style |= wxTAB_TRAVERSAL;
53
54 return wxTopLevelWindow::Create(parent, id, title, pos, size, style, name);
55 }
56
57 void wxDialog::OnApply(wxCommandEvent &WXUNUSED(event))
58 {
59 if ( Validate() )
60 TransferDataFromWindow();
61 }
62
63 void wxDialog::OnCancel(wxCommandEvent &WXUNUSED(event))
64 {
65 if ( IsModal() )
66 {
67 EndModal(wxID_CANCEL);
68 }
69 else
70 {
71 SetReturnCode(wxID_CANCEL);
72 Show(FALSE);
73 }
74 }
75
76 void wxDialog::OnOK(wxCommandEvent &WXUNUSED(event))
77 {
78 if ( Validate() && TransferDataFromWindow() )
79 {
80 if ( IsModal() )
81 {
82 EndModal(wxID_OK);
83 }
84 else
85 {
86 SetReturnCode(wxID_OK);
87 Show(FALSE);
88 }
89 }
90 }
91
92 void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
93 {
94 // We'll send a Cancel message by default,
95 // which may close the dialog.
96 // Check for looping if the Cancel event handler calls Close().
97
98 // Note that if a cancel button and handler aren't present in the dialog,
99 // nothing will happen when you close the dialog via the window manager, or
100 // via Close().
101 // We wouldn't want to destroy the dialog by default, since the dialog may have been
102 // created on the stack.
103 // However, this does mean that calling dialog->Close() won't delete the dialog
104 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
105 // sure to destroy the dialog.
106 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
107
108 static wxList s_closing;
109
110 if (s_closing.Member(this))
111 return; // no loops
112
113 s_closing.Append(this);
114
115 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
116 cancelEvent.SetEventObject(this);
117 GetEventHandler()->ProcessEvent(cancelEvent);
118 s_closing.DeleteObject(this);
119 }
120
121 bool wxDialog::Show(bool show)
122 {
123 if ( !show )
124 {
125 // if we had disabled other app windows, reenable them back now because
126 // if they stay disabled Windows will activate another window (one
127 // which is enabled, anyhow) and we will lose activation
128 if ( m_windowDisabler )
129 {
130 delete m_windowDisabler;
131 m_windowDisabler = NULL;
132 }
133
134 if ( IsModal() )
135 EndModal(wxID_CANCEL);
136 }
137
138 bool ret = wxDialogBase::Show(show);
139
140 if ( show )
141 InitDialog();
142
143 return ret;
144 }
145
146 bool wxDialog::IsModal() const
147 {
148 return m_isShowingModal;
149 }
150
151 void wxDialog::SetModal(bool WXUNUSED(flag))
152 {
153 wxFAIL_MSG( wxT("wxDialog:SetModal obsolete now") );
154 }
155
156 int wxDialog::ShowModal()
157 {
158 if ( IsModal() )
159 {
160 wxFAIL_MSG( wxT("wxDialog:ShowModal called twice") );
161 return GetReturnCode();
162 }
163
164 // use the apps top level window as parent if none given unless explicitly
165 // forbidden
166 if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
167 {
168 wxWindow *parent = wxTheApp->GetTopWindow();
169 if ( parent && parent != this )
170 {
171 m_parent = parent;
172 }
173 }
174
175 wxBusyCursorSuspender cs; // temporarily suppress the busy cursor
176
177 Show(TRUE);
178
179 m_isShowingModal = TRUE;
180
181 wxASSERT_MSG( !m_windowDisabler, _T("disabling windows twice?") );
182
183 m_windowDisabler = new wxWindowDisabler(this);
184 if ( !m_eventLoop )
185 m_eventLoop = new wxEventLoop;
186
187 m_eventLoop->Run();
188
189 return GetReturnCode();
190 }
191
192 void wxDialog::EndModal(int retCode)
193 {
194 wxASSERT_MSG( m_eventLoop, _T("wxDialog is not modal") );
195
196 SetReturnCode(retCode);
197
198 if ( !IsModal() )
199 {
200 wxFAIL_MSG( wxT("wxDialog:EndModal called twice") );
201 return;
202 }
203
204 m_isShowingModal = FALSE;
205
206 m_eventLoop->Exit();
207
208 Show(FALSE);
209 }