From d54bb5324762ff24a012049dcf5b1b1520d9e9e8 Mon Sep 17 00:00:00 2001 From: Qiang Li Date: Thu, 9 Sep 2021 15:58:57 +0800 Subject: [PATCH] QPlainTextEdit: fix the visibility of placeholderText If one calls setPlainText("") before setting a placeholder text, the placeholder visibility is not updated, and the placeholder is not visible. Fix it by updating placeholderVisible properly. Fixes: QTBUG-96212 Pick-to: 5.15 6.2 6.3 Change-Id: I1bd3f0cb4c59973a847bcf3787e35d7c17b6d673 Reviewed-by: Volker Hilsheimer --- src/widgets/widgets/qplaintextedit.cpp | 7 +- src/widgets/widgets/qplaintextedit.h | 2 +- src/widgets/widgets/qplaintextedit_p.h | 2 +- .../qplaintextedit/tst_qplaintextedit.cpp | 105 ++++++++++++++++++ 4 files changed, 110 insertions(+), 6 deletions(-) diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 9ca5bff8277..e30bc64d236 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -793,7 +793,7 @@ void QPlainTextEditPrivate::init(const QString &txt) QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged())); QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged())); - QObject::connect(control, SIGNAL(textChanged()), q, SLOT(_q_textChanged())); + QObject::connect(control, SIGNAL(textChanged()), q, SLOT(_q_updatePlaceholderVisibility())); QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus())); // set a null page size initially to avoid any relayouting until the textedit @@ -822,7 +822,7 @@ void QPlainTextEditPrivate::init(const QString &txt) #endif } -void QPlainTextEditPrivate::_q_textChanged() +void QPlainTextEditPrivate::_q_updatePlaceholderVisibility() { Q_Q(QPlainTextEdit); @@ -1368,8 +1368,7 @@ void QPlainTextEdit::setPlaceholderText(const QString &placeholderText) Q_D(QPlainTextEdit); if (d->placeholderText != placeholderText) { d->placeholderText = placeholderText; - if (d->control->document()->isEmpty()) - d->viewport->update(); + d->_q_updatePlaceholderVisibility(); } } diff --git a/src/widgets/widgets/qplaintextedit.h b/src/widgets/widgets/qplaintextedit.h index f581e09341f..cce098136ff 100644 --- a/src/widgets/widgets/qplaintextedit.h +++ b/src/widgets/widgets/qplaintextedit.h @@ -277,7 +277,7 @@ protected: private: Q_DISABLE_COPY(QPlainTextEdit) Q_PRIVATE_SLOT(d_func(), void _q_repaintContents(const QRectF &r)) - Q_PRIVATE_SLOT(d_func(), void _q_textChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_updatePlaceholderVisibility()) Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars()) Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int)) Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged()) diff --git a/src/widgets/widgets/qplaintextedit_p.h b/src/widgets/widgets/qplaintextedit_p.h index 114db015747..85fdca5bcaa 100644 --- a/src/widgets/widgets/qplaintextedit_p.h +++ b/src/widgets/widgets/qplaintextedit_p.h @@ -121,7 +121,7 @@ public: void init(const QString &txt = QString()); void _q_repaintContents(const QRectF &contentsRect); - void _q_textChanged(); + void _q_updatePlaceholderVisibility(); inline QPoint mapToContents(const QPoint &point) const { return QPoint(point.x() + horizontalOffset(), point.y() + verticalOffset()); } diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp index 297eb5ec51a..118e4902dbf 100644 --- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -154,6 +155,8 @@ private slots: void updateCursorPositionAfterEdit(); #endif void appendTextWhenInvisible(); + void placeholderVisibility_data(); + void placeholderVisibility(); private: void createSelection(); @@ -1837,5 +1840,107 @@ void tst_QPlainTextEdit::appendTextWhenInvisible() QCOMPARE(maxAfterAppend, maxAfterSet); } +enum SetupCommand { + ClearPlaceHolder, // set empty placeholder text + SetPlaceHolder, // set a non-empty placeholder text + ClearContent, // set empty text as content + SetContent // set non-empty text as content +}; + +void tst_QPlainTextEdit::placeholderVisibility_data() +{ + QTest::addColumn>("setupCommands"); + QTest::addColumn("placeholderVisible"); + QTest::addRow("no placeholder set + no text set") + << QList{} << true; + QTest::addRow("no placeholder set + text set or text set + no placeholder set") + << QList{ SetContent } << false; + QTest::addRow("no placeholder set + text set + empty text set") + << QList{ SetContent , ClearContent } + << false; + QTest::addRow("no placeholder set + empty text set + text set") + << QList{ ClearContent, SetContent } + << false; + QTest::addRow("empty placeholder set + no text set") + << QList{ ClearPlaceHolder } << true; + QTest::addRow("empty placeholder set + text set") + << QList{ ClearPlaceHolder, SetContent } + << false; + QTest::addRow("empty placeholder set + text set + empty text set") + << QList{ ClearPlaceHolder, SetContent, ClearContent } + << false; + QTest::addRow("empty placeholder set + empty text set + text set") + << QList{ ClearPlaceHolder, ClearContent, SetContent } + << false; + QTest::addRow("placeholder set + no text set") + << QList{ SetPlaceHolder, ClearContent } + << true; + QTest::addRow("placeholder set + text set") + << QList{ SetPlaceHolder, SetContent } + << false; + QTest::addRow("placeholder set + text set + empty text set") + << QList{ SetPlaceHolder, SetContent, ClearContent } + << true; + QTest::addRow("placeholder set + empty text set + text set") + << QList{ SetPlaceHolder, ClearContent, SetContent } + << false; + QTest::addRow("placeholder set + text set + empty placeholder set") + << QList{ SetPlaceHolder, SetContent, ClearPlaceHolder} + << false; + QTest::addRow("placeholder set + empty placeholder set + text set") + << QList{ SetPlaceHolder, ClearPlaceHolder, SetContent } + << false; + QTest::addRow("placeholder set + empty placeholder set + empty text set") + << QList{ SetPlaceHolder, ClearPlaceHolder, ClearContent } + << false; + QTest::addRow("placeholder set + empty text set + empty placeholder set") + << QList{ SetPlaceHolder, ClearContent, ClearPlaceHolder } + << false; + QTest::addRow("text set + no placeholder set + empty text set") + << QList{ SetContent, ClearContent } + << false; + QTest::addRow("text set + empty placeholder set") + << QList{ SetContent, ClearPlaceHolder } + << false; + QTest::addRow("text set + placeholder set") + << QList{ SetContent, SetPlaceHolder } + << false; + QTest::addRow("text set + placeholder set + empty text set") + << QList{ SetContent, SetPlaceHolder, ClearContent } + << true; + QTest::addRow("text set + placeholder set + empty placeholder set") + << QList{ SetContent, SetPlaceHolder, ClearPlaceHolder } + << false; +} + +void tst_QPlainTextEdit::placeholderVisibility() +{ + QFETCH(QList, setupCommands); + QFETCH(bool, placeholderVisible); + + QPlainTextEdit plainTextEdit; + for (auto command : setupCommands) { + switch (command) { + case ClearPlaceHolder: + plainTextEdit.setPlaceholderText(""); + break; + case SetPlaceHolder: + plainTextEdit.setPlaceholderText("Qt is awesome !"); + break; + case ClearContent: + plainTextEdit.setPlainText(""); + break; + case SetContent: + plainTextEdit.setPlainText("PlainText..."); + break; + } + } + auto *plainTextEdit_d = static_cast(qt_widget_private(&plainTextEdit)); + + plainTextEdit.show(); + QVERIFY(QTest::qWaitForWindowExposed(&plainTextEdit)); + QTRY_VERIFY(plainTextEdit_d->placeholderVisible == placeholderVisible); +} + QTEST_MAIN(tst_QPlainTextEdit) #include "tst_qplaintextedit.moc"