Commit 3a030e62 authored by Artur Grunau's avatar Artur Grunau
Browse files

Highlight the structure of log messages

Things like date-stamps, time-stamps, categories, and log levels are now
highlighted in every log message. This should make the contents of the
log viewer easier to scan by indicating which information is important.
parent f12ee2f7
......@@ -29,13 +29,15 @@
#include "loghighlighter.h"
#include <QPalette>
namespace campvis {
LogHighlighter::LogHighlighter(QTextEdit* parent)
: QSyntaxHighlighter(parent)
, _filterRegExp(0)
, _logLevelRegExp(0)
, _filterMatchFormat()
, _rules(3)
, _logLevelRules(5)
{
QBrush fgBrush = QBrush(Qt::white);
// Firefox's green highlight
......@@ -43,6 +45,45 @@ namespace campvis {
_filterMatchFormat.setBackground(bgBrush);
_filterMatchFormat.setForeground(fgBrush);
// Rules for highlighting date stamps, time stamps, and categories
std::list<std::pair<QRegExp, QTextCharFormat>>::iterator it = _rules.begin();
std::pair<QRegExp, QTextCharFormat>& dateStampRule = *it++;
dateStampRule.first.setPattern("\\[(\\d{2}\\.){2}\\d{4}\\]");
dateStampRule.second.setForeground(Qt::gray);
std::pair<QRegExp, QTextCharFormat>& timeStampRule = *it++;
timeStampRule.first.setPattern("\\[(\\d{2}:){2}\\d{2}\\]");
timeStampRule.second.setForeground(Qt::gray);
std::pair<QRegExp, QTextCharFormat>& categoryRule = *it++;
categoryRule.first.setPattern("\\w+(\\.\\w+)*");
categoryRule.second.setFontWeight(QFont::Bold);
// Rules for highlighting log levels
_logLevelRegExp = new QRegExp("\\((Debug|Info|Warning|Error|Fatal)\\)");
std::list<std::pair<QString, QTextCharFormat>>::iterator logLevelIt = _logLevelRules.begin();
std::pair<QString, QTextCharFormat>& debugRule = *logLevelIt++;
debugRule.first = "Debug";
debugRule.second.setForeground(Qt::blue);
std::pair<QString, QTextCharFormat>& infoRule = *logLevelIt++;
infoRule.first = "Info";
infoRule.second.setForeground(Qt::darkGreen);
std::pair<QString, QTextCharFormat>& warningRule = *logLevelIt++;
warningRule.first = "Warning";
warningRule.second.setForeground(Qt::darkYellow);
std::pair<QString, QTextCharFormat>& errorRule = *logLevelIt++;
errorRule.first = "Error";
errorRule.second.setForeground(Qt::red);
std::pair<QString, QTextCharFormat>& fatalRule = *logLevelIt++;
fatalRule.first = "Fatal";
fatalRule.second.setForeground(Qt::magenta);
}
LogHighlighter::~LogHighlighter() {
......@@ -59,6 +100,22 @@ namespace campvis {
void LogHighlighter::highlightBlock(const QString& text)
{
int offset = 0;
std::list<std::pair<QRegExp, QTextCharFormat>>::iterator it = _rules.begin();
do {
std::pair<QRegExp, QTextCharFormat>& rule = *it++;
offset = highlightRegExp(text, offset, rule.first, rule.second);
if (offset == -1) {
break;
}
} while (it != _rules.end());
if (offset != -1) {
highlightLogLevel(text, offset);
}
if (_filterRegExp != 0) {
highlightFilterMatches(text);
}
......@@ -75,4 +132,36 @@ namespace campvis {
}
}
int LogHighlighter::highlightRegExp(const QString &text, int offset, const QRegExp& regExp,
const QTextCharFormat& format) {
int pos = regExp.indexIn(text, offset);
if (pos != -1) {
int matchedLength = regExp.matchedLength();
setFormat(pos, matchedLength, format);
return pos + matchedLength;
}
return -1;
}
void LogHighlighter::highlightLogLevel(const QString &text, int offset) {
int pos = _logLevelRegExp->indexIn(text, offset);
if (pos != -1) {
QString& logLevel = _logLevelRegExp->cap(1);
std::list<std::pair<QString, QTextCharFormat>>::iterator it = _logLevelRules.begin();
do {
std::pair<QString, QTextCharFormat>& rule = *it++;
if (rule.first == logLevel) {
int matchedLength = _logLevelRegExp->matchedLength();
setFormat(pos, matchedLength, rule.second);
break;
}
} while (it != _logLevelRules.end());
}
}
}
......@@ -37,7 +37,7 @@ namespace campvis {
class LogHighlighter : public QSyntaxHighlighter {
Q_OBJECT;
Q_OBJECT
public:
......@@ -68,6 +68,8 @@ namespace campvis {
/**
* Set the current filter regexp to highlight.
*
* LogHighlighter takes ownership of the given regexp.
*
* \param filterRegExp the current filter regexp
*/
void setFilterRegExp(const QRegExp* filterRegExp);
......@@ -78,10 +80,32 @@ namespace campvis {
*
* \param text the log block to highlight
*/
void highlightFilterMatches(const QString &text);
void highlightFilterMatches(const QString& text);
/**
* Highlight log level information in the given log block.
*
* \param text the log block to highlight
* \param offset the offset at which log level matching should start
*/
void highlightLogLevel(const QString& text, int offset);
/**
* Highlight text matching the provided regexp in the given log block.
*
* \param text the log block to highlight
* \param offset the offset at which matching should start
* \param regExp the regular expression to match
* \param format the format used to highlight matches
* \return end of the matched string (the new offset), or -1 if nothing was matched
*/
int highlightRegExp(const QString& text, int offset, const QRegExp& regExp, const QTextCharFormat& format);
const QRegExp* _filterRegExp; ///< Current filter regexp
QTextCharFormat _filterMatchFormat; ///< Format for highlighting filter matches
const QRegExp* _filterRegExp; ///< Current filter regexp
const QRegExp* _logLevelRegExp; ///< Regexp matching log level strings
QTextCharFormat _filterMatchFormat; ///< Format for highlighting filter matches
std::list<std::pair<QRegExp, QTextCharFormat>> _rules; ///< Set of general highlighting rules
std::list<std::pair<QString, QTextCharFormat>> _logLevelRules; ///< Highlighting rules for log levels
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment