]> git.saurik.com Git - wxWidgets.git/commitdiff
added wxLogChain and wxLogPassThrough classes
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 11 Jul 2001 09:43:40 +0000 (09:43 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 11 Jul 2001 09:43:40 +0000 (09:43 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10961 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/log.h
include/wx/setup.h
src/common/log.cpp
src/generic/logg.cpp
src/univ/winuniv.cpp

index 7c8c0eadbea04f07b42a4b299ab814aa011ebbbb..5ea8d6f649888778c579b8b66b84961400bbba9a 100644 (file)
@@ -238,7 +238,7 @@ public:
     // redirect log output to a FILE
     wxLogStderr(FILE *fp = (FILE *) NULL);
 
-private:
+protected:
     // implement sink function
     virtual void DoLogString(const wxChar *szString, time_t t);
 
@@ -246,6 +246,7 @@ private:
 };
 
 #if wxUSE_STD_IOSTREAM
+
 // log everything to an "ostream", cerr by default
 class WXDLLEXPORT wxLogStream : public wxLog
 {
@@ -260,7 +261,8 @@ protected:
     // using ptr here to avoid including <iostream.h> from this file
     wxSTD ostream *m_ostr;
 };
-#endif
+
+#endif // wxUSE_STD_IOSTREAM
 
 // the following log targets are only compiled in if the we're compiling the
 // GUI part (andnot just the base one) of the library, they're implemented in
@@ -286,6 +288,89 @@ private:
 
 #endif // wxUSE_TEXTCTRL
 
+// ----------------------------------------------------------------------------
+// /dev/null log target: suppress logging until this object goes out of scope
+// ----------------------------------------------------------------------------
+
+// example of usage:
+/*
+    void Foo()
+    {
+        wxFile file;
+
+        // wxFile.Open() normally complains if file can't be opened, we don't
+        // want it
+        wxLogNull logNo;
+
+        if ( !file.Open("bar") )
+            ... process error ourselves ...
+
+        // ~wxLogNull called, old log sink restored
+    }
+ */
+class WXDLLEXPORT wxLogNull
+{
+public:
+    wxLogNull() { m_flagOld = wxLog::EnableLogging(FALSE); }
+    ~wxLogNull() { (void)wxLog::EnableLogging(m_flagOld);   }
+
+private:
+    bool m_flagOld; // the previous value of the wxLog::ms_doLog
+};
+
+// ----------------------------------------------------------------------------
+// chaining log target: installs itself as a log target and passes all
+// messages to the real log target given to it in the ctor but also forwards
+// them to the previously active one
+//
+// note that you don't have to call SetActiveTarget() with this class, it
+// does it itself in its ctor
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxLogChain : public wxLog
+{
+public:
+    wxLogChain(wxLog *logger);
+    virtual ~wxLogChain() { delete m_logOld; }
+
+    // change the new log target
+    void SetLog(wxLog *logger);
+
+    // this can be used to temporarily disable (and then reenable) passing
+    // messages to the old logger (by default we do pass them)
+    void PassMessages(bool bDoPass) { m_bPassMessages = bDoPass; }
+
+    // are we passing the messages to the previous log target?
+    bool IsPassingMessages() const { return m_bPassMessages; }
+
+    // return the previous log target (may be NULL)
+    wxLog *GetOldLog() const { return m_logOld; }
+
+    // override base class version to flush the old logger as well
+    virtual void Flush();
+
+protected:
+    // pass the chain to the old logger if needed
+    virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
+
+private:
+    // the current log target
+    wxLog *m_logNew;
+
+    // the previous log target
+    wxLog *m_logOld;
+
+    // do we pass the messages to the old logger?
+    bool m_bPassMessages;
+};
+
+// a chain log target which uses itself as the new logger
+class WXDLLEXPORT wxLogPassThrough : public wxLogChain
+{
+public:
+    wxLogPassThrough() : wxLogChain(this) { }
+};
+
 // ----------------------------------------------------------------------------
 // GUI log target, the default one for wxWindows programs
 // ----------------------------------------------------------------------------
@@ -325,13 +410,14 @@ protected:
 
 #if wxUSE_LOGWINDOW
 
-class WXDLLEXPORT wxLogWindow : public wxLog
+class WXDLLEXPORT wxLogWindow : public wxLogPassThrough
 {
 public:
     wxLogWindow(wxFrame *pParent,         // the parent frame (can be NULL)
-            const wxChar *szTitle,      // the title of the frame
-            bool bShow = TRUE,        // show window immediately?
-            bool bPassToOld = TRUE);  // pass log messages to the old target?
+                const wxChar *szTitle,    // the title of the frame
+                bool bShow = TRUE,        // show window immediately?
+                bool bPassToOld = TRUE);  // pass messages to the old target?
+
     ~wxLogWindow();
 
     // window operations
@@ -340,21 +426,6 @@ public:
         // retrieve the pointer to the frame
     wxFrame *GetFrame() const;
 
-    // accessors
-        // the previous log target (may be NULL)
-    wxLog *GetOldLog() const { return m_pOldLog; }
-        // are we passing the messages to the previous log target?
-    bool IsPassingMessages() const { return m_bPassMessages; }
-
-    // we can pass the messages to the previous log target (we're in this mode by
-    // default: we collect all messages in the window, but also let the default
-    // processing take place)
-    void PassMessages(bool bDoPass) { m_bPassMessages = bDoPass; }
-
-    // base class virtuals
-        // we don't need it ourselves, but we pass it to the previous logger
-    virtual void Flush();
-
     // overridables
         // called immediately after the log frame creation allowing for
         // any extra initializations
@@ -373,8 +444,6 @@ protected:
     virtual void DoLogString(const wxChar *szString, time_t t);
 
 private:
-    bool        m_bPassMessages;  // pass messages to m_pOldLog?
-    wxLog      *m_pOldLog;        // previous log target
     wxLogFrame *m_pLogFrame;      // the log frame
 };
 
