]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/appbase.cpp
Update version to 2.9.4 in version.bkl too and rebake everything.
[wxWidgets.git] / src / common / appbase.cpp
index c2d019fd253b4b9b7c08dc2aca1fe5b3d3a08efe..9ac78f57f6010213dc34169ec96703250464d4c9 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     19.06.2003 (extracted from common/appcmn.cpp)
 // RCS-ID:      $Id$
 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
 // Created:     19.06.2003 (extracted from common/appcmn.cpp)
 // RCS-ID:      $Id$
 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
-// License:     wxWindows license
+// Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 ///////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
@@ -43,6 +43,7 @@
 #include "wx/filename.h"
 #include "wx/msgout.h"
 #include "wx/scopedptr.h"
 #include "wx/filename.h"
 #include "wx/msgout.h"
 #include "wx/scopedptr.h"
+#include "wx/sysopt.h"
 #include "wx/tokenzr.h"
 #include "wx/thread.h"
 
 #include "wx/tokenzr.h"
 #include "wx/thread.h"
 
@@ -146,14 +147,21 @@ wxAppConsoleBase::wxAppConsoleBase()
     // In unicode mode the SetTraceMasks call can cause an apptraits to be
     // created, but since we are still in the constructor the wrong kind will
     // be created for GUI apps.  Destroy it so it can be created again later.
     // In unicode mode the SetTraceMasks call can cause an apptraits to be
     // created, but since we are still in the constructor the wrong kind will
     // be created for GUI apps.  Destroy it so it can be created again later.
-    delete m_traits;
-    m_traits = NULL;
+    wxDELETE(m_traits);
 #endif
 #endif
 #endif
 #endif
+
+    wxEvtHandler::AddFilter(this);
 }
 
 wxAppConsoleBase::~wxAppConsoleBase()
 {
 }
 
 wxAppConsoleBase::~wxAppConsoleBase()
 {
+    wxEvtHandler::RemoveFilter(this);
+
+    // we're being destroyed and using this object from now on may not work or
+    // even crash so don't leave dangling pointers to it
+    ms_appInstance = NULL;
+
     delete m_traits;
 }
 
     delete m_traits;
 }
 
@@ -161,21 +169,45 @@ wxAppConsoleBase::~wxAppConsoleBase()
 // initialization/cleanup
 // ----------------------------------------------------------------------------
 
 // initialization/cleanup
 // ----------------------------------------------------------------------------
 
-bool wxAppConsoleBase::Initialize(int& WXUNUSED(argc), wxChar **argv)
+bool wxAppConsoleBase::Initialize(int& WXUNUSED(argc), wxChar **WXUNUSED(argv))
 {
 #if wxUSE_INTL
     GetTraits()->SetLocale();
 #endif // wxUSE_INTL
 
 {
 #if wxUSE_INTL
     GetTraits()->SetLocale();
 #endif // wxUSE_INTL
 
+    return true;
+}
+
+wxString wxAppConsoleBase::GetAppName() const
+{
+    wxString name = m_appName;
 #ifndef __WXPALMOS__
 #ifndef __WXPALMOS__
-    if ( m_appName.empty() && argv && argv[0] )
+    if ( name.empty() )
     {
     {
-        // the application name is, by default, the name of its executable file
-        wxFileName::SplitPath(argv[0], NULL, &m_appName, NULL);
+        if ( argv )
+        {
+            // the application name is, by default, the name of its executable file
+            wxFileName::SplitPath(argv[0], NULL, &name, NULL);
+        }
     }
 #endif // !__WXPALMOS__
     }
 #endif // !__WXPALMOS__
+    return name;
+}
 
 
-    return true;
+wxString wxAppConsoleBase::GetAppDisplayName() const
+{
+    // use the explicitly provided display name, if any
+    if ( !m_appDisplayName.empty() )
+        return m_appDisplayName;
+
+    // if the application name was explicitly set, use it as is as capitalizing
+    // it won't always produce good results
+    if ( !m_appName.empty() )
+        return m_appName;
+
+    // if neither is set, use the capitalized version of the program file as
+    // it's the most reasonable default
+    return GetAppName().Capitalize();
 }
 
 wxEventLoopBase *wxAppConsoleBase::CreateMainLoop()
 }
 
 wxEventLoopBase *wxAppConsoleBase::CreateMainLoop()
