Fix broken QPlainTextDocumentLayout after removing chars
This fixes an issue where, if characters were removed from several blocks in a single edit, the document layout would end up being corrupted since the document layout manager wouldn't re-layout the proper number of text blocks. Task-number: QTBUG-30051 Change-Id: Idf3a6f567120e6a5dbebf1f65f685d374219328a Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
This commit is contained in:
parent
ff31090d07
commit
2983cb9531
@ -284,14 +284,15 @@ void QPlainTextDocumentLayoutPrivate::relayout()
|
|||||||
|
|
||||||
/*! \reimp
|
/*! \reimp
|
||||||
*/
|
*/
|
||||||
void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, int charsAdded)
|
void QPlainTextDocumentLayout::documentChanged(int from, int charsRemoved, int charsAdded)
|
||||||
{
|
{
|
||||||
Q_D(QPlainTextDocumentLayout);
|
Q_D(QPlainTextDocumentLayout);
|
||||||
QTextDocument *doc = document();
|
QTextDocument *doc = document();
|
||||||
int newBlockCount = doc->blockCount();
|
int newBlockCount = doc->blockCount();
|
||||||
|
int charsChanged = qMax(charsRemoved, charsAdded);
|
||||||
|
|
||||||
QTextBlock changeStartBlock = doc->findBlock(from);
|
QTextBlock changeStartBlock = doc->findBlock(from);
|
||||||
QTextBlock changeEndBlock = doc->findBlock(qMax(0, from + charsAdded - 1));
|
QTextBlock changeEndBlock = doc->findBlock(qMax(0, from + charsChanged - 1));
|
||||||
|
|
||||||
if (changeStartBlock == changeEndBlock && newBlockCount == d->blockCount) {
|
if (changeStartBlock == changeEndBlock && newBlockCount == d->blockCount) {
|
||||||
QTextBlock block = changeStartBlock;
|
QTextBlock block = changeStartBlock;
|
||||||
|
@ -154,6 +154,7 @@ private slots:
|
|||||||
void findBackwardWithRegExp();
|
void findBackwardWithRegExp();
|
||||||
void findWithRegExpReturnsFalseIfNoMoreResults();
|
void findWithRegExpReturnsFalseIfNoMoreResults();
|
||||||
#endif
|
#endif
|
||||||
|
void layoutAfterMultiLineRemove();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createSelection();
|
void createSelection();
|
||||||
@ -1567,5 +1568,49 @@ void tst_QPlainTextEdit::findWithRegExpReturnsFalseIfNoMoreResults()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void tst_QPlainTextEdit::layoutAfterMultiLineRemove()
|
||||||
|
{
|
||||||
|
ed->setVisible(true); // The widget must be visible to reproduce this bug.
|
||||||
|
|
||||||
|
QString contents;
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
contents.append("\ttest\n");
|
||||||
|
|
||||||
|
ed->setPlainText(contents);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove the tab from the beginning of lines 2-4, in an edit block. The
|
||||||
|
* edit block is required for the bug to be reproduced.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QTextCursor curs = ed->textCursor();
|
||||||
|
curs.movePosition(QTextCursor::Start);
|
||||||
|
curs.movePosition(QTextCursor::NextBlock);
|
||||||
|
|
||||||
|
curs.beginEditBlock();
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
curs.deleteChar();
|
||||||
|
curs.movePosition(QTextCursor::NextBlock);
|
||||||
|
}
|
||||||
|
curs.endEditBlock();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, we're going to perform the following actions:
|
||||||
|
*
|
||||||
|
* - Move to the beginning of the document.
|
||||||
|
* - Move down three times - this should put us at the front of block 3.
|
||||||
|
* - Move to the end of the line.
|
||||||
|
*
|
||||||
|
* At this point, if the document layout is behaving correctly, we should
|
||||||
|
* still be positioned on block 3. Verify that this is the case.
|
||||||
|
*/
|
||||||
|
|
||||||
|
curs.movePosition(QTextCursor::Start);
|
||||||
|
curs.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 3);
|
||||||
|
curs.movePosition(QTextCursor::EndOfLine);
|
||||||
|
|
||||||
|
QCOMPARE(curs.blockNumber(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QPlainTextEdit)
|
QTEST_MAIN(tst_QPlainTextEdit)
|
||||||
#include "tst_qplaintextedit.moc"
|
#include "tst_qplaintextedit.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user