Add information about the log message generation location to wxLog.

This means that wxLog::DoLogRecord() can now retrieve the file name, line
number and the function where the message was logged.

An unfortunate consequence of this change is that now

	if ( condition )
		wxLogError("Whatever");

results in a warning from g++ 4.x with -Wparentehses, so extra parentheses had
to be added in many places.

Finally, also allow storing arbitrary attributes in wxLogRecordInfo. This had
to be added to implement our own overloaded wxLogStatus() and wxLogSysError()
and will probably be useful for the others as well.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61363 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-07-09 20:26:34 +00:00
parent ca21a4e729
commit af58844636
27 changed files with 883 additions and 630 deletions

View File

@@ -71,10 +71,12 @@ argument list pointer. Here are all of them:
as the first argument. as the first argument.
@li wxLogDebug is @b the right function for debug output. It only does anything @li wxLogDebug is @b the right function for debug output. It only does anything
at all in the debug mode (when the preprocessor symbol __WXDEBUG__ is at all in the debug mode (when the preprocessor symbol __WXDEBUG__ is
defined) and expands to nothing in release mode (otherwise). @b Tip: under defined) and expands to nothing in release mode (otherwise).
Windows, you must either run the program under debugger or use a 3rd party
program such as DebugView to actually see the debug output. @b Tip: under Windows, you must either run the program under debugger or
- DebugView: http://www.microsoft.com/technet/sysinternals/Miscellaneous/DebugView.mspx use a 3rd party program such as DebugView
(http://www.microsoft.com/technet/sysinternals/Miscellaneous/DebugView.mspx)
to actually see the debug output.
@li wxLogTrace as wxLogDebug only does something in debug build. The reason for @li wxLogTrace as wxLogDebug only does something in debug build. The reason for
making it a separate function from it is that usually there are a lot of making it a separate function from it is that usually there are a lot of
trace messages, so it might make sense to separate them from other debug trace messages, so it might make sense to separate them from other debug
@@ -133,12 +135,16 @@ the active target with a call to @e SetActiveTarget() and it will be used
automatically by all subsequent calls to @e wxLogXXX() functions. automatically by all subsequent calls to @e wxLogXXX() functions.
To create a new log target class you only need to derive it from wxLog and To create a new log target class you only need to derive it from wxLog and
implement one (or both) of @e DoLog() and @e DoLogString() in it. The second override one or several of wxLog::DoLogRecord(), wxLog::DoLogTextAtLevel() and
one is enough if you're happy with the standard wxLog message formatting wxLog::DoLogText() in it. The first one is the most flexible and allows you to
(prepending "Error:" or "Warning:", timestamping @&c) but just want to send change the formatting of the messages, dynamically filter and redirect them and
the messages somewhere else. The first one may be overridden to do whatever so on -- all log messages, except for those generated by wxLogFatalError(),
you want but you have to distinguish between the different message types pass by this function. wxLog::DoLogTextAtLevel() should be overridden if you
yourself. simply want to redirect the log messages somewhere else, without changing their
formatting. Finally, it is enough to override wxLog::DoLogText() if you only
want to redirect the log messages and the destination doesn't depend on the
message log level.
There are some predefined classes deriving from wxLog and which might be There are some predefined classes deriving from wxLog and which might be
helpful to see how you can create a new log target class and, of course, may helpful to see how you can create a new log target class and, of course, may

View File

@@ -748,5 +748,8 @@ WX_DECLARE_HASH_MAP_WITH_DECL( long, long, wxIntegerHash, wxIntegerEqual,
WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxString, wxStringToStringHashMap, WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxString, wxStringToStringHashMap,
class WXDLLIMPEXP_BASE ); class WXDLLIMPEXP_BASE );
WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxUIntPtr, wxStringToNumHashMap,
class WXDLLIMPEXP_BASE );
#endif // _WX_HASHMAP_H_ #endif // _WX_HASHMAP_H_

View File