@@ -185,11 +217,7 @@ wxEventLoopBase *wxAppConsoleBase::CreateMainLoop()
 
 void wxAppConsoleBase::CleanUp()
 {
 
 void wxAppConsoleBase::CleanUp()
 {
-    if ( m_mainLoop )
-    {
-        delete m_mainLoop;
-        m_mainLoop = NULL;
-    }
+    wxDELETE(m_mainLoop);
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -321,8 +349,11 @@ bool wxAppConsoleBase::Dispatch()
 bool wxAppConsoleBase::Yield(bool onlyIfNeeded)
 {
     wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
 bool wxAppConsoleBase::Yield(bool onlyIfNeeded)
 {
     wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
+    if ( loop )
+       return loop->Yield(onlyIfNeeded);
 
 
-    return loop && loop->Yield(onlyIfNeeded);
+    wxScopedPtr<wxEventLoopBase> tmpLoop(CreateMainLoop());
+    return tmpLoop->Yield(onlyIfNeeded);
 }
 
 void wxAppConsoleBase::WakeUpIdle()
 }
 
 void wxAppConsoleBase::WakeUpIdle()
@@ -346,6 +377,9 @@ bool wxAppConsoleBase::ProcessIdle()
     wxLog::FlushActive();
 #endif
 
     wxLog::FlushActive();
 #endif
 
+    // Garbage collect all objects previously scheduled for destruction.
+    DeletePendingObjects();
+
     return event.MoreRequested();
 }
 
     return event.MoreRequested();
 }
 
@@ -371,7 +405,7 @@ bool wxAppConsoleBase::IsMainLoopRunning()
 int wxAppConsoleBase::FilterEvent(wxEvent& WXUNUSED(event))
 {
     // process the events normally by default
 int wxAppConsoleBase::FilterEvent(wxEvent& WXUNUSED(event))
 {
     // process the events normally by default
-    return -1;
+    return Event_Skip;
 }
 
 void wxAppConsoleBase::DelayPendingEventHandler(wxEvtHandler* toDelay)
 }
 
 void wxAppConsoleBase::DelayPendingEventHandler(wxEvtHandler* toDelay)
@@ -485,9 +519,6 @@ void wxAppConsoleBase::ProcessPendingEvents()
 
         wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
     }
 
         wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
     }
-
-    // Garbage collect all objects previously scheduled for destruction.
-    DeletePendingObjects();
 }
 
 void wxAppConsoleBase::DeletePendingEvents()
 }
 
 void wxAppConsoleBase::DeletePendingEvents()
@@ -511,7 +542,7 @@ void wxAppConsoleBase::DeletePendingEvents()
 
 bool wxAppConsoleBase::IsScheduledForDestruction(wxObject *object) const
 {
 
 bool wxAppConsoleBase::IsScheduledForDestruction(wxObject *object) const
 {
-    return wxPendingDelete.Member(object) != NULL;
+    return wxPendingDelete.Member(object);
 }
 
 void wxAppConsoleBase::ScheduleForDestruction(wxObject *object)
 }
 
 void wxAppConsoleBase::ScheduleForDestruction(wxObject *object)