@@ -382,33 +451,6 @@ private:
 
 #endif // wxUSE_GUI
 
-// ----------------------------------------------------------------------------
-// /dev/null log target: suppress logging until this object goes out of scope
-// ----------------------------------------------------------------------------
-
-// example of usage:
-/*
-   void Foo() {
-   wxFile file;
-
-// wxFile.Open() normally complains if file can't be opened, we don't want it
-wxLogNull logNo;
-if ( !file.Open("bar") )
-... process error ourselves ...
-
-// ~wxLogNull called, old log sink restored
-}
- */
-class WXDLLEXPORT wxLogNull
-{
-public:
-    wxLogNull() { m_flagOld = wxLog::EnableLogging(FALSE); }
-    ~wxLogNull() { (void)wxLog::EnableLogging(m_flagOld);   }
-
-private:
-    bool m_flagOld; // the previous value of the wxLog::ms_doLog
-};
-
 // ============================================================================
 // global functions
 // ============================================================================
@@ -418,12 +460,6 @@ private:
 // for log messages for easy redirection
 // ----------------------------------------------------------------------------
 
-// are we in 'verbose' mode?
-// (note that it's often handy to change this var manually from the
-//  debugger, thus enabling/disabling verbose reporting for some
-//  parts of the program only)
-WXDLLEXPORT_DATA(extern bool) g_bVerbose;
-
 // ----------------------------------------------------------------------------
 // get error code/error message from system in a portable way
 // ----------------------------------------------------------------------------
index 0ccee557d00e2346f15bed7b2b1279aa356f5541..a4bf2e32c5223b284e0cd50f9ed247741cc0b704 100644 (file)
 #error No __WXxxx__ define set! Please define one of __WXBASE__,__WXGTK__,__WXMSW__,__WXMOTIF__,__WXMAC__,__WXQT__,__WXPM__,__WXSTUBS__
 #endif
 