@@ -54,6 +54,7 @@ typedef unsigned long wxLogLevel;
#endif // ! __WXPALMOS5__ #endif // ! __WXPALMOS5__
#include "wx/dynarray.h" #include "wx/dynarray.h"
#include "wx/hashmap.h"
#if wxUSE_THREADS #if wxUSE_THREADS
#include "wx/thread.h" #include "wx/thread.h"
@@ -124,19 +125,66 @@ enum wxLogLevelValues
// information about a log record, i.e. unit of log output // information about a log record, i.e. unit of log output
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
struct wxLogRecordInfo class wxLogRecordInfo
{ {
public:
// default ctor creates an uninitialized object
wxLogRecordInfo() wxLogRecordInfo()
{ {
timestamp = 0; memset(this, 0, sizeof(this));
#if wxUSE_THREADS
threadId = 0;
#endif // wxUSE_THREADS
} }
// default copy ctor, assignment operator and dtor are ok // normal ctor, used by wxLogger specifies the location of the log
// statement; its time stamp and thread id are set up here
wxLogRecordInfo(const char *filename_,
int line_,
const char *func_)
{
filename = filename_;
func = func_;
line = line_;
timestamp = time(NULL);
#if wxUSE_THREADS
threadId = wxThread::GetCurrentId();
#endif // wxUSE_THREADS
m_data = NULL;
}
// we need to define copy ctor and assignment operator because of m_data
wxLogRecordInfo(const wxLogRecordInfo& other)
{
Copy(other);
}
wxLogRecordInfo& operator=(const wxLogRecordInfo& other)
{
if ( &other != this )
{
delete m_data;
Copy(other);
}
return *this;
}
// dtor is non-virtual, this class is not meant to be derived from
~wxLogRecordInfo()
{
delete m_data;
}
// the file name and line number of the file where the log record was
// generated, if available or NULL and 0 otherwise
const char *filename;
int line;
// the name of the function where the log record was generated (may be NULL
// if the compiler doesn't support __FUNCTION__)
const char *func;
// time of record generation // time of record generation
time_t timestamp; time_t timestamp;
@@ -145,8 +193,81 @@ struct wxLogRecordInfo
// id of the thread which logged this record // id of the thread which logged this record
wxThreadIdType threadId; wxThreadIdType threadId;
#endif // wxUSE_THREADS #endif // wxUSE_THREADS
// store an arbitrary value in this record context
//
// wxWidgets always uses keys starting with "wx.", e.g. "wx.sys_error"
void StoreValue(const wxString& key, wxUIntPtr val)
{
if ( !m_data )
m_data = new ExtraData;
m_data->numValues[key] = val;
}
void StoreValue(const wxString& key, const wxString& val)
{
if ( !m_data )
m_data = new ExtraData;
m_data->strValues[key] = val;
}
// these functions retrieve the value of either numeric or string key,
// return false if not found
bool GetNumValue(const wxString& key, wxUIntPtr *val) const
{
if ( !m_data )
return false;
wxStringToNumHashMap::const_iterator it = m_data->numValues.find(key);
if ( it == m_data->numValues.end() )
return false;
*val = it->second;
return true;
}
bool GetStrValue(const wxString& key, wxString *val) const
{
if ( !m_data )
return false;
wxStringToStringHashMap::const_iterator it = m_data->strValues.find(key);
if ( it == m_data->strValues.end() )
return false;
*val = it->second;
return true;
}
private:
void Copy(const wxLogRecordInfo& other)
{
memcpy(this, &other, sizeof(wxLogRecordInfo));
if ( other.m_data )
m_data = new ExtraData(*other.m_data);
}
// extra data associated with the log record: this is completely optional
// and can be used to pass information from the log function to the log
// sink (e.g. wxLogSysError() uses this to pass the error code)
struct ExtraData
{
wxStringToNumHashMap numValues;
wxStringToStringHashMap strValues;
};
// NULL if not used
ExtraData *m_data;
}; };
#define wxLOG_KEY_TRACE_MASK "wx.trace_mask"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// derive from this class to redirect (or suppress, or ...) log messages // derive from this class to redirect (or suppress, or ...) log messages
// normally, only a single instance of this class exists but it's not enforced // normally, only a single instance of this class exists but it's not enforced
@@ -338,7 +459,7 @@ protected:
// for every "record", i.e. a unit of log output, to be logged and by // for every "record", i.e. a unit of log output, to be logged and by
// default formats the message and passes it to DoLogTextAtLevel() which in // default formats the message and passes it to DoLogTextAtLevel() which in
// turn passes it to DoLogText() by default // turn passes it to DoLogText() by default
// override this method if you want to change message formatting or do // override this method if you want to change message formatting or do
// dynamic filtering // dynamic filtering
virtual void DoLogRecord(wxLogLevel level, virtual void DoLogRecord(wxLogLevel level,
@@ -599,15 +720,333 @@ private:
#include "wx/generic/logg.h" #include "wx/generic/logg.h"
#endif // wxUSE_GUI #endif // wxUSE_GUI
// ----------------------------------------------------------------------------
// wxLogger
// ----------------------------------------------------------------------------
// wxLogger is a helper class used by wxLogXXX() functions implementation,
// don't use it directly as it's experimental and subject to change (OTOH it
// might become public in the future if it's deemed to be useful enough)
// contains information about the context from which a log message originates
// and provides Log() vararg method which forwards to wxLog::OnLog() and passes
// this context to it
class wxLogger
{
public:
// ctor takes the basic information about the log record
wxLogger(wxLogLevel level,
const char *filename,
int line,
const char *func)
: m_level(level),
m_info(filename, line, func)
{
}
// store extra data in our log record and return this object itself (so
// that further calls to its functions could be chained)
template <typename T>
wxLogger& Store(const wxString& key, T val)
{
m_info.StoreValue(key, val);
return *this;
}
// hack for "overloaded" wxLogXXX() functions: calling this method
// indicates that we may have an extra first argument preceding the format
// string and that if we do have it, we should store it in m_info using the
// given key (while by default 0 value will be used)
wxLogger& MaybeStore(const wxString& key)
{
wxASSERT_MSG( m_optKey.empty(), "can only have one optional value" );
m_optKey = key;
m_info.StoreValue(key, 0);
return *this;
}
// non-vararg function used by wxVLogXXX():
// log the message at the level specified in the ctor if this log message
// is enabled
void LogV(const wxString& format, va_list argptr)
{
// remember that fatal errors can't be disabled
if ( m_level == wxLOG_FatalError || wxLog::IsLevelEnabled(m_level) )
DoCallOnLog(format, argptr);
}
// overloads used by functions with optional leading arguments (whose
// values are stored in the key passed to MaybeStore())
void LogV(long num, const wxString& format, va_list argptr)
{
Store(m_optKey, num);
LogV(format, argptr);
}
void LogV(void *ptr, const wxString& format, va_list argptr)
{
Store(m_optKey, wxPtrToUInt(ptr));
LogV(format, argptr);
}
// vararg functions used by wxLogXXX():
// will log the message at the level specified in the ctor
//
// notice that this function supposes that the caller already checked that
// the level was enabled and does no checks itself
WX_DEFINE_VARARG_FUNC_VOID
(
Log,
1, (const wxFormatString&),
DoLog, DoLogUtf8
)
// same as Log() but with an extra numeric or pointer parameters: this is
// used to pass an optional value by storing it in m_info under the name
// passed to MaybeStore() and is required to support "overloaded" versions
// of wxLogStatus() and wxLogSysError()
WX_DEFINE_VARARG_FUNC_VOID
(
Log,
2, (long, const wxFormatString&),
DoLogWithNum, DoLogWithNumUtf8
)
WX_DEFINE_VARARG_FUNC_VOID
(
Log,
2, (void *, const wxFormatString&),
DoLogWithPtr, DoLogWithPtrUtf8
)
// log the message at the level specified as its first argument
//
// as the macros don't have access to the level argument in this case, this
// function does check that the level is enabled itself
WX_DEFINE_VARARG_FUNC_VOID
(
LogAtLevel,
2, (wxLogLevel, const wxFormatString&),
DoLogAtLevel, DoLogAtLevelUtf8
)
// special versions for wxLogTrace() which is passed either string or
// integer (TODO) mask as first argument determining whether the message
// should be logged or not
WX_DEFINE_VARARG_FUNC_VOID
(
LogTrace,
2, (const wxString&, const wxFormatString&),
DoLogTrace, DoLogTraceUtf8
)
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
WX_VARARG_WATCOM_WORKAROUND(void, Log,
1, (const wxString&),
(wxFormatString(f1)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
1, (const wxCStrData&),
(wxFormatString(f1)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
1, (const char*),
(wxFormatString(f1)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
1, (const wchar_t*),
(wxFormatString(f1)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
2, (long, const wxString&),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
2, (long, const wxCStrData&),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
2, (long, const char *),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
2, (long, const wchar_t *),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
2, (void *, const wxString&),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
2, (void *, const wxCStrData&),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
2, (void *, const char *),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, Log,
2, (void *, const wchar_t *),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, LogAtLevel,
2, (wxLogLevel, const wxString&),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, LogAtLevel,
2, (wxLogLevel, const wxCStrData&),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, LogAtLevel,
2, (wxLogLevel, const char *),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, LogAtLevel,
2, (wxLogLevel, const wchar_t *),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, LogTrace,
2, (const wxString&, const wxString&),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, LogTrace,
2, (const wxString&, const wxCStrData&),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, LogTrace,
2, (const wxString&, const char *),
(f1, wxFormatString(f2)))
WX_VARARG_WATCOM_WORKAROUND(void, LogTrace,
2, (const wxString&, const wchar_t *),
(f1, wxFormatString(f2)))
#endif // __WATCOMC__
private:
#if !wxUSE_UTF8_LOCALE_ONLY
void DoLog(const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
DoCallOnLog(format, argptr);
va_end(argptr);
}
void DoLogWithNum(long num, const wxChar *format, ...)
{
Store(m_optKey, num);
va_list argptr;
va_start(argptr, format);
DoCallOnLog(format, argptr);
va_end(argptr);
}
void DoLogWithPtr(void *ptr, const wxChar *format, ...)
{
Store(m_optKey, wxPtrToUInt(ptr));
va_list argptr;
va_start(argptr, format);
DoCallOnLog(format, argptr);
va_end(argptr);
}
void DoLogAtLevel(wxLogLevel level, const wxChar *format, ...)
{
if ( !wxLog::IsLevelEnabled(level) )
return;
va_list argptr;
va_start(argptr, format);
DoCallOnLog(level, format, argptr);
va_end(argptr);
}
void DoLogTrace(const wxString& mask, const wxChar *format, ...)
{
if ( !wxLog::IsAllowedTraceMask(mask) )
return;
Store(wxLOG_KEY_TRACE_MASK, mask);
va_list argptr;
va_start(argptr, format);
DoCallOnLog(format, argptr);
va_end(argptr);
}
#endif // !wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void DoLogUtf8(const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
DoCallOnLog(format, argptr);
va_end(argptr);
}
void DoLogWithNumUtf8(long num, const char *format, ...)
{
Store(m_optKey, num);
va_list argptr;
va_start(argptr, format);
DoCallOnLog(format, argptr);
va_end(argptr);
}
void DoLogWithPtrUtf8(void *ptr, const char *format, ...)
{
Store(m_optKey, wxPtrToUInt(ptr));
va_list argptr;
va_start(argptr, format);
DoCallOnLog(format, argptr);
va_end(argptr);
}
void DoLogAtLevelUtf8(wxLogLevel level, const char *format, ...)
{
if ( !wxLog::IsLevelEnabled(level) )
return;
va_list argptr;
va_start(argptr, format);
DoCallOnLog(level, format, argptr);
va_end(argptr);
}
void DoLogTraceUtf8(const wxString& mask, const char *format, ...)
{
if ( !wxLog::IsAllowedTraceMask(mask) )
return;
Store(wxLOG_KEY_TRACE_MASK, mask);
va_list argptr;
va_start(argptr, format);
DoCallOnLog(format, argptr);
va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
void DoCallOnLog(wxLogLevel level, const wxString& format, va_list argptr)
{
wxLog::OnLog(level, wxString::FormatV(format, argptr), m_info);
}
void DoCallOnLog(const wxString& format, va_list argptr)
{
wxLog::OnLog(m_level, wxString::FormatV(format, argptr), m_info);
}
const wxLogLevel m_level;
wxLogRecordInfo m_info;
wxString m_optKey;
wxDECLARE_NO_COPY_CLASS(wxLogger);
};
// ============================================================================ // ============================================================================
// global functions // global functions
// ============================================================================ // ============================================================================
// ----------------------------------------------------------------------------
// Log functions should be used by application instead of stdio, iostream &c
// for log messages for easy redirection
// ----------------------------------------------------------------------------
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// get error code/error message from system in a portable way // get error code/error message from system in a portable way
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -619,76 +1058,152 @@ WXDLLIMPEXP_BASE unsigned long wxSysErrorCode();
WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0); WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// define wxLog<level> // define wxLog<level>() functions which can be used by application instead of
// stdio, iostream &c for log messages for easy redirection
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#define DECLARE_LOG_FUNCTION(level) \ /*
extern void WXDLLIMPEXP_BASE \ The code below is unreadable because it (unfortunately unavoidably)
wxDoLog##level##Wchar(const wxChar *format, ...); \ contains a lot of macro magic but all it does is to define wxLogXXX() such
extern void WXDLLIMPEXP_BASE \ that you can call them as vararg functions to log a message at the
wxDoLog##level##Utf8(const char *format, ...); \ corresponding level.
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
1, (const wxFormatString&), \
wxDoLog##level##Wchar, wxDoLog##level##Utf8) \
DECLARE_LOG_FUNCTION_WATCOM(level) \
extern void WXDLLIMPEXP_BASE wxVLog##level(const wxString& format, \
va_list argptr)
#ifdef __WATCOMC__ More precisely, it defines:
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351;
// can't use WX_WATCOM_ONLY_CODE here because the macro would expand to - wxLog{FatalError,Error,Warning,Message,Verbose,Debug}() functions
// something too big for Borland C++ to handle taking the format string and additional vararg arguments if needed.
#define DECLARE_LOG_FUNCTION_WATCOM(level) \ - wxLogGeneric(wxLogLevel level, const wxString& format, ...) which
WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \ takes the log level explicitly.
1, (const wxString&), \ - wxLogSysError(const wxString& format, ...) and wxLogSysError(long
(wxFormatString(f1))) \ err, const wxString& format, ...) which log a wxLOG_Error severity
WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \ message with the error message corresponding to the system error code
1, (const wxCStrData&), \ err or the last error.
(wxFormatString(f1))) \ - wxLogStatus(const wxString& format, ...) which logs the message into
WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \ the status bar of the main application window and its overload
1, (const char*), \ wxLogStatus(wxFrame *frame, const wxString& format, ...) which logs it
(wxFormatString(f1))) \ into the status bar of the specified frame.
WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \ - wxLogTrace(Mask mask, const wxString& format, ...) which only logs
1, (const wchar_t*), \ the message is the specified mask is enabled. This comes in two kinds:
(wxFormatString(f1))) Mask can be a wxString or a long. Both are deprecated.
#else
#define DECLARE_LOG_FUNCTION_WATCOM(level) In addition, wxVLogXXX() versions of all the functions above are also
#endif defined. They take a va_list argument instead of "...".
*/
// creates wxLogger object for the current location
#define wxMAKE_LOGGER(level) \
wxLogger(wxLOG_##level, __FILE__, __LINE__, __WXFUNCTION__)
// this macro generates the expression which logs whatever follows it in
// parentheses at the level specified as argument
#define wxDO_LOG(level) wxMAKE_LOGGER(level).Log
// this is the non-vararg equivalent
#define wxDO_LOGV(level, format, argptr) \
wxMAKE_LOGGER(level).LogV(format, argptr)
// this macro declares wxLog<level>() macro which logs whatever follows it if
// logging at specified level is enabled (notice that if it is false, the
// following arguments are not even evaluated which is good as it avoids
// unnecessary overhead)
//
// Note: the strange if/else construct is needed to make the following code
//
// if ( cond )
// wxLogError("!!!");
// else
// ...
//
// work as expected, without it the second "else" would match the "if"
// inside wxLogError(). Unfortunately code like
//
// if ( cond )
// wxLogError("!!!");
//
// now provokes "suggest explicit braces to avoid ambiguous 'else'"
// warnings from g++ 4.3 and later with -Wparentheses on but they can be
// easily fixed by adding curly braces around wxLogError() and at least
// the code still does do the right thing.
#define wxDO_LOG_IF_ENABLED(level) \
if ( !wxLog::IsLevelEnabled(wxLOG_##level) ) \
{} \
else \
wxDO_LOG(level)
// wxLogFatalError() is special as it can't be disabled
#define wxLogFatalError wxDO_LOG(FatalError)
#define wxVLogFatalError(format, argptr) wxDO_LOGV(FatalError, format, argptr)
#define wxLogError wxDO_LOG_IF_ENABLED(Error)
#define wxVLogError(format, argptr) wxDO_LOGV(Error, format, argptr)
#define wxLogWarning wxDO_LOG_IF_ENABLED(Warning)
#define wxVLogWarning(format, argptr) wxDO_LOGV(Warning, format, argptr)
#define wxLogMessage wxDO_LOG_IF_ENABLED(Message)
#define wxVLogMessage(format, argptr) wxDO_LOGV(Message, format, argptr)
// this one is special as it only logs if we're in verbose mode
#define wxLogVerbose \
if ( !(wxLog::IsLevelEnabled(wxLOG_Info) && wxLog::GetVerbose()) ) \
{} \
else \
wxDO_LOG(Info)
#define wxVLogVerbose(format, argptr) \
if ( !(wxLog::IsLevelEnabled(wxLOG_Info) && wxLog::GetVerbose()) ) \
{} \
else \
wxDO_LOGV(Info, format, argptr)
// deprecated synonyms for wxLogVerbose() and wxVLogVerbose()
#define wxLogInfo wxLogVerbose
#define wxVLogInfo wxVLogVerbose
#define DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, expdecl) \ // another special case: the level is passed as first argument of the function
extern void expdecl wxDoLog##level##Wchar(argclass arg, \ // and so is not available to the macro
const wxChar *format, ...); \ //
extern void expdecl wxDoLog##level##Utf8(argclass arg, \ // notice that because of this, arguments of wxLogGeneric() are currently
const char *format, ...); \ // always evaluated, unlike for the other log functions
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \ #define wxLogGeneric wxMAKE_LOGGER(Max).LogAtLevel
2, (argclass, const wxFormatString&), \ #define wxVLogGeneric(level, format, argptr) \
wxDoLog##level##Wchar, wxDoLog##level##Utf8) \ if ( !wxLog::IsLevelEnabled(wxLOG_##level) ) \
DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) \ {} \
extern void expdecl wxVLog##level(argclass arg, \ else \
const wxString& format, \ wxDO_LOGV(level, format, argptr)
va_list argptr)
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351; // wxLogSysError() needs to stash the error code value in the log record info
// can't use WX_WATCOM_ONLY_CODE here because the macro would expand to // so it needs special handling too; additional complications arise because the
// something too big for Borland C++ to handle // error code may or not be present as the first argument
#define DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) \ #define wxLOG_KEY_SYS_ERROR_CODE "wx.sys_error"
WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
2, (argclass, const wxString&), \ #define wxLogSysError \
(f1, wxFormatString(f2))) \ if ( !wxLog::IsLevelEnabled(wxLOG_Error) ) \
WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \ {} \
2, (argclass, const wxCStrData&), \ else \
(f1, wxFormatString(f2))) \ wxMAKE_LOGGER(Error).MaybeStore(wxLOG_KEY_SYS_ERROR_CODE).Log
WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
2, (argclass, const char*), \ // unfortunately we can't have overloaded macros so we can't define versions
(f1, wxFormatString(f2))) \ // both with and without error code argument and have to rely on LogV()
WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \ // overloads in wxLogger to select between them
2, (argclass, const wchar_t*), \ #define wxVLogSysError \
(f1, wxFormatString(f2))) wxMAKE_LOGGER(Error).MaybeStore(wxLOG_KEY_SYS_ERROR_CODE).LogV
#else
#define DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) #if wxUSE_GUI
#endif // wxLogStatus() is similar to wxLogSysError() as it allows to optionally
// specify the frame to which the message should go
#define wxLOG_KEY_FRAME "wx.frame"
#define wxLogStatus \
if ( !wxLog::IsLevelEnabled(wxLOG_Status) ) \
{} \
else \
wxMAKE_LOGGER(Status).MaybeStore(wxLOG_KEY_FRAME).Log
#define wxVLogStatus(format, argptr) \
wxMAKE_LOGGER(Status).MaybeStore(wxLOG_KEY_FRAME).LogV
#endif // wxUSE_GUI
#else // !wxUSE_LOG #else // !wxUSE_LOG
@@ -699,13 +1214,6 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
#undef wxUSE_LOG_TRACE #undef wxUSE_LOG_TRACE
#define wxUSE_LOG_TRACE 0 #define wxUSE_LOG_TRACE 0
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
#define WX_WATCOM_ONLY_CODE( x ) x
#else
#define WX_WATCOM_ONLY_CODE( x )
#endif
#if defined(__WATCOMC__) || defined(__MINGW32__) #if defined(__WATCOMC__) || defined(__MINGW32__)
// Mingw has similar problem with wxLogSysError: // Mingw has similar problem with wxLogSysError:
#define WX_WATCOM_OR_MINGW_ONLY_CODE( x ) x #define WX_WATCOM_OR_MINGW_ONLY_CODE( x ) x
@@ -713,8 +1221,11 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
#define WX_WATCOM_OR_MINGW_ONLY_CODE( x ) #define WX_WATCOM_OR_MINGW_ONLY_CODE( x )
#endif #endif
// log functions do nothing at all // define macros for defining log functions which do nothing at all
#define DECLARE_LOG_FUNCTION(level) \ //
// WX_WATCOM_ONLY_CODE is needed to work around
// http://bugzilla.openwatcom.org/show_bug.cgi?id=351
#define wxDEFINE_EMPTY_LOG_FUNCTION(level) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const wxString&)) \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const wxString&)) \
WX_WATCOM_ONLY_CODE( \ WX_WATCOM_ONLY_CODE( \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const char*)) \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const char*)) \
@@ -724,7 +1235,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
inline void wxVLog##level(const wxString& WXUNUSED(format), \ inline void wxVLog##level(const wxString& WXUNUSED(format), \
va_list WXUNUSED(argptr)) { } \ va_list WXUNUSED(argptr)) { } \
#define DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, expdecl) \ #define wxDEFINE_EMPTY_LOG_FUNCTION2(level, argclass) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const wxString&)) \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const wxString&)) \
WX_WATCOM_OR_MINGW_ONLY_CODE( \ WX_WATCOM_OR_MINGW_ONLY_CODE( \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const char*)) \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const char*)) \
@@ -735,6 +1246,22 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
const wxString& WXUNUSED(format), \ const wxString& WXUNUSED(format), \
va_list WXUNUSED(argptr)) {} va_list WXUNUSED(argptr)) {}
wxDEFINE_EMPTY_LOG_FUNCTION(FatalError);
wxDEFINE_EMPTY_LOG_FUNCTION(Error);
wxDEFINE_EMPTY_LOG_FUNCTION(SysError);
wxDEFINE_EMPTY_LOG_FUNCTION2(SysError, long);
wxDEFINE_EMPTY_LOG_FUNCTION(Warning);
wxDEFINE_EMPTY_LOG_FUNCTION(Message);
wxDEFINE_EMPTY_LOG_FUNCTION(Info);
wxDEFINE_EMPTY_LOG_FUNCTION(Verbose);
wxDEFINE_EMPTY_LOG_FUNCTION2(Generic, wxLogLevel);
#if wxUSE_GUI
wxDEFINE_EMPTY_LOG_FUNCTION(Status);
wxDEFINE_EMPTY_LOG_FUNCTION2(Status, wxFrame *);
#endif // wxUSE_GUI
// Empty Class to fake wxLogNull // Empty Class to fake wxLogNull
class WXDLLIMPEXP_BASE wxLogNull class WXDLLIMPEXP_BASE wxLogNull
{ {
@@ -751,51 +1278,6 @@ public:
#endif // wxUSE_LOG/!wxUSE_LOG #endif // wxUSE_LOG/!wxUSE_LOG
#define DECLARE_LOG_FUNCTION2(level, argclass, arg) \
DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, WXDLLIMPEXP_BASE)
// VC6 produces a warning if we a macro expanding to nothing to
// DECLARE_LOG_FUNCTION2:
#if defined(__VISUALC__) && __VISUALC__ < 1300
#pragma warning(push)
// "not enough actual parameters for macro 'DECLARE_LOG_FUNCTION2_EXP'"
#pragma warning(disable:4003)
#endif
// a generic function for all levels (level is passes as parameter)
DECLARE_LOG_FUNCTION2(Generic, wxLogLevel, level);
// one function per each level
DECLARE_LOG_FUNCTION(FatalError);
DECLARE_LOG_FUNCTION(Error);
DECLARE_LOG_FUNCTION(Warning);
DECLARE_LOG_FUNCTION(Message);
DECLARE_LOG_FUNCTION(Info);
DECLARE_LOG_FUNCTION(Verbose);
// this function sends the log message to the status line of the top level
// application frame, if any
DECLARE_LOG_FUNCTION(Status);
#if wxUSE_GUI
// this one is the same as previous except that it allows to explicitly
class WXDLLIMPEXP_FWD_CORE wxFrame;
// specify the frame to which the output should go
DECLARE_LOG_FUNCTION2_EXP(Status, wxFrame *, pFrame, WXDLLIMPEXP_CORE);
#endif // wxUSE_GUI
// additional one: as wxLogError, but also logs last system call error code
// and the corresponding error message if available
DECLARE_LOG_FUNCTION(SysError);
// and another one which also takes the error code (for those broken APIs
// that don't set the errno (like registry APIs in Win32))
DECLARE_LOG_FUNCTION2(SysError, long, lErrCode);
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode);
#endif
// debug functions can be completely disabled in optimized builds // debug functions can be completely disabled in optimized builds
@@ -820,7 +1302,8 @@ DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode);
#endif #endif
#if wxUSE_LOG_DEBUG #if wxUSE_LOG_DEBUG
DECLARE_LOG_FUNCTION(Debug); #define wxLogDebug wxDO_LOG_IF_ENABLED(Debug)
#define wxVLogDebug(format, argptr) wxDO_LOGV(Debug, format, argptr)
#else // !wxUSE_LOG_DEBUG #else // !wxUSE_LOG_DEBUG
#define wxVLogDebug(fmt, valist) wxLogNop() #define wxVLogDebug(fmt, valist) wxLogNop()
@@ -832,26 +1315,11 @@ DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode);
#endif // wxUSE_LOG_DEBUG/!wxUSE_LOG_DEBUG #endif // wxUSE_LOG_DEBUG/!wxUSE_LOG_DEBUG
#if wxUSE_LOG_TRACE #if wxUSE_LOG_TRACE
// this version only logs the message if the mask had been added to the #define wxLogTrace \
// list of masks with AddTraceMask() if ( !wxLog::IsLevelEnabled(wxLOG_Trace) ) \
DECLARE_LOG_FUNCTION2(Trace, const wxString&, mask); {} \
#ifdef __WATCOMC__ else \
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 wxMAKE_LOGGER(Trace).LogTrace
DECLARE_LOG_FUNCTION2(Trace, const char*, mask);
DECLARE_LOG_FUNCTION2(Trace, const wchar_t*, mask);
#endif
// and this one does nothing if all of level bits are not set in
// wxLog::GetActive()->GetTraceMask() -- it's deprecated in favour of
// string identifiers
#if WXWIN_COMPATIBILITY_2_8
DECLARE_LOG_FUNCTION2(Trace, wxTraceMask, mask);
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
DECLARE_LOG_FUNCTION2(Trace, int, mask);
#endif
#endif // WXWIN_COMPATIBILITY_2_8
#else // !wxUSE_LOG_TRACE #else // !wxUSE_LOG_TRACE
#define wxVLogTrace(mask, fmt, valist) wxLogNop() #define wxVLogTrace(mask, fmt, valist) wxLogNop()
@@ -870,10 +1338,6 @@ DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode);
#endif // HAVE_VARIADIC_MACROS/!HAVE_VARIADIC_MACROS #endif // HAVE_VARIADIC_MACROS/!HAVE_VARIADIC_MACROS
#endif // wxUSE_LOG_TRACE/!wxUSE_LOG_TRACE #endif // wxUSE_LOG_TRACE/!wxUSE_LOG_TRACE
#if defined(__VISUALC__) && __VISUALC__ < 1300
#pragma warning(pop)
#endif
// wxLogFatalError helper: show the (fatal) error to the user in a safe way, // wxLogFatalError helper: show the (fatal) error to the user in a safe way,
// i.e. without using wxMessageBox() for example because it could crash // i.e. without using wxMessageBox() for example because it could crash
void WXDLLIMPEXP_BASE void WXDLLIMPEXP_BASE

