QProgressDialog: don't crash when setting the same {bar,button,label} again

The associated test has unearthed that setBar() fails to make the new bar a child
of the progress dialog. This will be fixed in a separate commit.

Task-number: QTBUG-40502
Change-Id: I2d09ebb07ae6395449a4efe38a638df831eebdd7
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Marc Mutz 2014-07-29 15:31:44 +02:00
parent 41dae1e33a
commit e2331c6f76
2 changed files with 64 additions and 0 deletions

View File

@ -354,6 +354,11 @@ QProgressDialog::~QProgressDialog()
void QProgressDialog::setLabel(QLabel *label)
{
Q_D(QProgressDialog);
if (label == d->label) {
if (label)
qWarning("QProgressDialog::setLabel: Attempt to set the same label again");
return;
}
delete d->label;
d->label = label;
if (label) {
@ -411,6 +416,11 @@ void QProgressDialog::setLabelText(const QString &text)
void QProgressDialog::setCancelButton(QPushButton *cancelButton)
{
Q_D(QProgressDialog);
if (d->cancel == cancelButton) {
if (cancelButton)
qWarning("QProgressDialog::setCancelButton: Attempt to set the same button again");
return;
}
delete d->cancel;
d->cancel = cancelButton;
if (cancelButton) {
@ -483,6 +493,10 @@ void QProgressDialog::setBar(QProgressBar *bar)
qWarning("QProgressDialog::setBar: Cannot set a new progress bar "
"while the old one is active");
#endif
if (bar == d->bar) {
qWarning("QProgressDialog::setBar: Attempt to set the same progress bar again");
return;
}
delete d->bar;
d->bar = bar;
int w = qMax(isVisible() ? width() : 0, sizeHint().width());

View File

@ -44,8 +44,11 @@
#include <qapplication.h>
#include <qdebug.h>
#include <qprogressbar.h>
#include <qprogressdialog.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qpointer.h>
#include <qthread.h>
class tst_QProgressDialog : public QObject
@ -59,6 +62,7 @@ private Q_SLOTS:
void getSetCheck();
void task198202();
void QTBUG_31046();
void settingCustomWidgets();
};
void tst_QProgressDialog::cleanup()
@ -184,5 +188,51 @@ void tst_QProgressDialog::QTBUG_31046()
QCOMPARE(50, dlg.value());
}
void tst_QProgressDialog::settingCustomWidgets()
{
QPointer<QLabel> l = new QLabel;
QPointer<QPushButton> btn = new QPushButton;
QPointer<QProgressBar> bar = new QProgressBar;
QVERIFY(!l->parent());
QVERIFY(!btn->parent());
QVERIFY(!bar->parent());
{
QProgressDialog dlg;
QVERIFY(!dlg.isAncestorOf(l));
dlg.setLabel(l);
QVERIFY(dlg.isAncestorOf(l));
QTest::ignoreMessage(QtWarningMsg, "QProgressDialog::setLabel: Attempt to set the same label again");
dlg.setLabel(l); // setting the same widget again should not crash
QVERIFY(l); // and not delete the (old == new) widget
QVERIFY(!dlg.isAncestorOf(btn));
dlg.setCancelButton(btn);
QVERIFY(dlg.isAncestorOf(btn));
QTest::ignoreMessage(QtWarningMsg, "QProgressDialog::setCancelButton: Attempt to set the same button again");
dlg.setCancelButton(btn); // setting the same widget again should not crash
QVERIFY(btn); // and not delete the (old == new) widget
QVERIFY(!dlg.isAncestorOf(bar));
dlg.setBar(bar);
QEXPECT_FAIL("", "QProgressBar doesn't adopt custom progress bar as children", Continue);
QVERIFY(dlg.isAncestorOf(bar));
QTest::ignoreMessage(QtWarningMsg, "QProgressDialog::setBar: Attempt to set the same progress bar again");
dlg.setBar(bar); // setting the same widget again should not crash
QVERIFY(bar); // and not delete the (old == new) widget
}
QVERIFY(!l);
QVERIFY(!btn);
#if 0
QEXPECT_FAIL("", "QProgressBar doesn't clean up custom progress bars", Continue);
QVERIFY(!bar);
#else
// make cleanup() pass
delete bar;
#endif
}
QTEST_MAIN(tst_QProgressDialog)
#include "tst_qprogressdialog.moc"