Qt 5 "highlight current line" doesn't render properly after "undo"
I'm working on creating a simple editing component, and one of the things I've added so far is the ability to highlight the current line (just like the CodeEditor demo shows), as well as the ability to indent a group of lines when "Tab" is pressed. However, I have encountered a bug which I simply cannot figure out how to solve - in fact, I'm beginning to suspect that it is a but in Qt's rendering of extra text selections. Here is the simplest example I could write which reproduces this bug:
Code:
#include <QApplication>
#include <QMainWindow>
#include <QPlainTextEdit>
#include "HBPlainTextEdit.h"
{
public:
HBWindow
(QWidget *p
= 0, Qt
::WindowFlags f
= 0) {
editor = new HBPlainTextEdit(this);
setCentralWidget(editor);
}
virtual ~HBWindow()
{
}
private:
HBPlainTextEdit *editor;
};
int main(int argc, char *argv[])
{
HBWindow w;
w.show();
return app.exec();
}
Code:
#ifndef INCLUDE_HB_PLAIN_TEXT_EDIT_H
#define INCLUDE_HB_PLAIN_TEXT_EDIT_H
#include <QPlainTextEdit>
class HBPlainTextEdit : public QPlainTextEdit
{
Q_OBJECT
public:
virtual ~HBPlainTextEdit();
protected:
private:
void increaseSelectionIndent();
private slots:
void highlightCurrentLine();
};
#endif
Code:
#include "HBPlainTextEdit.h"
#include <QKeyEvent>
#include <QTextBlock>
HBPlainTextEdit
::HBPlainTextEdit(QWidget *p
) : QPlainTextEdit(p)
{
QObject::connect( this,
SIGNAL( cursorPositionChanged
() ),
this, SLOT( highlightCurrentLine() ) );
highlightCurrentLine();
}
HBPlainTextEdit::~HBPlainTextEdit()
{
}
void HBPlainTextEdit
::keyPressEvent(QKeyEvent *e
) {
if( (e->modifiers() == Qt::NoModifier) &&
(e->key() == Qt::Key_Tab) &&
textCursor().hasSelection() )
{
e->accept();
increaseSelectionIndent();
}
else
{
QPlainTextEdit::keyPressEvent(e);
}
}
void HBPlainTextEdit::increaseSelectionIndent()
{ /* SLOT */
// Do nothing if we don't have a selection.
if(!curs.hasSelection())
return;
// Get the first and count of lines to indent.
int spos = curs.anchor(), epos = curs.position();
if(spos > epos)
{
int hold = spos;
spos = epos;
epos = hold;
}
int sblock = curs.block().blockNumber();
int eblock = curs.block().blockNumber();
// Do the indent.
curs.beginEditBlock();
for(int i = 0; i <= (eblock - sblock); ++i)
{
curs.insertText("\t");
}
curs.endEditBlock();
// Set our cursor's selection to span all of the involved lines.
while(curs.block().blockNumber() < eblock)
{
}
// Done!
setTextCursor(curs);
}
void HBPlainTextEdit::highlightCurrentLine()
{
QList<QTextEdit::ExtraSelection> es;
selection.
format.
setBackground(QColor(175,
175,
175));
selection.
format.
setProperty(QTextFormat::FullWidthSelection,
true);
selection.cursor = textCursor();
selection.cursor.clearSelection();
es.append(selection);
setExtraSelections(es);
}
So, to reproduce this bug, the following steps should be taken after running this example program:
- Select two or more lines of text that have been entered
- Press "tab" to indent all of the lines
- Press CTRL+Z to undo the previous action
- Note that the highlight on the last line no longer extends the full width of the editor
The highlighting can be "fixed" by:
- Adding any characters to the broken line
- Resizing the window in any way
Does anyone have any insight into what is going wrong, or whether I should be filing a bug on Qt's bug tracker?
Re: Qt 5 "highlight current line" doesn't render properly after "undo"
No-one has seen this bug before? :(