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