aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/types/qqmldelegatemodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/types/qqmldelegatemodel.cpp')
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp134
1 files changed, 85 insertions, 49 deletions
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index aa665e4283..afd2a49155 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -144,8 +144,9 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent)
The VisualDataModel type encapsulates a model and the delegate that will
be instantiated for items in a model.
- This type is provided by QtQuick 2 for compatibility reasons. The same implementation
- is now primarily available as DelegateModel in the QtQml.Models module.
+ This type is provided by the \l{Qt QML} module due to compatibility reasons.
+ The same implementation is now primarily available as DelegateModel in the
+ \l{Qt QML Models QML Types}{Qt QML Models} module.
\sa {QtQml.Models2::DelegateModel}
*/
@@ -158,9 +159,6 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent)
The DelegateModel type encapsulates a model and the delegate that will
be instantiated for items in the model.
- This element is also available as DelegateModel in the QtQuick module. For full details,
- see the \l DelegateModel documentation.
-
It is usually not necessary to create a DelegateModel.
However, it can be useful for manipulating and accessing the \l modelIndex
when a QAbstractItemModel subclass is used as the
@@ -170,7 +168,10 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent)
The example below illustrates using a DelegateModel with a ListView.
- \snippet qml/visualdatamodel.qml 0
+ \snippet delegatemodel/visualdatamodel.qml 0
+
+ \note This type is also available as \l VisualDataModel in the \l{Qt QML}
+ module due to compatibility reasons.
*/
QQmlDelegateModelPrivate::QQmlDelegateModelPrivate(QQmlContext *ctxt)
@@ -243,6 +244,8 @@ QQmlDelegateModel::~QQmlDelegateModel()
cacheItem->objectRef = 0;
if (!cacheItem->isReferenced())
delete cacheItem;
+ else if (cacheItem->incubationTask)
+ cacheItem->incubationTask->vdm = 0;
}
}
@@ -408,10 +411,10 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
the new directory's contents.
\c main.cpp:
- \snippet qml/visualdatamodel_rootindex/main.cpp 0
+ \snippet delegatemodel/visualdatamodel_rootindex/main.cpp 0
\c view.qml:
- \snippet qml/visualdatamodel_rootindex/view.qml 0
+ \snippet delegatemodel/visualdatamodel_rootindex/view.qml 0
If the \l model is a QAbstractItemModel subclass, the delegate can also
reference a \c hasModelChildren property (optionally qualified by a
@@ -615,7 +618,7 @@ QQmlDelegateModelGroup *QQmlDelegateModelPrivate::group_at(
The following example illustrates using groups to select items in a model.
- \snippet qml/visualdatagroup.qml 0
+ \snippet delegatemodel/visualdatagroup.qml 0
*/
QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups()
@@ -791,9 +794,28 @@ 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)
{
- vdm->incubatorStatusChanged(this, status);
+ if (vdm) {
+ vdm->incubatorStatusChanged(this, status);
+ } else if (isDoneIncubating(status)) {
+ Q_ASSERT(incubating);
+ // The model was deleted from under our feet, cleanup ourselves
+ if (incubating->object) {
+ delete incubating->object;
+
+ incubating->object = 0;
+ incubating->contextData->destroy();
+ incubating->contextData = 0;
+ }
+ incubating->scriptRef = 0;
+ incubating->deleteLater();
+ }
}
void QQmlDelegateModelPrivate::releaseIncubator(QQDMIncubationTask *incubationTask)
@@ -821,7 +843,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;
@@ -830,10 +852,12 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba
releaseIncubator(incubationTask);
if (status == QQmlIncubator::Ready) {
+ cacheItem->referenceObject();
if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object))
emitCreatedPackage(incubationTask, package);
else
emitCreatedItem(incubationTask, cacheItem->object);
+ cacheItem->releaseObject();
} else if (status == QQmlIncubator::Error) {
qmlInfo(q, m_delegate->errors()) << "Error creating delegate";
}
@@ -846,8 +870,10 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba
delete cacheItem->object;
cacheItem->object = 0;
cacheItem->scriptRef -= 1;
- cacheItem->contextData->destroy();
+ if (cacheItem->contextData)
+ cacheItem->contextData->destroy();
cacheItem->contextData = 0;
+
if (!cacheItem->isReferenced()) {
removeCacheItem(cacheItem);
delete cacheItem;
@@ -945,7 +971,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();
@@ -960,7 +986,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bo
/*
If asynchronous is true or the component is being loaded asynchronously due
to an ancestor being loaded asynchronously, item() may return 0. In this
- case itemCreated() will be emitted when the item is available. The item
+ case createdItem() will be emitted when the item is available. The item
at this stage does not have any references, so item() must be called again
to ensure a reference is held. Any call to item() which returns a valid item
must be matched by a call to release() in order to destroy the item.
@@ -1168,8 +1194,8 @@ void QQmlDelegateModelPrivate::itemsInserted(
cacheIndex = insert.cacheIndex + insert.count;
}
}
- for (; cacheIndex < m_cache.count(); ++cacheIndex)
- incrementIndexes(m_cache.at(cacheIndex), m_groupCount, inserted);
+ for (const QList<QQmlDelegateModelItem *> cache = m_cache; cacheIndex < cache.count(); ++cacheIndex)
+ incrementIndexes(cache.at(cacheIndex), m_groupCount, inserted);
}
void QQmlDelegateModelPrivate::itemsInserted(const QVector<Compositor::Insert> &inserts)
@@ -1193,8 +1219,9 @@ void QQmlDelegateModel::_q_itemsInserted(int index, int count)
d->m_count += count;
- for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
- QQmlDelegateModelItem *item = d->m_cache.at(i);
+ const QList<QQmlDelegateModelItem *> cache = d->m_cache;
+ for (int i = 0, c = cache.count(); i < c; ++i) {
+ QQmlDelegateModelItem *item = cache.at(i);
if (item->modelIndex() >= index)
item->setModelIndex(item->modelIndex() + count);
}
@@ -1285,8 +1312,8 @@ void QQmlDelegateModelPrivate::itemsRemoved(
}
}
- for (; cacheIndex < m_cache.count(); ++cacheIndex)
- incrementIndexes(m_cache.at(cacheIndex), m_groupCount, removed);
+ for (const QList<QQmlDelegateModelItem *> cache = m_cache; cacheIndex < cache.count(); ++cacheIndex)
+ incrementIndexes(cache.at(cacheIndex), m_groupCount, removed);
}
void QQmlDelegateModelPrivate::itemsRemoved(const QVector<Compositor::Remove> &removes)
@@ -1308,9 +1335,9 @@ void QQmlDelegateModel::_q_itemsRemoved(int index, int count)
return;
d->m_count -= count;
-
- for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
- QQmlDelegateModelItem *item = d->m_cache.at(i);
+ const QList<QQmlDelegateModelItem *> cache = d->m_cache;
+ for (int i = 0, c = cache.count(); i < c; ++i) {
+ QQmlDelegateModelItem *item = cache.at(i);
if (item->modelIndex() >= index + count)
item->setModelIndex(item->modelIndex() - count);
else if (item->modelIndex() >= index)
@@ -1356,8 +1383,9 @@ void QQmlDelegateModel::_q_itemsMoved(int from, int to, int count)
const int maximum = qMax(from, to) + count;
const int difference = from > to ? count : -count;
- for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
- QQmlDelegateModelItem *item = d->m_cache.at(i);
+ const QList<QQmlDelegateModelItem *> cache = d->m_cache;
+ for (int i = 0, c = cache.count(); i < c; ++i) {
+ QQmlDelegateModelItem *item = cache.at(i);
if (item->modelIndex() >= from && item->modelIndex() < from + count)
item->setModelIndex(item->modelIndex() - from + to);
else if (item->modelIndex() >= minimum && item->modelIndex() < maximum)
@@ -1413,8 +1441,9 @@ void QQmlDelegateModel::_q_modelReset()
if (d->m_complete) {
d->m_count = d->m_adaptorModel.count();
- for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
- QQmlDelegateModelItem *item = d->m_cache.at(i);
+ const QList<QQmlDelegateModelItem *> cache = d->m_cache;
+ for (int i = 0, c = cache.count(); i < c; ++i) {
+ QQmlDelegateModelItem *item = cache.at(i);
if (item->modelIndex() != -1)
item->setModelIndex(-1);
}
@@ -1773,8 +1802,12 @@ QQmlDelegateModelItem::~QQmlDelegateModelItem()
Q_ASSERT(objectRef == 0);
Q_ASSERT(!object);
- if (incubationTask && metaType->model)
- QQmlDelegateModelPrivate::get(metaType->model)->releaseIncubator(incubationTask);
+ if (incubationTask) {
+ if (metaType->model)
+ QQmlDelegateModelPrivate::get(metaType->model)->releaseIncubator(incubationTask);
+ else
+ delete incubationTask;
+ }
metaType->release();
@@ -2149,14 +2182,31 @@ void QQmlDelegateModelGroupPrivate::destroyingPackage(QQuickPackage *package)
}
/*!
- \qmltype DelegateModelGroup
+ \qmltype VisualDataGroup
\instantiates QQmlDelegateModelGroup
\inqmlmodule QtQuick 2
\ingroup qtquick-models
\brief Encapsulates a filtered set of visual data items
- The DelegateModelGroup type provides a means to address the model data of a DelegateModel's
- delegate items, as well as sort and filter these delegate items.
+ The VisualDataGroup type provides a means to address the model data of a
+ model's delegate items, as well as sort and filter these delegate items.
+
+ This type is provided by the \l{Qt QML} module due to compatibility reasons.
+ The same implementation is now primarily available as \l DelegateModelGroup
+ in the \l{Qt QML Models QML Types}{Qt QML Models} module.
+
+ \sa {QtQml.Models2::DelegateModelGroup}
+*/
+/*!
+ \qmltype DelegateModelGroup
+ \instantiates QQmlDelegateModelGroup
+ \inqmlmodule QtQml.Models 2
+ \ingroup qtquick-models
+ \brief Encapsulates a filtered set of visual data items
+
+ The DelegateModelGroup type provides a means to address the model data of a
+ DelegateModel's delegate items, as well as sort and filter these delegate
+ items.
The initial set of instantiable delegate items in a DelegateModel is represented
by its \l {QtQml.Models2::DelegateModel::items}{items} group, which normally directly reflects
@@ -2180,24 +2230,11 @@ void QQmlDelegateModelGroupPrivate::destroyingPackage(QQuickPackage *package)
type or to cherry-pick specific items that should be instantiated irregardless of whether
they're currently within a view's visible area.
- \sa {QML Dynamic View Ordering Tutorial}
-*/
-/*!
- \qmltype DelegateModelGroup
- \instantiates QQmlDelegateModelGroup
- \inqmlmodule QtQml.Models 2
- \brief Encapsulates a filtered set of visual data items
-
- The DelegateModelGroup type provides a means to address the model data of a DelegateModel's
- delegate items, as well as sort and filter these delegate items.
-
- This element is also available as DelegateModelGroup in the QtQuick module. For full details,
- see the \l DelegateModelGroup documentation.
+ \note This type is also available as \l VisualDataGroup in the \l{Qt QML}
+ module due to compatibility reasons.
- \sa {QtQuick::DelegateModelGroup}
+ \sa {QML Dynamic View Ordering Tutorial}
*/
-
-
QQmlDelegateModelGroup::QQmlDelegateModelGroup(QObject *parent)
: QObject(*new QQmlDelegateModelGroupPrivate, parent)
{
@@ -3222,4 +3259,3 @@ QV4::Value QQmlDelegateModelEngineData::array(
}
QT_END_NAMESPACE
-