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 <volker.hilsheimer@qt.io>
This commit is contained in:
Qiang Li 2021-09-09 15:58:57 +08:00 committed by Volker Hilsheimer
parent 81b9ee66b8
commit d54bb53247
4 changed files with 110 additions and 6 deletions

View File

@ -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();
}
}

View File

@ -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())

View File

@ -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()); }

View File

@ -38,6 +38,7 @@
#include <qclipboard.h>
#include <qtextbrowser.h>
#include <private/qwidgettextcontrol_p.h>
#include <private/qplaintextedit_p.h>
#include <qscrollbar.h>
#include <qtextobject.h>
#include <qmenu.h>
@ -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<QList<SetupCommand>>("setupCommands");
QTest::addColumn<bool>("placeholderVisible");
QTest::addRow("no placeholder set + no text set")
<< QList<SetupCommand>{} << true;
QTest::addRow("no placeholder set + text set or text set + no placeholder set")
<< QList<SetupCommand>{ SetContent } << false;
QTest::addRow("no placeholder set + text set + empty text set")
<< QList<SetupCommand>{ SetContent , ClearContent }
<< false;
QTest::addRow("no placeholder set + empty text set + text set")
<< QList<SetupCommand>{ ClearContent, SetContent }
<< false;
QTest::addRow("empty placeholder set + no text set")
<< QList<SetupCommand>{ ClearPlaceHolder } << true;
QTest::addRow("empty placeholder set + text set")
<< QList<SetupCommand>{ ClearPlaceHolder, SetContent }
<< false;
QTest::addRow("empty placeholder set + text set + empty text set")
<< QList<SetupCommand>{ ClearPlaceHolder, SetContent, ClearContent }
<< false;
QTest::addRow("empty placeholder set + empty text set + text set")
<< QList<SetupCommand>{ ClearPlaceHolder, ClearContent, SetContent }
<< false;
QTest::addRow("placeholder set + no text set")
<< QList<SetupCommand>{ SetPlaceHolder, ClearContent }
<< true;
QTest::addRow("placeholder set + text set")
<< QList<SetupCommand>{ SetPlaceHolder, SetContent }
<< false;
QTest::addRow("placeholder set + text set + empty text set")
<< QList<SetupCommand>{ SetPlaceHolder, SetContent, ClearContent }
<< true;
QTest::addRow("placeholder set + empty text set + text set")
<< QList<SetupCommand>{ SetPlaceHolder, ClearContent, SetContent }
<< false;
QTest::addRow("placeholder set + text set + empty placeholder set")
<< QList<SetupCommand>{ SetPlaceHolder, SetContent, ClearPlaceHolder}
<< false;
QTest::addRow("placeholder set + empty placeholder set + text set")
<< QList<SetupCommand>{ SetPlaceHolder, ClearPlaceHolder, SetContent }
<< false;
QTest::addRow("placeholder set + empty placeholder set + empty text set")
<< QList<SetupCommand>{ SetPlaceHolder, ClearPlaceHolder, ClearContent }
<< false;
QTest::addRow("placeholder set + empty text set + empty placeholder set")
<< QList<SetupCommand>{ SetPlaceHolder, ClearContent, ClearPlaceHolder }
<< false;
QTest::addRow("text set + no placeholder set + empty text set")
<< QList<SetupCommand>{ SetContent, ClearContent }
<< false;
QTest::addRow("text set + empty placeholder set")
<< QList<SetupCommand>{ SetContent, ClearPlaceHolder }
<< false;
QTest::addRow("text set + placeholder set")
<< QList<SetupCommand>{ SetContent, SetPlaceHolder }
<< false;
QTest::addRow("text set + placeholder set + empty text set")
<< QList<SetupCommand>{ SetContent, SetPlaceHolder, ClearContent }
<< true;
QTest::addRow("text set + placeholder set + empty placeholder set")
<< QList<SetupCommand>{ SetContent, SetPlaceHolder, ClearPlaceHolder }
<< false;
}
void tst_QPlainTextEdit::placeholderVisibility()
{
QFETCH(QList<SetupCommand>, 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<QPlainTextEditPrivate *>(qt_widget_private(&plainTextEdit));
plainTextEdit.show();
QVERIFY(QTest::qWaitForWindowExposed(&plainTextEdit));
QTRY_VERIFY(plainTextEdit_d->placeholderVisible == placeholderVisible);
}
QTEST_MAIN(tst_QPlainTextEdit)
#include "tst_qplaintextedit.moc"