// 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);
};
#if wxUSE_STD_IOSTREAM
+
// log everything to an "ostream", cerr by default
class WXDLLEXPORT wxLogStream : public wxLog
{
// 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
#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
// ----------------------------------------------------------------------------
#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
// 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
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
};
#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
// ============================================================================
// 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
// ----------------------------------------------------------------------------
#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_ */
void wxLog::Flush()
{
- // do nothing
+ // remember that we don't have any more messages to show
+ m_bHasMessages = FALSE;
}
// ----------------------------------------------------------------------------
}
#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
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
}
}
#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
// ============================================================================
// 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);
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 ) {
wxLogWindow::~wxLogWindow()
{
- delete m_pOldLog;
-
// may be NULL if log frame already auto destroyed itself
delete m_pLogFrame;
}
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
);