@@ -844,22 +875,19 @@ void WXDLLIMPEXP_BASE wxMutexGuiLeave()
 bool wxAppTraitsBase::ShowAssertDialog(const wxString& msgOriginal)
 {
 #if wxDEBUG_LEVEL
 bool wxAppTraitsBase::ShowAssertDialog(const wxString& msgOriginal)
 {
 #if wxDEBUG_LEVEL
-    wxString msg = msgOriginal;
+    wxString msg;
 
 #if wxUSE_STACKWALKER
 
 #if wxUSE_STACKWALKER
-#if !defined(__WXMSW__)
-    // 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);
-#endif
-
     const wxString stackTrace = GetAssertStackTrace();
     if ( !stackTrace.empty() )
     const wxString stackTrace = GetAssertStackTrace();
     if ( !stackTrace.empty() )
+    {
         msg << wxT("\n\nCall stack:\n") << stackTrace;
         msg << wxT("\n\nCall stack:\n") << stackTrace;
+
+        wxMessageOutputDebug().Output(msg);
+    }
 #endif // wxUSE_STACKWALKER
 
 #endif // wxUSE_STACKWALKER
 
-    return DoShowAssertDialog(msg);
+    return DoShowAssertDialog(msgOriginal + msg);
 #else // !wxDEBUG_LEVEL
     wxUnusedVar(msgOriginal);
 
 #else // !wxDEBUG_LEVEL
     wxUnusedVar(msgOriginal);
 
@@ -871,6 +899,15 @@ bool wxAppTraitsBase::ShowAssertDialog(const wxString& msgOriginal)
 wxString wxAppTraitsBase::GetAssertStackTrace()
 {
 #if wxDEBUG_LEVEL
 wxString wxAppTraitsBase::GetAssertStackTrace()
 {
 #if wxDEBUG_LEVEL
+
+#if !defined(__WXMSW__)
+    // 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, "Collecting stack trace information, please wait...");
+    fflush(stderr);
+#endif // !__WXMSW__
+
+
     wxString stackTrace;
 
     class StackDump : public wxStackWalker
     wxString stackTrace;
 
     class StackDump : public wxStackWalker
@@ -993,6 +1030,10 @@ wxDefaultAssertHandler(const wxString& file,
                        const wxString& cond,
                        const wxString& msg)
 {
                        const wxString& cond,
                        const wxString& msg)
 {
+    // If this option is set, we should abort immediately when assert happens.
+    if ( wxSystemOptions::GetOptionInt("exit-on-assert") )
+        abort();
+
     // FIXME MT-unsafe
     static int s_bInAssert = 0;
 
     // FIXME MT-unsafe
     static int s_bInAssert = 0;
 
@@ -1022,6 +1063,11 @@ wxDefaultAssertHandler(const wxString& file,
 
 wxAssertHandler_t wxTheAssertHandler = wxDefaultAssertHandler;
 
 
 wxAssertHandler_t wxTheAssertHandler = wxDefaultAssertHandler;
 
+void wxSetDefaultAssertHandler()
+{
+    wxTheAssertHandler = wxDefaultAssertHandler;
+}
+
 void wxOnAssert(const wxString& file,
                 int line,
                 const wxString& func,
 void wxOnAssert(const wxString& file,
                 int line,
                 const wxString& func,
@@ -1153,14 +1199,10 @@ bool DoShowAssertDialog(const wxString& msg)
         //case IDNO: nothing to do
     }
 #else // !__WXMSW__
         //case IDNO: nothing to do
     }
 #else // !__WXMSW__
-    wxFprintf(stderr, wxT("%s\n"), msg.c_str());
-    fflush(stderr);
-
-    // TODO: ask the user to enter "Y" or "N" on the console?
-    wxTrap();
+    wxUnusedVar(msg);
 #endif // __WXMSW__/!__WXMSW__
 
 #endif // __WXMSW__/!__WXMSW__
 
-    // continue with the asserts
+    // continue with the asserts by default
     return false;
 }
 
     return false;
 }
 
@@ -1203,27 +1245,15 @@ void ShowAssertDialog(const wxString& file,
     // since dialogs cannot be displayed
     if ( !wxThread::IsMain() )
     {
     // since dialogs cannot be displayed
     if ( !wxThread::IsMain() )
     {
-        msg += wxT(" [in child thread]");
-
-#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
-        msg << wxT("\r\n");
-        OutputDebugString(msg.wx_str());
-#else
-        // send to stderr
-        wxFprintf(stderr, wxT("%s\n"), msg.c_str());
-        fflush(stderr);
-#endif
-        // He-e-e-e-elp!! we're asserting in a child thread
-        wxTrap();
+        msg += wxString::Format(" [in thread %lx]", wxThread::GetCurrentId());
     }
     }
-    else
 #endif // wxUSE_THREADS
 
 #endif // wxUSE_THREADS
 
+    // log the assert in any case
+    wxMessageOutputDebug().Output(msg);
+
     if ( !s_bNoAsserts )
     {
     if ( !s_bNoAsserts )
     {
-        // send it to the normal log destination
-        wxLogDebug(wxT("%s"), msg.c_str());
-
         if ( traits )
         {
             // delegate showing assert dialog (if possible) to that class
         if ( traits )
         {
             // delegate showing assert dialog (if possible) to that class