]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/appcmn.cpp
better spacing
[wxWidgets.git] / src / common / appcmn.cpp
index 05d7cb3bfee35039d59ad200a3c3fe2f1621984d..e22ebf4a3395befa5e3716b9ec0c7cbb847dc1e2 100644 (file)
@@ -32,6 +32,9 @@
     #include "wx/app.h"
     #include "wx/intl.h"
     #include "wx/list.h"
+    #if wxUSE_LOG
+        #include "wx/log.h"
+    #endif // wxUSE_LOG
     #if wxUSE_GUI
         #include "wx/msgdlg.h"
     #endif // wxUSE_GUI
@@ -42,6 +45,7 @@
 #include "wx/confbase.h"
 #include "wx/tokenzr.h"
 #include "wx/utils.h"
+#include "wx/msgout.h"
 
 #if wxUSE_GUI
     #include "wx/artprov.h"
@@ -83,8 +87,21 @@ wxAppBase::wxAppBase()
 #if wxUSE_GUI
     m_topWindow = (wxWindow *)NULL;
     m_useBestVisual = FALSE;
-    m_exitOnFrameDelete = TRUE;
     m_isActive = TRUE;
+
+    // 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
+    // to Yes initially as this dialog would be the last top level window.
+    // OTOH, if we set it to No initially we'll have to overwrite it with Yes
+    // when we enter our OnRun() because we do want the default behaviour from
+    // then on. But this would be a problem if the user code calls
+    // SetExitOnFrameDelete(FALSE) from OnInit().
+    //
+    // So we use the special "Later" value which is such that
+    // GetExitOnFrameDelete() returns FALSE for it but which we know we can
+    // safely (i.e. without losing the effect of the users SetExitOnFrameDelete
+    // call) overwrite in OnRun()
+    m_exitOnFrameDelete = Later;
 #endif // wxUSE_GUI
 
 #ifdef __WXDEBUG__
@@ -98,18 +115,30 @@ wxAppBase::~wxAppBase()
 }
 
 #if wxUSE_GUI
+
 bool wxAppBase::OnInitGui()
 {
 #ifdef __WXUNIVERSAL__
     if ( !wxTheme::Get() && !wxTheme::CreateDefault() )
         return FALSE;
-    wxArtProvider *art = wxTheme::Get()->GetArtProvider();
-    if ( art )
-        wxArtProvider::PushProvider(art);
 #endif // __WXUNIVERSAL__
 
     return TRUE;
 }
+
+int wxAppBase::OnRun()
+{
+    // see the comment in ctor: if the initial value hasn't been changed, use
+    // the default Yes from now on
+    if ( m_exitOnFrameDelete == Later )
+    {
+        m_exitOnFrameDelete = Yes;
+    }
+    //else: it has been changed, assume the user knows what he is doing
+
+    return MainLoop();
+}
+
 #endif // wxUSE_GUI
 
 int wxAppBase::OnExit()
@@ -124,9 +153,49 @@ int wxAppBase::OnExit()
     delete wxTheme::Set(NULL);
 #endif // __WXUNIVERSAL__
 
+    // use Set(NULL) and not Get() to avoid creating a message output object on
+    // demand when we just want to delete it
+    delete wxMessageOutput::Set(NULL);
+
     return 0;
 }
 
+// ----------------------------------------------------------------------------
+// customization hooks
+// ----------------------------------------------------------------------------
+
+#if wxUSE_LOG
+
+wxLog *wxAppBase::CreateLogTarget()
+{
+#if wxUSE_GUI && wxUSE_LOGGUI && !defined(__WXMICROWIN__)
+    return new wxLogGui;
+#else // !GUI
+    return new wxLogStderr;
+#endif // wxUSE_GUI
+}
+
+#endif // wxUSE_LOG
+
+wxMessageOutput *wxAppBase::CreateMessageOutput()
+{
+    // The standard way of printing help on command line arguments (app --help)
+    // is (according to common practice):
+    //     - console apps: to stderr (on any platform)
+    //     - GUI apps: stderr on Unix platforms (!)
+    //                 message box under Windows and others
+#if wxUSE_GUI && !defined(__UNIX__)
+    // wxMessageOutputMessageBox doesn't work under Motif
+    #ifdef __WXMOTIF__
+        return new wxMessageOutputLog;
+    #else
+        return new wxMessageOutputMessageBox;
+    #endif
+#else // !wxUSE_GUI || __UNIX__
+    return new wxMessageOutputStderr;
+#endif
+}
+
 // ---------------------------------------------------------------------------
 // wxAppBase
 // ----------------------------------------------------------------------------
@@ -143,10 +212,10 @@ void wxAppBase::ProcessPendingEvents()
     }
 
     // iterate until the list becomes empty
-    wxNode *node = wxPendingEvents->First();
+    wxNode *node = wxPendingEvents->GetFirst();
     while (node)
     {
-        wxEvtHandler *handler = (wxEvtHandler *)node->Data();
+        wxEvtHandler *handler = (wxEvtHandler *)node->GetData();
         delete node;
 
         // In ProcessPendingEvents(), new handlers might be add
@@ -155,7 +224,7 @@ void wxAppBase::ProcessPendingEvents()
         handler->ProcessPendingEvents();
         wxENTER_CRIT_SECT( *wxPendingEventsLocker );
 
-        node = wxPendingEvents->First();
+        node = wxPendingEvents->GetFirst();
     }
 
     wxLEAVE_CRIT_SECT( *wxPendingEventsLocker );
@@ -182,6 +251,12 @@ void wxAppBase::SetActive(bool active, wxWindow * WXUNUSED(lastFocus))
 
 #endif // wxUSE_GUI
 
