]> git.saurik.com Git - wxWidgets.git/blob - src/common/appcmn.cpp
extracted common initialization/cleanup functions in common/init.cpp; standardized...
[wxWidgets.git] / src / common / appcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/appcmn.cpp
3 // Purpose: wxAppConsole and wxAppBase methods common to all platforms
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 18.10.99
7 // RCS-ID: $Id$
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "appbase.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #if defined(__BORLANDC__)
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/intl.h"
34 #include "wx/list.h"
35 #include "wx/log.h"
36 #include "wx/msgdlg.h"
37 #endif
38
39 #include "wx/apptrait.h"
40 #if wxUSE_FONTMAP
41 #include "wx/fontmap.h"
42 #endif // wxUSE_FONTMAP
43 #include "wx/msgout.h"
44 #include "wx/thread.h"
45 #include "wx/utils.h"
46
47 // ============================================================================
48 // wxAppBase implementation
49 // ============================================================================
50
51 // ----------------------------------------------------------------------------
52 // initialization
53 // ----------------------------------------------------------------------------
54
55 wxAppBase::wxAppBase()
56 {
57 m_topWindow = (wxWindow *)NULL;
58 m_useBestVisual = FALSE;
59 m_isActive = TRUE;
60
61 // We don't want to exit the app if the user code shows a dialog from its
62 // OnInit() -- but this is what would happen if we set m_exitOnFrameDelete
63 // to Yes initially as this dialog would be the last top level window.
64 // OTOH, if we set it to No initially we'll have to overwrite it with Yes
65 // when we enter our OnRun() because we do want the default behaviour from
66 // then on. But this would be a problem if the user code calls
67 // SetExitOnFrameDelete(FALSE) from OnInit().
68 //
69 // So we use the special "Later" value which is such that
70 // GetExitOnFrameDelete() returns FALSE for it but which we know we can
71 // safely (i.e. without losing the effect of the users SetExitOnFrameDelete
72 // call) overwrite in OnRun()
73 m_exitOnFrameDelete = Later;
74 }
75
76 bool wxAppBase::Initialize(int argc, wxChar **argv)
77 {
78 if ( !wxAppConsole::Initialize(argc, argv) )
79 return false;
80
81 // for compatibility call the old initialization function too
82 if ( !OnInitGui() )
83 {
84 wxAppConsole::CleanUp();
85
86 return false;
87 }
88
89 #if wxUSE_THREADS
90 wxPendingEventsLocker = new wxCriticalSection;
91 #endif
92
93 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
94 wxTheColourDatabase->Initialize();
95
96 wxInitializeStockLists();
97 wxInitializeStockObjects();
98
99 wxBitmap::InitStandardHandlers();
100
101 return true;
102 }
103
104 // ----------------------------------------------------------------------------
105 // cleanup
106 // ----------------------------------------------------------------------------
107
108 wxAppBase::~wxAppBase()
109 {
110 // this destructor is required for Darwin
111 }
112
113 void wxAppBase::CleanUp()
114 {
115 // one last chance for pending objects to be cleaned up
116 DeletePendingObjects();
117
118 wxBitmap::CleanUpHandlers();
119
120 wxDeleteStockObjects();
121
122 wxDeleteStockLists();
123
124 delete wxTheColourDatabase;
125 wxTheColourDatabase = NULL;
126
127 #if wxUSE_THREADS
128 delete wxPendingEvents;
129 wxPendingEvents = NULL;
130
131 delete wxPendingEventsLocker;
132 wxPendingEventsLocker = NULL;
133
134 #if wxUSE_VALIDATORS
135 // If we don't do the following, we get an apparent memory leak.
136 ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
137 #endif // wxUSE_VALIDATORS
138 #endif // wxUSE_THREADS
139 }
140
141 // ----------------------------------------------------------------------------
142 // OnXXX() hooks
143 // ----------------------------------------------------------------------------
144
145 bool wxAppBase::OnInitGui()
146 {
147 #ifdef __WXUNIVERSAL__
148 if ( !wxTheme::Get() && !wxTheme::CreateDefault() )
149 return FALSE;
150 #endif // __WXUNIVERSAL__
151
152 return TRUE;
153 }
154
155 int wxAppBase::OnRun()
156 {
157 // see the comment in ctor: if the initial value hasn't been changed, use
158 // the default Yes from now on
159 if ( m_exitOnFrameDelete == Later )
160 {
161 m_exitOnFrameDelete = Yes;
162 }
163 //else: it has been changed, assume the user knows what he is doing
164
165 return MainLoop();
166 }
167
168 void wxAppBase::Exit()
169 {
170 ExitMainLoop();
171 }
172
173 wxAppTraits *wxAppBase::CreateTraits()
174 {
175 return wxAppTraits::CreateGUI();
176 }
177
178 // ----------------------------------------------------------------------------
179 // misc
180 // ----------------------------------------------------------------------------
181
182 void wxAppBase::SetActive(bool active, wxWindow * WXUNUSED(lastFocus))
183 {
184 if ( active == m_isActive )
185 return;
186
187 m_isActive = active;
188
189 wxActivateEvent event(wxEVT_ACTIVATE_APP, active);
190 event.SetEventObject(this);
191
192 (void)ProcessEvent(event);
193 }
194
195 void wxAppBase::DeletePendingObjects()
196 {
197 wxNode *node = wxPendingDelete.GetFirst();
198 while (node)
199 {
200 wxObject *obj = node->GetData();
201
202 delete obj;
203
204 if (wxPendingDelete.Member(obj))
205 delete node;
206
207 // Deleting one object may have deleted other pending
208 // objects, so start from beginning of list again.
209 node = wxPendingDelete.GetFirst();
210 }
211 }
212
213 // ----------------------------------------------------------------------------
214 // wxGUIAppTraitsBase
215 // ----------------------------------------------------------------------------
216
217 #if wxUSE_LOG
218
219 wxLog *wxGUIAppTraitsBase::CreateLogTarget()
220 {
221 return new wxLogGui;
222 }
223
224 #endif // wxUSE_LOG
225
226 wxMessageOutput *wxGUIAppTraitsBase::CreateMessageOutput()
227 {
228 // The standard way of printing help on command line arguments (app --help)
229 // is (according to common practice):
230 // - console apps: to stderr (on any platform)
231 // - GUI apps: stderr on Unix platforms (!)
232 // message box under Windows and others
233 #ifdef __UNIX__
234 return new wxMessageOutputStderr;
235 #else // !__UNIX__
236 // wxMessageOutputMessageBox doesn't work under Motif
237 #ifdef __WXMOTIF__
238 return new wxMessageOutputLog;
239 #else
240 return new wxMessageOutputMessageBox;
241 #endif
242 #endif // __UNIX__/!__UNIX__
243 }
244
245 #if wxUSE_FONTMAP
246
247 wxFontMapper *wxGUIAppTraitsBase::CreateFontMapper()
248 {
249 return new wxFontMapper;
250 }
251
252 #endif // wxUSE_FONTMAP
253
254 #ifdef __WXDEBUG__
255
256 bool wxGUIAppTraitsBase::ShowAssertDialog(const wxString& msg)
257 {
258 // under MSW we prefer to use the base class version using ::MessageBox()
259 // even if wxMessageBox() is available because it has less chances to
260 // double fault our app than our wxMessageBox()
261 #if defined(__WXMSW__) || !wxUSE_MSGDLG
262 return wxAppTraitsBase::ShowAssertDialog(msg);
263 #else // wxUSE_MSGDLG
264 // this message is intentionally not translated -- it is for
265 // developpers only
266 wxString msgDlg(msg);
267 msgDlg += wxT("\nDo you want to stop the program?\n")
268 wxT("You can also choose [Cancel] to suppress ")
269 wxT("further warnings.");
270
271 switch ( wxMessageBox(msgDlg, wxT("wxWindows Debug Alert"),
272 wxYES_NO | wxCANCEL | wxICON_STOP ) )
273 {
274 case wxYES:
275 wxTrap();
276 break;
277
278 case wxCANCEL:
279 // no more asserts
280 return true;
281
282 //case wxNO: nothing to do
283 }
284
285 return false;
286 #endif // !wxUSE_MSGDLG/wxUSE_MSGDLG
287 }
288
289 #endif // __WXDEBUG__
290
291 bool wxGUIAppTraitsBase::HasStderr()
292 {
293 // we consider that under Unix stderr always goes somewhere, even if the
294 // user doesn't always see it under GUI desktops
295 #ifdef __UNIX__
296 return true;
297 #else
298 return false;
299 #endif
300 }
301
302 void wxGUIAppTraitsBase::ScheduleForDestroy(wxObject *object)
303 {
304 if ( !wxPendingDelete.Member(object) )
305 wxPendingDelete.Append(object);
306 }
307
308 void wxGUIAppTraitsBase::RemoveFromPendingDelete(wxObject *object)
309 {
310 wxPendingDelete.DeleteObject(object);
311 }
312
313 // ----------------------------------------------------------------------------
314 // wxAppTraits
315 // ----------------------------------------------------------------------------
316
317 wxAppTraits *wxAppTraitsBase::CreateGUI()
318 {
319 return new wxGUIAppTraits;
320 }
321