]> git.saurik.com Git - wxWidgets.git/blame - src/common/appcmn.cpp
fixed the menu bug introduced by the previous commit
[wxWidgets.git] / src / common / appcmn.cpp
CommitLineData
72cdf4c9
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/appcmn.cpp
3// Purpose: 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"
bf188f1a 33 #include "wx/intl.h"
e87271f3 34 #include "wx/list.h"
a5f1fd3e
VZ
35 #if wxUSE_GUI
36 #include "wx/msgdlg.h"
37 #endif // wxUSE_GUI
72cdf4c9
VZ
38#endif
39
bf188f1a 40#include "wx/cmdline.h"
72cdf4c9 41#include "wx/thread.h"
7beba2fc 42#include "wx/confbase.h"
697c5f51 43#include "wx/tokenzr.h"
bebc39e3 44#include "wx/utils.h"
536b70ac 45#include "wx/artprov.h"
e1ee679c 46
a5f1fd3e
VZ
47#if !defined(__WXMSW__) || defined(__WXMICROWIN__)
48 #include <signal.h> // for SIGTRAP used by wxTrap()
49#endif //Win/Unix
50
51#if defined(__WXMSW__)
52 #include "wx/msw/private.h" // includes windows.h for MessageBox()
53#endif
54
5128e3be
SC
55#if defined(__WXMAC__)
56 #include "wx/mac/private.h" // includes mac headers
57#endif
58
d54598dd
VZ
59// ===========================================================================
60// implementation
61// ===========================================================================
62
bf188f1a
VZ
63// ----------------------------------------------------------------------------
64// initialization and termination
65// ----------------------------------------------------------------------------
66
697c5f51
VS
67#ifdef __WXDEBUG__
68static void LINKAGEMODE SetTraceMasks()
69{
70 wxString mask;
71 if ( wxGetEnv(wxT("WXTRACE"), &mask) )
72 {
73 wxStringTokenizer tkn(mask, wxT(","));
74 while ( tkn.HasMoreTokens() )
75 wxLog::AddTraceMask(tkn.GetNextToken());
76 }
77}
78#endif
79
1e6feb95
VZ
80wxAppBase::wxAppBase()
81{
82 wxTheApp = (wxApp *)this;
83
73deed44 84#if WXWIN_COMPATIBILITY_2_2
1e6feb95 85 m_wantDebugOutput = FALSE;
73deed44 86#endif // WXWIN_COMPATIBILITY_2_2
1e6feb95
VZ
87
88#if wxUSE_GUI
89 m_topWindow = (wxWindow *)NULL;
90 m_useBestVisual = FALSE;
91 m_exitOnFrameDelete = TRUE;
92 m_isActive = TRUE;
93#endif // wxUSE_GUI
697c5f51
VS
94
95#ifdef __WXDEBUG__
96 SetTraceMasks();
97#endif
1e6feb95
VZ
98}
99
799ea011
GD
100wxAppBase::~wxAppBase()
101{
102 // this destructor is required for Darwin
103}
104
1e6feb95
VZ
105#if wxUSE_GUI
106bool wxAppBase::OnInitGui()
107{
108#ifdef __WXUNIVERSAL__
bf188f1a 109 if ( !wxTheme::Get() && !wxTheme::CreateDefault() )
1e6feb95 110 return FALSE;
536b70ac
VS
111 wxArtProvider *art = wxTheme::Get()->GetArtProvider();
112 if ( art )
113 wxArtProvider::PushProvider(art);
1e6feb95
VZ
114#endif // __WXUNIVERSAL__
115
116 return TRUE;
117}
118#endif // wxUSE_GUI
119
120int wxAppBase::OnExit()
121{
122#if wxUSE_CONFIG
123 // delete the config object if any (don't use Get() here, but Set()
124 // because Get() could create a new config object)
125 delete wxConfigBase::Set((wxConfigBase *) NULL);
126#endif // wxUSE_CONFIG
127
128#ifdef __WXUNIVERSAL__
129 delete wxTheme::Set(NULL);
130#endif // __WXUNIVERSAL__
131
132 return 0;
133}
134
72cdf4c9
VZ
135// ---------------------------------------------------------------------------
136// wxAppBase
137// ----------------------------------------------------------------------------
138
139void wxAppBase::ProcessPendingEvents()
140{
141 // ensure that we're the only thread to modify the pending events list
16c1f79c 142 wxENTER_CRIT_SECT( *wxPendingEventsLocker );
72cdf4c9
VZ
143
144 if ( !wxPendingEvents )
16c1f79c
RR
145 {
146 wxLEAVE_CRIT_SECT( *wxPendingEventsLocker );
72cdf4c9 147 return;
16c1f79c 148 }
72cdf4c9
VZ
149
150 // iterate until the list becomes empty
151 wxNode *node = wxPendingEvents->First();
152 while (node)
153 {
154 wxEvtHandler *handler = (wxEvtHandler *)node->Data();
16c1f79c 155 delete node;
72cdf4c9 156
16c1f79c 157 // In ProcessPendingEvents(), new handlers might be add
1d910ac1 158 // and we can safely leave the critical section here.
16c1f79c 159 wxLEAVE_CRIT_SECT( *wxPendingEventsLocker );
72cdf4c9 160 handler->ProcessPendingEvents();
16c1f79c 161 wxENTER_CRIT_SECT( *wxPendingEventsLocker );
72cdf4c9 162
72cdf4c9
VZ
163 node = wxPendingEvents->First();
164 }
1d910ac1 165
16c1f79c 166 wxLEAVE_CRIT_SECT( *wxPendingEventsLocker );
72cdf4c9
VZ
167}
168
1e6feb95
VZ
169// ----------------------------------------------------------------------------
170// misc
171// ----------------------------------------------------------------------------
172
173#if wxUSE_GUI
174
6e169cf3 175void wxAppBase::SetActive(bool active, wxWindow * WXUNUSED(lastFocus))
7beba2fc 176{
66dfed9b
VZ
177 if ( active == m_isActive )
178 return;
179
1e6feb95 180 m_isActive = active;
66dfed9b
VZ
181
182 wxActivateEvent event(wxEVT_ACTIVATE_APP, active);
183 event.SetEventObject(this);
184
185 (void)ProcessEvent(event);
7beba2fc 186}
1e6feb95
VZ
187
188#endif // wxUSE_GUI
bf188f1a
VZ
189
190// ----------------------------------------------------------------------------
191// cmd line parsing
192// ----------------------------------------------------------------------------
193
194bool wxAppBase::OnInit()
195{
196#if wxUSE_CMDLINE_PARSER
197 wxCmdLineParser parser(argc, argv);
198
199 OnInitCmdLine(parser);
200
201 bool cont;
be03c0ec 202 switch ( parser.Parse(FALSE /* don't show usage */) )
bf188f1a
VZ
203 {
204 case -1:
205 cont = OnCmdLineHelp(parser);
206 break;
207
208 case 0:
209 cont = OnCmdLineParsed(parser);
210 break;
211
212 default:
213 cont = OnCmdLineError(parser);
214 break;
215 }
216
217 if ( !cont )
218 return FALSE;
219#endif // wxUSE_CMDLINE_PARSER
220
221 return TRUE;
222}
223
224#if wxUSE_CMDLINE_PARSER
225
226#define OPTION_VERBOSE _T("verbose")
227#define OPTION_THEME _T("theme")
c358c660 228#define OPTION_MODE _T("mode")
bf188f1a
VZ
229
230void wxAppBase::OnInitCmdLine(wxCmdLineParser& parser)
231{
232 // the standard command line options
233 static const wxCmdLineEntryDesc cmdLineDesc[] =
234 {
235 {
236 wxCMD_LINE_SWITCH,
237 _T("h"),
238 _T("help"),
239 gettext_noop("show this help message"),
240 wxCMD_LINE_VAL_NONE,
241 wxCMD_LINE_OPTION_HELP
242 },
243
244#if wxUSE_LOG
245 {
246 wxCMD_LINE_SWITCH,
247 _T(""),
248 OPTION_VERBOSE,
249 gettext_noop("generate verbose log messages")
250 },
0f02d3d0 251#endif // wxUSE_LOG
bf188f1a
VZ
252
253#ifdef __WXUNIVERSAL__
254 {
255 wxCMD_LINE_OPTION,
256 _T(""),
257 OPTION_THEME,
258 gettext_noop("specify the theme to use"),
259 wxCMD_LINE_VAL_STRING
260 },
261#endif // __WXUNIVERSAL__
262
c358c660
VS
263#if defined(__WXMGL__)
264 // VS: this is not specific to wxMGL, all fullscreen (framebuffer) ports
265 // should provide this option. That's why it is in common/appcmn.cpp
266 // and not mgl/app.cpp
267 {
268 wxCMD_LINE_OPTION,
269 _T(""),
270 OPTION_MODE,
271 gettext_noop("specify display mode to use (e.g. 640x480-16)"),
272 wxCMD_LINE_VAL_STRING
273 },
274#endif // __WXMGL__
275
bf188f1a
VZ
276 // terminator
277 { wxCMD_LINE_NONE }
278 };
279
280 parser.SetDesc(cmdLineDesc);
281}
282
283bool wxAppBase::OnCmdLineParsed(wxCmdLineParser& parser)
284{
285#if wxUSE_LOG
286 if ( parser.Found(OPTION_VERBOSE) )
287 {
288 wxLog::SetVerbose(TRUE);
289 }
290#endif // wxUSE_LOG
291
292#ifdef __WXUNIVERSAL__
293 wxString themeName;
294 if ( parser.Found(OPTION_THEME, &themeName) )
295 {
296 wxTheme *theme = wxTheme::Create(themeName);
297 if ( !theme )
298 {
299 wxLogError(_("Unsupported theme '%s'."), themeName.c_str());
300
301 return FALSE;
302 }
303
304 wxTheme::Set(theme);
305 }
306#endif // __WXUNIVERSAL__
307
c358c660
VS
308#if defined(__WXMGL__)
309 wxString modeDesc;
310 if ( parser.Found(OPTION_MODE, &modeDesc) )
311 {
312 unsigned w, h, bpp;
313 if ( wxSscanf(modeDesc.c_str(), _T("%ux%u-%u"), &w, &h, &bpp) != 3 )
314 {
49e885f8 315 wxLogError(_("Invalid display mode specification '%s'."), modeDesc.c_str());
c358c660
VS
316
317 return FALSE;
318 }
319
07082b28 320 if ( !SetDisplayMode(wxDisplayModeInfo(w, h, bpp)) )
49e885f8 321 return FALSE;
c358c660 322 }
be03c0ec 323#endif // __WXMGL__
c358c660 324
bf188f1a
VZ
325 return TRUE;
326}
327
328bool wxAppBase::OnCmdLineHelp(wxCmdLineParser& parser)
329{
330 parser.Usage();
331
332 return FALSE;
333}
334
335bool wxAppBase::OnCmdLineError(wxCmdLineParser& parser)
336{
337 parser.Usage();
338
339 return FALSE;
340}
341
342#endif // wxUSE_CMDLINE_PARSER
343
a5f1fd3e
VZ
344// ----------------------------------------------------------------------------
345// debugging support
346// ----------------------------------------------------------------------------
347
348#ifdef __WXDEBUG__
349
350// wxASSERT() helper
351bool wxAssertIsEqual(int x, int y)
352{
353 return x == y;
354}
355
356// break into the debugger
357void wxTrap()
358{
359#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
360 DebugBreak();
c31ad41d 361#elif defined(__WXMAC__) && !defined(__DARWIN__)
a5f1fd3e
VZ
362#if __powerc
363 Debugger();
364#else
365 SysBreak();
366#endif
367#elif defined(__UNIX__)
368 raise(SIGTRAP);
369#else
370 // TODO
371#endif // Win/Unix
372}
373
374// show the assert modal dialog
375static
376void ShowAssertDialog(const wxChar *szFile, int nLine, const wxChar *szMsg)
377{
378 // this variable can be set to true to suppress "assert failure" messages
379 static bool s_bNoAsserts = FALSE;
a5f1fd3e
VZ
380
381 wxChar szBuf[4096];
382
383 // make life easier for people using VC++ IDE: clicking on the message
384 // will take us immediately to the place of the failed assert
385 wxSnprintf(szBuf, WXSIZEOF(szBuf),
386#ifdef __VISUALC__
387 wxT("%s(%d): assert failed"),
388#else // !VC++
389 // make the error message more clear for all the others
390 wxT("Assert failed in file %s at line %d"),
391#endif // VC/!VC
392 szFile, nLine);
393
394 if ( szMsg != NULL )
395 {
396 wxStrcat(szBuf, wxT(": "));
397 wxStrcat(szBuf, szMsg);
398 }
399 else // no message given
400 {
401 wxStrcat(szBuf, wxT("."));
402 }
403
404 if ( !s_bNoAsserts )
405 {
406 // send it to the normal log destination
407 wxLogDebug(szBuf);
408
409#if (wxUSE_GUI && wxUSE_MSGDLG) || defined(__WXMSW__)
410 // this message is intentionally not translated - it is for
411 // developpers only
412 wxStrcat(szBuf, wxT("\nDo you want to stop the program?\nYou can also choose [Cancel] to suppress further warnings."));
413
414 // use the native message box if available: this is more robust than
415 // using our own
416#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
417 switch ( ::MessageBox(NULL, szBuf, _T("Debug"),
418 MB_YESNOCANCEL | MB_ICONSTOP ) )
419 {
420 case IDYES:
421 wxTrap();
422 break;
423
424 case IDCANCEL:
425 s_bNoAsserts = TRUE;
426 break;
427
428 //case IDNO: nothing to do
429 }
430#else // !MSW
431 switch ( wxMessageBox(szBuf, wxT("Debug"),
432 wxYES_NO | wxCANCEL | wxICON_STOP ) )
433 {
434 case wxYES:
435 wxTrap();
436 break;
437
438 case wxCANCEL:
439 s_bNoAsserts = TRUE;
440 break;
441
442 //case wxNO: nothing to do
443 }
444#endif // GUI or MSW
445
446#else // !GUI
447 wxTrap();
448#endif // GUI/!GUI
449 }
a5f1fd3e
VZ
450}
451
452// this function is called when an assert fails
453void wxOnAssert(const wxChar *szFile, int nLine, const wxChar *szMsg)
454{
76456676
VZ
455 // FIXME MT-unsafe
456 static bool s_bInAssert = FALSE;
457
458 if ( s_bInAssert )
459 {
460 // He-e-e-e-elp!! we're trapped in endless loop
461 wxTrap();
462
463 s_bInAssert = FALSE;
464
465 return;
466 }
467
468 s_bInAssert = TRUE;
469
a5f1fd3e
VZ
470 if ( !wxTheApp )
471 {
472 // by default, show the assert dialog box - we can't customize this
473 // behaviour
474 ShowAssertDialog(szFile, nLine, szMsg);
475 }
476 else
477 {
478 // let the app process it as it wants
479 wxTheApp->OnAssert(szFile, nLine, szMsg);
480 }
76456676
VZ
481
482 s_bInAssert = FALSE;
a5f1fd3e
VZ
483}
484
485void wxAppBase::OnAssert(const wxChar *file, int line, const wxChar *msg)
486{
487 ShowAssertDialog(file, line, msg);
488}
489
490#endif //WXDEBUG
491