Fix updating the text cursor position after editing

In some cases when editing the text (for example when removing the
selected text, or pasting a text block) the text cursor position is
updated, but its visual x position is not updated. This causes the next
cursor movements to start from a wrong position.

Force the update for those cases.

Fixes: QTBUG-78479
Change-Id: Ia496be62beec58660f5e1695e5aafae09c79684e
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
This commit is contained in:
Sona Kurazyan 2019-12-05 16:45:31 +01:00
parent ca7033935a
commit 29adc0eed9
3 changed files with 53 additions and 0 deletions

View File

@ -2261,6 +2261,7 @@ void QTextCursor::insertFragment(const QTextDocumentFragment &fragment)
d->remove();
fragment.d->insert(*this);
d->priv->endEditBlock();
d->setX();
if (fragment.d && fragment.d->doc)
d->priv->mergeCachedResources(fragment.d->doc->docHandle());

View File

@ -1283,6 +1283,8 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
} else {
QTextCursor localCursor = cursor;
localCursor.deletePreviousChar();
if (cursor.d)
cursor.d->setX();
}
goto accept;
}
@ -1322,9 +1324,13 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
else if (e == QKeySequence::Delete) {
QTextCursor localCursor = cursor;
localCursor.deleteChar();
if (cursor.d)
cursor.d->setX();
} else if (e == QKeySequence::Backspace) {
QTextCursor localCursor = cursor;
localCursor.deletePreviousChar();
if (cursor.d)
cursor.d->setX();
}else if (e == QKeySequence::DeleteEndOfWord) {
if (!cursor.hasSelection())
cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);

View File

@ -155,6 +155,7 @@ private slots:
#if QT_CONFIG(scrollbar)
void updateAfterChangeCenterOnScroll();
#endif
void updateCursorPositionAfterEdit();
private:
void createSelection();
@ -1789,5 +1790,50 @@ void tst_QPlainTextEdit::updateAfterChangeCenterOnScroll()
#endif
void tst_QPlainTextEdit::updateCursorPositionAfterEdit()
{
QPlainTextEdit plaintextEdit;
plaintextEdit.setPlainText("some text some text\nsome text some text");
const auto initialPosition = 1;
// select some text
auto cursor = plaintextEdit.textCursor();
cursor.setPosition(initialPosition, QTextCursor::MoveAnchor);
cursor.setPosition(initialPosition + 3, QTextCursor::KeepAnchor);
plaintextEdit.setTextCursor(cursor);
QVERIFY(plaintextEdit.textCursor().hasSelection());
QTest::keyClick(&plaintextEdit, Qt::Key_Delete);
QTest::keyClick(&plaintextEdit, Qt::Key_Down);
QTest::keyClick(&plaintextEdit, Qt::Key_Up);
// Moving the cursor down and up should bring it to the initial position
QCOMPARE(plaintextEdit.textCursor().position(), initialPosition);
// Test the same with backspace
cursor = plaintextEdit.textCursor();
cursor.setPosition(initialPosition + 3, QTextCursor::KeepAnchor);
plaintextEdit.setTextCursor(cursor);
QVERIFY(plaintextEdit.textCursor().hasSelection());
QTest::keyClick(&plaintextEdit, Qt::Key_Backspace);
QTest::keyClick(&plaintextEdit, Qt::Key_Down);
QTest::keyClick(&plaintextEdit, Qt::Key_Up);
// Moving the cursor down and up should bring it to the initial position
QCOMPARE(plaintextEdit.textCursor().position(), initialPosition);
// Test insertion
const QString txt("txt");
QApplication::clipboard()->setText(txt);
plaintextEdit.paste();
QTest::keyClick(&plaintextEdit, Qt::Key_Down);
QTest::keyClick(&plaintextEdit, Qt::Key_Up);
// The curser should move back to the end of the copied text
QCOMPARE(plaintextEdit.textCursor().position(), initialPosition + txt.length());
}
QTEST_MAIN(tst_QPlainTextEdit)
#include "tst_qplaintextedit.moc"