aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2017-11-08 11:01:35 +0100
committerRichard Moe Gustavsen <richard.gustavsen@qt.io>2017-11-30 07:36:05 +0000
commit816b5a667f0b5b47c3f80c2c775535310c89b727 (patch)
tree191e96ceb0aaa24bbbf17a9d2b056f641143b6ec /src
parent60d589ccddb036e84883a6c2ef63a5292c8ad022 (diff)
QQmlDelegateModel: add incubationStatus(), and use it to determine 'requestedIndex'
We used to assign the currently incubating item to 'requestedIndex' based on requested incubation mode alone. This is not sufficient, as the item can also be loaded async when the mode is AsyncIfNested. To check if the item is really loading async (and that we're not getting nullptr because of some other failure), we need to ask the incubator. Task-number: QTBUG-61537 Change-Id: Id1f458db4a7584a6b58d5bad0e7832ce4fc341dc Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp20
-rw-r--r--src/qml/types/qqmldelegatemodel_p.h1
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h1
-rw-r--r--src/qml/types/qqmlobjectmodel.cpp5
-rw-r--r--src/qml/types/qqmlobjectmodel_p.h2
-rw-r--r--src/quick/items/qquickitemview.cpp12
6 files changed, 38 insertions, 3 deletions
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 4da7199d1e..9dd82494ca 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -1036,6 +1036,16 @@ QObject *QQmlDelegateModel::object(int index, QQmlIncubator::IncubationMode incu
return d->object(d->m_compositorGroup, index, incubationMode);
}
+QQmlIncubator::Status QQmlDelegateModel::incubationStatus(int index)
+{
+ Q_D(QQmlDelegateModel);
+ Compositor::iterator it = d->m_compositor.find(d->m_compositorGroup, index);
+ if (!it->inCache())
+ return QQmlIncubator::Null;
+
+ return d->m_cache.at(it.cacheIndex)->incubationTask->status();
+}
+
QString QQmlDelegateModelPrivate::stringValue(Compositor::Group group, int index, const QString &name)
{
Compositor::iterator it = m_compositor.find(group, index);
@@ -3203,6 +3213,16 @@ void QQmlPartsModel::setWatchedRoles(const QList<QByteArray> &roles)
m_watchedRoles = roles;
}
+QQmlIncubator::Status QQmlPartsModel::incubationStatus(int index)
+{
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
+ Compositor::iterator it = model->m_compositor.find(model->m_compositorGroup, index);
+ if (!it->inCache())
+ return QQmlIncubator::Null;
+
+ return model->m_cache.at(it.cacheIndex)->incubationTask->status();
+}
+
int QQmlPartsModel::indexOf(QObject *item, QObject *) const
{
QHash<QObject *, QQuickPackage *>::const_iterator it = m_packaged.find(item);
diff --git a/src/qml/types/qqmldelegatemodel_p.h b/src/qml/types/qqmldelegatemodel_p.h
index 5ae2d48969..71179fd8be 100644
--- a/src/qml/types/qqmldelegatemodel_p.h
+++ b/src/qml/types/qqmldelegatemodel_p.h
@@ -115,6 +115,7 @@ public:
void cancel(int index) override;
QString stringValue(int index, const QString &role) override;
void setWatchedRoles(const QList<QByteArray> &roles) override;
+ QQmlIncubator::Status incubationStatus(int index) override;
int indexOf(QObject *object, QObject *objectContext) const override;
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index a6a7853116..d8e61b05a1 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -362,6 +362,7 @@ public:
QString stringValue(int index, const QString &role) override;
QList<QByteArray> watchedRoles() const { return m_watchedRoles; }
void setWatchedRoles(const QList<QByteArray> &roles) override;
+ QQmlIncubator::Status incubationStatus(int index) override;
int indexOf(QObject *item, QObject *objectContext) const override;
diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp
index dcb41469ba..54da0867d4 100644
--- a/src/qml/types/qqmlobjectmodel.cpp
+++ b/src/qml/types/qqmlobjectmodel.cpp
@@ -298,6 +298,11 @@ QString QQmlObjectModel::stringValue(int index, const QString &name)
return QQmlEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString();
}
+QQmlIncubator::Status QQmlObjectModel::incubationStatus(int)
+{
+ return QQmlIncubator::Ready;
+}
+
int QQmlObjectModel::indexOf(QObject *item, QObject *) const
{
Q_D(const QQmlObjectModel);
diff --git a/src/qml/types/qqmlobjectmodel_p.h b/src/qml/types/qqmlobjectmodel_p.h
index 5e4a9c686f..b3cf45ca62 100644
--- a/src/qml/types/qqmlobjectmodel_p.h
+++ b/src/qml/types/qqmlobjectmodel_p.h
@@ -80,6 +80,7 @@ public:
virtual void cancel(int) {}
virtual QString stringValue(int, const QString &) = 0;
virtual void setWatchedRoles(const QList<QByteArray> &roles) = 0;
+ virtual QQmlIncubator::Status incubationStatus(int index) = 0;
virtual int indexOf(QObject *object, QObject *objectContext) const = 0;
@@ -118,6 +119,7 @@ public:
ReleaseFlags release(QObject *object) override;
QString stringValue(int index, const QString &role) override;
void setWatchedRoles(const QList<QByteArray> &) override {}
+ QQmlIncubator::Status incubationStatus(int index) override;
int indexOf(QObject *object, QObject *objectContext) const override;
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 82dbf04090..10f6c63170 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2340,14 +2340,20 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, QQmlIncubator::Inc
}
}
- if (incubationMode == QQmlIncubator::Asynchronous)
- requestedIndex = modelIndex;
inRequest = true;
QObject* object = model->object(modelIndex, incubationMode);
QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
+
if (!item) {
- if (object) {
+ if (!object) {
+ if (requestedIndex == -1 && model->incubationStatus(modelIndex) == QQmlIncubator::Loading) {
+ // The reason we didn't receive an item is because it's incubating async. We keep track
+ // of this by assigning the index we're waiting for to 'requestedIndex'. This will e.g. let
+ // the view avoid unnecessary layout calls until the item has been loaded.
+ requestedIndex = modelIndex;
+ }
+ } else {
model->release(object);
if (!delegateValidated) {
delegateValidated = true;