QAbstractProxyModel: fix binding loops

... by using valueBypassingBindings() when accessing the properties
from the setters.

This commit is mostly trivial.
Had to change the template parameters in the unit-test, because the
updated QTestPrivate::testReadWritePropertyBasics() creates an instance
of the TestedClass, and QAbstractProxyModel cannot be instantiated,
since it has pure virtual methods.

Task-number: QTBUG-116346
Change-Id: I0cae29263ea9bb92c9de06891b0ba8633fb9fd72
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 6a873778b976b4752e874a2d87ea84e5d9e0d3c5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Ivan Solovev 2023-08-25 15:35:08 +02:00 committed by Qt Cherry-pick Bot
parent 5381df0240
commit 8d47db7a78
2 changed files with 9 additions and 8 deletions

View File

@ -159,7 +159,8 @@ void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
d->model.removeBindingUnlessInWrapper();
// Special case to handle nullptr models. Otherwise we will have unwanted
// notifications.
if (!sourceModel && d->model == QAbstractItemModelPrivate::staticEmptyModel())
const QAbstractItemModel *currentModel = d->model.valueBypassingBindings();
if (!sourceModel && currentModel == QAbstractItemModelPrivate::staticEmptyModel())
return;
static const struct {
const char *signalName;
@ -176,16 +177,16 @@ void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
// clang-format on
};
if (sourceModel != d->model) {
if (d->model) {
if (sourceModel != currentModel) {
if (currentModel) {
for (const auto &c : connectionTable)
disconnect(d->model, c.signalName, this, c.slotName);
disconnect(currentModel, c.signalName, this, c.slotName);
}
if (sourceModel) {
d->model.setValueBypassingBindings(sourceModel);
for (const auto &c : connectionTable)
connect(d->model, c.signalName, this, c.slotName);
connect(sourceModel, c.signalName, this, c.slotName);
} else {
d->model.setValueBypassingBindings(QAbstractItemModelPrivate::staticEmptyModel());
}

View File

@ -610,7 +610,7 @@ void tst_QAbstractProxyModel::sourceModelBinding()
SubQAbstractProxyModel proxy;
QStandardItemModel model1;
QStandardItemModel model2;
QTestPrivate::testReadWritePropertyBasics<QAbstractProxyModel, QAbstractItemModel *>(
QTestPrivate::testReadWritePropertyBasics<SubQAbstractProxyModel, QAbstractItemModel *>(
proxy, &model1, &model2, "sourceModel");
if (QTest::currentTestFailed()) {
qDebug("Failed model - model test");
@ -618,7 +618,7 @@ void tst_QAbstractProxyModel::sourceModelBinding()
}
proxy.setSourceModel(&model2);
QTestPrivate::testReadWritePropertyBasics<QAbstractProxyModel, QAbstractItemModel *>(
QTestPrivate::testReadWritePropertyBasics<SubQAbstractProxyModel, QAbstractItemModel *>(
proxy, &model1, nullptr, "sourceModel");
if (QTest::currentTestFailed()) {
qDebug("Failed model - nullptr test");
@ -626,7 +626,7 @@ void tst_QAbstractProxyModel::sourceModelBinding()
}
proxy.setSourceModel(&model1);
QTestPrivate::testReadWritePropertyBasics<QAbstractProxyModel, QAbstractItemModel *>(
QTestPrivate::testReadWritePropertyBasics<SubQAbstractProxyModel, QAbstractItemModel *>(
proxy, nullptr, &model2, "sourceModel");
if (QTest::currentTestFailed()) {
qDebug("Failed nullptr - model test");