diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-07-11 14:51:40 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-07-11 17:24:39 +0200 |
commit | 13374ceb165c44658aa97890c37b206859c9a31c (patch) | |
tree | 562362b196a459ee3449a5a1e60e5216a9dd6984 /src/qmlmodels | |
parent | ae47deba4c943c496412530a8d2a5a688ae12038 (diff) | |
parent | b5d18be5a03406d0aac83856dd41e1525fd14a28 (diff) |
Merge remote-tracking branch 'origin/wip/qt6' into wip/cmake
Change-Id: I2963c1209316fb6755f572969f368970450d7991
Diffstat (limited to 'src/qmlmodels')
-rw-r--r-- | src/qmlmodels/qqmldelegatecomponent.cpp | 36 | ||||
-rw-r--r-- | src/qmlmodels/qqmldelegatemodel.cpp | 19 |
2 files changed, 52 insertions, 3 deletions
diff --git a/src/qmlmodels/qqmldelegatecomponent.cpp b/src/qmlmodels/qqmldelegatecomponent.cpp index a7e9536917..ccb0d60053 100644 --- a/src/qmlmodels/qqmldelegatecomponent.cpp +++ b/src/qmlmodels/qqmldelegatecomponent.cpp @@ -199,11 +199,45 @@ bool QQmlDelegateChoice::match(int row, int column, const QVariant &value) const The DelegateChooser is a special \l Component type intended for those scenarios where a Component is required by a view and used as a delegate. DelegateChooser encapsulates a set of \l {DelegateChoice}s. - These choices are used determine the delegate that will be instantiated for each + These choices are used to determine the delegate that will be instantiated for each item in the model. The selection of the choice is performed based on the value that a model item has for \l role, and also based on index. + DelegateChooser is commonly used when a view needs to display a set of delegates that are significantly + different from each other. For example, a typical phone settings view might include toggle switches, + sliders, radio buttons, and other visualizations based on the type of each setting. In this case, DelegateChooser + could provide an easy way to associate a different type of delegate with each setting: + + \qml \QtMinorVersion + import QtQuick 2.\1 + import QtQuick.Controls 2.\1 + import Qt.labs.qmlmodels 1.0 + + ListView { + width: 200; height: 400 + + ListModel { + id: listModel + ListElement { type: "info"; ... } + ListElement { type: "switch"; ... } + ListElement { type: "swipe"; ... } + ListElement { type: "switch"; ... } + } + + DelegateChooser { + id: chooser + role: "type" + DelegateChoice { roleValue: "info"; ItemDelegate { ... } } + DelegateChoice { roleValue: "switch"; SwitchDelegate { ... } } + DelegateChoice { roleValue: "swipe"; SwipeDelegate { ... } } + } + + model: listModel + delegate: chooser + } + \endqml + \note This type is intended to transparently work only with TableView and any DelegateModel-based view. Views (including user-defined views) that aren't internally based on a DelegateModel need to explicitly support this type of component to make it function as described. diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index 2216e5fb50..6c80f4a3e5 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -1344,6 +1344,11 @@ void QQmlDelegateModel::_q_itemsInserted(int index, int count) const QList<QQmlDelegateModelItem *> cache = d->m_cache; for (int i = 0, c = cache.count(); i < c; ++i) { QQmlDelegateModelItem *item = cache.at(i); + // layout change triggered by changing the modelIndex might have + // already invalidated this item in d->m_cache and deleted it. + if (!d->m_cache.isSharedWith(cache) && !d->m_cache.contains(item)) + continue; + if (item->modelIndex() >= index) { const int newIndex = item->modelIndex() + count; const int row = newIndex; @@ -1487,7 +1492,7 @@ void QQmlDelegateModel::_q_itemsRemoved(int index, int count) QQmlDelegateModelItem *item = cache.at(i); // layout change triggered by removal of a previous item might have // already invalidated this item in d->m_cache and deleted it - if (!d->m_cache.contains(item)) + if (!d->m_cache.isSharedWith(cache) && !d->m_cache.contains(item)) continue; if (item->modelIndex() >= index + count) { @@ -1542,6 +1547,11 @@ void QQmlDelegateModel::_q_itemsMoved(int from, int to, int count) const QList<QQmlDelegateModelItem *> cache = d->m_cache; for (int i = 0, c = cache.count(); i < c; ++i) { QQmlDelegateModelItem *item = cache.at(i); + // layout change triggered by changing the modelIndex might have + // already invalidated this item in d->m_cache and deleted it. + if (!d->m_cache.isSharedWith(cache) && !d->m_cache.contains(item)) + continue; + if (item->modelIndex() >= from && item->modelIndex() < from + count) { const int newIndex = item->modelIndex() - from + to; const int row = newIndex; @@ -1634,6 +1644,11 @@ void QQmlDelegateModel::_q_modelReset() const QList<QQmlDelegateModelItem *> cache = d->m_cache; for (int i = 0, c = cache.count(); i < c; ++i) { QQmlDelegateModelItem *item = cache.at(i); + // layout change triggered by changing the modelIndex might have + // already invalidated this item in d->m_cache and deleted it. + if (!d->m_cache.isSharedWith(cache) && !d->m_cache.contains(item)) + continue; + if (item->modelIndex() != -1) item->setModelIndex(-1, -1, -1); } @@ -2639,10 +2654,10 @@ QJSValue QQmlDelegateModelGroup::get(int index) model->m_cacheMetaType->initializePrototype(); QV4::ExecutionEngine *v4 = model->m_cacheMetaType->v4Engine; QV4::Scope scope(v4); + ++cacheItem->scriptRef; QV4::ScopedObject o(scope, v4->memoryManager->allocate<QQmlDelegateModelItemObject>(cacheItem)); QV4::ScopedObject p(scope, model->m_cacheMetaType->modelItemProto.value()); o->setPrototypeOf(p); - ++cacheItem->scriptRef; return QJSValue(v4, o->asReturnedValue()); } |