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