summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2017-03-02 08:55:35 +0100
committerOlivier Goffart (Woboq GmbH) <ogoffart@woboq.com>2017-03-02 10:42:55 +0000
commit8387d87bdcf7dfb359515f44b17f523791bc8edb (patch)
treebde1b191f5b28d7edb6c662f101607341dbaea3e
parent6965b8a59217e5f1db9e5986d6ccc8f5ff5f4e9c (diff)
QDialogButtonGroup: Fix removal of deleted buttons
As the destroyed() signal is emitted from ~QObject, it is not allowed to use static_cast to a QAbstractButton on that pointer anymore. And the qobject_cast will also fail which will keep a dangling pointer in the hash. Change-Id: If0d22fcc30cde87e771e70914c3afb04ea207289 Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp5
-rw-r--r--tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp19
2 files changed, 21 insertions, 3 deletions
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index 23158cf82f..984669f29a 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -716,8 +716,7 @@ void QDialogButtonBox::removeButton(QAbstractButton *button)
return;
// Remove it from the standard button hash first and then from the roles
- if (QPushButton *pushButton = qobject_cast<QPushButton *>(button))
- d->standardButtonHash.remove(pushButton);
+ d->standardButtonHash.remove(reinterpret_cast<QPushButton *>(button));
for (int i = 0; i < NRoles; ++i) {
QList<QAbstractButton *> &list = d->buttonLists[i];
for (int j = 0; j < list.count(); ++j) {
@@ -883,7 +882,7 @@ void QDialogButtonBoxPrivate::_q_handleButtonDestroyed()
Q_Q(QDialogButtonBox);
if (QObject *object = q->sender()) {
QBoolBlocker skippy(internalRemove);
- q->removeButton(static_cast<QAbstractButton *>(object));
+ q->removeButton(reinterpret_cast<QAbstractButton *>(object));
}
}
diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
index a35ea8eb6e..f127fd98f7 100644
--- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
+++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
@@ -97,6 +97,8 @@ private slots:
void testDefaultButton();
void task191642_default();
+ void testDeletedStandardButton();
+
private:
qint64 timeStamp;
qint64 buttonClicked1TimeStamp;
@@ -843,5 +845,22 @@ void tst_QDialogButtonBox::task191642_default()
QCOMPARE(clicked.count(), 1);
}
+void tst_QDialogButtonBox::testDeletedStandardButton()
+{
+ QDialogButtonBox buttonBox;
+ delete buttonBox.addButton(QDialogButtonBox::Ok);
+ QPointer<QPushButton> buttonC = buttonBox.addButton(QDialogButtonBox::Cancel);
+ delete buttonBox.addButton(QDialogButtonBox::Cancel);
+ QPointer<QPushButton> buttonA = buttonBox.addButton(QDialogButtonBox::Apply);
+ delete buttonBox.addButton(QDialogButtonBox::Help);
+ // A few button have been deleted, they should automatically be removed
+ QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Apply | QDialogButtonBox::Cancel);
+
+ buttonBox.setStandardButtons(QDialogButtonBox::Reset | QDialogButtonBox::Cancel);
+ // setStanderdButton should delete previous buttons
+ QVERIFY(!buttonA);
+ QVERIFY(!buttonC);
+}
+
QTEST_MAIN(tst_QDialogButtonBox)
#include "tst_qdialogbuttonbox.moc"