View File

@@ -338,18 +338,22 @@
/* /*
This macro can be used to test the Open Watcom version. Define Watcom-specific macros.
*/ */
#ifndef __WATCOMC__ #ifndef __WATCOMC__
# define wxWATCOM_VERSION(major,minor) 0 # define wxWATCOM_VERSION(major,minor) 0
# define wxCHECK_WATCOM_VERSION(major,minor) 0 # define wxCHECK_WATCOM_VERSION(major,minor) 0
# define wxONLY_WATCOM_EARLIER_THAN(major,minor) 0 # define wxONLY_WATCOM_EARLIER_THAN(major,minor) 0
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200 # define WX_WATCOM_ONLY_CODE( x )
# error "Only Open Watcom is supported in this release"
#else #else
# if __WATCOMC__ < 1200
# error "Only Open Watcom is supported in this release"
# endif
# define wxWATCOM_VERSION(major,minor) ( major * 100 + minor * 10 + 1100 ) # define wxWATCOM_VERSION(major,minor) ( major * 100 + minor * 10 + 1100 )
# define wxCHECK_WATCOM_VERSION(major,minor) ( __WATCOMC__ >= wxWATCOM_VERSION(major,minor) ) # define wxCHECK_WATCOM_VERSION(major,minor) ( __WATCOMC__ >= wxWATCOM_VERSION(major,minor) )
# define wxONLY_WATCOM_EARLIER_THAN(major,minor) ( __WATCOMC__ < wxWATCOM_VERSION(major,minor) ) # define wxONLY_WATCOM_EARLIER_THAN(major,minor) ( __WATCOMC__ < wxWATCOM_VERSION(major,minor) )
# define WX_WATCOM_ONLY_CODE( x ) x
#endif #endif
/* /*

View File

@@ -37,8 +37,23 @@ typedef unsigned long wxLogLevel;
/** /**
Information about a log record (unit of the log output). Information about a log record (unit of the log output).
*/ */
struct wxLogRecordInfo class wxLogRecordInfo
{ {
public:
/// The name of the file where this log message was generated.
const char *filename;
/// The line number at which this log message was generated.
int line;
/**
The name of the function where the log record was generated.
This field may be @NULL if the compiler doesn't support @c __FUNCTION__
(but most modern compilers do).
*/
const char *func;
/// Time when the log message was generated. /// Time when the log message was generated.
time_t timestamp; time_t timestamp;
@@ -587,19 +602,23 @@ public:
@section log_derivingyours Deriving your own log target @section log_derivingyours Deriving your own log target
There are two functions which must be implemented by any derived class to There are several methods which may be overridden in the derived class to
actually process the log messages: DoLog() and DoLogString(). customize log messages handling: DoLogRecord(), DoLogTextAtLevel() and
The second function receives a string which just has to be output in some way DoLogText().
and the easiest way to write a new log target is to override just this function
in the derived class.
If more control over the output format is needed, then the first function must The last method is the simplest one: you should override it if you simply
be overridden which allows to construct custom messages depending on the log level want to redirect the log output elsewhere, without taking into account the
or even do completely different things depending on the message severity level of the message. If you do want to handle messages of different levels
(for example, throw away all messages except warnings and errors, show warnings differently, then you should override DoLogTextAtLevel().
on the screen and forward the error messages to the user's (or programmer's) cell
phone - maybe depending on whether the timestamp tells us if it is day or Finally, if more control over the output format is needed, then the first
night in the current time zone). function must be overridden as it allows to construct custom messages
depending on the log level or even do completely different things depending
on the message severity (for example, throw away all messages except
warnings and errors, show warnings on the screen and forward the error
messages to the user's (or programmer's) cell phone -- maybe depending on
whether the timestamp tells us if it is day or night in the current time
zone).
There also functions to support message buffering. Why are they needed? There also functions to support message buffering. Why are they needed?
Some of wxLog implementations, most notably the standard wxLogGui class, Some of wxLog implementations, most notably the standard wxLogGui class,
@@ -609,9 +628,7 @@ public:
Flush() shows them all and clears the buffer contents. Flush() shows them all and clears the buffer contents.
This function doesn't do anything if the buffer is already empty. This function doesn't do anything if the buffer is already empty.
See also: @see FlushActive()
@li Flush()
@li FlushActive()
@section log_tracemasks Using trace masks @section log_tracemasks Using trace masks