-// wxUniversal is defined together with one of other ports, so test for it
-// first
+/*
+  wxUniversal is defined together with one of other ports, so test for it
+  first
+ */
 #ifdef __WXUNIVERSAL__
 #if defined(__USE_WXCONFIG__) && defined(__WXDEBUG__)
 #include "wx/univd/setup.h"
 
 #include "wx/chkconf.h"
 
+/*
+   define some constants identifying wxWindows version in more details than
+   just the version number
+ */
+
+// wxLogChain class available
+#define wxHAS_LOG_CHAIN
+
+// define this when wxDC::Blit() respects SetDeviceOrigin() in wxGTK
+#undef wxHAS_WORKING_GTK_DC_BLIT
+
 #endif /* _WX_SETUP_H_BASE_ */
index fc67d1ef888f75e6b526b04e6e12583d58498db0..ebf14bf02c15df8b8925f7810746eede02bc501e 100644 (file)
@@ -407,7 +407,8 @@ void wxLog::DoLogString(const wxChar *WXUNUSED(szString), time_t WXUNUSED(t))
 
 void wxLog::Flush()
 {
-    // do nothing
+    // remember that we don't have any more messages to show
+    m_bHasMessages = FALSE;
 }
 
 // ----------------------------------------------------------------------------
@@ -423,82 +424,82 @@ wxLogStderr::wxLogStderr(FILE *fp)
 }
 
 #if defined(__WXMAC__) && !defined(__UNIX__)
-#define kDebuggerSignature             'MWDB'
+#define kDebuggerSignature        'MWDB'
 
 static Boolean FindProcessBySignature(OSType signature, ProcessInfoRec* info)
-{      
-       OSErr err;
-       ProcessSerialNumber psn;
-       Boolean found = false;
-       psn.highLongOfPSN = 0;
-       psn.lowLongOfPSN = kNoProcess;
-       
-       if (!info) return false;
-       
-       info->processInfoLength = sizeof(ProcessInfoRec);
-       info->processName = NULL;
-       info->processAppSpec = NULL;
-       
-       err = noErr;
-       while (!found && err == noErr)
-       {
-               err = GetNextProcess(&psn);
-               if (err == noErr)
-               {
-                       err = GetProcessInformation(&psn, info);
-                       found = err == noErr && info->processSignature == signature;
-               }
-       }                               
-       return found;
+{
+    OSErr err;
+    ProcessSerialNumber psn;
+    Boolean found = false;
+    psn.highLongOfPSN = 0;
+    psn.lowLongOfPSN = kNoProcess;
+
+    if (!info) return false;
+
+    info->processInfoLength = sizeof(ProcessInfoRec);
+    info->processName = NULL;
+    info->processAppSpec = NULL;
+
+    err = noErr;
+    while (!found && err == noErr)
+    {
+        err = GetNextProcess(&psn);
+        if (err == noErr)
+        {
+            err = GetProcessInformation(&psn, info);
+            found = err == noErr && info->processSignature == signature;
+        }
+    }
+    return found;
 }
 
 pascal Boolean MWDebuggerIsRunning(void)
 {
-       ProcessInfoRec info;
-       return FindProcessBySignature(kDebuggerSignature, &info);
+    ProcessInfoRec info;
+    return FindProcessBySignature(kDebuggerSignature, &info);
 }
 
 pascal OSErr AmIBeingMWDebugged(Boolean* result)
 {
-       OSErr err;
-       ProcessSerialNumber psn;
-       OSType sig = kDebuggerSignature;
-       AppleEvent      theAE = {typeNull, NULL};
-       AppleEvent      theReply = {typeNull, NULL};
-       AEAddressDesc addr  = {typeNull, NULL};
-       DescType actualType;
-       Size actualSize;
-       
-       if (!result) return paramErr;
-       
-       err = AECreateDesc(typeApplSignature, &sig, sizeof(sig), &addr);
-       if (err != noErr) goto exit;
-       
-       err = AECreateAppleEvent('MWDB', 'Dbg?', &addr,
-                               kAutoGenerateReturnID, kAnyTransactionID, &theAE);
-       if (err != noErr) goto exit;
-               
-       GetCurrentProcess(&psn);
-       err = AEPutParamPtr(&theAE, keyDirectObject, typeProcessSerialNumber,
-                       &psn, sizeof(psn));
-       if (err != noErr) goto exit;
-       
-       err = AESend(&theAE, &theReply, kAEWaitReply, kAENormalPriority,
-                                       kAEDefaultTimeout, NULL, NULL);
-       if (err != noErr) goto exit;
-       
-       err = AEGetParamPtr(&theReply, keyAEResult, typeBoolean, &actualType, result, 
-                               sizeof(Boolean), &actualSize);
+    OSErr err;
+    ProcessSerialNumber psn;
+    OSType sig = kDebuggerSignature;
+    AppleEvent    theAE = {typeNull, NULL};
+    AppleEvent    theReply = {typeNull, NULL};
+    AEAddressDesc addr  = {typeNull, NULL};
+    DescType actualType;
+    Size actualSize;
 
-exit:
-       if (addr.dataHandle)
-               AEDisposeDesc(&addr);
-       if (theAE.dataHandle)
-               AEDisposeDesc(&theAE);
-       if (theReply.dataHandle)
-               AEDisposeDesc(&theReply);
+    if (!result) return paramErr;
+
+    err = AECreateDesc(typeApplSignature, &sig, sizeof(sig), &addr);
+    if (err != noErr) goto exit;
+
+    err = AECreateAppleEvent(kDebuggerSignature, 'Dbg?', &addr,
+                kAutoGenerateReturnID, kAnyTransactionID, &theAE);
+    if (err != noErr) goto exit;
+
+    GetCurrentProcess(&psn);
+    err = AEPutParamPtr(&theAE, keyDirectObject, typeProcessSerialNumber,
+            &psn, sizeof(psn));
+    if (err != noErr) goto exit;
+
+    err = AESend(&theAE, &theReply, kAEWaitReply, kAENormalPriority,
+                    kAEDefaultTimeout, NULL, NULL);
+    if (err != noErr) goto exit;
 
-       return err;
+    err = AEGetParamPtr(&theReply, keyAEResult, typeBoolean, &actualType, result,
+                sizeof(Boolean), &actualSize);
+
+exit:
+    if (addr.dataHandle)
+        AEDisposeDesc(&addr);
+    if (theAE.dataHandle)
+        AEDisposeDesc(&theAE);
+    if (theReply.dataHandle)
+        AEDisposeDesc(&theReply);
+
+    return err;
 }
 #endif
 
@@ -519,36 +520,36 @@ void wxLogStderr::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
     OutputDebugString(str.c_str());
 #endif // MSW
 #if defined(__WXMAC__) && !defined(__WXMAC_X__) && wxUSE_GUI
-       Str255 pstr ;
-       strcpy( (char*) pstr , str.c_str() ) ;
-       strcat( (char*) pstr , ";g" ) ;
-       c2pstr( (char*) pstr ) ;
+    Str255 pstr ;
+    strcpy( (char*) pstr , str.c_str() ) ;
+    strcat( (char*) pstr , ";g" ) ;
+    c2pstr( (char*) pstr ) ;
 #if __WXDEBUG__
-       Boolean running = false ;
-       
+    Boolean running = false ;
+
 /*
-       if ( MWDebuggerIsRunning() )
-       {
-               AmIBeingMWDebugged( &running ) ;
-       }
+    if ( MWDebuggerIsRunning() )
+    {
+        AmIBeingMWDebugged( &running ) ;
+    }
 */
-       if (running)
-       {
-       #ifdef __powerc
-               DebugStr(pstr);
-       #else
-               SysBreakStr(pstr);
-       #endif
-       }
-       else            
+    if (running)
+    {
+#ifdef __powerc
+        DebugStr(pstr);
+#else
+        SysBreakStr(pstr);
+#endif
+    }
+    else
+#endif
+    {
+#ifdef __powerc
+        DebugStr(pstr);
+#else
+        DebugStr(pstr);
 #endif
-       {
-       #ifdef __powerc
-               DebugStr(pstr);
-       #else
-               DebugStr(pstr);
-       #endif
-       }
+    }
 #endif // Mac
 }
 
