Do not return cacheItem->object if it is still incubating

It can happen that cacheItem->object in QQmlDelegateModelPrivate::object
already has a value but that the cacheItem->incubationTask is still
Loading. If we return the object here we can confuse some of QQmlDelegateModel
consumers like QQuickItemView.

E.g. in QQuickItemView if we get to return the object before the createdItem
signal is emitted we will make that when the createdItem signal happens
QQuickItemView::createdItem will be called it will add the item
to unrequestedItems items and will expect that layout/refill will
remove it from unrequestedItems if it is really one of the items we are
creating, but as it has been already created the item will wrongly remain
in unrequestedItems making the item view to act weird

Task-number: QTBUG-28403

Change-Id: I4359391eb2a4012afd3f01d082a99692d63b6639
Reviewed-by: Alan Alpert <aalpert@blackberry.com>
This commit is contained in:
Albert Astals Cid 2013-05-21 16:09:58 +02:00 committed by The Qt Project
parent 0e9cd8b409
commit 8a3d48915c
1 changed files with 8 additions and 3 deletions

View File

@ -780,11 +780,16 @@ void QQmlDelegateModelPrivate::emitDestroyingPackage(QQuickPackage *package)
QQmlDelegateModelGroupPrivate::get(m_groups[i])->destroyingPackage(package);
}
static bool isDoneIncubating(QQmlIncubator::Status status)
{
return status == QQmlIncubator::Ready || status == QQmlIncubator::Error;
}
void QQDMIncubationTask::statusChanged(Status status)
{
if (vdm) {
vdm->incubatorStatusChanged(this, status);
} else if (status == QQmlIncubator::Ready || status == QQmlIncubator::Error) {
} else if (isDoneIncubating(status)) {
Q_ASSERT(incubating);
// The model was deleted from under our feet, cleanup ourselves
if (incubating->object) {
@ -824,7 +829,7 @@ void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem)
void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status)
{
Q_Q(QQmlDelegateModel);
if (status != QQmlIncubator::Ready && status != QQmlIncubator::Error)
if (!isDoneIncubating(status))
return;
QQmlDelegateModelItem *cacheItem = incubationTask->incubating;
@ -951,7 +956,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bo
// Remove the temporary reference count.
cacheItem->scriptRef -= 1;
if (cacheItem->object)
if (cacheItem->object && (!cacheItem->incubationTask || isDoneIncubating(cacheItem->incubationTask->status())))
return cacheItem->object;
cacheItem->releaseObject();