Unsolved QSyntaxHighlighter::highlightBlock highlights previous and current block
-
Implementation:
CustomHighlighter::CustomHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) { } void CustomHighlighter::setHighlighterFormat(const QTextCharFormat &format) { this->format = format; } void CustomHighlighter::highlightBlock(const QString &text) { // if(text.isEmpty() || currentBlockState() == 1) // return; setFormat(0, text.length(), format); // setCurrentBlockState(1); } Logger::Logger(QWidget *parent) : QPlainTextEdit(parent) { setMaximumBlockCount(50); highlighter = new CustomHighlighter(document()); } Logger::~Logger() { delete highlighter; } void Logger::setFormat(const QTextCharFormat &format) { highlighter->setHighlighterFormat(format); }
Next is a timer slot, just for example:
QTextCharFormat format; format.setFontWeight(250); int x = random() % 3; switch(x) { case 0: format.setForeground(Qt::red); break; case 1: format.setForeground(Qt::green); break; case 2: format.setForeground(Qt::blue); break; } logger->setFormat(format); QDateTime date = QDateTime::currentDateTime(); logger->appendPlainText(date.toString() + "\n");
This works fine. But if new line character is removed both current appended and previous line (block) are highlighted.
-
So I added enum to check block states:
enum { FORMATTED = 1, LAST = 2 };
Then made changes in highlightBlock:
void CustomHighlighter::highlightBlock(const QString &text) { if(text.isEmpty() || currentBlockState() == LAST) return; if(currentBlockState() == FORMATTED) { setFormat(0, text.length(), previousFormat); setCurrentBlockState(LAST); } else { setFormat(0, text.length(), format); previousFormat = format; setCurrentBlockState(FORMATTED); } }
This has one problem. After maximum blocks are appended the top most block "looses" format.
But anyway it seems that I am overdoing it. And why is formatted text returned to highlightBlock? -
Okay, this works:
void CustomHighlighter::highlightBlock(const QString &text) { if(text.isEmpty()) return; int start = 0; if(currentBlockState() == LAST) { BlockFormat block = queue.dequeue(); QTextCharFormat lastFormat = block.first; int length = block.second; setFormat(start, length, lastFormat); } else if(currentBlockState() == FORMATTED) { setFormat(start, text.length(), previousFormat); setCurrentBlockState(LAST); queue.enqueue(BlockFormat(format, text.length())); } else { setFormat(start, text.length(), format); previousFormat = format; setCurrentBlockState(FORMATTED); } }
Where BlockFormat is:
typedef QPair<QTextCharFormat, int> BlockFormat;
Question is same, am I overdoing it? Is this the simplest solution?