@@ -573,6 +574,52 @@ void wxLogStream::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
 }
 #endif // wxUSE_STD_IOSTREAM
 
+// ----------------------------------------------------------------------------
+// wxLogChain
+// ----------------------------------------------------------------------------
+
+wxLogChain::wxLogChain(wxLog *logger)
+{
+    m_logNew = logger;
+    m_logOld = wxLog::SetActiveTarget(this);
+}
+
+void wxLogChain::SetLog(wxLog *logger)
+{
+    if ( m_logNew != this )
+        delete m_logNew;
+
+    wxLog::SetActiveTarget(logger);
+
+    m_logNew = logger;
+}
+
+void wxLogChain::Flush()
+{
+    if ( m_logOld )
+        m_logOld->Flush();
+
+    // be careful to avoid inifinite recursion
+    if ( m_logNew && m_logNew != this )
+        m_logNew->Flush();
+}
+
+void wxLogChain::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
+{
+    // let the previous logger show it
+    if ( m_logOld && IsPassingMessages() )
+    {
+        // bogus cast just to access protected DoLog
+        ((wxLogChain *)m_logOld)->DoLog(level, szString, t);
+    }
+
+    if ( m_logNew && m_logNew != this )
+    {
+        // as above...
+        ((wxLogChain *)m_logNew)->DoLog(level, szString, t);
+    }
+}
+
 // ============================================================================
 // Global functions/variables
 // ============================================================================
index c5e260c9b20eb54b23496a009391e63c88207a03..911c39c5a7d4b032e71ba1a0a7139e040cca3968 100644 (file)
@@ -546,15 +546,15 @@ wxLogFrame::~wxLogFrame()
 
 // wxLogWindow
 // -----------
+
 wxLogWindow::wxLogWindow(wxFrame *pParent,
                          const wxChar *szTitle,
                          bool bShow,
                          bool bDoPass)
 {
-    m_bPassMessages = bDoPass;
+    PassMessages(bDoPass);
 
     m_pLogFrame = new wxLogFrame(pParent, this, szTitle);
-    m_pOldLog = wxLog::SetActiveTarget(this);
 
     if ( bShow )
         m_pLogFrame->Show(TRUE);
@@ -565,21 +565,10 @@ void wxLogWindow::Show(bool bShow)
     m_pLogFrame->Show(bShow);
 }
 
-void wxLogWindow::Flush()
-{
-    if ( m_pOldLog != NULL )
-        m_pOldLog->Flush();
-
-    m_bHasMessages = FALSE;
-}
-
 void wxLogWindow::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
 {
     // first let the previous logger show it
-    if ( m_pOldLog != NULL && m_bPassMessages ) {
-        // bogus cast just to access protected DoLog
-        ((wxLogWindow *)m_pOldLog)->DoLog(level, szString, t);
-    }
+    wxLogPassThrough::DoLog(level, szString, t);
 
     if ( m_pLogFrame ) {
         switch ( level ) {
@@ -652,8 +641,6 @@ void wxLogWindow::OnFrameDelete(wxFrame * WXUNUSED(frame))
 
 wxLogWindow::~wxLogWindow()
 {
-    delete m_pOldLog;
-
     // may be NULL if log frame already auto destroyed itself
     delete m_pLogFrame;
 }
index b3d73e3ed4fc7ce57fe30fbe80205608a7cc9ff0..6039e08f44192ef4846a766a5f04242d4dcdd84c 100644 (file)
@@ -852,7 +852,7 @@ wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal)
         dcMem.SelectObject(bmp);
 
         dcMem.Blit(wxPoint(0, 0), size, &dc, ptSource
-#if defined(__WXGTK__) && !defined(__WX_DC_BLIT_FIXED__)
+#if defined(__WXGTK__) && !defined(wxHAS_WORKING_GTK_DC_BLIT)
                 + GetClientAreaOrigin()
 #endif // broken wxGTK wxDC::Blit
                   );