aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qmlmodels/qqmldelegatemodel.cpp9
-rw-r--r--src/qmlmodels/qqmldelegatemodel_p.h3
-rw-r--r--src/quick/items/qquickitemview.cpp38
-rw-r--r--src/quick/items/qquickitemview_p_p.h2
-rw-r--r--tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp40
5 files changed, 73 insertions, 19 deletions
diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index e7868517cd..65c99d9bc0 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -454,7 +454,8 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
}
if (d->m_delegate == delegate)
return;
- bool wasValid = d->m_delegate != nullptr;
+ if (d->m_complete)
+ _q_itemsRemoved(0, d->m_count);
d->m_delegate.setObject(delegate, this);
d->m_delegateValidated = false;
if (d->m_delegateChooser)
@@ -470,7 +471,11 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
[d](){ d->delegateChanged(); });
}
}
- d->delegateChanged(d->m_delegate, wasValid);
+ if (d->m_complete) {
+ _q_itemsInserted(0, d->adaptorModelCount());
+ d->requestMoreIfNecessary();
+ }
+ emit delegateChanged();
}
/*!
diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h
index 21eaef02e0..9e846ccc3e 100644
--- a/src/qmlmodels/qqmldelegatemodel_p.h
+++ b/src/qmlmodels/qqmldelegatemodel_p.h
@@ -77,7 +77,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, p
Q_DECLARE_PRIVATE(QQmlDelegateModel)
Q_PROPERTY(QVariant model READ model WRITE setModel)
- Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate)
+ Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
Q_PROPERTY(QQmlDelegateModelGroup *items READ items CONSTANT) //TODO : worth renaming?
Q_PROPERTY(QQmlDelegateModelGroup *persistedItems READ persistedItems CONSTANT)
@@ -136,6 +136,7 @@ Q_SIGNALS:
void filterGroupChanged();
void defaultGroupsChanged();
void rootIndexChanged();
+ void delegateChanged();
private Q_SLOTS:
void _q_itemsChanged(int index, int count, const QVector<int> &roles);
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index bbfbf6244c..e1af65c986 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -247,6 +247,8 @@ void QQuickItemView::setModel(const QVariant &m)
connect(d->model, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
this, SLOT(modelUpdated(QQmlChangeSet,bool)));
+ if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model))
+ QObjectPrivate::connect(dataModel, &QQmlDelegateModel::delegateChanged, d, &QQuickItemViewPrivate::applyDelegateChange);
emit countChanged();
}
emit modelChanged();
@@ -277,22 +279,8 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate)
if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
int oldCount = dataModel->count();
dataModel->setDelegate(delegate);
- if (isComponentComplete()) {
- d->releaseVisibleItems();
- d->releaseItem(d->currentItem);
- d->currentItem = nullptr;
- d->updateSectionCriteria();
- d->refill();
- d->moveReason = QQuickItemViewPrivate::SetIndex;
- d->updateCurrent(d->currentIndex);
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->resetHighlightPosition();
- d->updateTrackedItem();
- }
- d->moveReason = QQuickItemViewPrivate::Other;
- d->updateViewport();
- }
+ if (isComponentComplete())
+ d->applyDelegateChange();
if (oldCount != dataModel->count())
emit countChanged();
}
@@ -1089,6 +1077,24 @@ qreal QQuickItemViewPrivate::calculatedMaxExtent() const
return maxExtent;
}
+void QQuickItemViewPrivate::applyDelegateChange()
+{
+ releaseVisibleItems();
+ releaseItem(currentItem);
+ currentItem = nullptr;
+ updateSectionCriteria();
+ refill();
+ moveReason = QQuickItemViewPrivate::SetIndex;
+ updateCurrent(currentIndex);
+ if (highlight && currentItem) {
+ if (autoHighlight)
+ resetHighlightPosition();
+ updateTrackedItem();
+ }
+ moveReason = QQuickItemViewPrivate::Other;
+ updateViewport();
+}
+
// for debugging only
void QQuickItemViewPrivate::checkVisible() const
{
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index ef674f0fc7..860cf5fa20 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -191,6 +191,8 @@ public:
qreal calculatedMinExtent() const;
qreal calculatedMaxExtent() const;
+ void applyDelegateChange();
+
void applyPendingChanges();
bool applyModelChanges(ChangeResult *insertionResult, ChangeResult *removalResult);
bool applyRemovalChange(const QQmlChangeSet::Change &removal, ChangeResult *changeResult, int *removedCount);
diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
index 32008f675a..fe56cad018 100644
--- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
+++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
@@ -432,6 +432,7 @@ private slots:
void asynchronousCancel();
void invalidContext();
void externalManagedModel();
+ void delegateModelChangeDelegate();
private:
template <int N> void groups_verify(
@@ -4302,6 +4303,45 @@ void tst_qquickvisualdatamodel::externalManagedModel()
QTRY_VERIFY(!object->property("running").toBool());
}
+void tst_qquickvisualdatamodel::delegateModelChangeDelegate()
+{
+ // Verify that QTBUG-63477 is fixed.
+ // Changing the delegate would not update existing items.
+ QQmlEngine engine;
+ QScopedPointer<QQmlContext> context(new QQmlContext(engine.rootContext()));
+
+ QQmlComponent c(&engine);
+ c.setData("import QtQml.Models 2.2\nDelegateModel {}\n", QUrl());
+ QCOMPARE(c.status(), QQmlComponent::Ready);
+
+ QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create(context.data()));
+ QVERIFY(visualModel);
+ visualModel->setModel(QVariant(3));
+
+ QQmlComponent first(&engine);
+ first.setData("import QtQuick 2.0\nItem { objectName: \"old\" }\n", QUrl());
+ QCOMPARE(first.status(), QQmlComponent::Ready);
+
+ // Without delegate, claim to have an item count of 0
+ QCOMPARE(visualModel->count(), 0);
+
+ visualModel->setDelegate(&first);
+ // The first delegate has been set, verify we get it
+ QObject* old = visualModel->object(0, QQmlIncubator::Synchronous);
+ QVERIFY(old);
+ QCOMPARE(visualModel->object(0, QQmlIncubator::Synchronous)->objectName(), QStringLiteral("old"));
+ QCOMPARE(visualModel->count(), 3);
+
+ QQmlComponent second(&engine);
+ second.setData("import QtQuick 2.0\nItem { objectName: \"new\" }\n", QUrl());
+ QCOMPARE(second.status(), QQmlComponent::Ready);
+
+ visualModel->setDelegate(&second);
+ // After changing the delegate, expect the existing item to have the new delegate
+ QCOMPARE(visualModel->object(0, QQmlIncubator::Synchronous)->objectName(), QStringLiteral("new"));
+ QCOMPARE(visualModel->count(), 3);
+}
+
QTEST_MAIN(tst_qquickvisualdatamodel)
#include "tst_qquickvisualdatamodel.moc"