PDA

View Full Version : QPlainTextEdit::find() highlighting



cic1988
15th July 2014, 14:21
Hello,

maybe some of you have worked with the sample code, which finds the matched cases and highlights the results:




void MyEditor :: highlight(const QString& txt)
{
QList<QTextEdit::ExtraSelection> extraSelections;

if (txt.isEmpty()) {
setExtraSelections(extraSelections);
return;
}

QTextDocument::FindFlags flags = ...;
QColor color(Qt::lightGray);

while (find(txt, flags)) {
QTextEdit::ExtraSelection extra;
extra.format.setBackground(color);
extra.cursor = textCursor();
extraSelections.append(extra);
}
setExtraSelections(extraSelections);
}


so the code worked fine. text are found and highlighted from where the cursor stays till document's end.

however, when the text is very long, e.g 10000 lines. the highlighting behavior costs much time.
i thought where qplaintextedit had provided a way to update the highlighted text only in the visible page?

the code i looked into has some seemingly correct alternatives like viewportEvent(), updateRequest() etc.. (a mass of things....)

then it would, much possibly, go into another issues like:
1. update and highlight the text when user scrolls to see the new content.
2. when users during the highlighting changes the text
...

mass...:confused:

----------------------------------------------- :D im update line ------------------------------------------------------------------

worked sometime and came up a solution maybe it would help for those have similar problem like me.

i havent tested it deeply, a potential bug might be a endless loop in the updateHighlight() when it triggers highlight()





void MyEditor :: highlight(const Qtring& txt, QTextDocument::FindFlags flags, int start, int end)
{
if (document()) {
QList<QTextEdit::ExtraSelection> extraSelections;
QColor color(Qt::lightGray);

QTextCursor cursor(document());
cursor.setPosition(start);
cursor = document() -> find(txt, cursor, flags);

while (! cursor.isNull()) {
if (cursor.position() > end) {
break;
}
QTextEdit::ExtraSelection extra;
extra.format.setBackground(color);
extra.cursor = cursor;
extraSelections.append(extra);

cursor = document() -> find(txt, cursor, flags);
}
setExtraSelections(extraSelections);
}
}


void MyEditor :: updateHighlight(const QRect& rect, int dy)
{
if (dy != 0) {
if (isHighlightEnabled) {

//------------------------------------------------------------------------------
// update only the visible part
//------------------------------------------------------------------------------

QTextCursor cursor = cursorForPosition(QPoint(0, 0));
QPoint pageY = viewport() ? QPoint(viewport() -> width() - 1, viewport() -> height() - 1) : QPoint(0, 0);
highlight(txt, findFlags, cursor.position(), cursorForPosition(pageY).position());
}
}
}

MyEditor :: MyEditor(QObject* p)
{
connect(this, SIGNAL(updateRequest(const QRect&, int)), SLOT(updateHighlight(const QRect&, int)));
}


instead of using QPlainTextEdit::find() which move the cursor eachtime when he finds a result, QTextDocument::find() doesnt do that.