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:
parent
ca7033935a
commit
29adc0eed9
@ -2261,6 +2261,7 @@ void QTextCursor::insertFragment(const QTextDocumentFragment &fragment)
|
|||||||
d->remove();
|
d->remove();
|
||||||
fragment.d->insert(*this);
|
fragment.d->insert(*this);
|
||||||
d->priv->endEditBlock();
|
d->priv->endEditBlock();
|
||||||
|
d->setX();
|
||||||
|
|
||||||
if (fragment.d && fragment.d->doc)
|
if (fragment.d && fragment.d->doc)
|
||||||
d->priv->mergeCachedResources(fragment.d->doc->docHandle());
|
d->priv->mergeCachedResources(fragment.d->doc->docHandle());
|
||||||
|
@ -1283,6 +1283,8 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
|
|||||||
} else {
|
} else {
|
||||||
QTextCursor localCursor = cursor;
|
QTextCursor localCursor = cursor;
|
||||||
localCursor.deletePreviousChar();
|
localCursor.deletePreviousChar();
|
||||||
|
if (cursor.d)
|
||||||
|
cursor.d->setX();
|
||||||
}
|
}
|
||||||
goto accept;
|
goto accept;
|
||||||
}
|
}
|
||||||
@ -1322,9 +1324,13 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
|
|||||||
else if (e == QKeySequence::Delete) {
|
else if (e == QKeySequence::Delete) {
|
||||||
QTextCursor localCursor = cursor;
|
QTextCursor localCursor = cursor;
|
||||||
localCursor.deleteChar();
|
localCursor.deleteChar();
|
||||||
|
if (cursor.d)
|
||||||
|
cursor.d->setX();
|
||||||
} else if (e == QKeySequence::Backspace) {
|
} else if (e == QKeySequence::Backspace) {
|
||||||
QTextCursor localCursor = cursor;
|
QTextCursor localCursor = cursor;
|
||||||
localCursor.deletePreviousChar();
|
localCursor.deletePreviousChar();
|
||||||
|
if (cursor.d)
|
||||||
|
cursor.d->setX();
|
||||||
}else if (e == QKeySequence::DeleteEndOfWord) {
|
}else if (e == QKeySequence::DeleteEndOfWord) {
|
||||||
if (!cursor.hasSelection())
|
if (!cursor.hasSelection())
|
||||||
cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
|
cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
|
||||||
|
@ -155,6 +155,7 @@ private slots:
|
|||||||
#if QT_CONFIG(scrollbar)
|
#if QT_CONFIG(scrollbar)
|
||||||
void updateAfterChangeCenterOnScroll();
|
void updateAfterChangeCenterOnScroll();
|
||||||
#endif
|
#endif
|
||||||
|
void updateCursorPositionAfterEdit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createSelection();
|
void createSelection();
|
||||||
@ -1789,5 +1790,50 @@ void tst_QPlainTextEdit::updateAfterChangeCenterOnScroll()
|
|||||||
|
|
||||||
#endif
|
#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)
|
QTEST_MAIN(tst_QPlainTextEdit)
|
||||||
#include "tst_qplaintextedit.moc"
|
#include "tst_qplaintextedit.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user