+int wxAppBase::FilterEvent(wxEvent& WXUNUSED(event))
+{
+    // process the events normally by default
+    return -1;
+}
+
 // ----------------------------------------------------------------------------
 // cmd line parsing
 // ----------------------------------------------------------------------------
@@ -303,10 +378,11 @@ bool wxAppBase::OnCmdLineParsed(wxCmdLineParser& parser)
         if ( !theme )
         {
             wxLogError(_("Unsupported theme '%s'."), themeName.c_str());
-
             return FALSE;
         }
 
+        // Delete the defaultly created theme and set the new theme.
+        delete wxTheme::Get();
         wxTheme::Set(theme);
     }
 #endif // __WXUNIVERSAL__
@@ -319,7 +395,6 @@ bool wxAppBase::OnCmdLineParsed(wxCmdLineParser& parser)
         if ( wxSscanf(modeDesc.c_str(), _T("%ux%u-%u"), &w, &h, &bpp) != 3 )
         {
             wxLogError(_("Invalid display mode specification '%s'."), modeDesc.c_str());
-
             return FALSE;
         }
 
@@ -368,8 +443,23 @@ bool wxAppBase::CheckBuildOptions(const wxBuildOptions& opts)
 
     if ( !(wxCMP(isDebug) && wxCMP(verMaj) && wxCMP(verMin)) )
     {
-        wxLogFatalError(_T("Mismatch between the program and library build ")
-                        _T("versions detected."));
+        wxString msg;
+        wxString libDebug, progDebug;
+
+        if (isDebug)
+            libDebug = wxT("debug");
+        else
+            libDebug = wxT("no debug");
+
+        if (opts.m_isDebug)
+            progDebug = wxT("debug");
+        else
+            progDebug = wxT("no debug");
+        
+        msg.Printf(_T("Mismatch between the program and library build versions detected.\nThe library used %d.%d (%s), and your program used %d.%d (%s)."),
+                   verMaj, verMin, libDebug.c_str(), opts.m_verMaj, opts.m_verMin, progDebug.c_str());
+        
+        wxLogFatalError(msg);
 
         // normally wxLogFatalError doesn't return
         return FALSE;
@@ -383,6 +473,7 @@ bool wxAppBase::CheckBuildOptions(const wxBuildOptions& opts)
 
 static void LINKAGEMODE SetTraceMasks()
 {
+#if wxUSE_LOG
     wxString mask;
     if ( wxGetEnv(wxT("WXTRACE"), &mask) )
     {
@@ -390,6 +481,7 @@ static void LINKAGEMODE SetTraceMasks()
         while ( tkn.HasMoreTokens() )
             wxLog::AddTraceMask(tkn.GetNextToken());
     }
+#endif // wxUSE_LOG
 }
 
 // wxASSERT() helper
@@ -416,25 +508,35 @@ void wxTrap()
 #endif // Win/Unix
 }
 
+
+void wxAssert(int cond,
+                  const wxChar *szFile,
+                  int nLine,
+                  const wxChar *szCond,
+                  const wxChar *szMsg) 
+{
+   if ( !cond )
+          wxOnAssert(szFile, nLine, szCond, szMsg);
+}
+  
 // show the assert modal dialog
 static
-void ShowAssertDialog(const wxChar *szFile, int nLine, const wxChar *szMsg)
+void ShowAssertDialog(const wxChar *szFile,
+                      int nLine,
+                      const wxChar *szCond,
+                      const wxChar *szMsg)
 {
     // this variable can be set to true to suppress "assert failure" messages
     static bool s_bNoAsserts = FALSE;
 
     wxChar szBuf[4096];
 
-    // make life easier for people using VC++ IDE: clicking on the message
-    // will take us immediately to the place of the failed assert
+    // make life easier for people using VC++ IDE by using this format: like
+    // this, clicking on the message will take us immediately to the place of
+    // the failed assert
     wxSnprintf(szBuf, WXSIZEOF(szBuf),
-#ifdef __VISUALC__
-               wxT("%s(%d): assert failed"),
-#else  // !VC++
-    // make the error message more clear for all the others
-               wxT("Assert failed in file %s at line %d"),
-#endif // VC/!VC
-               szFile, nLine);
+               wxT("%s(%d): assert \"%s\" failed"),
+               szFile, nLine, szCond);
 
     if ( szMsg != NULL )
     {
@@ -495,7 +597,10 @@ void ShowAssertDialog(const wxChar *szFile, int nLine, const wxChar *szMsg)
 }
 
 // this function is called when an assert fails
-void wxOnAssert(const wxChar *szFile, int nLine, const wxChar *szMsg)
+void wxOnAssert(const wxChar *szFile,
+                int nLine,
+                const wxChar *szCond,
+                const wxChar *szMsg)
 {
     // FIXME MT-unsafe
     static bool s_bInAssert = FALSE;
@@ -516,20 +621,23 @@ void wxOnAssert(const wxChar *szFile, int nLine, const wxChar *szMsg)
     {
         // by default, show the assert dialog box - we can't customize this
         // behaviour
-        ShowAssertDialog(szFile, nLine, szMsg);
+        ShowAssertDialog(szFile, nLine, szCond, szMsg);
     }
     else
     {
         // let the app process it as it wants
-        wxTheApp->OnAssert(szFile, nLine, szMsg);
+        wxTheApp->OnAssert(szFile, nLine, szCond, szMsg);
     }
 
     s_bInAssert = FALSE;
 }
 
-void wxAppBase::OnAssert(const wxChar *file, int line, const wxChar *msg)
+void wxAppBase::OnAssert(const wxChar *file,
+                         int line,
+                         const wxChar *cond,
+                         const wxChar *msg)
 {
-    ShowAssertDialog(file, line, msg);
+    ShowAssertDialog(file, line, cond, msg);
 }
 
 #endif  //WXDEBUG