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