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