- Fixed wxDb::Open(wxDbConnectInf) when using connection string (Hellwolf Misty)
- Fixed crash in wxDb::Open() in Unicode build (Massimiliano Marretta)
- Fixed wxTimeSpan::Format() for negative time spans
+- Optionally count repeating wxLog messages instead of logging all (Lauri Nurmi)
All (GUI):
\helpref{SetTimestamp}{wxlogsettimestamp}\\
\helpref{GetTimestamp}{wxloggettimestamp}\\
\helpref{SetTraceMask}{wxlogsettracemask}\\
-\helpref{GetTraceMask}{wxloggettracemask}
+\helpref{GetTraceMask}{wxloggettracemask}\\
+\helpref{SetRepetitionCounting}{wxlogsetrepetitioncounting}\\
+\helpref{GetRepetitionCounting}{wxloggetrepetitioncounting}
%%%%% MEMBERS HERE %%%%%
\helponly{\insertatlevel{2}{
Returns the current log level limit.
+\membersection{wxLog::SetRepetitionCounting}\label{wxlogsetrepetitioncounting}
+
+\func{static void}{SetRepetitionCounting}{\param{bool }{ repetCounting = true}}
+
+Enables logging mode in which a log message is logged once, and in case exactly
+the same message successively repeats one or more times, only the number of
+repetitions is logged.
+
+\membersection{wxLog::GetRepetitionCounting}\label{wxloggetrepetitioncounting}
+
+\func{static bool}{GetRepetitionCounting}{\void}
+
+Returns whether the repetition counting mode is enabled.
+
+
\membersection{wxLog::SetTimestamp}\label{wxlogsettimestamp}
\func{void}{SetTimestamp}{\param{const char * }{ format}}
// static sink function - see DoLog() for function to overload in the
// derived classes
- static void OnLog(wxLogLevel level, const wxChar *szString, time_t t)
- {
- if ( IsEnabled() && ms_logLevel >= level )
- {
- wxLog *pLogger = GetActiveTarget();
- if ( pLogger )
- pLogger->DoLog(level, szString, t);
- }
- }
+ static void OnLog(wxLogLevel level, const wxChar *szString, time_t t);
// message buffering
// current is NULL?
static void DontCreateOnDemand();
+ // log the count of repeating messages instead of logging the messages
+ // multiple times
+ static void SetRepetitionCounting(bool bRepetCounting = true)
+ { ms_bRepetCounting = bRepetCounting; }
+
+ // gets duplicate counting status
+ static bool GetRepetitionCounting() { return ms_bRepetCounting; }
+
// trace mask (see wxTraceXXX constants for details)
static void SetTraceMask(wxTraceMask ulMask) { ms_ulTraceMask = ulMask; }
static void TimeStamp(wxString *str);
// make dtor virtual for all derived classes
- virtual ~wxLog() { }
+ virtual ~wxLog();
// this method exists for backwards compatibility only, don't use
// you override DoLog() you might not need it at all
virtual void DoLogString(const wxChar *szString, time_t t);
+ // log a line containing the number of times the previous message was
+ // repeated
+ // returns: the number
+ static unsigned DoLogNumberOfRepeats();
+
private:
// static variables
// ----------------
+ // traditional behaviour or counting repetitions
+ static bool ms_bRepetCounting;
+ static wxString ms_prevString; // previous message that was logged
+ // how many times the previous message was logged
+ static unsigned ms_prevCounter;
+ static time_t ms_prevTimeStamp;// timestamp of the previous message
+ static wxLogLevel ms_prevLevel; // level of the previous message
+
static wxLog *ms_pLogger; // currently active log sink
static bool ms_doLog; // false => all logging disabled
static bool ms_bAutoCreate; // create new log targets on demand?
// wxLog class implementation
// ----------------------------------------------------------------------------
+/* static */
+unsigned wxLog::DoLogNumberOfRepeats()
+{
+ long retval = ms_prevCounter;
+ wxLog *pLogger = GetActiveTarget();
+ if ( pLogger && ms_prevCounter > 0 )
+ {
+ wxString msg;
+ msg.Printf(wxPLURAL("The previous message repeated once.",
+ "The previous message repeated %lu times.",
+ ms_prevCounter),
+ ms_prevCounter);
+ ms_prevCounter = 0;
+ ms_prevString.clear();
+ pLogger->DoLog(ms_prevLevel, msg.c_str(), ms_prevTimeStamp);
+ }
+ return retval;
+}
+
+wxLog::~wxLog()
+{
+ if ( ms_prevCounter > 0 )
+ {
+ // looks like the repeat count has not been logged yet,
+ // so let's do it now
+ wxLog::DoLogNumberOfRepeats();
+ }
+}
+
+/* static */
+void wxLog::OnLog(wxLogLevel level, const wxChar *szString, time_t t)
+{
+ if ( IsEnabled() && ms_logLevel >= level )
+ {
+ wxLog *pLogger = GetActiveTarget();
+ if ( pLogger )
+ {
+ if ( GetRepetitionCounting() && ms_prevString == szString )
+ {
+ ms_prevCounter++;
+ }
+ else
+ {
+ if ( GetRepetitionCounting() )
+ {
+ pLogger->DoLogNumberOfRepeats();
+ }
+ ms_prevString = szString;
+ ms_prevLevel = level;
+ ms_prevTimeStamp = t;
+ pLogger->DoLog(level, szString, t);
+ }
+ }
+ }
+}
+
wxChar *wxLog::SetLogBuffer( wxChar *buf, size_t size)
{
wxChar *oldbuf = s_szBuf;
// static variables
// ----------------------------------------------------------------------------
+bool wxLog::ms_bRepetCounting = false;
+wxString wxLog::ms_prevString;
+size_t wxLog::ms_prevCounter = 0;
+time_t wxLog::ms_prevTimeStamp= 0;
+wxLogLevel wxLog::ms_prevLevel;
+
wxLog *wxLog::ms_pLogger = (wxLog *)NULL;
bool wxLog::ms_doLog = true;
bool wxLog::ms_bAutoCreate = true;
// do it right now to block any new calls to Flush() while we're here
m_bHasMessages = false;
+ unsigned repeatCount = 0;
+ if ( wxLog::GetRepetitionCounting() )
+ {
+ repeatCount = wxLog::DoLogNumberOfRepeats();
+ }
+
wxString appName = wxTheApp->GetAppName();
if ( !appName.empty() )
appName[0u] = (wxChar)wxToupper(appName[0u]);
{
#if wxUSE_LOG_DIALOG
+ if ( repeatCount > 0 )
+ m_aMessages[nMsgCount-1] += wxString::Format(wxT(" (%s)"), m_aMessages[nMsgCount-2].c_str());
wxLogDialog dlg(NULL,
m_aMessages, m_aSeverity, m_aTimes,
title, style);