diff options
author | Axel Spoerl <axel.spoerl@qt.io> | 2023-12-21 14:04:38 +0100 |
---|---|---|
committer | Axel Spoerl <axel.spoerl@qt.io> | 2023-12-21 21:38:26 +0100 |
commit | 729e23f15f366f013da8e149fa95e618c9a95e13 (patch) | |
tree | 865b40b1284c62a13e1cae0cd055602b3bd819db | |
parent | 9e78256579e8dc704066a98cb4816a1aab0e7e3b (diff) |
QPlainTextEdit: update viewport, when placeholder text disappears
QPlainTextEditPrivate::updatePlaceholderVisibility() issued a full
viewport update, when the document became empty and the placeholder text
needed to be shown. No update was issued, when the placeholder text was
replaced by a first text character entered.
That relied on the assumption, that the placeholder text would disappear
with the first text line being rendered (even if it has just one char).
When the placeholder text covered multiple line, only the first of them
disappeared.
This patch adds a boolean to remember, that the placeholder text is
shown. If that is the case and the first char is entered, a full update
is issued, to remove all lines of the placeholder text. The boolean flag
is cleared thereafter, to avoid unnecessary viewport updates.
isPlaceHolderTextVisible() is renamed into placeHolderTextToBeShown(),
because the method returns an instruction, rather than a state.
tst_QPlainTextEdit::placeholderVisibility() is adapted to test the
boolean flag, hence the real visibility of the placeholder text.
That extends its scope to the bug at hand.
Fixes: QTBUG-119808
Pick-to: 6.7 6.6 6.5 6.2
Change-Id: I07a7059ae619dc85d0c21247d829120e6afa7115
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
-rw-r--r-- | src/widgets/widgets/qplaintextedit.cpp | 18 | ||||
-rw-r--r-- | src/widgets/widgets/qplaintextedit_p.h | 5 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp | 2 |
3 files changed, 16 insertions, 9 deletions
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 8a0caf5962..134fc30964 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -725,8 +725,14 @@ void QPlainTextEditPrivate::updateViewport() } QPlainTextEditPrivate::QPlainTextEditPrivate() - : tabChangesFocus(false), showCursorOnInitialShow(false), backgroundVisible(false), - centerOnScroll(false), inDrag(false), clickCausedFocus(false), pageUpDownLastCursorYIsValid(false) + : tabChangesFocus(false) + , showCursorOnInitialShow(false) + , backgroundVisible(false) + , centerOnScroll(false) + , inDrag(false) + , clickCausedFocus(false) + , pageUpDownLastCursorYIsValid(false) + , placeholderTextShown(false) { } @@ -793,14 +799,14 @@ void QPlainTextEditPrivate::init(const QString &txt) void QPlainTextEditPrivate::updatePlaceholderVisibility() { - Q_Q(QPlainTextEdit); - // We normally only repaint the part of view that contains text in the // document that has changed (in repaintContents). But the placeholder // text is not a part of the document, but is drawn on separately. So whenever // we either show or hide the placeholder text, we issue a full update. - if (q->document()->isEmpty()) + if (placeholderTextShown != placeHolderTextToBeShown()) { viewport->update(); + placeholderTextShown = placeHolderTextToBeShown(); + } } void QPlainTextEditPrivate::repaintContents(const QRectF &contentsRect) @@ -1902,7 +1908,7 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e) er.setRight(qMin(er.right(), maxX)); painter.setClipRect(er); - if (d->isPlaceHolderTextVisible()) { + if (d->placeHolderTextToBeShown()) { const QColor col = d->control->palette().placeholderText().color(); painter.setPen(col); painter.setClipRect(e->rect()); diff --git a/src/widgets/widgets/qplaintextedit_p.h b/src/widgets/widgets/qplaintextedit_p.h index f788f1a647..9ca1cdcc67 100644 --- a/src/widgets/widgets/qplaintextedit_p.h +++ b/src/widgets/widgets/qplaintextedit_p.h @@ -131,6 +131,7 @@ public: uint inDrag : 1; uint clickCausedFocus : 1; uint pageUpDownLastCursorYIsValid : 1; + uint placeholderTextShown : 1; void setTopLine(int visualTopLine, int dx = 0); void setTopBlock(int newTopBlock, int newTopLine, int dx = 0); @@ -145,9 +146,9 @@ public: void cursorPositionChanged(); void modificationChanged(bool); - inline bool isPlaceHolderTextVisible() + inline bool placeHolderTextToBeShown() const { - Q_Q(QPlainTextEdit); + Q_Q(const QPlainTextEdit); return q->document()->isEmpty() && !q->placeholderText().isEmpty(); } }; diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp index ffcb35710e..3a1d414376 100644 --- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp @@ -1916,7 +1916,7 @@ void tst_QPlainTextEdit::placeholderVisibility() plainTextEdit.show(); QVERIFY(QTest::qWaitForWindowExposed(&plainTextEdit)); - QTRY_VERIFY(plainTextEdit_d->isPlaceHolderTextVisible() == placeholderVisible); + QTRY_COMPARE(plainTextEdit_d->placeholderTextShown, placeholderVisible); } |