View File

@@ -1521,10 +1521,9 @@ void MyFrame::OnNotifMsgShow(wxCommandEvent& WXUNUSED(event))
void MyFrame::OnNotifMsgHide(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnNotifMsgHide(wxCommandEvent& WXUNUSED(event))
{ {
if ( m_notifMsg ) if ( m_notifMsg && !m_notifMsg->Close() )
{ {
if ( !m_notifMsg->Close() ) wxLogStatus("Failed to hide manual notification message");
wxLogStatus("Failed to hide manual notification message");
} }
} }

View File

@@ -560,7 +560,9 @@ void wxTempFile::Discard()
{ {
m_file.Close(); m_file.Close();
if ( wxRemove(m_strTemp) != 0 ) if ( wxRemove(m_strTemp) != 0 )
{
wxLogSysError(_("can't remove temporary file '%s'"), m_strTemp.c_str()); wxLogSysError(_("can't remove temporary file '%s'"), m_strTemp.c_str());
}
} }
#endif // wxUSE_FILE #endif // wxUSE_FILE

View File

@@ -77,8 +77,12 @@ void wxHyperlinkCtrlBase::SendEvent()
wxString url = GetURL(); wxString url = GetURL();
wxHyperlinkEvent linkEvent(this, GetId(), url); wxHyperlinkEvent linkEvent(this, GetId(), url);
if (!GetEventHandler()->ProcessEvent(linkEvent)) // was the event skipped ? if (!GetEventHandler()->ProcessEvent(linkEvent)) // was the event skipped ?
{
if (!wxLaunchDefaultBrowser(url)) if (!wxLaunchDefaultBrowser(url))
{
wxLogWarning(wxT("Could not launch the default browser with url '%s' !"), url.c_str()); wxLogWarning(wxT("Could not launch the default browser with url '%s' !"), url.c_str());
}
}
} }
#endif // wxUSE_HYPERLINKCTRL #endif // wxUSE_HYPERLINKCTRL

