X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5aad18a52bd34084e11c13753204c03aa3ff1686..7fca7a731d1b2bc4a7b1fb6275a1c92ffa49cf75:/src/common/appcmn.cpp diff --git a/src/common/appcmn.cpp b/src/common/appcmn.cpp index 1e30f70f15..e6a72a3d27 100644 --- a/src/common/appcmn.cpp +++ b/src/common/appcmn.cpp @@ -26,13 +26,12 @@ #ifndef WX_PRECOMP #include "wx/app.h" + #include "wx/window.h" #include "wx/bitmap.h" - #include "wx/intl.h" - #include "wx/list.h" #include "wx/log.h" #include "wx/msgdlg.h" - #include "wx/bitmap.h" #include "wx/confbase.h" + #include "wx/utils.h" #endif #include "wx/apptrait.h" @@ -40,9 +39,15 @@ #include "wx/evtloop.h" #include "wx/msgout.h" #include "wx/thread.h" -#include "wx/utils.h" +#include "wx/vidmode.h" #include "wx/ptr_scpd.h" +#ifdef __WXDEBUG__ + #if wxUSE_STACKWALKER + #include "wx/stackwalk.h" + #endif // wxUSE_STACKWALKER +#endif // __WXDEBUG__ + #if defined(__WXMSW__) #include "wx/msw/private.h" // includes windows.h for LOGFONT #endif @@ -55,6 +60,7 @@ #include "wx/build.h" WX_CHECK_BUILD_OPTIONS("wxCore") +WXDLLIMPEXP_DATA_CORE(wxList) wxPendingDelete; // ---------------------------------------------------------------------------- // wxEventLoopPtr @@ -74,12 +80,13 @@ wxDEFINE_TIED_SCOPED_PTR_TYPE(wxEventLoop) wxAppBase::wxAppBase() { m_topWindow = (wxWindow *)NULL; + m_useBestVisual = false; + m_forceTrueColour = false; + m_isActive = true; -#if wxUSE_EVTLOOP_IN_APP m_mainLoop = NULL; -#endif // wxUSE_EVTLOOP_IN_APP // We don't want to exit the app if the user code shows a dialog from its // OnInit() -- but this is what would happen if we set m_exitOnFrameDelete @@ -106,7 +113,6 @@ bool wxAppBase::Initialize(int& argcOrig, wxChar **argvOrig) #endif wxInitializeStockLists(); - wxInitializeStockObjects(); wxBitmap::InitStandardHandlers(); @@ -139,7 +145,7 @@ void wxAppBase::CleanUp() // undo everything we did in Initialize() above wxBitmap::CleanUpHandlers(); - wxDeleteStockObjects(); + wxStockGDI::DeleteAll(); wxDeleteStockLists(); @@ -160,6 +166,41 @@ void wxAppBase::CleanUp() #endif // wxUSE_THREADS } +// ---------------------------------------------------------------------------- +// various accessors +// ---------------------------------------------------------------------------- + +wxWindow* wxAppBase::GetTopWindow() const +{ + wxWindow* window = m_topWindow; + if (window == NULL && wxTopLevelWindows.GetCount() > 0) + window = wxTopLevelWindows.GetFirst()->GetData(); + return window; +} + +wxVideoMode wxAppBase::GetDisplayMode() const +{ + return wxVideoMode(); +} + +wxLayoutDirection wxAppBase::GetLayoutDirection() const +{ +#if wxUSE_INTL + const wxLocale *const locale = wxGetLocale(); + if ( locale ) + { + const wxLanguageInfo *const + info = wxLocale::GetLanguageInfo(locale->GetLanguage()); + + if ( info ) + return info->LayoutDirection; + } +#endif // wxUSE_INTL + + // we don't know + return wxLayout_Default; +} + #if wxUSE_CMDLINE_PARSER // ---------------------------------------------------------------------------- @@ -262,51 +303,37 @@ bool wxAppBase::OnCmdLineParsed(wxCmdLineParser& parser) int wxAppBase::MainLoop() { -#if wxUSE_EVTLOOP_IN_APP wxEventLoopTiedPtr mainLoop(&m_mainLoop, new wxEventLoop); return m_mainLoop->Run(); -#else // !wxUSE_EVTLOOP_IN_APP - return 0; -#endif // wxUSE_EVTLOOP_IN_APP/!wxUSE_EVTLOOP_IN_APP } void wxAppBase::ExitMainLoop() { -#if wxUSE_EVTLOOP_IN_APP // we should exit from the main event loop, not just any currently active // (e.g. modal dialog) event loop if ( m_mainLoop && m_mainLoop->IsRunning() ) { m_mainLoop->Exit(0); } -#endif // wxUSE_EVTLOOP_IN_APP } bool wxAppBase::Pending() { -#if wxUSE_EVTLOOP_IN_APP // use the currently active message loop here, not m_mainLoop, because if // we're showing a modal dialog (with its own event loop) currently the // main event loop is not running anyhow wxEventLoop * const loop = wxEventLoop::GetActive(); return loop && loop->Pending(); -#else // wxUSE_EVTLOOP_IN_APP - return false; -#endif // wxUSE_EVTLOOP_IN_APP/!wxUSE_EVTLOOP_IN_APP } bool wxAppBase::Dispatch() { -#if wxUSE_EVTLOOP_IN_APP // see comment in Pending() wxEventLoop * const loop = wxEventLoop::GetActive(); return loop && loop->Dispatch(); -#else // wxUSE_EVTLOOP_IN_APP - return true; -#endif // wxUSE_EVTLOOP_IN_APP/!wxUSE_EVTLOOP_IN_APP } // ---------------------------------------------------------------------------- @@ -372,6 +399,10 @@ void wxAppBase::SetActive(bool active, wxWindow * WXUNUSED(lastFocus)) (void)ProcessEvent(event); } +// ---------------------------------------------------------------------------- +// idle handling +// ---------------------------------------------------------------------------- + void wxAppBase::DeletePendingObjects() { wxList::compatibility_iterator node = wxPendingDelete.GetFirst(); @@ -379,11 +410,14 @@ void wxAppBase::DeletePendingObjects() { wxObject *obj = node->GetData(); - delete obj; - - if (wxPendingDelete.Member(obj)) + // remove it from the list first so that if we get back here somehow + // during the object deletion (e.g. wxYield called from its dtor) we + // wouldn't try to delete it the second time + if ( wxPendingDelete.Member(obj) ) wxPendingDelete.Erase(node); + delete obj; + // Deleting one object may have deleted other pending // objects, so start from beginning of list again. node = wxPendingDelete.GetFirst(); @@ -463,6 +497,24 @@ void wxAppBase::OnIdle(wxIdleEvent& WXUNUSED(event)) } +// ---------------------------------------------------------------------------- +// exceptions support +// ---------------------------------------------------------------------------- + +#if wxUSE_EXCEPTIONS + +bool wxAppBase::OnExceptionInMainLoop() +{ + throw; + + // some compilers are too stupid to know that we never return after throw +#if defined(__DMC__) || (defined(_MSC_VER) && _MSC_VER < 1200) + return false; +#endif +} + +#endif // wxUSE_EXCEPTIONS + // ---------------------------------------------------------------------------- // wxGUIAppTraitsBase // ---------------------------------------------------------------------------- @@ -519,15 +571,27 @@ wxRendererNative *wxGUIAppTraitsBase::CreateRenderer() bool wxGUIAppTraitsBase::ShowAssertDialog(const wxString& msg) { +#if defined(__WXMSW__) || !wxUSE_MSGDLG // under MSW we prefer to use the base class version using ::MessageBox() // even if wxMessageBox() is available because it has less chances to // double fault our app than our wxMessageBox() -#if defined(__WXMSW__) || !wxUSE_MSGDLG return wxAppTraitsBase::ShowAssertDialog(msg); #else // wxUSE_MSGDLG + wxString msgDlg = msg; + +#if wxUSE_STACKWALKER + // on Unix stack frame generation may take some time, depending on the + // size of the executable mainly... warn the user that we are working + wxFprintf(stderr, wxT("[Debug] Generating a stack trace... please wait")); + fflush(stderr); + + const wxString stackTrace = GetAssertStackTrace(); + if ( !stackTrace.empty() ) + msgDlg << _T("\n\nCall stack:\n") << stackTrace; +#endif // wxUSE_STACKWALKER + // this message is intentionally not translated -- it is for // developpers only - wxString msgDlg(msg); msgDlg += wxT("\nDo you want to stop the program?\n") wxT("You can also choose [Cancel] to suppress ") wxT("further warnings.");