From 03147cd08e78ba8a709ee019a8a51ac6b57e6f32 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 11 Jul 2001 09:43:40 +0000 Subject: [PATCH] added wxLogChain and wxLogPassThrough classes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10961 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/log.h | 148 +++++++++++++++++----------- include/wx/setup.h | 17 +++- src/common/log.cpp | 229 ++++++++++++++++++++++++++----------------- src/generic/logg.cpp | 19 +--- src/univ/winuniv.cpp | 2 +- 5 files changed, 249 insertions(+), 166 deletions(-) diff --git a/include/wx/log.h b/include/wx/log.h index 7c8c0eadbe..5ea8d6f649 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -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 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 // ---------------------------------------------------------------------------- diff --git a/include/wx/setup.h b/include/wx/setup.h index 0ccee557d0..a4bf2e32c5 100644 --- a/include/wx/setup.h +++ b/include/wx/setup.h @@ -15,8 +15,10 @@ #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" @@ -68,4 +70,15 @@ #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_ */ diff --git a/src/common/log.cpp b/src/common/log.cpp index fc67d1ef88..ebf14bf02c 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -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 // ============================================================================ diff --git a/src/generic/logg.cpp b/src/generic/logg.cpp index c5e260c9b2..911c39c5a7 100644 --- a/src/generic/logg.cpp +++ b/src/generic/logg.cpp @@ -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; } diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index b3d73e3ed4..6039e08f44 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -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 ); -- 2.45.2