View File

@@ -84,7 +84,9 @@ bool wxBMPHandler::SaveDib(wxImage *image,
if ( !image->Ok() ) if ( !image->Ok() )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("BMP: Couldn't save invalid image.")); wxLogError(_("BMP: Couldn't save invalid image."));
}
return false; return false;
} }
@@ -118,7 +120,9 @@ bool wxBMPHandler::SaveDib(wxImage *image,
) )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("BMP: wxImage doesn't have own wxPalette.")); wxLogError(_("BMP: wxImage doesn't have own wxPalette."));
}
return false; return false;
} }
bpp = 8; bpp = 8;
@@ -222,7 +226,9 @@ bool wxBMPHandler::SaveDib(wxImage *image,
) )
{ {
if (verbose) if (verbose)
{
wxLogError(_("BMP: Couldn't write the file (Bitmap) header.")); wxLogError(_("BMP: Couldn't write the file (Bitmap) header."));
}
return false; return false;
} }
} }
@@ -243,7 +249,9 @@ bool wxBMPHandler::SaveDib(wxImage *image,
) )
{ {
if (verbose) if (verbose)
{
wxLogError(_("BMP: Couldn't write the file (BitmapInfo) header.")); wxLogError(_("BMP: Couldn't write the file (BitmapInfo) header."));
}
return false; return false;
} }
} }
@@ -317,7 +325,9 @@ bool wxBMPHandler::SaveDib(wxImage *image,
if ( !stream.Write(rgbquad, palette_size*4) ) if ( !stream.Write(rgbquad, palette_size*4) )
{ {
if (verbose) if (verbose)
{
wxLogError(_("BMP: Couldn't write RGB color map.")); wxLogError(_("BMP: Couldn't write RGB color map."));
}
delete[] rgbquad; delete[] rgbquad;
#if wxUSE_PALETTE #if wxUSE_PALETTE
delete palette; delete palette;
@@ -450,7 +460,9 @@ bool wxBMPHandler::SaveDib(wxImage *image,
if ( !stream.Write(buffer, row_width) ) if ( !stream.Write(buffer, row_width) )
{ {
if (verbose) if (verbose)
{
wxLogError(_("BMP: Couldn't write data.")); wxLogError(_("BMP: Couldn't write data."));
}
delete[] buffer; delete[] buffer;
#if wxUSE_PALETTE #if wxUSE_PALETTE
delete palette; delete palette;
@@ -498,7 +510,9 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
if ( !cmap ) if ( !cmap )
{ {
if (verbose) if (verbose)
{
wxLogError(_("BMP: Couldn't allocate memory.")); wxLogError(_("BMP: Couldn't allocate memory."));
}
return false; return false;
} }
} }
@@ -518,7 +532,9 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
if ( !ptr ) if ( !ptr )
{ {
if ( verbose ) if ( verbose )
{
wxLogError( _("BMP: Couldn't allocate memory.") ); wxLogError( _("BMP: Couldn't allocate memory.") );
}
return false; return false;
} }
@@ -531,7 +547,9 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
if ( !alpha ) if ( !alpha )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("BMP: Couldn't allocate memory.")); wxLogError(_("BMP: Couldn't allocate memory."));
}
return false; return false;
} }
} }
@@ -924,13 +942,17 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream,
if ( width > 32767 ) if ( width > 32767 )
{ {
if (verbose) if (verbose)
{
wxLogError( _("DIB Header: Image width > 32767 pixels for file.") ); wxLogError( _("DIB Header: Image width > 32767 pixels for file.") );
}
return false; return false;
} }
if ( height > 32767 ) if ( height > 32767 )
{ {
if (verbose) if (verbose)
{
wxLogError( _("DIB Header: Image height > 32767 pixels for file.") ); wxLogError( _("DIB Header: Image height > 32767 pixels for file.") );
}
return false; return false;
} }
@@ -944,7 +966,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream,
if ( bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32 ) if ( bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32 )
{ {
if (verbose) if (verbose)
{
wxLogError( _("DIB Header: Unknown bitdepth in file.") ); wxLogError( _("DIB Header: Unknown bitdepth in file.") );
}
return false; return false;
} }
@@ -954,7 +978,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream,
comp != BI_BITFIELDS ) comp != BI_BITFIELDS )
{ {
if (verbose) if (verbose)
{
wxLogError( _("DIB Header: Unknown encoding in file.") ); wxLogError( _("DIB Header: Unknown encoding in file.") );
}
return false; return false;
} }
@@ -969,7 +995,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream,
((comp == BI_BITFIELDS) && (bpp != 16 && bpp != 32))) ((comp == BI_BITFIELDS) && (bpp != 16 && bpp != 32)))
{ {
if (verbose) if (verbose)
{
wxLogError( _("DIB Header: Encoding doesn't match bitdepth.") ); wxLogError( _("DIB Header: Encoding doesn't match bitdepth.") );
}
return false; return false;
} }
@@ -978,7 +1006,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream,
verbose, IsBmp, true) ) verbose, IsBmp, true) )
{ {
if (verbose) if (verbose)
{
wxLogError( _("Error in reading image DIB.") ); wxLogError( _("Error in reading image DIB.") );
}
return false; return false;
} }
@@ -991,7 +1021,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream,
verbose, IsBmp, false) ) verbose, IsBmp, false) )
{ {
if (verbose) if (verbose)
{
wxLogError( _("ICO: Error in reading mask DIB.") ); wxLogError( _("ICO: Error in reading mask DIB.") );
}
return false; return false;
} }
image->SetMaskFromImage(mask, 255, 255, 255); image->SetMaskFromImage(mask, 255, 255, 255);
@@ -1069,13 +1101,17 @@ bool wxICOHandler::SaveFile(wxImage *image,
if ( image->GetHeight () > 127 ) if ( image->GetHeight () > 127 )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("ICO: Image too tall for an icon.")); wxLogError(_("ICO: Image too tall for an icon."));
}
return false; return false;
} }
if ( image->GetWidth () > 255 ) if ( image->GetWidth () > 255 )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("ICO: Image too wide for an icon.")); wxLogError(_("ICO: Image too wide for an icon."));
}
return false; return false;
} }
@@ -1101,7 +1137,9 @@ bool wxICOHandler::SaveFile(wxImage *image,
if ( !stream.IsOk() ) if ( !stream.IsOk() )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("ICO: Error writing the image file!")); wxLogError(_("ICO: Error writing the image file!"));
}
return false; return false;
} }
@@ -1160,7 +1198,9 @@ bool wxICOHandler::SaveFile(wxImage *image,
if ( !bResult ) if ( !bResult )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("ICO: Error writing the image file!")); wxLogError(_("ICO: Error writing the image file!"));
}
return false; return false;
} }
IsMask = true; IsMask = true;
@@ -1169,7 +1209,9 @@ bool wxICOHandler::SaveFile(wxImage *image,
if ( !bResult ) if ( !bResult )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("ICO: Error writing the image file!")); wxLogError(_("ICO: Error writing the image file!"));
}
return false; return false;
} }
wxUint32 Size = cStream.GetSize(); wxUint32 Size = cStream.GetSize();
@@ -1224,7 +1266,9 @@ bool wxICOHandler::SaveFile(wxImage *image,
if ( !stream.IsOk() ) if ( !stream.IsOk() )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("ICO: Error writing the image file!")); wxLogError(_("ICO: Error writing the image file!"));
}
return false; return false;
} }
@@ -1234,7 +1278,9 @@ bool wxICOHandler::SaveFile(wxImage *image,
if ( !bResult ) if ( !bResult )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("ICO: Error writing the image file!")); wxLogError(_("ICO: Error writing the image file!"));
}
return false; return false;
} }
IsMask = true; IsMask = true;
@@ -1243,7 +1289,9 @@ bool wxICOHandler::SaveFile(wxImage *image,
if ( !bResult ) if ( !bResult )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(_("ICO: Error writing the image file!")); wxLogError(_("ICO: Error writing the image file!"));
}
return false; return false;
} }

View File

@@ -89,7 +89,9 @@ bool wxGIFHandler::SaveFile( wxImage * WXUNUSED(image),
wxOutputStream& WXUNUSED(stream), bool verbose ) wxOutputStream& WXUNUSED(stream), bool verbose )
{ {
if (verbose) if (verbose)
{
wxLogDebug(wxT("GIF: the handler is read-only!!")); wxLogDebug(wxT("GIF: the handler is read-only!!"));
}
return false; return false;
} }

View File

@@ -777,7 +777,9 @@ bool wxIFFHandler::SaveFile(wxImage * WXUNUSED(image),
wxOutputStream& WXUNUSED(stream), bool verbose) wxOutputStream& WXUNUSED(stream), bool verbose)
{ {
if (verbose) if (verbose)
{
wxLogDebug(wxT("IFF: the handler is read-only!!")); wxLogDebug(wxT("IFF: the handler is read-only!!"));
}
return false; return false;
} }

View File

@@ -251,7 +251,9 @@ bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
* We need to clean up the JPEG object, close the input file, and return. * We need to clean up the JPEG object, close the input file, and return.
*/ */
if (verbose) if (verbose)
{
wxLogError(_("JPEG: Couldn't load - file is probably corrupted.")); wxLogError(_("JPEG: Couldn't load - file is probably corrupted."));
}
(cinfo.src->term_source)(&cinfo); (cinfo.src->term_source)(&cinfo);
jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);
if (image->Ok()) image->Destroy(); if (image->Ok()) image->Destroy();
@@ -421,7 +423,9 @@ bool wxJPEGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
* We need to clean up the JPEG object, close the input file, and return. * We need to clean up the JPEG object, close the input file, and return.
*/ */
if (verbose) if (verbose)
{
wxLogError(_("JPEG: Couldn't save image.")); wxLogError(_("JPEG: Couldn't save image."));
}
jpeg_destroy_compress(&cinfo); jpeg_destroy_compress(&cinfo);
return false; return false;
} }

View File

@@ -439,7 +439,9 @@ bool wxPCXHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
if (!CanRead(stream)) if (!CanRead(stream))
{ {
if (verbose) if (verbose)
{
wxLogError(_("PCX: this is not a PCX file.")); wxLogError(_("PCX: this is not a PCX file."));
}
return false; return false;
} }

View File

@@ -165,7 +165,9 @@ PNGLINKAGEMODE wx_png_warning(png_structp png_ptr, png_const_charp message)
{ {
wxPNGInfoStruct *info = png_ptr ? WX_PNG_INFO(png_ptr) : NULL; wxPNGInfoStruct *info = png_ptr ? WX_PNG_INFO(png_ptr) : NULL;
if ( !info || info->verbose ) if ( !info || info->verbose )
{
wxLogWarning( wxString::FromAscii(message) ); wxLogWarning( wxString::FromAscii(message) );
}
} }
// from pngerror.c // from pngerror.c
@@ -608,7 +610,9 @@ wxPNGHandler::LoadFile(wxImage *image,
error: error:
if (verbose) if (verbose)
{
wxLogError(_("Couldn't load a PNG image - file is corrupted or not enough memory.")); wxLogError(_("Couldn't load a PNG image - file is corrupted or not enough memory."));
}
if ( image->Ok() ) if ( image->Ok() )
{ {
@@ -657,7 +661,9 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos
if (!png_ptr) if (!png_ptr)
{ {
if (verbose) if (verbose)
{
wxLogError(_("Couldn't save PNG image.")); wxLogError(_("Couldn't save PNG image."));
}
return false; return false;
} }
@@ -666,7 +672,9 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos
{ {
png_destroy_write_struct( &png_ptr, (png_infopp)NULL ); png_destroy_write_struct( &png_ptr, (png_infopp)NULL );
if (verbose) if (verbose)
{
wxLogError(_("Couldn't save PNG image.")); wxLogError(_("Couldn't save PNG image."));
}
return false; return false;
} }
@@ -674,7 +682,9 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos
{ {
png_destroy_write_struct( &png_ptr, (png_infopp)NULL ); png_destroy_write_struct( &png_ptr, (png_infopp)NULL );
if (verbose) if (verbose)
{
wxLogError(_("Couldn't save PNG image.")); wxLogError(_("Couldn't save PNG image."));
}
return false; return false;
} }

View File

@@ -69,7 +69,10 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
case wxT('5'): // RAW Grey case wxT('5'): // RAW Grey
case wxT('6'): break; case wxT('6'): break;
default: default:
if (verbose) wxLogError(_("PNM: File format is not recognized.")); if (verbose)
{
wxLogError(_("PNM: File format is not recognized."));
}
return false; return false;
} }
@@ -85,7 +88,9 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
if (!ptr) if (!ptr)
{ {
if (verbose) if (verbose)
{
wxLogError( _("PNM: Couldn't allocate memory.") ); wxLogError( _("PNM: Couldn't allocate memory.") );
}
return false; return false;
} }
@@ -103,7 +108,10 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
*ptr++=(unsigned char)value; // B *ptr++=(unsigned char)value; // B
if ( !buf_stream ) if ( !buf_stream )
{ {
if (verbose) wxLogError(_("PNM: File seems truncated.")); if (verbose)
{
wxLogError(_("PNM: File seems truncated."));
}
return false; return false;
} }
} }
@@ -122,7 +130,10 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
if ( !buf_stream ) if ( !buf_stream )
{ {
if (verbose) wxLogError(_("PNM: File seems truncated.")); if (verbose)
{
wxLogError(_("PNM: File seems truncated."));
}
return false; return false;
} }
} }
@@ -141,7 +152,10 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
*ptr++=value; // B *ptr++=value; // B
if ( !buf_stream ) if ( !buf_stream )
{ {
if (verbose) wxLogError(_("PNM: File seems truncated.")); if (verbose)
{
wxLogError(_("PNM: File seems truncated."));
}
return false; return false;
} }
} }

View File

@@ -669,7 +669,9 @@ bool wxTGAHandler::LoadFile(wxImage* image,
if ( !CanRead(stream) ) if ( !CanRead(stream) )
{ {
if ( verbose ) if ( verbose )
{
wxLogError(wxT("TGA: this is not a TGA file.")); wxLogError(wxT("TGA: this is not a TGA file."));
}
return false; return false;
} }

View File

@@ -270,7 +270,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
if (!tif) if (!tif)
{ {
if (verbose) if (verbose)
{
wxLogError( _("TIFF: Error loading image.") ); wxLogError( _("TIFF: Error loading image.") );
}
return false; return false;
} }
@@ -278,7 +280,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
if (!TIFFSetDirectory( tif, (tdir_t)index )) if (!TIFFSetDirectory( tif, (tdir_t)index ))
{ {
if (verbose) if (verbose)
{
wxLogError( _("Invalid TIFF image index.") ); wxLogError( _("Invalid TIFF image index.") );
}
TIFFClose( tif ); TIFFClose( tif );
@@ -305,7 +309,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
if ( bytesNeeded >= wxUINT32_MAX ) if ( bytesNeeded >= wxUINT32_MAX )
{ {
if ( verbose ) if ( verbose )
{
wxLogError( _("TIFF: Image size is abnormally big.") ); wxLogError( _("TIFF: Image size is abnormally big.") );
}
TIFFClose(tif); TIFFClose(tif);
@@ -317,7 +323,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
if (!raster) if (!raster)
{ {
if (verbose) if (verbose)
{
wxLogError( _("TIFF: Couldn't allocate memory.") ); wxLogError( _("TIFF: Couldn't allocate memory.") );
}
TIFFClose( tif ); TIFFClose( tif );
@@ -328,7 +336,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
if (!image->Ok()) if (!image->Ok())
{ {
if (verbose) if (verbose)
{
wxLogError( _("TIFF: Couldn't allocate memory.") ); wxLogError( _("TIFF: Couldn't allocate memory.") );
}
_TIFFfree( raster ); _TIFFfree( raster );
TIFFClose( tif ); TIFFClose( tif );
@@ -342,7 +352,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
if (!TIFFReadRGBAImage( tif, w, h, raster, 0 )) if (!TIFFReadRGBAImage( tif, w, h, raster, 0 ))
{ {
if (verbose) if (verbose)
{
wxLogError( _("TIFF: Error reading image.") ); wxLogError( _("TIFF: Error reading image.") );
}
_TIFFfree( raster ); _TIFFfree( raster );
image->Destroy(); image->Destroy();
@@ -450,7 +462,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
if (!tif) if (!tif)
{ {
if (verbose) if (verbose)
{
wxLogError( _("TIFF: Error saving image.") ); wxLogError( _("TIFF: Error saving image.") );
}
return false; return false;
} }
@@ -530,7 +544,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
if (!buf) if (!buf)
{ {
if (verbose) if (verbose)
{
wxLogError( _("TIFF: Couldn't allocate memory.") ); wxLogError( _("TIFF: Couldn't allocate memory.") );
}
TIFFClose( tif ); TIFFClose( tif );
@@ -576,7 +592,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
if ( TIFFWriteScanline(tif, buf ? buf : ptr, (uint32)row, 0) < 0 ) if ( TIFFWriteScanline(tif, buf ? buf : ptr, (uint32)row, 0) < 0 )
{ {
if (verbose) if (verbose)
{
wxLogError( _("TIFF: Error writing image.") ); wxLogError( _("TIFF: Error writing image.") );
}
TIFFClose( tif ); TIFFClose( tif );
if (buf) if (buf)

View File

@@ -1635,7 +1635,9 @@ bool wxLocale::Init(const wxString& name,
m_pszOldLocale = NULL; m_pszOldLocale = NULL;
if ( m_pszOldLocale == NULL ) if ( m_pszOldLocale == NULL )
{
wxLogError(_("locale '%s' can not be set."), szLocale); wxLogError(_("locale '%s' can not be set."), szLocale);
}
// the short name will be used to look for catalog files as well, // the short name will be used to look for catalog files as well,
// so we need something here // so we need something here

View File

@@ -137,82 +137,9 @@ PreviousLogInfo gs_prevLog;
// ============================================================================ // ============================================================================
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// implementation of Log functions // helper global functions
//
// NB: unfortunately we need all these distinct functions, we can't make them
// macros and not all compilers inline vararg functions.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// generic log function
void wxVLogGeneric(wxLogLevel level, const wxString& format, va_list argptr)
{
if ( wxLog::IsEnabled() )
{
wxLog::OnLog(level, wxString::FormatV(format, argptr));
}
}
#if !wxUSE_UTF8_LOCALE_ONLY
void wxDoLogGenericWchar(wxLogLevel level, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogGeneric(level, format, argptr);
va_end(argptr);
}
#endif // wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void wxDoLogGenericUtf8(wxLogLevel level, const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogGeneric(level, format, argptr);
va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
#if !wxUSE_UTF8_LOCALE_ONLY
#define IMPLEMENT_LOG_FUNCTION_WCHAR(level) \
void wxDoLog##level##Wchar(const wxChar *format, ...) \
{ \
va_list argptr; \
va_start(argptr, format); \
wxVLog##level(format, argptr); \
va_end(argptr); \
}
#else
#define IMPLEMENT_LOG_FUNCTION_WCHAR(level)
#endif
#if wxUSE_UNICODE_UTF8
#define IMPLEMENT_LOG_FUNCTION_UTF8(level) \
void wxDoLog##level##Utf8(const char *format, ...) \
{ \
va_list argptr; \
va_start(argptr, format); \
wxVLog##level(format, argptr); \
va_end(argptr); \
}
#else
#define IMPLEMENT_LOG_FUNCTION_UTF8(level)
#endif
#define IMPLEMENT_LOG_FUNCTION(level) \
void wxVLog##level(const wxString& format, va_list argptr) \
{ \
if ( wxLog::IsEnabled() ) \
wxLog::OnLog(wxLOG_##level, wxString::FormatV(format, argptr)); \
} \
IMPLEMENT_LOG_FUNCTION_WCHAR(level) \
IMPLEMENT_LOG_FUNCTION_UTF8(level)
IMPLEMENT_LOG_FUNCTION(Error)
IMPLEMENT_LOG_FUNCTION(Warning)
IMPLEMENT_LOG_FUNCTION(Message)
IMPLEMENT_LOG_FUNCTION(Info)
IMPLEMENT_LOG_FUNCTION(Status)
void wxSafeShowMessage(const wxString& title, const wxString& text) void wxSafeShowMessage(const wxString& title, const wxString& text)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
@@ -223,291 +150,6 @@ void wxSafeShowMessage(const wxString& title, const wxString& text)
#endif #endif
} }
// fatal errors can't be suppressed nor handled by the custom log target and
// always terminate the program
void wxVLogFatalError(const wxString& format, va_list argptr)
{
wxSafeShowMessage(wxS("Fatal Error"), wxString::FormatV(format, argptr));
#ifdef __WXWINCE__
ExitThread(3);
#else
abort();
#endif
}
#if !wxUSE_UTF8_LOCALE_ONLY
void wxDoLogFatalErrorWchar(const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogFatalError(format, argptr);
// some compilers warn about unreachable code and it shouldn't matter
// for the others anyhow...
//va_end(argptr);
}
#endif // wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void wxDoLogFatalErrorUtf8(const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogFatalError(format, argptr);
// some compilers warn about unreachable code and it shouldn't matter
// for the others anyhow...
//va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
// same as info, but only if 'verbose' mode is on
void wxVLogVerbose(const wxString& format, va_list argptr)
{
if ( wxLog::IsEnabled() ) {
if ( wxLog::GetActiveTarget() != NULL && wxLog::GetVerbose() )
wxLog::OnLog(wxLOG_Info, wxString::FormatV(format, argptr));
}
}
#if !wxUSE_UTF8_LOCALE_ONLY
void wxDoLogVerboseWchar(const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogVerbose(format, argptr);
va_end(argptr);
}
#endif // !wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void wxDoLogVerboseUtf8(const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogVerbose(format, argptr);
va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
// ----------------------------------------------------------------------------
// debug and trace functions
// ----------------------------------------------------------------------------
#if wxUSE_LOG_DEBUG
void wxVLogDebug(const wxString& format, va_list argptr)
{
if ( wxLog::IsEnabled() )
{
wxLog::OnLog(wxLOG_Debug, wxString::FormatV(format, argptr));
}
}
#if !wxUSE_UTF8_LOCALE_ONLY
void wxDoLogDebugWchar(const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogDebug(format, argptr);
va_end(argptr);
}
#endif // !wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void wxDoLogDebugUtf8(const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogDebug(format, argptr);
va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
#endif // wxUSE_LOG_DEBUG
#if wxUSE_LOG_TRACE
void wxVLogTrace(const wxString& mask, const wxString& format, va_list argptr)
{
if ( wxLog::IsEnabled() && wxLog::IsAllowedTraceMask(mask) ) {
wxString msg;
msg << wxS("(") << mask << wxS(") ") << wxString::FormatV(format, argptr);
wxLog::OnLog(wxLOG_Trace, msg);
}
}
#if !wxUSE_UTF8_LOCALE_ONLY
void wxDoLogTraceWchar(const wxString& mask, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
#endif // !wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void wxDoLogTraceUtf8(const wxString& mask, const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
// deprecated (but not declared as such because we don't want to complicate
// DECLARE_LOG_FUNCTION macros even more) overloads for wxTraceMask
#if WXWIN_COMPATIBILITY_2_8
void wxVLogTrace(wxTraceMask mask, const wxString& format, va_list argptr)
{
// we check that all of mask bits are set in the current mask, so
// that wxLogTrace(wxTraceRefCount | wxTraceOle) will only do something
// if both bits are set.
if ( wxLog::IsEnabled() && ((wxLog::GetTraceMask() & mask) == mask) ) {
wxLog::OnLog(wxLOG_Trace, wxString::FormatV(format, argptr));
}
}
#if !wxUSE_UTF8_LOCALE_ONLY
void wxDoLogTraceWchar(wxTraceMask mask, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
#endif // !wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void wxDoLogTraceUtf8(wxTraceMask mask, const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
#endif // WXWIN_COMPATIBILITY_2_8
#ifdef __WATCOMC__
#if WXWIN_COMPATIBILITY_2_8
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
void wxDoLogTraceWchar(int mask, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
#endif // WXWIN_COMPATIBILITY_2_8
void wxDoLogTraceWchar(const char *mask, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
void wxDoLogTraceWchar(const wchar_t *mask, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
#if WXWIN_COMPATIBILITY_2_8
void wxVLogTrace(int mask, const wxString& format, va_list argptr)
{ wxVLogTrace((wxTraceMask)mask, format, argptr); }
#endif // WXWIN_COMPATIBILITY_2_8
void wxVLogTrace(const char *mask, const wxString& format, va_list argptr)
{ wxVLogTrace(wxString(mask), format, argptr); }
void wxVLogTrace(const wchar_t *mask, const wxString& format, va_list argptr)
{ wxVLogTrace(wxString(mask), format, argptr); }
#endif // __WATCOMC__
#endif // wxUSE_LOG_TRACE
// wxLogSysError: one uses the last error code, for other you must give it
// explicitly
// return the system error message description
static inline wxString wxLogSysErrorHelper(long err)
{
return wxString::Format(_(" (error %ld: %s)"), err, wxSysErrorMsg(err));
}
void WXDLLIMPEXP_BASE wxVLogSysError(const wxString& format, va_list argptr)
{
wxVLogSysError(wxSysErrorCode(), format, argptr);
}
#if !wxUSE_UTF8_LOCALE_ONLY
void WXDLLIMPEXP_BASE wxDoLogSysErrorWchar(const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogSysError(format, argptr);
va_end(argptr);
}
#endif // !wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void WXDLLIMPEXP_BASE wxDoLogSysErrorUtf8(const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogSysError(format, argptr);
va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
void WXDLLIMPEXP_BASE wxVLogSysError(long err, const wxString& format, va_list argptr)
{
if ( wxLog::IsEnabled() )
{
wxLog::OnLog(wxLOG_Error,
wxString::FormatV(format, argptr) + wxLogSysErrorHelper(err));
}
}
#if !wxUSE_UTF8_LOCALE_ONLY
void WXDLLIMPEXP_BASE wxDoLogSysErrorWchar(long lErrCode, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogSysError(lErrCode, format, argptr);
va_end(argptr);
}
#endif // !wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void WXDLLIMPEXP_BASE wxDoLogSysErrorUtf8(long lErrCode, const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogSysError(lErrCode, format, argptr);
va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
void WXDLLIMPEXP_BASE wxDoLogSysErrorWchar(unsigned long lErrCode, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogSysError(lErrCode, format, argptr);
va_end(argptr);
}
void WXDLLIMPEXP_BASE wxVLogSysError(unsigned long err, const wxString& format, va_list argptr)
{ wxVLogSysError((long)err, format, argptr); }
#endif // __WATCOMC__
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxLog class implementation // wxLog class implementation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -581,35 +223,65 @@ wxLog::OnLog(wxLogLevel level,
const wxString& msg, const wxString& msg,
const wxLogRecordInfo& info) const wxLogRecordInfo& info)
{ {
if ( IsEnabled() && ms_logLevel >= level ) // fatal errors can't be suppressed nor handled by the custom log target
// and always terminate the program
if ( level == wxLOG_FatalError )
{ {
wxLog *pLogger = GetActiveTarget(); wxSafeShowMessage(wxS("Fatal Error"), msg);
if ( pLogger )
{
if ( GetRepetitionCounting() )
{
wxCRIT_SECT_LOCKER(lock, GetPreviousLogCS());
if ( msg == gs_prevLog.msg ) #ifdef __WXWINCE__
{ ExitThread(3);
gs_prevLog.numRepeated++; #else
abort();
// nothing else to do, in particular, don't log the #endif
// repeated message
return;
}
pLogger->LogLastRepeatIfNeededUnlocked();
// reset repetition counter for a new message
gs_prevLog.msg = msg;
gs_prevLog.level = level;
gs_prevLog.info = info;
}
pLogger->DoLogRecord(level, msg, info);
}
} }
wxLog *pLogger = GetActiveTarget();
if ( !pLogger )
return;
if ( GetRepetitionCounting() )
{
wxCRIT_SECT_LOCKER(lock, GetPreviousLogCS());
if ( msg == gs_prevLog.msg )
{
gs_prevLog.numRepeated++;
// nothing else to do, in particular, don't log the
// repeated message
return;
}
pLogger->LogLastRepeatIfNeededUnlocked();
// reset repetition counter for a new message
gs_prevLog.msg = msg;
gs_prevLog.level = level;
gs_prevLog.info = info;
}
// handle extra data which may be passed to us by wxLogXXX()
wxString prefix, suffix;
wxUIntPtr num;
if ( info.GetNumValue(wxLOG_KEY_SYS_ERROR_CODE, &num) )
{
long err = static_cast<long>(num);
if ( !err )
err = wxSysErrorCode();
suffix.Printf(_(" (error %ld: %s)"), err, wxSysErrorMsg(err));
}
#if wxUSE_LOG_TRACE
wxString str;
if ( level == wxLOG_Trace && info.GetStrValue(wxLOG_KEY_TRACE_MASK, &str) )
{
prefix = "(" + str + ") ";
}
#endif // wxUSE_LOG_TRACE
pLogger->DoLogRecord(level, prefix + msg + suffix, info);
} }
void wxLog::DoLogRecord(wxLogLevel level, void wxLog::DoLogRecord(wxLogLevel level,

View File

@@ -176,7 +176,7 @@ void wxMessageOutputLog::Output(const wxString& str)
out.Replace(wxT("\t"), wxT(" ")); out.Replace(wxT("\t"), wxT(" "));
::wxLogMessage(wxT("%s"), out.c_str()); wxLogMessage(wxT("%s"), out.c_str());
} }
#endif // wxUSE_BASE #endif // wxUSE_BASE

View File

@@ -819,7 +819,9 @@ void wxSocketBase::Init()
// this Initialize() will be undone by wxSocketModule::OnExit(), all // this Initialize() will be undone by wxSocketModule::OnExit(), all
// the other calls to it should be matched by a call to Shutdown() // the other calls to it should be matched by a call to Shutdown()
if (!Initialize()) if (!Initialize())
{
wxLogError("Cannot initialize wxSocketBase"); wxLogError("Cannot initialize wxSocketBase");
}
} }
} }

View File

@@ -793,7 +793,9 @@ wxStreamError wxTarInputStream::ReadHeaders()
while (!done) { while (!done) {
m_hdr->Read(*m_parent_i_stream); m_hdr->Read(*m_parent_i_stream);
if (m_parent_i_stream->Eof()) if (m_parent_i_stream->Eof())
{
wxLogError(_("incomplete header block in tar")); wxLogError(_("incomplete header block in tar"));
}
if (!*m_parent_i_stream) if (!*m_parent_i_stream)
return wxSTREAM_READ_ERROR; return wxSTREAM_READ_ERROR;
m_offset += TAR_BLOCKSIZE; m_offset += TAR_BLOCKSIZE;
@@ -1040,7 +1042,9 @@ size_t wxTarInputStream::OnSysRead(void *buffer, size_t size)
} else if (!m_parent_i_stream->IsOk()) { } else if (!m_parent_i_stream->IsOk()) {
// any other error will have been reported by the underlying stream // any other error will have been reported by the underlying stream
if (m_parent_i_stream->Eof()) if (m_parent_i_stream->Eof())
{
wxLogError(_("unexpected end of file")); wxLogError(_("unexpected end of file"));
}
m_lasterror = wxSTREAM_READ_ERROR; m_lasterror = wxSTREAM_READ_ERROR;
} }

View File

@@ -1269,7 +1269,9 @@ bool wxZipEndRec::Read(wxInputStream& stream, wxMBConv& conv)
if (m_DiskNumber != 0 || m_StartDisk != 0 || if (m_DiskNumber != 0 || m_StartDisk != 0 ||
m_EntriesHere != m_TotalEntries) m_EntriesHere != m_TotalEntries)
{
wxLogWarning(_("assuming this is a multi-part zip concatenated")); wxLogWarning(_("assuming this is a multi-part zip concatenated"));
}
return true; return true;
} }

View File

@@ -224,7 +224,9 @@ size_t wxZlibInputStream::OnSysRead(void *buffer, size_t size)
// by the parent strean, // by the parent strean,
m_lasterror = wxSTREAM_READ_ERROR; m_lasterror = wxSTREAM_READ_ERROR;
if (m_parent_i_stream->Eof()) if (m_parent_i_stream->Eof())
{
wxLogError(_("Can't read inflate stream: unexpected EOF in underlying stream.")); wxLogError(_("Can't read inflate stream: unexpected EOF in underlying stream."));
}
break; break;
default: default:

View File

@@ -201,60 +201,10 @@ static int OpenLogFile(wxFile& file, wxString *filename = NULL, wxWindow *parent
#endif // CAN_SAVE_FILES #endif // CAN_SAVE_FILES
// ----------------------------------------------------------------------------
// global variables
// ----------------------------------------------------------------------------
// we use a global variable to store the frame pointer for wxLogStatus - bad,
// but it's the easiest way
static wxFrame *gs_pFrame = NULL; // FIXME MT-unsafe
// ============================================================================ // ============================================================================
// implementation // implementation
// ============================================================================ // ============================================================================
// ----------------------------------------------------------------------------
// global functions
// ----------------------------------------------------------------------------
// accepts an additional argument which tells to which frame the output should
// be directed
void wxVLogStatus(wxFrame *pFrame, const wxString& format, va_list argptr)
{
wxString msg;
wxLog *pLog = wxLog::GetActiveTarget();
if ( pLog != NULL )
{
msg.PrintfV(format, argptr);
wxASSERT( gs_pFrame == NULL ); // should be reset!
gs_pFrame = pFrame;
wxLog::OnLog(wxLOG_Status, msg);
gs_pFrame = NULL;
}
}
#if !wxUSE_UTF8_LOCALE_ONLY
void wxDoLogStatusWchar(wxFrame *pFrame, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogStatus(pFrame, format, argptr);
va_end(argptr);
}
#endif // !wxUSE_UTF8_LOCALE_ONLY
#if wxUSE_UNICODE_UTF8
void wxDoLogStatusUtf8(wxFrame *pFrame, const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogStatus(pFrame, format, argptr);
va_end(argptr);
}
#endif // wxUSE_UNICODE_UTF8
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxLogGui implementation (FIXME MT-unsafe) // wxLogGui implementation (FIXME MT-unsafe)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -420,8 +370,16 @@ void wxLogGui::DoLogRecord(wxLogLevel level,
case wxLOG_Status: case wxLOG_Status:
#if wxUSE_STATUSBAR #if wxUSE_STATUSBAR
{ {
wxFrame *pFrame = NULL;
// check if the frame was passed to us explicitly
wxUIntPtr ptr;
if ( info.GetNumValue(wxLOG_KEY_FRAME, &ptr) )
{
pFrame = static_cast<wxFrame *>(wxUIntToPtr(ptr));
}
// find the top window and set it's status text if it has any // find the top window and set it's status text if it has any
wxFrame *pFrame = gs_pFrame;
if ( pFrame == NULL ) { if ( pFrame == NULL ) {
wxWindow *pWin = wxTheApp->GetTopWindow(); wxWindow *pWin = wxTheApp->GetTopWindow();
if ( pWin != NULL && pWin->IsKindOf(CLASSINFO(wxFrame)) ) { if ( pWin != NULL && pWin->IsKindOf(CLASSINFO(wxFrame)) ) {
@@ -1080,7 +1038,9 @@ void wxLogDialog::OnSave(wxCommandEvent& WXUNUSED(event))
} }
if ( !rc || !file.Write(GetLogMessages()) || !file.Close() ) if ( !rc || !file.Write(GetLogMessages()) || !file.Close() )
{
wxLogError(_("Can't save log contents to file.")); wxLogError(_("Can't save log contents to file."));
}
} }
#endif // CAN_SAVE_FILES #endif // CAN_SAVE_FILES

View File

@@ -2572,9 +2572,11 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *WXUNUSED(column),
wx_model->GetValue( value, item, cell->GetOwner()->GetModelColumn() ); wx_model->GetValue( value, item, cell->GetOwner()->GetModelColumn() );
if (value.GetType() != cell->GetVariantType()) if (value.GetType() != cell->GetVariantType())
{
wxLogError( wxT("Wrong type, required: %s but: %s"), wxLogError( wxT("Wrong type, required: %s but: %s"),
value.GetType().c_str(), value.GetType().c_str(),
cell->GetVariantType().c_str() ); cell->GetVariantType().c_str() );
}
cell->SetValue( value ); cell->SetValue( value );

View File

@@ -4671,7 +4671,9 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR
int s1 = selectionRange.GetStart()-1; int s1 = selectionRange.GetStart()-1;
int fragmentLen = s1 - r1 + 1; int fragmentLen = s1 - r1 + 1;
if (fragmentLen < 0) if (fragmentLen < 0)
{
wxLogDebug(wxT("Mid(%d, %d"), (int)(r1 - offset), (int)fragmentLen); wxLogDebug(wxT("Mid(%d, %d"), (int)(r1 - offset), (int)fragmentLen);
}
wxString stringFragment = str.Mid(r1 - offset, fragmentLen); wxString stringFragment = str.Mid(r1 - offset, fragmentLen);
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false); DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false);
@@ -4702,7 +4704,9 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR
int fragmentLen = s2 - s1 + 1; int fragmentLen = s2 - s1 + 1;
if (fragmentLen < 0) if (fragmentLen < 0)
{
wxLogDebug(wxT("Mid(%d, %d"), (int)(s1 - offset), (int)fragmentLen); wxLogDebug(wxT("Mid(%d, %d"), (int)(s1 - offset), (int)fragmentLen);
}
wxString stringFragment = str.Mid(s1 - offset, fragmentLen); wxString stringFragment = str.Mid(s1 - offset, fragmentLen);
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, true); DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, true);
@@ -4733,7 +4737,9 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR
int fragmentLen = r2 - s2 + 1; int fragmentLen = r2 - s2 + 1;
if (fragmentLen < 0) if (fragmentLen < 0)
{
wxLogDebug(wxT("Mid(%d, %d"), (int)(s2 - offset), (int)fragmentLen); wxLogDebug(wxT("Mid(%d, %d"), (int)(s2 - offset), (int)fragmentLen);
}
wxString stringFragment = str.Mid(s2 - offset, fragmentLen); wxString stringFragment = str.Mid(s2 - offset, fragmentLen);
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false); DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false);