aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-04-03 15:22:22 +0200
committerUlf Hermann <ulf.hermann@qt.io>2019-05-02 09:26:04 +0000
commit325e6305b418ffe1dfb9a36c2516c6a8a3de5733 (patch)
treec03b4f8263b41986b6f5d4ac9c6e35e371e98a33 /src/qml
parent0d409333d8679c75beeeda2711a9f01b5e708743 (diff)
Move model types into their own library
The model types are not part of the core QML runtime and should only be loaded if you explicitly import them. We cannot enforce that in Qt5 as some of them are available from the QtQml import, but we can change it in Qt6. Change-Id: I1e49e84d748e352537ec2d4af901c034c91d038f Reviewed-by: Erik Verbruggen <erik.verbruggen@me.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/configure.json16
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h12
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h2
-rw-r--r--src/qml/jsruntime/qv4object_p.h2
-rw-r--r--src/qml/jsruntime/qv4propertykey_p.h2
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp73
-rw-r--r--src/qml/jsruntime/qv4vtable_p.h2
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h2
-rw-r--r--src/qml/types/qqmldelegatecomponent.cpp300
-rw-r--r--src/qml/types/qqmldelegatecomponent_p.h155
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp3540
-rw-r--r--src/qml/types/qqmldelegatemodel_p.h248
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h450
-rw-r--r--src/qml/types/qqmlinstantiator.cpp509
-rw-r--r--src/qml/types/qqmlinstantiator_p.h119
-rw-r--r--src/qml/types/qqmlinstantiator_p_p.h98
-rw-r--r--src/qml/types/qqmlitemmodels.qdoc110
-rw-r--r--src/qml/types/qqmlitemselectionmodel.qdoc239
-rw-r--r--src/qml/types/qqmllistmodel.cpp2900
-rw-r--r--src/qml/types/qqmllistmodel_p.h208
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h428
-rw-r--r--src/qml/types/qqmllistmodelworkeragent.cpp177
-rw-r--r--src/qml/types/qqmllistmodelworkeragent_p.h140
-rw-r--r--src/qml/types/qqmlmodelsmodule.cpp123
-rw-r--r--src/qml/types/qqmlmodelsmodule_p.h72
-rw-r--r--src/qml/types/qqmlobjectmodel.cpp431
-rw-r--r--src/qml/types/qqmlobjectmodel_p.h194
-rw-r--r--src/qml/types/qqmltableinstancemodel.cpp547
-rw-r--r--src/qml/types/qqmltableinstancemodel_p.h162
-rw-r--r--src/qml/types/qqmltablemodel.cpp1059
-rw-r--r--src/qml/types/qqmltablemodel_p.h170
-rw-r--r--src/qml/types/qqmltablemodelcolumn.cpp200
-rw-r--r--src/qml/types/qqmltablemodelcolumn_p.h224
-rw-r--r--src/qml/types/qquickpackage.cpp198
-rw-r--r--src/qml/types/qquickpackage_p.h101
-rw-r--r--src/qml/types/types.pri41
-rw-r--r--src/qml/util/qqmladaptormodel.cpp1037
-rw-r--r--src/qml/util/qqmladaptormodel_p.h179
-rw-r--r--src/qml/util/qqmlchangeset.cpp583
-rw-r--r--src/qml/util/qqmlchangeset_p.h161
-rw-r--r--src/qml/util/qqmllistaccessor.cpp160
-rw-r--r--src/qml/util/qqmllistaccessor_p.h83
-rw-r--r--src/qml/util/qqmllistcompositor.cpp1482
-rw-r--r--src/qml/util/qqmllistcompositor_p.h372
-rw-r--r--src/qml/util/util.pri14
46 files changed, 62 insertions, 17265 deletions
diff --git a/src/qml/configure.json b/src/qml/configure.json
index 0f7de29594..2f88aef1fb 100644
--- a/src/qml/configure.json
+++ b/src/qml/configure.json
@@ -149,12 +149,6 @@
"section": "QML",
"output": [ "privateFeature" ]
},
- "qml-list-model": {
- "label": "QML list model",
- "purpose": "Provides the ListModel QML type.",
- "section": "QML",
- "output": [ "privateFeature" ]
- },
"qml-xml-http-request": {
"label": "QML XML http request",
"purpose": "Provides support for sending XML http requests.",
@@ -178,12 +172,6 @@
"condition": "features.animation",
"output": [ "privateFeature" ]
},
- "qml-delegate-model": {
- "label": "QML delegate model",
- "purpose": "Provides the DelegateModel QML type.",
- "section": "QML",
- "output": [ "privateFeature" ]
- },
"qml-worker-script": {
"label": "QML WorkerScript",
"purpose": "Enables the use of threads in QML.",
@@ -201,10 +189,8 @@
"qml-debug",
"qml-jit",
"qml-sequence-object",
- "qml-list-model",
"qml-xml-http-request",
- "qml-locale",
- "qml-delegate-model"
+ "qml-locale"
]
}
]
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 5b9934282c..a87eb92caf 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -96,7 +96,7 @@ struct DateObject: Object {
double date() const { return d()->date; }
void setDate(double date) { d()->date = date; }
- QDateTime toQDateTime() const;
+ Q_QML_PRIVATE_EXPORT QDateTime toQDateTime() const;
};
template<>
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index e03d49c74d..4fee26f341 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -87,11 +87,11 @@ DECLARE_HEAP_OBJECT(FunctionObject, Object) {
}
Q_QML_PRIVATE_EXPORT void init(QV4::ExecutionContext *scope, QV4::String *name, VTable::Call call);
- void init(QV4::ExecutionContext *scope, QV4::String *name = nullptr);
- void init(QV4::ExecutionContext *scope, QV4::Function *function, QV4::String *n = nullptr);
- void init(QV4::ExecutionContext *scope, const QString &name);
- void init();
- void destroy();
+ Q_QML_PRIVATE_EXPORT void init(QV4::ExecutionContext *scope, QV4::String *name = nullptr);
+ Q_QML_PRIVATE_EXPORT void init(QV4::ExecutionContext *scope, QV4::Function *function, QV4::String *n = nullptr);
+ Q_QML_PRIVATE_EXPORT void init(QV4::ExecutionContext *scope, const QString &name);
+ Q_QML_PRIVATE_EXPORT void init();
+ Q_QML_PRIVATE_EXPORT void destroy();
void setFunction(Function *f);
@@ -260,7 +260,7 @@ struct FunctionPrototype: FunctionObject
static ReturnedValue method_hasInstance(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
-struct IndexedBuiltinFunction : FunctionObject
+struct Q_QML_PRIVATE_EXPORT IndexedBuiltinFunction : FunctionObject
{
V4_OBJECT2(IndexedBuiltinFunction, FunctionObject)
};
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index 7309749a81..f2e0afd797 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-struct Lookup {
+struct Q_QML_PRIVATE_EXPORT Lookup {
union {
ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const Value &object);
ReturnedValue (*globalGetter)(Lookup *l, ExecutionEngine *engine);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 567382cbc0..38055ef407 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -410,7 +410,7 @@ private:
friend struct ObjectPrototype;
};
-struct ObjectOwnPropertyKeyIterator : OwnPropertyKeyIterator
+struct Q_QML_PRIVATE_EXPORT ObjectOwnPropertyKeyIterator : OwnPropertyKeyIterator
{
uint arrayIndex = 0;
uint memberIndex = 0;
diff --git a/src/qml/jsruntime/qv4propertykey_p.h b/src/qml/jsruntime/qv4propertykey_p.h
index 523afd4ccf..b2a2ec3dea 100644
--- a/src/qml/jsruntime/qv4propertykey_p.h
+++ b/src/qml/jsruntime/qv4propertykey_p.h
@@ -124,7 +124,7 @@ public:
return m();
}
- bool isString() const;
+ Q_QML_EXPORT bool isString() const;
bool isSymbol() const;
bool isCanonicalNumericIndexString() const;
diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp
index a84521e205..a5e62d3e35 100644
--- a/src/qml/jsruntime/qv4serialize.cpp
+++ b/src/qml/jsruntime/qv4serialize.cpp
@@ -39,11 +39,6 @@
#include "qv4serialize_p.h"
-#if QT_CONFIG(qml_list_model)
-#include <private/qqmllistmodel_p.h>
-#include <private/qqmllistmodelworkeragent_p.h>
-#endif
-
#include <private/qv4value_p.h>
#include <private/qv4dateobject_p.h>
#include <private/qv4regexpobject_p.h>
@@ -85,9 +80,7 @@ enum Type {
WorkerNumber,
WorkerDate,
WorkerRegexp,
-#if QT_CONFIG(qml_list_model)
WorkerListModel,
-#endif
#if QT_CONFIG(qml_sequence_object)
WorkerSequence
#endif
@@ -235,18 +228,15 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
} else if (const QObjectWrapper *qobjectWrapper = v.as<QV4::QObjectWrapper>()) {
// XXX TODO: Generalize passing objects between the main thread and worker scripts so
// that others can trivially plug in their elements.
-#if QT_CONFIG(qml_list_model)
- QQmlListModel *lm = qobject_cast<QQmlListModel *>(qobjectWrapper->object());
- if (lm && lm->agent()) {
- QQmlListModelWorkerAgent *agent = lm->agent();
- agent->addref();
- push(data, valueheader(WorkerListModel));
- push(data, (void *)agent);
- return;
+ if (QObject *lm = qobjectWrapper->object()) {
+ if (QObject *agent = qvariant_cast<QObject *>(lm->property("agent"))) {
+ if (QMetaObject::invokeMethod(agent, "addref")) {
+ push(data, valueheader(WorkerListModel));
+ push(data, (void *)agent);
+ return;
+ }
+ }
}
-#else
- Q_UNUSED(qobjectWrapper);
-#endif
// No other QObject's are allowed to be sent
push(data, valueheader(WorkerUndefined));
} else if (const Object *o = v.as<Object>()) {
@@ -298,6 +288,41 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
}
}
+struct VariantRef
+{
+ VariantRef() : obj(nullptr) {}
+ VariantRef(const VariantRef &r) : obj(r.obj) { addref(); }
+ VariantRef(QObject *a) : obj(a) { addref(); }
+ ~VariantRef() { release(); }
+
+ VariantRef &operator=(const VariantRef &o) {
+ o.addref();
+ release();
+ obj = o.obj;
+ return *this;
+ }
+
+ void addref() const
+ {
+ if (obj)
+ QMetaObject::invokeMethod(obj, "addref");
+ }
+
+ void release() const
+ {
+ if (obj)
+ QMetaObject::invokeMethod(obj, "release");
+
+ }
+
+ QObject *obj;
+};
+
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(VariantRef)
+Q_DECLARE_METATYPE(QV4::ExecutionEngine *)
+QT_BEGIN_NAMESPACE
+
ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
{
quint32 header = popUint32(data);
@@ -366,24 +391,21 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
data += ALIGN(length * sizeof(quint16));
return Encode(engine->newRegExpObject(pattern, flags));
}
-#if QT_CONFIG(qml_list_model)
case WorkerListModel:
{
- void *ptr = popPtr(data);
- QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr;
+ QObject *agent = reinterpret_cast<QObject *>(popPtr(data));
QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(engine, agent));
// ### Find a better solution then the ugly property
- QQmlListModelWorkerAgent::VariantRef ref(agent);
+ VariantRef ref(agent);
QVariant var = QVariant::fromValue(ref);
QV4::ScopedValue v(scope, scope.engine->fromVariant(var));
QV4::ScopedString s(scope, engine->newString(QStringLiteral("__qml:hidden:ref")));
rv->as<Object>()->defineReadonlyProperty(s, v);
- agent->release();
- agent->setEngine(engine);
+ QMetaObject::invokeMethod(agent, "release");
+ agent->setProperty("engine", QVariant::fromValue(engine));
return rv->asReturnedValue();
}
-#endif
#if QT_CONFIG(qml_sequence_object)
case WorkerSequence:
{
@@ -423,4 +445,3 @@ ReturnedValue Serialize::deserialize(const QByteArray &data, ExecutionEngine *en
}
QT_END_NAMESPACE
-
diff --git a/src/qml/jsruntime/qv4vtable_p.h b/src/qml/jsruntime/qv4vtable_p.h
index a4d91640c5..9dda104cd1 100644
--- a/src/qml/jsruntime/qv4vtable_p.h
+++ b/src/qml/jsruntime/qv4vtable_p.h
@@ -58,7 +58,7 @@ namespace QV4 {
struct Lookup;
-struct OwnPropertyKeyIterator {
+struct Q_QML_PRIVATE_EXPORT OwnPropertyKeyIterator {
virtual ~OwnPropertyKeyIterator() = 0;
virtual PropertyKey next(const Object *o, Property *p = nullptr, PropertyAttributes *attrs = nullptr) = 0;
};
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index 453c8ab8a8..92f2ccbb4a 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -182,7 +182,7 @@ private:
QV4::Function *m_v4Function;
};
-class QQmlPropertyCapture
+class Q_QML_PRIVATE_EXPORT QQmlPropertyCapture
{
public:
QQmlPropertyCapture(QQmlEngine *engine, QQmlJavaScriptExpression *e, QQmlJavaScriptExpression::DeleteWatcher *w)
diff --git a/src/qml/types/qqmldelegatecomponent.cpp b/src/qml/types/qqmldelegatecomponent.cpp
deleted file mode 100644
index 470f6cab6a..0000000000
--- a/src/qml/types/qqmldelegatecomponent.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmldelegatecomponent_p.h"
-#include <QtQml/private/qqmladaptormodel_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QQmlAbstractDelegateComponent::QQmlAbstractDelegateComponent(QObject *parent)
- : QQmlComponent(parent)
-{
-}
-
-QQmlAbstractDelegateComponent::~QQmlAbstractDelegateComponent()
-{
-}
-
-QVariant QQmlAbstractDelegateComponent::value(QQmlAdaptorModel *adaptorModel, int row, int column, const QString &role) const
-{
- if (!adaptorModel)
- return QVariant();
- return adaptorModel->value(adaptorModel->indexAt(row, column), role);
-}
-
-/*!
- \qmlmodule Qt.labs.qmlmodels 1.0
- \title Qt Labs QML Models - QML Types
- \ingroup qmlmodules
- \brief The Qt Labs QML Models module provides various model-related types for use with views.
-
- To use this module, import the module with the following line:
-
- \qml
- import Qt.labs.qmlmodels 1.0
- \endqml
-*/
-
-/*!
- \qmltype DelegateChoice
- \instantiates QQmlDelegateChoice
- \inqmlmodule Qt.labs.qmlmodels
- \brief Encapsulates a delegate and when to use it.
-
- The DelegateChoice type wraps a delegate and defines the circumstances
- in which it should be chosen.
-
- DelegateChoices can be nested inside a DelegateChooser.
-
- \sa DelegateChooser
-*/
-
-/*!
- \qmlproperty string QtQml.Models::DelegateChoice::roleValue
- This property holds the value used to match the role data for the role provided by \l DelegateChooser::role.
-*/
-QVariant QQmlDelegateChoice::roleValue() const
-{
- return m_value;
-}
-
-void QQmlDelegateChoice::setRoleValue(const QVariant &value)
-{
- if (m_value == value)
- return;
- m_value = value;
- emit roleValueChanged();
- emit changed();
-}
-
-/*!
- \qmlproperty index QtQml.Models::DelegateChoice::row
- This property holds the value used to match the row value of model elements.
- With models that have only the index property (and thus only one column), this property
- should be intended as an index, and set to the desired index value.
-
- \note Setting both row and index has undefined behavior. The two are equivalent and only
- one should be used.
-
- \sa index
-*/
-
-/*!
- \qmlproperty index QtQml.Models::DelegateChoice::index
- This property holds the value used to match the index value of model elements.
- This is effectively an alias for \l row.
-
- \sa row
-*/
-int QQmlDelegateChoice::row() const
-{
- return m_row;
-}
-
-void QQmlDelegateChoice::setRow(int r)
-{
- if (m_row == r)
- return;
- m_row = r;
- emit rowChanged();
- emit indexChanged();
- emit changed();
-}
-
-/*!
- \qmlproperty index QtQml.Models::DelegateChoice::column
- This property holds the value used to match the column value of model elements.
-*/
-int QQmlDelegateChoice::column() const
-{
- return m_column;
-}
-
-void QQmlDelegateChoice::setColumn(int c)
-{
- if (m_column == c)
- return;
- m_column = c;
- emit columnChanged();
- emit changed();
-}
-
-QQmlComponent *QQmlDelegateChoice::delegate() const
-{
- return m_delegate;
-}
-
-/*!
- \qmlproperty Component QtQml.Models::DelegateChoice::delegate
- This property holds the delegate to use if this choice matches the model item.
-*/
-void QQmlDelegateChoice::setDelegate(QQmlComponent *delegate)
-{
- if (m_delegate == delegate)
- return;
- QQmlAbstractDelegateComponent *adc = static_cast<QQmlAbstractDelegateComponent *>(m_delegate);
- if (adc)
- disconnect(adc, &QQmlAbstractDelegateComponent::delegateChanged, this, &QQmlDelegateChoice::delegateChanged);
- m_delegate = delegate;
- adc = static_cast<QQmlAbstractDelegateComponent *>(delegate);
- if (adc)
- connect(adc, &QQmlAbstractDelegateComponent::delegateChanged, this, &QQmlDelegateChoice::delegateChanged);
- emit delegateChanged();
- emit changed();
-}
-
-bool QQmlDelegateChoice::match(int row, int column, const QVariant &value) const
-{
- if (!m_value.isValid() && m_row < 0 && m_column < 0)
- return true;
-
- const bool roleMatched = (m_value.isValid()) ? value == m_value : true;
- const bool rowMatched = (m_row < 0 ) ? true : m_row == row;
- const bool columnMatched = (m_column < 0 ) ? true : m_column == column;
- return roleMatched && rowMatched && columnMatched;
-}
-
-/*!
- \qmltype DelegateChooser
- \instantiates QQmlDelegateChooser
- \inqmlmodule Qt.labs.qmlmodels
- \brief Allows a view to use different delegates for different types of items in the model.
-
- 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
- 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.
-
- \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.
-
- \sa DelegateChoice
-*/
-
-/*!
- \qmlproperty string QtQml.Models::DelegateChooser::role
- This property holds the role used to determine the delegate for a given model item.
-
- \sa DelegateChoice
-*/
-void QQmlDelegateChooser::setRole(const QString &role)
-{
- if (m_role == role)
- return;
- m_role = role;
- emit roleChanged();
-}
-
-/*!
- \qmlproperty list<DelegateChoice> QtQml.Models::DelegateChooser::choices
- \default
-
- The list of DelegateChoices for the chooser.
-
- The list is treated as an ordered list, where the first DelegateChoice to match
- will be used be a view.
-
- It should not generally be necessary to refer to the \c choices property,
- as it is the default property for DelegateChooser and thus all child items are
- automatically assigned to this property.
-*/
-
-QQmlListProperty<QQmlDelegateChoice> QQmlDelegateChooser::choices()
-{
- return QQmlListProperty<QQmlDelegateChoice>(this, nullptr,
- QQmlDelegateChooser::choices_append,
- QQmlDelegateChooser::choices_count,
- QQmlDelegateChooser::choices_at,
- QQmlDelegateChooser::choices_clear);
-}
-
-void QQmlDelegateChooser::choices_append(QQmlListProperty<QQmlDelegateChoice> *prop, QQmlDelegateChoice *choice)
-{
- QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
- q->m_choices.append(choice);
- connect(choice, &QQmlDelegateChoice::changed, q, &QQmlAbstractDelegateComponent::delegateChanged);
- q->delegateChanged();
-}
-
-int QQmlDelegateChooser::choices_count(QQmlListProperty<QQmlDelegateChoice> *prop)
-{
- QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser*>(prop->object);
- return q->m_choices.count();
-}
-
-QQmlDelegateChoice *QQmlDelegateChooser::choices_at(QQmlListProperty<QQmlDelegateChoice> *prop, int index)
-{
- QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser*>(prop->object);
- return q->m_choices.at(index);
-}
-
-void QQmlDelegateChooser::choices_clear(QQmlListProperty<QQmlDelegateChoice> *prop)
-{
- QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
- for (QQmlDelegateChoice *choice : q->m_choices)
- disconnect(choice, &QQmlDelegateChoice::changed, q, &QQmlAbstractDelegateComponent::delegateChanged);
- q->m_choices.clear();
- q->delegateChanged();
-}
-
-QQmlComponent *QQmlDelegateChooser::delegate(QQmlAdaptorModel *adaptorModel, int row, int column) const
-{
- QVariant v;
- if (!m_role.isNull())
- v = value(adaptorModel, row, column, m_role);
- if (!v.isValid()) { // check if the row only has modelData, for example if the row is a QVariantMap
- v = value(adaptorModel, row, column, QStringLiteral("modelData"));
- if (v.isValid())
- v = v.toMap().value(m_role);
- }
- // loop through choices, finding first one that fits
- for (int i = 0; i < m_choices.count(); ++i) {
- const QQmlDelegateChoice *choice = m_choices.at(i);
- if (choice->match(row, column, v))
- return choice->delegate();
- }
-
- return nullptr;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/types/qqmldelegatecomponent_p.h b/src/qml/types/qqmldelegatecomponent_p.h
deleted file mode 100644
index c925ed9a60..0000000000
--- a/src/qml/types/qqmldelegatecomponent_p.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLDELEGATECOMPONENT_P_H
-#define QQMLDELEGATECOMPONENT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtqmlglobal_p.h>
-#include <qqmlcomponent.h>
-
-QT_REQUIRE_CONFIG(qml_delegate_model);
-
-QT_BEGIN_NAMESPACE
-
-// TODO: consider making QQmlAbstractDelegateComponent public API
-class QQmlAbstractDelegateComponentPrivate;
-class QQmlAdaptorModel;
-class Q_QML_PRIVATE_EXPORT QQmlAbstractDelegateComponent : public QQmlComponent
-{
- Q_OBJECT
-public:
- QQmlAbstractDelegateComponent(QObject *parent = nullptr);
- ~QQmlAbstractDelegateComponent() override;
-
- virtual QQmlComponent *delegate(QQmlAdaptorModel *adaptorModel, int row, int column = 0) const = 0;
-
-signals:
- void delegateChanged();
-
-protected:
- QVariant value(QQmlAdaptorModel *adaptorModel,int row, int column, const QString &role) const;
-
-private:
- Q_DECLARE_PRIVATE(QQmlAbstractDelegateComponent)
- Q_DISABLE_COPY(QQmlAbstractDelegateComponent)
-};
-
-class Q_QML_PRIVATE_EXPORT QQmlDelegateChoice : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QVariant roleValue READ roleValue WRITE setRoleValue NOTIFY roleValueChanged)
- Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged)
- Q_PROPERTY(int index READ row WRITE setRow NOTIFY indexChanged)
- Q_PROPERTY(int column READ column WRITE setColumn NOTIFY columnChanged)
- Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
- Q_CLASSINFO("DefaultProperty", "delegate")
-public:
- QVariant roleValue() const;
- void setRoleValue(const QVariant &roleValue);
-
- int row() const;
- void setRow(int r);
-
- int column() const;
- void setColumn(int c);
-
- QQmlComponent *delegate() const;
- void setDelegate(QQmlComponent *delegate);
-
- virtual bool match(int row, int column, const QVariant &value) const;
-
-signals:
- void roleValueChanged();
- void rowChanged();
- void indexChanged();
- void columnChanged();
- void delegateChanged();
- void changed();
-
-private:
- QVariant m_value;
- int m_row = -1;
- int m_column = -1;
- QQmlComponent *m_delegate = nullptr;
-};
-
-class Q_QML_PRIVATE_EXPORT QQmlDelegateChooser : public QQmlAbstractDelegateComponent
-{
- Q_OBJECT
- Q_PROPERTY(QString role READ role WRITE setRole NOTIFY roleChanged)
- Q_PROPERTY(QQmlListProperty<QQmlDelegateChoice> choices READ choices CONSTANT)
- Q_CLASSINFO("DefaultProperty", "choices")
-
-public:
- QString role() const { return m_role; }
- void setRole(const QString &role);
-
- virtual QQmlListProperty<QQmlDelegateChoice> choices();
- static void choices_append(QQmlListProperty<QQmlDelegateChoice> *, QQmlDelegateChoice *);
- static int choices_count(QQmlListProperty<QQmlDelegateChoice> *);
- static QQmlDelegateChoice *choices_at(QQmlListProperty<QQmlDelegateChoice> *, int);
- static void choices_clear(QQmlListProperty<QQmlDelegateChoice> *);
-
- QQmlComponent *delegate(QQmlAdaptorModel *adaptorModel, int row, int column = -1) const override;
-
-signals:
- void roleChanged();
-
-private:
- QString m_role;
- QList<QQmlDelegateChoice *> m_choices;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQmlDelegateChoice)
-QML_DECLARE_TYPE(QQmlDelegateChooser)
-
-#endif // QQMLDELEGATECOMPONENT_P_H
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
deleted file mode 100644
index 0e57119368..0000000000
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ /dev/null
@@ -1,3540 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmldelegatemodel_p_p.h"
-#include "qqmldelegatecomponent_p.h"
-
-#include <QtQml/qqmlinfo.h>
-
-#include <private/qquickpackage_p.h>
-#include <private/qmetaobjectbuilder_p.h>
-#include <private/qqmladaptormodel_p.h>
-#include <private/qqmlchangeset_p.h>
-#include <private/qqmlengine_p.h>
-#include <private/qqmlcomponent_p.h>
-#include <private/qqmlincubator_p.h>
-
-#include <private/qv4value_p.h>
-#include <private/qv4functionobject_p.h>
-#include <qv4objectiterator_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlDelegateModelItem;
-
-namespace QV4 {
-
-namespace Heap {
-
-struct DelegateModelGroupFunction : FunctionObject {
- void init(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg));
-
- QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg);
- uint flag;
-};
-
-struct QQmlDelegateModelGroupChange : Object {
- void init() { Object::init(); }
-
- QQmlChangeSet::ChangeData change;
-};
-
-struct QQmlDelegateModelGroupChangeArray : Object {
- void init(const QVector<QQmlChangeSet::Change> &changes);
- void destroy() {
- delete changes;
- Object::destroy();
- }
-
- QVector<QQmlChangeSet::Change> *changes;
-};
-
-
-}
-
-struct DelegateModelGroupFunction : QV4::FunctionObject
-{
- V4_OBJECT2(DelegateModelGroupFunction, FunctionObject)
-
- static Heap::DelegateModelGroupFunction *create(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg))
- {
- return scope->engine()->memoryManager->allocate<DelegateModelGroupFunction>(scope, flag, code);
- }
-
- static ReturnedValue virtualCall(const QV4::FunctionObject *that, const Value *thisObject, const Value *argv, int argc)
- {
- QV4::Scope scope(that->engine());
- QV4::Scoped<DelegateModelGroupFunction> f(scope, static_cast<const DelegateModelGroupFunction *>(that));
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject);
- if (!o)
- return scope.engine->throwTypeError(QStringLiteral("Not a valid DelegateModel object"));
-
- QV4::ScopedValue v(scope, argc ? argv[0] : Value::undefinedValue());
- return f->d()->code(o->d()->item, f->d()->flag, v);
- }
-};
-
-void Heap::DelegateModelGroupFunction::init(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg))
-{
- QV4::Heap::FunctionObject::init(scope, QStringLiteral("DelegateModelGroupFunction"));
- this->flag = flag;
- this->code = code;
-}
-
-}
-
-DEFINE_OBJECT_VTABLE(QV4::DelegateModelGroupFunction);
-
-
-
-class QQmlDelegateModelEngineData : public QV8Engine::Deletable
-{
-public:
- QQmlDelegateModelEngineData(QV4::ExecutionEngine *v4);
- ~QQmlDelegateModelEngineData();
-
- QV4::ReturnedValue array(QV4::ExecutionEngine *engine,
- const QVector<QQmlChangeSet::Change> &changes);
-
- QV4::PersistentValue changeProto;
-};
-
-V4_DEFINE_EXTENSION(QQmlDelegateModelEngineData, engineData)
-
-
-void QQmlDelegateModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop)
-{
- prop.setWritable(false);
-}
-
-QVariant QQmlDelegateModelPartsMetaObject::initialValue(int id)
-{
- QQmlDelegateModelParts *parts = static_cast<QQmlDelegateModelParts *>(object());
- QQmlPartsModel *m = new QQmlPartsModel(
- parts->model, QString::fromUtf8(name(id)), parts);
- parts->models.append(m);
- return QVariant::fromValue(static_cast<QObject *>(m));
-}
-
-QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent)
-: QObject(parent), model(parent)
-{
- new QQmlDelegateModelPartsMetaObject(this);
-}
-
-//---------------------------------------------------------------------------
-
-/*!
- \qmltype DelegateModel
- \instantiates QQmlDelegateModel
- \inqmlmodule QtQml.Models
- \brief Encapsulates a model and delegate.
-
- The DelegateModel type encapsulates a model and the delegate that will
- be instantiated for items in the model.
-
- 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
- model. Also, DelegateModel is used together with \l Package to
- provide delegates to multiple views, and with DelegateModelGroup to sort and filter
- delegate items.
-
- The example below illustrates using a DelegateModel with a ListView.
-
- \snippet delegatemodel/delegatemodel.qml 0
-*/
-
-QQmlDelegateModelPrivate::QQmlDelegateModelPrivate(QQmlContext *ctxt)
- : m_delegateChooser(nullptr)
- , m_cacheMetaType(nullptr)
- , m_context(ctxt)
- , m_parts(nullptr)
- , m_filterGroup(QStringLiteral("items"))
- , m_count(0)
- , m_groupCount(Compositor::MinimumGroupCount)
- , m_compositorGroup(Compositor::Cache)
- , m_complete(false)
- , m_delegateValidated(false)
- , m_reset(false)
- , m_transaction(false)
- , m_incubatorCleanupScheduled(false)
- , m_waitingToFetchMore(false)
- , m_cacheItems(nullptr)
- , m_items(nullptr)
- , m_persistedItems(nullptr)
-{
-}
-
-QQmlDelegateModelPrivate::~QQmlDelegateModelPrivate()
-{
- qDeleteAll(m_finishedIncubating);
-
- if (m_cacheMetaType)
- m_cacheMetaType->release();
-}
-
-int QQmlDelegateModelPrivate::adaptorModelCount() const
-{
- // QQmlDelegateModel currently only support list models.
- // So even if a model is a table model, only the first
- // column will be used.
- return m_adaptorModel.rowCount();
-}
-
-void QQmlDelegateModelPrivate::requestMoreIfNecessary()
-{
- Q_Q(QQmlDelegateModel);
- if (!m_waitingToFetchMore && m_adaptorModel.canFetchMore()) {
- m_waitingToFetchMore = true;
- QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
- }
-}
-
-void QQmlDelegateModelPrivate::init()
-{
- Q_Q(QQmlDelegateModel);
- m_compositor.setRemoveGroups(Compositor::GroupMask & ~Compositor::PersistedFlag);
-
- m_items = new QQmlDelegateModelGroup(QStringLiteral("items"), q, Compositor::Default, q);
- m_items->setDefaultInclude(true);
- m_persistedItems = new QQmlDelegateModelGroup(QStringLiteral("persistedItems"), q, Compositor::Persisted, q);
- QQmlDelegateModelGroupPrivate::get(m_items)->emitters.insert(this);
-}
-
-QQmlDelegateModel::QQmlDelegateModel()
- : QQmlDelegateModel(nullptr, nullptr)
-{
-}
-
-QQmlDelegateModel::QQmlDelegateModel(QQmlContext *ctxt, QObject *parent)
-: QQmlInstanceModel(*(new QQmlDelegateModelPrivate(ctxt)), parent)
-{
- Q_D(QQmlDelegateModel);
- d->init();
-}
-
-QQmlDelegateModel::~QQmlDelegateModel()
-{
- Q_D(QQmlDelegateModel);
- d->disconnectFromAbstractItemModel();
- d->m_adaptorModel.setObject(nullptr, this);
-
- for (QQmlDelegateModelItem *cacheItem : qAsConst(d->m_cache)) {
- if (cacheItem->object) {
- delete cacheItem->object;
-
- cacheItem->object = nullptr;
- cacheItem->contextData->invalidate();
- Q_ASSERT(cacheItem->contextData->refCount == 1);
- cacheItem->contextData = nullptr;
- cacheItem->scriptRef -= 1;
- }
- cacheItem->groups &= ~Compositor::UnresolvedFlag;
- cacheItem->objectRef = 0;
- if (!cacheItem->isReferenced())
- delete cacheItem;
- else if (cacheItem->incubationTask)
- cacheItem->incubationTask->vdm = nullptr;
- }
-}
-
-
-void QQmlDelegateModel::classBegin()
-{
- Q_D(QQmlDelegateModel);
- if (!d->m_context)
- d->m_context = qmlContext(this);
-}
-
-void QQmlDelegateModel::componentComplete()
-{
- Q_D(QQmlDelegateModel);
- d->m_complete = true;
-
- int defaultGroups = 0;
- QStringList groupNames;
- groupNames.append(QStringLiteral("items"));
- groupNames.append(QStringLiteral("persistedItems"));
- if (QQmlDelegateModelGroupPrivate::get(d->m_items)->defaultInclude)
- defaultGroups |= Compositor::DefaultFlag;
- if (QQmlDelegateModelGroupPrivate::get(d->m_persistedItems)->defaultInclude)
- defaultGroups |= Compositor::PersistedFlag;
- for (int i = Compositor::MinimumGroupCount; i < d->m_groupCount; ++i) {
- QString name = d->m_groups[i]->name();
- if (name.isEmpty()) {
- d->m_groups[i] = d->m_groups[d->m_groupCount - 1];
- --d->m_groupCount;
- --i;
- } else if (name.at(0).isUpper()) {
- qmlWarning(d->m_groups[i]) << QQmlDelegateModelGroup::tr("Group names must start with a lower case letter");
- d->m_groups[i] = d->m_groups[d->m_groupCount - 1];
- --d->m_groupCount;
- --i;
- } else {
- groupNames.append(name);
-
- QQmlDelegateModelGroupPrivate *group = QQmlDelegateModelGroupPrivate::get(d->m_groups[i]);
- group->setModel(this, Compositor::Group(i));
- if (group->defaultInclude)
- defaultGroups |= (1 << i);
- }
- }
-
- d->m_cacheMetaType = new QQmlDelegateModelItemMetaType(
- d->m_context->engine()->handle(), this, groupNames);
-
- d->m_compositor.setGroupCount(d->m_groupCount);
- d->m_compositor.setDefaultGroups(defaultGroups);
- d->updateFilterGroup();
-
- while (!d->m_pendingParts.isEmpty())
- static_cast<QQmlPartsModel *>(d->m_pendingParts.first())->updateFilterGroup();
-
- QVector<Compositor::Insert> inserts;
- d->m_count = d->adaptorModelCount();
- d->m_compositor.append(
- &d->m_adaptorModel,
- 0,
- d->m_count,
- defaultGroups | Compositor::AppendFlag | Compositor::PrependFlag,
- &inserts);
- d->itemsInserted(inserts);
- d->emitChanges();
- d->requestMoreIfNecessary();
-}
-
-/*!
- \qmlproperty model QtQml.Models::DelegateModel::model
- This property holds the model providing data for the DelegateModel.
-
- The model provides a set of data that is used to create the items
- for a view. For large or dynamic datasets the model is usually
- provided by a C++ model object. The C++ model object must be a \l
- {QAbstractItemModel} subclass or a simple list.
-
- Models can also be created directly in QML, using a \l{ListModel} or
- \l{QtQuick.XmlListModel::XmlListModel}{XmlListModel}.
-
- \sa {qml-data-models}{Data Models}
- \keyword dm-model-property
-*/
-QVariant QQmlDelegateModel::model() const
-{
- Q_D(const QQmlDelegateModel);
- return d->m_adaptorModel.model();
-}
-
-void QQmlDelegateModelPrivate::connectToAbstractItemModel()
-{
- Q_Q(QQmlDelegateModel);
- if (!m_adaptorModel.adaptsAim())
- return;
-
- auto aim = m_adaptorModel.aim();
-
- qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
- q, QQmlDelegateModel, SLOT(_q_rowsInserted(QModelIndex,int,int)));
- qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- q, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- q, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
- qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
- q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
- qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
- q, QQmlDelegateModel, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
- qmlobject_connect(aim, QAbstractItemModel, SIGNAL(modelReset()),
- q, QQmlDelegateModel, SLOT(_q_modelReset()));
- qmlobject_connect(aim, QAbstractItemModel, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
- q, QQmlDelegateModel, SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
-}
-
-void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel()
-{
- Q_Q(QQmlDelegateModel);
- if (!m_adaptorModel.adaptsAim())
- return;
-
- auto aim = m_adaptorModel.aim();
-
- QObject::disconnect(aim, SIGNAL(rowsInserted(QModelIndex,int,int)),
- q, SLOT(_q_rowsInserted(QModelIndex,int,int)));
- QObject::disconnect(aim, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
- QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- q, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
- q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
- QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
- q, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
- QObject::disconnect(aim, SIGNAL(modelReset()),
- q, SLOT(_q_modelReset()));
- QObject::disconnect(aim, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
- q, SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
-}
-
-void QQmlDelegateModel::setModel(const QVariant &model)
-{
- Q_D(QQmlDelegateModel);
-
- if (d->m_complete)
- _q_itemsRemoved(0, d->m_count);
-
- d->disconnectFromAbstractItemModel();
- d->m_adaptorModel.setModel(model, this, d->m_context->engine());
- d->connectToAbstractItemModel();
-
- d->m_adaptorModel.replaceWatchedRoles(QList<QByteArray>(), d->m_watchedRoles);
- for (int i = 0; d->m_parts && i < d->m_parts->models.count(); ++i) {
- d->m_adaptorModel.replaceWatchedRoles(
- QList<QByteArray>(), d->m_parts->models.at(i)->watchedRoles());
- }
-
- if (d->m_complete) {
- _q_itemsInserted(0, d->adaptorModelCount());
- d->requestMoreIfNecessary();
- }
-}
-
-/*!
- \qmlproperty Component QtQml.Models::DelegateModel::delegate
-
- The delegate provides a template defining each item instantiated by a view.
- The index is exposed as an accessible \c index property. Properties of the
- model are also available depending upon the type of \l {qml-data-models}{Data Model}.
-*/
-QQmlComponent *QQmlDelegateModel::delegate() const
-{
- Q_D(const QQmlDelegateModel);
- return d->m_delegate;
-}
-
-void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
-{
- Q_D(QQmlDelegateModel);
- if (d->m_transaction) {
- qmlWarning(this) << tr("The delegate of a DelegateModel cannot be changed within onUpdated.");
- return;
- }
- if (d->m_delegate == delegate)
- return;
- bool wasValid = d->m_delegate != nullptr;
- d->m_delegate.setObject(delegate, this);
- d->m_delegateValidated = false;
- if (d->m_delegateChooser)
- QObject::disconnect(d->m_delegateChooserChanged);
-
- d->m_delegateChooser = nullptr;
- if (delegate) {
- QQmlAbstractDelegateComponent *adc =
- qobject_cast<QQmlAbstractDelegateComponent *>(delegate);
- if (adc) {
- d->m_delegateChooser = adc;
- d->m_delegateChooserChanged = connect(adc, &QQmlAbstractDelegateComponent::delegateChanged,
- [d](){ d->delegateChanged(); });
- }
- }
- d->delegateChanged(d->m_delegate, wasValid);
-}
-
-/*!
- \qmlproperty QModelIndex QtQml.Models::DelegateModel::rootIndex
-
- QAbstractItemModel provides a hierarchical tree of data, whereas
- QML only operates on list data. \c rootIndex allows the children of
- any node in a QAbstractItemModel to be provided by this model.
-
- This property only affects models of type QAbstractItemModel that
- are hierarchical (e.g, a tree model).
-
- For example, here is a simple interactive file system browser.
- When a directory name is clicked, the view's \c rootIndex is set to the
- QModelIndex node of the clicked directory, thus updating the view to show
- the new directory's contents.
-
- \c main.cpp:
- \snippet delegatemodel/delegatemodel_rootindex/main.cpp 0
-
- \c view.qml:
- \snippet delegatemodel/delegatemodel_rootindex/view.qml 0
-
- If the \l {dm-model-property}{model} is a QAbstractItemModel subclass,
- the delegate can also reference a \c hasModelChildren property (optionally
- qualified by a \e model. prefix) that indicates whether the delegate's
- model item has any child nodes.
-
- \sa modelIndex(), parentModelIndex()
-*/
-QVariant QQmlDelegateModel::rootIndex() const
-{
- Q_D(const QQmlDelegateModel);
- return QVariant::fromValue(QModelIndex(d->m_adaptorModel.rootIndex));
-}
-
-void QQmlDelegateModel::setRootIndex(const QVariant &root)
-{
- Q_D(QQmlDelegateModel);
-
- QModelIndex modelIndex = qvariant_cast<QModelIndex>(root);
- const bool changed = d->m_adaptorModel.rootIndex != modelIndex;
- if (changed || !d->m_adaptorModel.isValid()) {
- const int oldCount = d->m_count;
- d->m_adaptorModel.rootIndex = modelIndex;
- if (!d->m_adaptorModel.isValid() && d->m_adaptorModel.aim()) {
- // The previous root index was invalidated, so we need to reconnect the model.
- d->disconnectFromAbstractItemModel();
- d->m_adaptorModel.setModel(d->m_adaptorModel.list.list(), this, d->m_context->engine());
- d->connectToAbstractItemModel();
- }
- if (d->m_adaptorModel.canFetchMore())
- d->m_adaptorModel.fetchMore();
- if (d->m_complete) {
- const int newCount = d->adaptorModelCount();
- if (oldCount)
- _q_itemsRemoved(0, oldCount);
- if (newCount)
- _q_itemsInserted(0, newCount);
- }
- if (changed)
- emit rootIndexChanged();
- }
-}
-
-/*!
- \qmlmethod QModelIndex QtQml.Models::DelegateModel::modelIndex(int index)
-
- QAbstractItemModel provides a hierarchical tree of data, whereas
- QML only operates on list data. This function assists in using
- tree models in QML.
-
- Returns a QModelIndex for the specified index.
- This value can be assigned to rootIndex.
-
- \sa rootIndex
-*/
-QVariant QQmlDelegateModel::modelIndex(int idx) const
-{
- Q_D(const QQmlDelegateModel);
- return d->m_adaptorModel.modelIndex(idx);
-}
-
-/*!
- \qmlmethod QModelIndex QtQml.Models::DelegateModel::parentModelIndex()
-
- QAbstractItemModel provides a hierarchical tree of data, whereas
- QML only operates on list data. This function assists in using
- tree models in QML.
-
- Returns a QModelIndex for the parent of the current rootIndex.
- This value can be assigned to rootIndex.
-
- \sa rootIndex
-*/
-QVariant QQmlDelegateModel::parentModelIndex() const
-{
- Q_D(const QQmlDelegateModel);
- return d->m_adaptorModel.parentModelIndex();
-}
-
-/*!
- \qmlproperty int QtQml.Models::DelegateModel::count
-*/
-
-int QQmlDelegateModel::count() const
-{
- Q_D(const QQmlDelegateModel);
- if (!d->m_delegate)
- return 0;
- return d->m_compositor.count(d->m_compositorGroup);
-}
-
-QQmlDelegateModel::ReleaseFlags QQmlDelegateModelPrivate::release(QObject *object)
-{
- if (!object)
- return QQmlDelegateModel::ReleaseFlags(0);
-
- QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(object);
- if (!cacheItem)
- return QQmlDelegateModel::ReleaseFlags(0);
-
- if (!cacheItem->releaseObject())
- return QQmlDelegateModel::Referenced;
-
- cacheItem->destroyObject();
- emitDestroyingItem(object);
- if (cacheItem->incubationTask) {
- releaseIncubator(cacheItem->incubationTask);
- cacheItem->incubationTask = nullptr;
- }
- cacheItem->Dispose();
- return QQmlInstanceModel::Destroyed;
-}
-
-/*
- Returns ReleaseStatus flags.
-*/
-
-QQmlDelegateModel::ReleaseFlags QQmlDelegateModel::release(QObject *item)
-{
- Q_D(QQmlDelegateModel);
- QQmlInstanceModel::ReleaseFlags stat = d->release(item);
- return stat;
-}
-
-// Cancel a requested async item
-void QQmlDelegateModel::cancel(int index)
-{
- Q_D(QQmlDelegateModel);
- if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) {
- qWarning() << "DelegateModel::cancel: index out range" << index << d->m_compositor.count(d->m_compositorGroup);
- return;
- }
-
- Compositor::iterator it = d->m_compositor.find(d->m_compositorGroup, index);
- QQmlDelegateModelItem *cacheItem = it->inCache() ? d->m_cache.at(it.cacheIndex) : 0;
- if (cacheItem) {
- if (cacheItem->incubationTask && !cacheItem->isObjectReferenced()) {
- d->releaseIncubator(cacheItem->incubationTask);
- cacheItem->incubationTask = nullptr;
-
- if (cacheItem->object) {
- QObject *object = cacheItem->object;
- cacheItem->destroyObject();
- if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object))
- d->emitDestroyingPackage(package);
- else
- d->emitDestroyingItem(object);
- }
-
- cacheItem->scriptRef -= 1;
- }
- if (!cacheItem->isReferenced()) {
- d->m_compositor.clearFlags(Compositor::Cache, it.cacheIndex, 1, Compositor::CacheFlag);
- d->m_cache.removeAt(it.cacheIndex);
- delete cacheItem;
- Q_ASSERT(d->m_cache.count() == d->m_compositor.count(Compositor::Cache));
- }
- }
-}
-
-void QQmlDelegateModelPrivate::group_append(
- QQmlListProperty<QQmlDelegateModelGroup> *property, QQmlDelegateModelGroup *group)
-{
- QQmlDelegateModelPrivate *d = static_cast<QQmlDelegateModelPrivate *>(property->data);
- if (d->m_complete)
- return;
- if (d->m_groupCount == Compositor::MaximumGroupCount) {
- qmlWarning(d->q_func()) << QQmlDelegateModel::tr("The maximum number of supported DelegateModelGroups is 8");
- return;
- }
- d->m_groups[d->m_groupCount] = group;
- d->m_groupCount += 1;
-}
-
-int QQmlDelegateModelPrivate::group_count(
- QQmlListProperty<QQmlDelegateModelGroup> *property)
-{
- QQmlDelegateModelPrivate *d = static_cast<QQmlDelegateModelPrivate *>(property->data);
- return d->m_groupCount - 1;
-}
-
-QQmlDelegateModelGroup *QQmlDelegateModelPrivate::group_at(
- QQmlListProperty<QQmlDelegateModelGroup> *property, int index)
-{
- QQmlDelegateModelPrivate *d = static_cast<QQmlDelegateModelPrivate *>(property->data);
- return index >= 0 && index < d->m_groupCount - 1
- ? d->m_groups[index + 1]
- : nullptr;
-}
-
-/*!
- \qmlproperty list<DelegateModelGroup> QtQml.Models::DelegateModel::groups
-
- This property holds a delegate model's group definitions.
-
- Groups define a sub-set of the items in a delegate model and can be used to filter
- a model.
-
- For every group defined in a DelegateModel two attached properties are added to each
- delegate item. The first of the form DelegateModel.in\e{GroupName} holds whether the
- item belongs to the group and the second DelegateModel.\e{groupName}Index holds the
- index of the item in that group.
-
- The following example illustrates using groups to select items in a model.
-
- \snippet delegatemodel/delegatemodelgroup.qml 0
- \keyword dm-groups-property
-*/
-
-QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups()
-{
- Q_D(QQmlDelegateModel);
- return QQmlListProperty<QQmlDelegateModelGroup>(
- this,
- d,
- QQmlDelegateModelPrivate::group_append,
- QQmlDelegateModelPrivate::group_count,
- QQmlDelegateModelPrivate::group_at,
- nullptr);
-}
-
-/*!
- \qmlproperty DelegateModelGroup QtQml.Models::DelegateModel::items
-
- This property holds default group to which all new items are added.
-*/
-
-QQmlDelegateModelGroup *QQmlDelegateModel::items()
-{
- Q_D(QQmlDelegateModel);
- return d->m_items;
-}
-
-/*!
- \qmlproperty DelegateModelGroup QtQml.Models::DelegateModel::persistedItems
-
- This property holds delegate model's persisted items group.
-
- Items in this group are not destroyed when released by a view, instead they are persisted
- until removed from the group.
-
- An item can be removed from the persistedItems group by setting the
- DelegateModel.inPersistedItems property to false. If the item is not referenced by a view
- at that time it will be destroyed. Adding an item to this group will not create a new
- instance.
-
- Items returned by the \l QtQml.Models::DelegateModelGroup::create() function are automatically added
- to this group.
-*/
-
-QQmlDelegateModelGroup *QQmlDelegateModel::persistedItems()
-{
- Q_D(QQmlDelegateModel);
- return d->m_persistedItems;
-}
-
-/*!
- \qmlproperty string QtQml.Models::DelegateModel::filterOnGroup
-
- This property holds name of the group that is used to filter the delegate model.
-
- Only items that belong to this group are visible to a view.
-
- By default this is the \l items group.
-*/
-
-QString QQmlDelegateModel::filterGroup() const
-{
- Q_D(const QQmlDelegateModel);
- return d->m_filterGroup;
-}
-
-void QQmlDelegateModel::setFilterGroup(const QString &group)
-{
- Q_D(QQmlDelegateModel);
-
- if (d->m_transaction) {
- qmlWarning(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
- return;
- }
-
- if (d->m_filterGroup != group) {
- d->m_filterGroup = group;
- d->updateFilterGroup();
- emit filterGroupChanged();
- }
-}
-
-void QQmlDelegateModel::resetFilterGroup()
-{
- setFilterGroup(QStringLiteral("items"));
-}
-
-void QQmlDelegateModelPrivate::updateFilterGroup()
-{
- Q_Q(QQmlDelegateModel);
- if (!m_cacheMetaType)
- return;
-
- QQmlListCompositor::Group previousGroup = m_compositorGroup;
- m_compositorGroup = Compositor::Default;
- for (int i = 1; i < m_groupCount; ++i) {
- if (m_filterGroup == m_cacheMetaType->groupNames.at(i - 1)) {
- m_compositorGroup = Compositor::Group(i);
- break;
- }
- }
-
- QQmlDelegateModelGroupPrivate::get(m_groups[m_compositorGroup])->emitters.insert(this);
- if (m_compositorGroup != previousGroup) {
- QVector<QQmlChangeSet::Change> removes;
- QVector<QQmlChangeSet::Change> inserts;
- m_compositor.transition(previousGroup, m_compositorGroup, &removes, &inserts);
-
- QQmlChangeSet changeSet;
- changeSet.move(removes, inserts);
- emit q->modelUpdated(changeSet, false);
-
- if (changeSet.difference() != 0)
- emit q->countChanged();
-
- if (m_parts) {
- auto partsCopy = m_parts->models; // deliberate; this may alter m_parts
- for (QQmlPartsModel *model : qAsConst(partsCopy))
- model->updateFilterGroup(m_compositorGroup, changeSet);
- }
- }
-}
-
-/*!
- \qmlproperty object QtQml.Models::DelegateModel::parts
-
- The \a parts property selects a DelegateModel which creates
- delegates from the part named. This is used in conjunction with
- the \l Package type.
-
- For example, the code below selects a model which creates
- delegates named \e list from a \l Package:
-
- \code
- DelegateModel {
- id: visualModel
- delegate: Package {
- Item { Package.name: "list" }
- }
- model: myModel
- }
-
- ListView {
- width: 200; height:200
- model: visualModel.parts.list
- }
- \endcode
-
- \sa Package
-*/
-
-QObject *QQmlDelegateModel::parts()
-{
- Q_D(QQmlDelegateModel);
- if (!d->m_parts)
- d->m_parts = new QQmlDelegateModelParts(this);
- return d->m_parts;
-}
-
-const QAbstractItemModel *QQmlDelegateModel::abstractItemModel() const
-{
- Q_D(const QQmlDelegateModel);
- return d->m_adaptorModel.adaptsAim() ? d->m_adaptorModel.aim() : nullptr;
-}
-
-void QQmlDelegateModelPrivate::emitCreatedPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package)
-{
- for (int i = 1; i < m_groupCount; ++i)
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->createdPackage(incubationTask->index[i], package);
-}
-
-void QQmlDelegateModelPrivate::emitInitPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package)
-{
- for (int i = 1; i < m_groupCount; ++i)
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->initPackage(incubationTask->index[i], package);
-}
-
-void QQmlDelegateModelPrivate::emitDestroyingPackage(QQuickPackage *package)
-{
- for (int i = 1; i < m_groupCount; ++i)
- 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 (isDoneIncubating(status)) {
- Q_ASSERT(incubating);
- // The model was deleted from under our feet, cleanup ourselves
- delete incubating->object;
- incubating->object = nullptr;
- if (incubating->contextData) {
- incubating->contextData->invalidate();
- Q_ASSERT(incubating->contextData->refCount == 1);
- incubating->contextData = nullptr;
- }
- incubating->scriptRef = 0;
- incubating->deleteLater();
- }
-}
-
-void QQmlDelegateModelPrivate::releaseIncubator(QQDMIncubationTask *incubationTask)
-{
- Q_Q(QQmlDelegateModel);
- if (!incubationTask->isError())
- incubationTask->clear();
- m_finishedIncubating.append(incubationTask);
- if (!m_incubatorCleanupScheduled) {
- m_incubatorCleanupScheduled = true;
- QCoreApplication::postEvent(q, new QEvent(QEvent::User));
- }
-}
-
-void QQmlDelegateModelPrivate::addCacheItem(QQmlDelegateModelItem *item, Compositor::iterator it)
-{
- m_cache.insert(it.cacheIndex, item);
- m_compositor.setFlags(it, 1, Compositor::CacheFlag);
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
-}
-
-void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem)
-{
- int cidx = m_cache.lastIndexOf(cacheItem);
- if (cidx >= 0) {
- m_compositor.clearFlags(Compositor::Cache, cidx, 1, Compositor::CacheFlag);
- m_cache.removeAt(cidx);
- }
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
-}
-
-void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status)
-{
- if (!isDoneIncubating(status))
- return;
-
- const QList<QQmlError> incubationTaskErrors = incubationTask->errors();
-
- QQmlDelegateModelItem *cacheItem = incubationTask->incubating;
- cacheItem->incubationTask = nullptr;
- incubationTask->incubating = nullptr;
- 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(m_delegate, incubationTaskErrors + m_delegate->errors()) << "Cannot create delegate";
- }
-
- if (!cacheItem->isObjectReferenced()) {
- if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object))
- emitDestroyingPackage(package);
- else
- emitDestroyingItem(cacheItem->object);
- delete cacheItem->object;
- cacheItem->object = nullptr;
- cacheItem->scriptRef -= 1;
- if (cacheItem->contextData) {
- cacheItem->contextData->invalidate();
- Q_ASSERT(cacheItem->contextData->refCount == 1);
- }
- cacheItem->contextData = nullptr;
-
- if (!cacheItem->isReferenced()) {
- removeCacheItem(cacheItem);
- delete cacheItem;
- }
- }
-}
-
-void QQDMIncubationTask::setInitialState(QObject *o)
-{
- vdm->setInitialState(this, o);
-}
-
-void QQmlDelegateModelPrivate::setInitialState(QQDMIncubationTask *incubationTask, QObject *o)
-{
- QQmlDelegateModelItem *cacheItem = incubationTask->incubating;
- cacheItem->object = o;
-
- if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object))
- emitInitPackage(incubationTask, package);
- else
- emitInitItem(incubationTask, cacheItem->object);
-}
-
-QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQmlIncubator::IncubationMode incubationMode)
-{
- if (!m_delegate || index < 0 || index >= m_compositor.count(group)) {
- qWarning() << "DelegateModel::item: index out range" << index << m_compositor.count(group);
- return nullptr;
- } else if (!m_context || !m_context->isValid()) {
- return nullptr;
- }
-
- Compositor::iterator it = m_compositor.find(group, index);
-
- QQmlDelegateModelItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0;
-
- if (!cacheItem) {
- cacheItem = m_adaptorModel.createItem(m_cacheMetaType, it.modelIndex());
- if (!cacheItem)
- return nullptr;
-
- cacheItem->groups = it->flags;
- addCacheItem(cacheItem, it);
- }
-
- // Bump the reference counts temporarily so neither the content data or the delegate object
- // are deleted if incubatorStatusChanged() is called synchronously.
- cacheItem->scriptRef += 1;
- cacheItem->referenceObject();
-
- if (cacheItem->incubationTask) {
- bool sync = (incubationMode == QQmlIncubator::Synchronous || incubationMode == QQmlIncubator::AsynchronousIfNested);
- if (sync && cacheItem->incubationTask->incubationMode() == QQmlIncubator::Asynchronous) {
- // previously requested async - now needed immediately
- cacheItem->incubationTask->forceCompletion();
- }
- } else if (!cacheItem->object) {
- QQmlComponent *delegate = m_delegate;
- if (m_delegateChooser) {
- QQmlAbstractDelegateComponent *chooser = m_delegateChooser;
- do {
- delegate = chooser->delegate(&m_adaptorModel, index);
- chooser = qobject_cast<QQmlAbstractDelegateComponent *>(delegate);
- } while (chooser);
- if (!delegate)
- return nullptr;
- }
-
- QQmlContext *creationContext = delegate->creationContext();
-
- cacheItem->scriptRef += 1;
-
- cacheItem->incubationTask = new QQDMIncubationTask(this, incubationMode);
- cacheItem->incubationTask->incubating = cacheItem;
- cacheItem->incubationTask->clear();
-
- for (int i = 1; i < m_groupCount; ++i)
- cacheItem->incubationTask->index[i] = it.index[i];
-
- QQmlContextData *ctxt = new QQmlContextData;
- ctxt->setParent(QQmlContextData::get(creationContext ? creationContext : m_context.data()));
- ctxt->contextObject = cacheItem;
- cacheItem->contextData = ctxt;
-
- if (m_adaptorModel.hasProxyObject()) {
- if (QQmlAdaptorModelProxyInterface *proxy
- = qobject_cast<QQmlAdaptorModelProxyInterface *>(cacheItem)) {
- ctxt = new QQmlContextData;
- ctxt->setParent(cacheItem->contextData, /*stronglyReferencedByParent*/true);
- QObject *proxied = proxy->proxiedObject();
- ctxt->contextObject = proxied;
- // We don't own the proxied object. We need to clear it if it goes away.
- QObject::connect(proxied, &QObject::destroyed,
- cacheItem, &QQmlDelegateModelItem::childContextObjectDestroyed);
- }
- }
-
- QQmlComponentPrivate *cp = QQmlComponentPrivate::get(delegate);
- cp->incubateObject(
- cacheItem->incubationTask,
- delegate,
- m_context->engine(),
- ctxt,
- QQmlContextData::get(m_context));
- }
-
- if (index == m_compositor.count(group) - 1)
- requestMoreIfNecessary();
-
- // Remove the temporary reference count.
- cacheItem->scriptRef -= 1;
- if (cacheItem->object && (!cacheItem->incubationTask || isDoneIncubating(cacheItem->incubationTask->status())))
- return cacheItem->object;
-
- cacheItem->releaseObject();
- if (!cacheItem->isReferenced()) {
- removeCacheItem(cacheItem);
- delete cacheItem;
- }
-
- return nullptr;
-}
-
-/*
- If asynchronous is true or the component is being loaded asynchronously due
- to an ancestor being loaded asynchronously, object() may return 0. In this
- case createdItem() will be emitted when the object is available. The object
- at this stage does not have any references, so object() must be called again
- to ensure a reference is held. Any call to object() which returns a valid object
- must be matched by a call to release() in order to destroy the object.
-*/
-QObject *QQmlDelegateModel::object(int index, QQmlIncubator::IncubationMode incubationMode)
-{
- Q_D(QQmlDelegateModel);
- if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) {
- qWarning() << "DelegateModel::item: index out range" << index << d->m_compositor.count(d->m_compositorGroup);
- return nullptr;
- }
-
- 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;
-
- if (auto incubationTask = d->m_cache.at(it.cacheIndex)->incubationTask)
- return incubationTask->status();
-
- return QQmlIncubator::Ready;
-}
-
-QVariant QQmlDelegateModelPrivate::variantValue(QQmlListCompositor::Group group, int index, const QString &name)
-{
- Compositor::iterator it = m_compositor.find(group, index);
- if (QQmlAdaptorModel *model = it.list<QQmlAdaptorModel>()) {
- QString role = name;
- int dot = name.indexOf(QLatin1Char('.'));
- if (dot > 0)
- role = name.left(dot);
- QVariant value = model->value(it.modelIndex(), role);
- while (dot > 0) {
- QObject *obj = qvariant_cast<QObject*>(value);
- if (!obj)
- return QVariant();
- const int from = dot + 1;
- dot = name.indexOf(QLatin1Char('.'), from);
- value = obj->property(name.midRef(from, dot - from).toUtf8());
- }
- return value;
- }
- return QVariant();
-}
-
-QVariant QQmlDelegateModel::variantValue(int index, const QString &role)
-{
- Q_D(QQmlDelegateModel);
- return d->variantValue(d->m_compositorGroup, index, role);
-}
-
-int QQmlDelegateModel::indexOf(QObject *item, QObject *) const
-{
- Q_D(const QQmlDelegateModel);
- if (QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(item))
- return cacheItem->groupIndex(d->m_compositorGroup);
- return -1;
-}
-
-void QQmlDelegateModel::setWatchedRoles(const QList<QByteArray> &roles)
-{
- Q_D(QQmlDelegateModel);
- d->m_adaptorModel.replaceWatchedRoles(d->m_watchedRoles, roles);
- d->m_watchedRoles = roles;
-}
-
-void QQmlDelegateModelPrivate::addGroups(
- Compositor::iterator from, int count, Compositor::Group group, int groupFlags)
-{
- QVector<Compositor::Insert> inserts;
- m_compositor.setFlags(from, count, group, groupFlags, &inserts);
- itemsInserted(inserts);
- emitChanges();
-}
-
-void QQmlDelegateModelPrivate::removeGroups(
- Compositor::iterator from, int count, Compositor::Group group, int groupFlags)
-{
- QVector<Compositor::Remove> removes;
- m_compositor.clearFlags(from, count, group, groupFlags, &removes);
- itemsRemoved(removes);
- emitChanges();
-}
-
-void QQmlDelegateModelPrivate::setGroups(
- Compositor::iterator from, int count, Compositor::Group group, int groupFlags)
-{
- QVector<Compositor::Remove> removes;
- QVector<Compositor::Insert> inserts;
-
- m_compositor.setFlags(from, count, group, groupFlags, &inserts);
- itemsInserted(inserts);
- const int removeFlags = ~groupFlags & Compositor::GroupMask;
-
- from = m_compositor.find(from.group, from.index[from.group]);
- m_compositor.clearFlags(from, count, group, removeFlags, &removes);
- itemsRemoved(removes);
- emitChanges();
-}
-
-bool QQmlDelegateModel::event(QEvent *e)
-{
- Q_D(QQmlDelegateModel);
- if (e->type() == QEvent::UpdateRequest) {
- d->m_waitingToFetchMore = false;
- d->m_adaptorModel.fetchMore();
- } else if (e->type() == QEvent::User) {
- d->m_incubatorCleanupScheduled = false;
- qDeleteAll(d->m_finishedIncubating);
- d->m_finishedIncubating.clear();
- }
- return QQmlInstanceModel::event(e);
-}
-
-void QQmlDelegateModelPrivate::itemsChanged(const QVector<Compositor::Change> &changes)
-{
- if (!m_delegate)
- return;
-
- QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> translatedChanges(m_groupCount);
-
- for (const Compositor::Change &change : changes) {
- for (int i = 1; i < m_groupCount; ++i) {
- if (change.inGroup(i)) {
- translatedChanges[i].append(QQmlChangeSet::Change(change.index[i], change.count));
- }
- }
- }
-
- for (int i = 1; i < m_groupCount; ++i)
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.change(translatedChanges.at(i));
-}
-
-void QQmlDelegateModel::_q_itemsChanged(int index, int count, const QVector<int> &roles)
-{
- Q_D(QQmlDelegateModel);
- if (count <= 0 || !d->m_complete)
- return;
-
- if (d->m_adaptorModel.notify(d->m_cache, index, count, roles)) {
- QVector<Compositor::Change> changes;
- d->m_compositor.listItemsChanged(&d->m_adaptorModel, index, count, &changes);
- d->itemsChanged(changes);
- d->emitChanges();
- }
-}
-
-static void incrementIndexes(QQmlDelegateModelItem *cacheItem, int count, const int *deltas)
-{
- if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
- for (int i = 1; i < count; ++i)
- incubationTask->index[i] += deltas[i];
- }
- if (QQmlDelegateModelAttached *attached = cacheItem->attached) {
- for (int i = 1; i < qMin<int>(count, Compositor::MaximumGroupCount); ++i)
- attached->m_currentIndex[i] += deltas[i];
- }
-}
-
-void QQmlDelegateModelPrivate::itemsInserted(
- const QVector<Compositor::Insert> &inserts,
- QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedInserts,
- QHash<int, QList<QQmlDelegateModelItem *> > *movedItems)
-{
- int cacheIndex = 0;
-
- int inserted[Compositor::MaximumGroupCount];
- for (int i = 1; i < m_groupCount; ++i)
- inserted[i] = 0;
-
- for (const Compositor::Insert &insert : inserts) {
- for (; cacheIndex < insert.cacheIndex; ++cacheIndex)
- incrementIndexes(m_cache.at(cacheIndex), m_groupCount, inserted);
-
- for (int i = 1; i < m_groupCount; ++i) {
- if (insert.inGroup(i)) {
- (*translatedInserts)[i].append(
- QQmlChangeSet::Change(insert.index[i], insert.count, insert.moveId));
- inserted[i] += insert.count;
- }
- }
-
- if (!insert.inCache())
- continue;
-
- if (movedItems && insert.isMove()) {
- QList<QQmlDelegateModelItem *> items = movedItems->take(insert.moveId);
- Q_ASSERT(items.count() == insert.count);
- m_cache = m_cache.mid(0, insert.cacheIndex) + items + m_cache.mid(insert.cacheIndex);
- }
- if (insert.inGroup()) {
- for (int offset = 0; cacheIndex < insert.cacheIndex + insert.count; ++cacheIndex, ++offset) {
- QQmlDelegateModelItem *cacheItem = m_cache.at(cacheIndex);
- cacheItem->groups |= insert.flags & Compositor::GroupMask;
-
- if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
- for (int i = 1; i < m_groupCount; ++i)
- incubationTask->index[i] = cacheItem->groups & (1 << i)
- ? insert.index[i] + offset
- : insert.index[i];
- }
- if (QQmlDelegateModelAttached *attached = cacheItem->attached) {
- for (int i = 1; i < m_groupCount; ++i)
- attached->m_currentIndex[i] = cacheItem->groups & (1 << i)
- ? insert.index[i] + offset
- : insert.index[i];
- }
- }
- } else {
- cacheIndex = insert.cacheIndex + insert.count;
- }
- }
- 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)
-{
- QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount);
- itemsInserted(inserts, &translatedInserts);
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
- if (!m_delegate)
- return;
-
- for (int i = 1; i < m_groupCount; ++i)
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.insert(translatedInserts.at(i));
-}
-
-void QQmlDelegateModel::_q_itemsInserted(int index, int count)
-{
-
- Q_D(QQmlDelegateModel);
- if (count <= 0 || !d->m_complete)
- return;
-
- d->m_count += count;
-
- 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) {
- const int newIndex = item->modelIndex() + count;
- const int row = newIndex;
- const int column = 0;
- item->setModelIndex(newIndex, row, column);
- }
- }
-
- QVector<Compositor::Insert> inserts;
- d->m_compositor.listItemsInserted(&d->m_adaptorModel, index, count, &inserts);
- d->itemsInserted(inserts);
- d->emitChanges();
-}
-
-//### This method should be split in two. It will remove delegates, and it will re-render the list.
-// When e.g. QQmlListModel::remove is called, the removal of the delegates should be done on
-// QAbstractItemModel::rowsAboutToBeRemoved, and the re-rendering on
-// QAbstractItemModel::rowsRemoved. Currently both are done on the latter signal. The problem is
-// that the destruction of an item will emit a changed signal that ends up at the delegate, which
-// in turn will try to load the data from the model (which should have already freed it), resulting
-// in a use-after-free. See QTBUG-59256.
-void QQmlDelegateModelPrivate::itemsRemoved(
- const QVector<Compositor::Remove> &removes,
- QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedRemoves,
- QHash<int, QList<QQmlDelegateModelItem *> > *movedItems)
-{
- int cacheIndex = 0;
- int removedCache = 0;
-
- int removed[Compositor::MaximumGroupCount];
- for (int i = 1; i < m_groupCount; ++i)
- removed[i] = 0;
-
- for (const Compositor::Remove &remove : removes) {
- for (; cacheIndex < remove.cacheIndex; ++cacheIndex)
- incrementIndexes(m_cache.at(cacheIndex), m_groupCount, removed);
-
- for (int i = 1; i < m_groupCount; ++i) {
- if (remove.inGroup(i)) {
- (*translatedRemoves)[i].append(
- QQmlChangeSet::Change(remove.index[i], remove.count, remove.moveId));
- removed[i] -= remove.count;
- }
- }
-
- if (!remove.inCache())
- continue;
-
- if (movedItems && remove.isMove()) {
- movedItems->insert(remove.moveId, m_cache.mid(remove.cacheIndex, remove.count));
- QList<QQmlDelegateModelItem *>::iterator begin = m_cache.begin() + remove.cacheIndex;
- QList<QQmlDelegateModelItem *>::iterator end = begin + remove.count;
- m_cache.erase(begin, end);
- } else {
- for (; cacheIndex < remove.cacheIndex + remove.count - removedCache; ++cacheIndex) {
- QQmlDelegateModelItem *cacheItem = m_cache.at(cacheIndex);
- if (remove.inGroup(Compositor::Persisted) && cacheItem->objectRef == 0 && cacheItem->object) {
- QObject *object = cacheItem->object;
- cacheItem->destroyObject();
- if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object))
- emitDestroyingPackage(package);
- else
- emitDestroyingItem(object);
- cacheItem->scriptRef -= 1;
- }
- if (!cacheItem->isReferenced()) {
- m_compositor.clearFlags(Compositor::Cache, cacheIndex, 1, Compositor::CacheFlag);
- m_cache.removeAt(cacheIndex);
- delete cacheItem;
- --cacheIndex;
- ++removedCache;
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
- } else if (remove.groups() == cacheItem->groups) {
- cacheItem->groups = 0;
- if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
- for (int i = 1; i < m_groupCount; ++i)
- incubationTask->index[i] = -1;
- }
- if (QQmlDelegateModelAttached *attached = cacheItem->attached) {
- for (int i = 1; i < m_groupCount; ++i)
- attached->m_currentIndex[i] = -1;
- }
- } else {
- if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
- if (!cacheItem->isObjectReferenced()) {
- releaseIncubator(cacheItem->incubationTask);
- cacheItem->incubationTask = nullptr;
- if (cacheItem->object) {
- QObject *object = cacheItem->object;
- cacheItem->destroyObject();
- if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object))
- emitDestroyingPackage(package);
- else
- emitDestroyingItem(object);
- }
- cacheItem->scriptRef -= 1;
- } else {
- for (int i = 1; i < m_groupCount; ++i) {
- if (remove.inGroup(i))
- incubationTask->index[i] = remove.index[i];
- }
- }
- }
- if (QQmlDelegateModelAttached *attached = cacheItem->attached) {
- for (int i = 1; i < m_groupCount; ++i) {
- if (remove.inGroup(i))
- attached->m_currentIndex[i] = remove.index[i];
- }
- }
- cacheItem->groups &= ~remove.flags;
- }
- }
- }
- }
-
- 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)
-{
- QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> translatedRemoves(m_groupCount);
- itemsRemoved(removes, &translatedRemoves);
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
- if (!m_delegate)
- return;
-
- for (int i = 1; i < m_groupCount; ++i)
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.remove(translatedRemoves.at(i));
-}
-
-void QQmlDelegateModel::_q_itemsRemoved(int index, int count)
-{
- Q_D(QQmlDelegateModel);
- if (count <= 0|| !d->m_complete)
- return;
-
- d->m_count -= 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 removal of a previous item might have
- // already invalidated this item in d->m_cache and deleted it
- if (!d->m_cache.contains(item))
- continue;
-
- if (item->modelIndex() >= index + count) {
- const int newIndex = item->modelIndex() - count;
- const int row = newIndex;
- const int column = 0;
- item->setModelIndex(newIndex, row, column);
- } else if (item->modelIndex() >= index) {
- item->setModelIndex(-1, -1, -1);
- }
- }
-
- QVector<Compositor::Remove> removes;
- d->m_compositor.listItemsRemoved(&d->m_adaptorModel, index, count, &removes);
- d->itemsRemoved(removes);
-
- d->emitChanges();
-}
-
-void QQmlDelegateModelPrivate::itemsMoved(
- const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts)
-{
- QHash<int, QList<QQmlDelegateModelItem *> > movedItems;
-
- QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> translatedRemoves(m_groupCount);
- itemsRemoved(removes, &translatedRemoves, &movedItems);
-
- QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount);
- itemsInserted(inserts, &translatedInserts, &movedItems);
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
- Q_ASSERT(movedItems.isEmpty());
- if (!m_delegate)
- return;
-
- for (int i = 1; i < m_groupCount; ++i) {
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.move(
- translatedRemoves.at(i),
- translatedInserts.at(i));
- }
-}
-
-void QQmlDelegateModel::_q_itemsMoved(int from, int to, int count)
-{
- Q_D(QQmlDelegateModel);
- if (count <= 0 || !d->m_complete)
- return;
-
- const int minimum = qMin(from, to);
- const int maximum = qMax(from, to) + count;
- const int difference = from > to ? count : -count;
-
- 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) {
- const int newIndex = item->modelIndex() - from + to;
- const int row = newIndex;
- const int column = 0;
- item->setModelIndex(newIndex, row, column);
- } else if (item->modelIndex() >= minimum && item->modelIndex() < maximum) {
- const int newIndex = item->modelIndex() + difference;
- const int row = newIndex;
- const int column = 0;
- item->setModelIndex(newIndex, row, column);
- }
- }
-
- QVector<Compositor::Remove> removes;
- QVector<Compositor::Insert> inserts;
- d->m_compositor.listItemsMoved(&d->m_adaptorModel, from, to, count, &removes, &inserts);
- d->itemsMoved(removes, inserts);
- d->emitChanges();
-}
-
-void QQmlDelegateModelPrivate::emitModelUpdated(const QQmlChangeSet &changeSet, bool reset)
-{
- Q_Q(QQmlDelegateModel);
- emit q->modelUpdated(changeSet, reset);
- if (changeSet.difference() != 0)
- emit q->countChanged();
-}
-
-void QQmlDelegateModelPrivate::delegateChanged(bool add, bool remove)
-{
- Q_Q(QQmlDelegateModel);
- if (!m_complete)
- return;
-
- if (m_transaction) {
- qmlWarning(q) << QQmlDelegateModel::tr("The delegates of a DelegateModel cannot be changed within onUpdated.");
- return;
- }
-
- if (remove) {
- for (int i = 1; i < m_groupCount; ++i) {
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.remove(
- 0, m_compositor.count(Compositor::Group(i)));
- }
- }
- if (add) {
- for (int i = 1; i < m_groupCount; ++i) {
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.insert(
- 0, m_compositor.count(Compositor::Group(i)));
- }
- }
- emitChanges();
-}
-
-void QQmlDelegateModelPrivate::emitChanges()
-{
- if (m_transaction || !m_complete || !m_context || !m_context->isValid())
- return;
-
- m_transaction = true;
- QV4::ExecutionEngine *engine = m_context->engine()->handle();
- for (int i = 1; i < m_groupCount; ++i)
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitChanges(engine);
- m_transaction = false;
-
- const bool reset = m_reset;
- m_reset = false;
- for (int i = 1; i < m_groupCount; ++i)
- QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitModelUpdated(reset);
-
- auto cacheCopy = m_cache; // deliberate; emitChanges may alter m_cache
- for (QQmlDelegateModelItem *cacheItem : qAsConst(cacheCopy)) {
- if (cacheItem->attached)
- cacheItem->attached->emitChanges();
- }
-}
-
-void QQmlDelegateModel::_q_modelReset()
-{
- Q_D(QQmlDelegateModel);
- if (!d->m_delegate)
- return;
-
- int oldCount = d->m_count;
- d->m_adaptorModel.rootIndex = QModelIndex();
-
- if (d->m_complete) {
- d->m_count = d->adaptorModelCount();
-
- 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, -1, -1);
- }
-
- QVector<Compositor::Remove> removes;
- QVector<Compositor::Insert> inserts;
- if (oldCount)
- d->m_compositor.listItemsRemoved(&d->m_adaptorModel, 0, oldCount, &removes);
- if (d->m_count)
- d->m_compositor.listItemsInserted(&d->m_adaptorModel, 0, d->m_count, &inserts);
- d->itemsMoved(removes, inserts);
- d->m_reset = true;
-
- if (d->m_adaptorModel.canFetchMore())
- d->m_adaptorModel.fetchMore();
-
- d->emitChanges();
- }
- emit rootIndexChanged();
-}
-
-void QQmlDelegateModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
-{
- Q_D(QQmlDelegateModel);
- if (parent == d->m_adaptorModel.rootIndex)
- _q_itemsInserted(begin, end - begin + 1);
-}
-
-void QQmlDelegateModel::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end)
-{
- Q_D(QQmlDelegateModel);
- if (!d->m_adaptorModel.rootIndex.isValid())
- return;
- const QModelIndex index = d->m_adaptorModel.rootIndex;
- if (index.parent() == parent && index.row() >= begin && index.row() <= end) {
- const int oldCount = d->m_count;
- d->m_count = 0;
- d->disconnectFromAbstractItemModel();
- d->m_adaptorModel.invalidateModel();
-
- if (d->m_complete && oldCount > 0) {
- QVector<Compositor::Remove> removes;
- d->m_compositor.listItemsRemoved(&d->m_adaptorModel, 0, oldCount, &removes);
- d->itemsRemoved(removes);
- d->emitChanges();
- }
- }
-}
-
-void QQmlDelegateModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end)
-{
- Q_D(QQmlDelegateModel);
- if (parent == d->m_adaptorModel.rootIndex)
- _q_itemsRemoved(begin, end - begin + 1);
-}
-
-void QQmlDelegateModel::_q_rowsMoved(
- const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
- const QModelIndex &destinationParent, int destinationRow)
-{
- Q_D(QQmlDelegateModel);
- const int count = sourceEnd - sourceStart + 1;
- if (destinationParent == d->m_adaptorModel.rootIndex && sourceParent == d->m_adaptorModel.rootIndex) {
- _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow - count, count);
- } else if (sourceParent == d->m_adaptorModel.rootIndex) {
- _q_itemsRemoved(sourceStart, count);
- } else if (destinationParent == d->m_adaptorModel.rootIndex) {
- _q_itemsInserted(destinationRow, count);
- }
-}
-
-void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
-{
- Q_D(QQmlDelegateModel);
- if (begin.parent() == d->m_adaptorModel.rootIndex)
- _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, roles);
-}
-
-bool QQmlDelegateModel::isDescendantOf(const QPersistentModelIndex& desc, const QList< QPersistentModelIndex >& parents) const
-{
- for (int i = 0, c = parents.count(); i < c; ++i) {
- for (QPersistentModelIndex parent = desc; parent.isValid(); parent = parent.parent()) {
- if (parent == parents[i])
- return true;
- }
- }
-
- return false;
-}
-
-void QQmlDelegateModel::_q_layoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint)
-{
- Q_D(QQmlDelegateModel);
- if (!d->m_complete)
- return;
-
- if (hint == QAbstractItemModel::VerticalSortHint) {
- if (!parents.isEmpty() && d->m_adaptorModel.rootIndex.isValid() && !isDescendantOf(d->m_adaptorModel.rootIndex, parents)) {
- return;
- }
-
- // mark all items as changed
- _q_itemsChanged(0, d->m_count, QVector<int>());
-
- } else if (hint == QAbstractItemModel::HorizontalSortHint) {
- // Ignored
- } else {
- // We don't know what's going on, so reset the model
- _q_modelReset();
- }
-}
-
-QQmlDelegateModelAttached *QQmlDelegateModel::qmlAttachedProperties(QObject *obj)
-{
- if (QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(obj)) {
- if (cacheItem->object == obj) { // Don't create attached item for child objects.
- cacheItem->attached = new QQmlDelegateModelAttached(cacheItem, obj);
- return cacheItem->attached;
- }
- }
- return new QQmlDelegateModelAttached(obj);
-}
-
-bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const QV4::Value &object, int groups)
-{
- if (!m_context || !m_context->isValid())
- return false;
-
- QQmlDelegateModelItem *cacheItem = m_adaptorModel.createItem(m_cacheMetaType, -1);
- if (!cacheItem)
- return false;
- if (!object.isObject())
- return false;
-
- QV4::ExecutionEngine *v4 = object.as<QV4::Object>()->engine();
- QV4::Scope scope(v4);
- QV4::ScopedObject o(scope, object);
- if (!o)
- return false;
-
- QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
- QV4::ScopedValue propertyName(scope);
- QV4::ScopedValue v(scope);
- while (1) {
- propertyName = it.nextPropertyNameAsString(v);
- if (propertyName->isNull())
- break;
- cacheItem->setValue(propertyName->toQStringNoThrow(), scope.engine->toVariant(v, QVariant::Invalid));
- }
-
- cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag;
-
- // Must be before the new object is inserted into the cache or its indexes will be adjusted too.
- itemsInserted(QVector<Compositor::Insert>(1, Compositor::Insert(before, 1, cacheItem->groups & ~Compositor::CacheFlag)));
-
- before = m_compositor.insert(before, nullptr, 0, 1, cacheItem->groups);
- m_cache.insert(before.cacheIndex, cacheItem);
-
- return true;
-}
-
-//============================================================================
-
-QQmlDelegateModelItemMetaType::QQmlDelegateModelItemMetaType(
- QV4::ExecutionEngine *engine, QQmlDelegateModel *model, const QStringList &groupNames)
- : model(model)
- , groupCount(groupNames.count() + 1)
- , v4Engine(engine)
- , metaObject(nullptr)
- , groupNames(groupNames)
-{
-}
-
-QQmlDelegateModelItemMetaType::~QQmlDelegateModelItemMetaType()
-{
- if (metaObject)
- metaObject->release();
-}
-
-void QQmlDelegateModelItemMetaType::initializeMetaObject()
-{
- QMetaObjectBuilder builder;
- builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
- builder.setClassName(QQmlDelegateModelAttached::staticMetaObject.className());
- builder.setSuperClass(&QQmlDelegateModelAttached::staticMetaObject);
-
- int notifierId = 0;
- for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
- QString propertyName = QLatin1String("in") + groupNames.at(i);
- propertyName.replace(2, 1, propertyName.at(2).toUpper());
- builder.addSignal("__" + propertyName.toUtf8() + "Changed()");
- QMetaPropertyBuilder propertyBuilder = builder.addProperty(
- propertyName.toUtf8(), "bool", notifierId);
- propertyBuilder.setWritable(true);
- }
- for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
- const QString propertyName = groupNames.at(i) + QLatin1String("Index");
- builder.addSignal("__" + propertyName.toUtf8() + "Changed()");
- QMetaPropertyBuilder propertyBuilder = builder.addProperty(
- propertyName.toUtf8(), "int", notifierId);
- propertyBuilder.setWritable(true);
- }
-
- metaObject = new QQmlDelegateModelAttachedMetaObject(this, builder.toMetaObject());
-}
-
-void QQmlDelegateModelItemMetaType::initializePrototype()
-{
- QV4::Scope scope(v4Engine);
-
- QV4::ScopedObject proto(scope, v4Engine->newObject());
- proto->defineAccessorProperty(QStringLiteral("model"), QQmlDelegateModelItem::get_model, nullptr);
- proto->defineAccessorProperty(QStringLiteral("groups"), QQmlDelegateModelItem::get_groups, QQmlDelegateModelItem::set_groups);
- QV4::ScopedString s(scope);
- QV4::ScopedProperty p(scope);
-
- s = v4Engine->newString(QStringLiteral("isUnresolved"));
- QV4::ScopedFunctionObject f(scope);
- QV4::ExecutionContext *global = scope.engine->rootContext();
- p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, 30, QQmlDelegateModelItem::get_member)));
- p->setSetter(nullptr);
- proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
-
- s = v4Engine->newString(QStringLiteral("inItems"));
- p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::get_member)));
- p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::set_member)));
- proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
-
- s = v4Engine->newString(QStringLiteral("inPersistedItems"));
- p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_member)));
- p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::set_member)));
- proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
-
- s = v4Engine->newString(QStringLiteral("itemsIndex"));
- p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::get_index)));
- proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
-
- s = v4Engine->newString(QStringLiteral("persistedItemsIndex"));
- p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_index)));
- p->setSetter(nullptr);
- proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
-
- for (int i = 2; i < groupNames.count(); ++i) {
- QString propertyName = QLatin1String("in") + groupNames.at(i);
- propertyName.replace(2, 1, propertyName.at(2).toUpper());
- s = v4Engine->newString(propertyName);
- p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::get_member)));
- p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::set_member)));
- proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- }
- for (int i = 2; i < groupNames.count(); ++i) {
- const QString propertyName = groupNames.at(i) + QLatin1String("Index");
- s = v4Engine->newString(propertyName);
- p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::get_index)));
- p->setSetter(nullptr);
- proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- }
- modelItemProto.set(v4Engine, proto);
-}
-
-int QQmlDelegateModelItemMetaType::parseGroups(const QStringList &groups) const
-{
- int groupFlags = 0;
- for (const QString &groupName : groups) {
- int index = groupNames.indexOf(groupName);
- if (index != -1)
- groupFlags |= 2 << index;
- }
- return groupFlags;
-}
-
-int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const
-{
- int groupFlags = 0;
- QV4::Scope scope(v4Engine);
-
- QV4::ScopedString s(scope, groups);
- if (s) {
- const QString groupName = s->toQString();
- int index = groupNames.indexOf(groupName);
- if (index != -1)
- groupFlags |= 2 << index;
- return groupFlags;
- }
-
- QV4::ScopedArrayObject array(scope, groups);
- if (array) {
- QV4::ScopedValue v(scope);
- uint arrayLength = array->getLength();
- for (uint i = 0; i < arrayLength; ++i) {
- v = array->get(i);
- const QString groupName = v->toQString();
- int index = groupNames.indexOf(groupName);
- if (index != -1)
- groupFlags |= 2 << index;
- }
- }
- return groupFlags;
-}
-
-QV4::ReturnedValue QQmlDelegateModelItem::get_model(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
-{
- QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
- if (!o)
- return b->engine()->throwTypeError(QStringLiteral("Not a valid DelegateModel object"));
- if (!o->d()->item->metaType->model)
- RETURN_UNDEFINED();
-
- return o->d()->item->get();
-}
-
-QV4::ReturnedValue QQmlDelegateModelItem::get_groups(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
-{
- QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
- if (!o)
- return scope.engine->throwTypeError(QStringLiteral("Not a valid DelegateModel object"));
-
- QStringList groups;
- for (int i = 1; i < o->d()->item->metaType->groupCount; ++i) {
- if (o->d()->item->groups & (1 << i))
- groups.append(o->d()->item->metaType->groupNames.at(i - 1));
- }
-
- return scope.engine->fromVariant(groups);
-}
-
-QV4::ReturnedValue QQmlDelegateModelItem::set_groups(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
-{
- QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
- if (!o)
- return scope.engine->throwTypeError(QStringLiteral("Not a valid DelegateModel object"));
-
- if (!argc)
- THROW_TYPE_ERROR();
-
- if (!o->d()->item->metaType->model)
- RETURN_UNDEFINED();
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(o->d()->item->metaType->model);
-
- const int groupFlags = model->m_cacheMetaType->parseGroups(argv[0]);
- const int cacheIndex = model->m_cache.indexOf(o->d()->item);
- Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
- model->setGroups(it, 1, Compositor::Cache, groupFlags);
- return QV4::Encode::undefined();
-}
-
-QV4::ReturnedValue QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
-{
- return QV4::Encode(bool(thisItem->groups & (1 << flag)));
-}
-
-QV4::ReturnedValue QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, uint flag, const QV4::Value &arg)
-{
- if (!cacheItem->metaType->model)
- return QV4::Encode::undefined();
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(cacheItem->metaType->model);
-
- bool member = arg.toBoolean();
- uint groupFlag = (1 << flag);
- if (member == ((cacheItem->groups & groupFlag) != 0))
- return QV4::Encode::undefined();
-
- const int cacheIndex = model->m_cache.indexOf(cacheItem);
- Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
- if (member)
- model->addGroups(it, 1, Compositor::Cache, groupFlag);
- else
- model->removeGroups(it, 1, Compositor::Cache, groupFlag);
- return QV4::Encode::undefined();
-}
-
-QV4::ReturnedValue QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
-{
- return QV4::Encode((int)thisItem->groupIndex(Compositor::Group(flag)));
-}
-
-void QQmlDelegateModelItem::childContextObjectDestroyed(QObject *childContextObject)
-{
- if (!contextData)
- return;
-
- for (QQmlContextData *ctxt = contextData->childContexts; ctxt; ctxt = ctxt->nextChild) {
- if (ctxt->contextObject == childContextObject)
- ctxt->contextObject = nullptr;
- }
-}
-
-
-//---------------------------------------------------------------------------
-
-DEFINE_OBJECT_VTABLE(QQmlDelegateModelItemObject);
-
-void QV4::Heap::QQmlDelegateModelItemObject::destroy()
-{
- item->Dispose();
- Object::destroy();
-}
-
-
-QQmlDelegateModelItem::QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType,
- QQmlAdaptorModel::Accessors *accessor,
- int modelIndex, int row, int column)
- : v4(metaType->v4Engine)
- , metaType(metaType)
- , contextData(nullptr)
- , object(nullptr)
- , attached(nullptr)
- , incubationTask(nullptr)
- , delegate(nullptr)
- , poolTime(0)
- , objectRef(0)
- , scriptRef(0)
- , groups(0)
- , index(modelIndex)
- , row(row)
- , column(column)
-{
- metaType->addref();
-
- if (accessor->propertyCache) {
- // The property cache in the accessor is common for all the model
- // items in the model it wraps. It describes available model roles,
- // together with revisioned properties like row, column and index, all
- // which should be available in the delegate. We assign this cache to the
- // model item so that the QML engine can use the revision information
- // when resolving the properties (rather than falling back to just
- // inspecting the QObject in the model item directly).
- QQmlData *qmldata = QQmlData::get(this, true);
- if (qmldata->propertyCache)
- qmldata->propertyCache->release();
- qmldata->propertyCache = accessor->propertyCache.data();
- qmldata->propertyCache->addref();
- }
-}
-
-QQmlDelegateModelItem::~QQmlDelegateModelItem()
-{
- Q_ASSERT(scriptRef == 0);
- Q_ASSERT(objectRef == 0);
- Q_ASSERT(!object);
-
- if (incubationTask) {
- if (metaType->model)
- QQmlDelegateModelPrivate::get(metaType->model)->releaseIncubator(incubationTask);
- else
- delete incubationTask;
- }
-
- metaType->release();
-
-}
-
-void QQmlDelegateModelItem::Dispose()
-{
- --scriptRef;
- if (isReferenced())
- return;
-
- if (metaType->model) {
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(metaType->model);
- model->removeCacheItem(this);
- }
- delete this;
-}
-
-void QQmlDelegateModelItem::setModelIndex(int idx, int newRow, int newColumn)
-{
- const int prevIndex = index;
- const int prevRow = row;
- const int prevColumn = column;
-
- index = idx;
- row = newRow;
- column = newColumn;
-
- if (idx != prevIndex)
- emit modelIndexChanged();
- if (row != prevRow)
- emit rowChanged();
- if (column != prevColumn)
- emit columnChanged();
-}
-
-void QQmlDelegateModelItem::destroyObject()
-{
- Q_ASSERT(object);
- Q_ASSERT(contextData);
-
- QQmlData *data = QQmlData::get(object);
- Q_ASSERT(data);
- if (data->ownContext) {
- data->ownContext->clearContext();
- if (data->ownContext->contextObject == object)
- data->ownContext->contextObject = nullptr;
- data->ownContext = nullptr;
- data->context = nullptr;
- }
- object->deleteLater();
-
- if (attached) {
- attached->m_cacheItem = nullptr;
- attached = nullptr;
- }
-
- contextData->invalidate();
- contextData = nullptr;
- object = nullptr;
-}
-
-QQmlDelegateModelItem *QQmlDelegateModelItem::dataForObject(QObject *object)
-{
- QQmlData *d = QQmlData::get(object);
- QQmlContextData *context = d ? d->context : nullptr;
- for (context = context ? context->parent : nullptr; context; context = context->parent) {
- if (QQmlDelegateModelItem *cacheItem = qobject_cast<QQmlDelegateModelItem *>(
- context->contextObject)) {
- return cacheItem;
- }
- }
- return nullptr;
-}
-
-int QQmlDelegateModelItem::groupIndex(Compositor::Group group)
-{
- if (QQmlDelegateModelPrivate * const model = metaType->model
- ? QQmlDelegateModelPrivate::get(metaType->model)
- : nullptr) {
- return model->m_compositor.find(Compositor::Cache, model->m_cache.indexOf(this)).index[group];
- }
- return -1;
-}
-
-//---------------------------------------------------------------------------
-
-QQmlDelegateModelAttachedMetaObject::QQmlDelegateModelAttachedMetaObject(
- QQmlDelegateModelItemMetaType *metaType, QMetaObject *metaObject)
- : metaType(metaType)
- , metaObject(metaObject)
- , memberPropertyOffset(QQmlDelegateModelAttached::staticMetaObject.propertyCount())
- , indexPropertyOffset(QQmlDelegateModelAttached::staticMetaObject.propertyCount() + metaType->groupNames.count())
-{
- // Don't reference count the meta-type here as that would create a circular reference.
- // Instead we rely the fact that the meta-type's reference count can't reach 0 without first
- // destroying all delegates with attached objects.
- *static_cast<QMetaObject *>(this) = *metaObject;
-}
-
-QQmlDelegateModelAttachedMetaObject::~QQmlDelegateModelAttachedMetaObject()
-{
- ::free(metaObject);
-}
-
-void QQmlDelegateModelAttachedMetaObject::objectDestroyed(QObject *)
-{
- release();
-}
-
-int QQmlDelegateModelAttachedMetaObject::metaCall(QObject *object, QMetaObject::Call call, int _id, void **arguments)
-{
- QQmlDelegateModelAttached *attached = static_cast<QQmlDelegateModelAttached *>(object);
- if (call == QMetaObject::ReadProperty) {
- if (_id >= indexPropertyOffset) {
- Compositor::Group group = Compositor::Group(_id - indexPropertyOffset + 1);
- *static_cast<int *>(arguments[0]) = attached->m_currentIndex[group];
- return -1;
- } else if (_id >= memberPropertyOffset) {
- Compositor::Group group = Compositor::Group(_id - memberPropertyOffset + 1);
- *static_cast<bool *>(arguments[0]) = attached->m_cacheItem->groups & (1 << group);
- return -1;
- }
- } else if (call == QMetaObject::WriteProperty) {
- if (_id >= memberPropertyOffset) {
- if (!metaType->model)
- return -1;
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(metaType->model);
- Compositor::Group group = Compositor::Group(_id - memberPropertyOffset + 1);
- const int groupFlag = 1 << group;
- const bool member = attached->m_cacheItem->groups & groupFlag;
- if (member && !*static_cast<bool *>(arguments[0])) {
- Compositor::iterator it = model->m_compositor.find(
- group, attached->m_currentIndex[group]);
- model->removeGroups(it, 1, group, groupFlag);
- } else if (!member && *static_cast<bool *>(arguments[0])) {
- for (int i = 1; i < metaType->groupCount; ++i) {
- if (attached->m_cacheItem->groups & (1 << i)) {
- Compositor::iterator it = model->m_compositor.find(
- Compositor::Group(i), attached->m_currentIndex[i]);
- model->addGroups(it, 1, Compositor::Group(i), groupFlag);
- break;
- }
- }
- }
- return -1;
- }
- }
- return attached->qt_metacall(call, _id, arguments);
-}
-
-QQmlDelegateModelAttached::QQmlDelegateModelAttached(QObject *parent)
- : m_cacheItem(nullptr)
- , m_previousGroups(0)
-{
- QQml_setParent_noEvent(this, parent);
-}
-
-QQmlDelegateModelAttached::QQmlDelegateModelAttached(
- QQmlDelegateModelItem *cacheItem, QObject *parent)
- : m_cacheItem(cacheItem)
- , m_previousGroups(cacheItem->groups)
-{
- QQml_setParent_noEvent(this, parent);
- resetCurrentIndex();
- // Let m_previousIndex be equal to m_currentIndex
- std::copy(std::begin(m_currentIndex), std::end(m_currentIndex), std::begin(m_previousIndex));
-
- if (!cacheItem->metaType->metaObject)
- cacheItem->metaType->initializeMetaObject();
-
- QObjectPrivate::get(this)->metaObject = cacheItem->metaType->metaObject;
- cacheItem->metaType->metaObject->addref();
-}
-
-void QQmlDelegateModelAttached::resetCurrentIndex()
-{
- if (QQDMIncubationTask *incubationTask = m_cacheItem->incubationTask) {
- for (int i = 1; i < qMin<int>(m_cacheItem->metaType->groupCount, Compositor::MaximumGroupCount); ++i)
- m_currentIndex[i] = incubationTask->index[i];
- } else {
- QQmlDelegateModelPrivate * const model = QQmlDelegateModelPrivate::get(m_cacheItem->metaType->model);
- Compositor::iterator it = model->m_compositor.find(
- Compositor::Cache, model->m_cache.indexOf(m_cacheItem));
- for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i)
- m_currentIndex[i] = it.index[i];
- }
-}
-
-/*!
- \qmlattachedproperty model QtQml.Models::DelegateModel::model
-
- This attached property holds the data model this delegate instance belongs to.
-
- It is attached to each instance of the delegate.
-*/
-
-QQmlDelegateModel *QQmlDelegateModelAttached::model() const
-{
- return m_cacheItem ? m_cacheItem->metaType->model : nullptr;
-}
-
-/*!
- \qmlattachedproperty stringlist QtQml.Models::DelegateModel::groups
-
- This attached property holds the name of DelegateModelGroups the item belongs to.
-
- It is attached to each instance of the delegate.
-*/
-
-QStringList QQmlDelegateModelAttached::groups() const
-{
- QStringList groups;
-
- if (!m_cacheItem)
- return groups;
- for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) {
- if (m_cacheItem->groups & (1 << i))
- groups.append(m_cacheItem->metaType->groupNames.at(i - 1));
- }
- return groups;
-}
-
-void QQmlDelegateModelAttached::setGroups(const QStringList &groups)
-{
- if (!m_cacheItem)
- return;
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_cacheItem->metaType->model);
-
- const int groupFlags = model->m_cacheMetaType->parseGroups(groups);
- const int cacheIndex = model->m_cache.indexOf(m_cacheItem);
- Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
- model->setGroups(it, 1, Compositor::Cache, groupFlags);
-}
-
-/*!
- \qmlattachedproperty bool QtQml.Models::DelegateModel::isUnresolved
-
- This attached property indicates whether the visual item is bound to a data model index.
- Returns true if the item is not bound to the model, and false if it is.
-
- An unresolved item can be bound to the data model using the DelegateModelGroup::resolve()
- function.
-
- It is attached to each instance of the delegate.
-*/
-
-bool QQmlDelegateModelAttached::isUnresolved() const
-{
- if (!m_cacheItem)
- return false;
-
- return m_cacheItem->groups & Compositor::UnresolvedFlag;
-}
-
-/*!
- \qmlattachedproperty int QtQml.Models::DelegateModel::inItems
-
- This attached property holds whether the item belongs to the default \l items DelegateModelGroup.
-
- Changing this property will add or remove the item from the items group.
-
- It is attached to each instance of the delegate.
-*/
-
-/*!
- \qmlattachedproperty int QtQml.Models::DelegateModel::itemsIndex
-
- This attached property holds the index of the item in the default \l items DelegateModelGroup.
-
- It is attached to each instance of the delegate.
-*/
-
-/*!
- \qmlattachedproperty int QtQml.Models::DelegateModel::inPersistedItems
-
- This attached property holds whether the item belongs to the \l persistedItems DelegateModelGroup.
-
- Changing this property will add or remove the item from the items group. Change with caution
- as removing an item from the persistedItems group will destroy the current instance if it is
- not referenced by a model.
-
- It is attached to each instance of the delegate.
-*/
-
-/*!
- \qmlattachedproperty int QtQml.Models::DelegateModel::persistedItemsIndex
-
- This attached property holds the index of the item in the \l persistedItems DelegateModelGroup.
-
- It is attached to each instance of the delegate.
-*/
-
-void QQmlDelegateModelAttached::emitChanges()
-{
- const int groupChanges = m_previousGroups ^ m_cacheItem->groups;
- m_previousGroups = m_cacheItem->groups;
-
- int indexChanges = 0;
- for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) {
- if (m_previousIndex[i] != m_currentIndex[i]) {
- m_previousIndex[i] = m_currentIndex[i];
- indexChanges |= (1 << i);
- }
- }
-
- int notifierId = 0;
- const QMetaObject *meta = metaObject();
- for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
- if (groupChanges & (1 << i))
- QMetaObject::activate(this, meta, notifierId, nullptr);
- }
- for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
- if (indexChanges & (1 << i))
- QMetaObject::activate(this, meta, notifierId, nullptr);
- }
-
- if (groupChanges)
- emit groupsChanged();
-}
-
-//============================================================================
-
-void QQmlDelegateModelGroupPrivate::setModel(QQmlDelegateModel *m, Compositor::Group g)
-{
- Q_ASSERT(!model);
- model = m;
- group = g;
-}
-
-bool QQmlDelegateModelGroupPrivate::isChangedConnected()
-{
- Q_Q(QQmlDelegateModelGroup);
- IS_SIGNAL_CONNECTED(q, QQmlDelegateModelGroup, changed, (const QJSValue &,const QJSValue &));
-}
-
-void QQmlDelegateModelGroupPrivate::emitChanges(QV4::ExecutionEngine *v4)
-{
- Q_Q(QQmlDelegateModelGroup);
- if (isChangedConnected() && !changeSet.isEmpty()) {
- emit q->changed(QJSValue(v4, engineData(v4)->array(v4, changeSet.removes())),
- QJSValue(v4, engineData(v4)->array(v4, changeSet.inserts())));
- }
- if (changeSet.difference() != 0)
- emit q->countChanged();
-}
-
-void QQmlDelegateModelGroupPrivate::emitModelUpdated(bool reset)
-{
- for (QQmlDelegateModelGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
- it->emitModelUpdated(changeSet, reset);
- changeSet.clear();
-}
-
-typedef QQmlDelegateModelGroupEmitterList::iterator GroupEmitterListIt;
-
-void QQmlDelegateModelGroupPrivate::createdPackage(int index, QQuickPackage *package)
-{
- for (GroupEmitterListIt it = emitters.begin(), end = emitters.end(); it != end; ++it)
- it->createdPackage(index, package);
-}
-
-void QQmlDelegateModelGroupPrivate::initPackage(int index, QQuickPackage *package)
-{
- for (GroupEmitterListIt it = emitters.begin(), end = emitters.end(); it != end; ++it)
- it->initPackage(index, package);
-}
-
-void QQmlDelegateModelGroupPrivate::destroyingPackage(QQuickPackage *package)
-{
- for (GroupEmitterListIt it = emitters.begin(), end = emitters.end(); it != end; ++it)
- it->destroyingPackage(package);
-}
-
-/*!
- \qmltype DelegateModelGroup
- \instantiates QQmlDelegateModelGroup
- \inqmlmodule QtQml.Models
- \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.Models::DelegateModel::items}{items} group, which normally directly reflects
- the contents of the model assigned to DelegateModel::model. This set can be changed to
- the contents of any other member of DelegateModel::groups by assigning the \l name of that
- DelegateModelGroup to the DelegateModel::filterOnGroup property.
-
- The data of an item in a DelegateModelGroup can be accessed using the get() function, which returns
- information about group membership and indexes as well as model data. In combination
- with the move() function this can be used to implement view sorting, with remove() to filter
- items out of a view, or with setGroups() and \l Package delegates to categorize items into
- different views. Different groups can only be sorted independently if they are disjunct. Moving
- an item in one group will also move it in all other groups it is a part of.
-
- Data from models can be supplemented by inserting data directly into a DelegateModelGroup
- with the insert() function. This can be used to introduce mock items into a view, or
- placeholder items that are later \l {resolve()}{resolved} to real model data when it becomes
- available.
-
- Delegate items can also be instantiated directly from a DelegateModelGroup using the
- create() function, making it possible to use DelegateModel without an accompanying view
- 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}
-*/
-QQmlDelegateModelGroup::QQmlDelegateModelGroup(QObject *parent)
- : QObject(*new QQmlDelegateModelGroupPrivate, parent)
-{
-}
-
-QQmlDelegateModelGroup::QQmlDelegateModelGroup(
- const QString &name, QQmlDelegateModel *model, int index, QObject *parent)
- : QQmlDelegateModelGroup(parent)
-{
- Q_D(QQmlDelegateModelGroup);
- d->name = name;
- d->setModel(model, Compositor::Group(index));
-}
-
-QQmlDelegateModelGroup::~QQmlDelegateModelGroup()
-{
-}
-
-/*!
- \qmlproperty string QtQml.Models::DelegateModelGroup::name
-
- This property holds the name of the group.
-
- Each group in a model must have a unique name starting with a lower case letter.
-*/
-
-QString QQmlDelegateModelGroup::name() const
-{
- Q_D(const QQmlDelegateModelGroup);
- return d->name;
-}
-
-void QQmlDelegateModelGroup::setName(const QString &name)
-{
- Q_D(QQmlDelegateModelGroup);
- if (d->model)
- return;
- if (d->name != name) {
- d->name = name;
- emit nameChanged();
- }
-}
-
-/*!
- \qmlproperty int QtQml.Models::DelegateModelGroup::count
-
- This property holds the number of items in the group.
-*/
-
-int QQmlDelegateModelGroup::count() const
-{
- Q_D(const QQmlDelegateModelGroup);
- if (!d->model)
- return 0;
- return QQmlDelegateModelPrivate::get(d->model)->m_compositor.count(d->group);
-}
-
-/*!
- \qmlproperty bool QtQml.Models::DelegateModelGroup::includeByDefault
-
- This property holds whether new items are assigned to this group by default.
-*/
-
-bool QQmlDelegateModelGroup::defaultInclude() const
-{
- Q_D(const QQmlDelegateModelGroup);
- return d->defaultInclude;
-}
-
-void QQmlDelegateModelGroup::setDefaultInclude(bool include)
-{
- Q_D(QQmlDelegateModelGroup);
- if (d->defaultInclude != include) {
- d->defaultInclude = include;
-
- if (d->model) {
- if (include)
- QQmlDelegateModelPrivate::get(d->model)->m_compositor.setDefaultGroup(d->group);
- else
- QQmlDelegateModelPrivate::get(d->model)->m_compositor.clearDefaultGroup(d->group);
- }
- emit defaultIncludeChanged();
- }
-}
-
-/*!
- \qmlmethod object QtQml.Models::DelegateModelGroup::get(int index)
-
- Returns a javascript object describing the item at \a index in the group.
-
- The returned object contains the same information that is available to a delegate from the
- DelegateModel attached as well as the model for that item. It has the properties:
-
- \list
- \li \b model The model data of the item. This is the same as the model context property in
- a delegate
- \li \b groups A list the of names of groups the item is a member of. This property can be
- written to change the item's membership.
- \li \b inItems Whether the item belongs to the \l {QtQml.Models::DelegateModel::items}{items} group.
- Writing to this property will add or remove the item from the group.
- \li \b itemsIndex The index of the item within the \l {QtQml.Models::DelegateModel::items}{items} group.
- \li \b {in<GroupName>} Whether the item belongs to the dynamic group \e groupName. Writing to
- this property will add or remove the item from the group.
- \li \b {<groupName>Index} The index of the item within the dynamic group \e groupName.
- \li \b isUnresolved Whether the item is bound to an index in the model assigned to
- DelegateModel::model. Returns true if the item is not bound to the model, and false if it is.
- \endlist
-*/
-
-QJSValue QQmlDelegateModelGroup::get(int index)
-{
- Q_D(QQmlDelegateModelGroup);
- if (!d->model)
- return QJSValue();
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
- if (!model->m_context || !model->m_context->isValid()) {
- return QJSValue();
- } else if (index < 0 || index >= model->m_compositor.count(d->group)) {
- qmlWarning(this) << tr("get: index out of range");
- return QJSValue();
- }
-
- Compositor::iterator it = model->m_compositor.find(d->group, index);
- QQmlDelegateModelItem *cacheItem = it->inCache()
- ? model->m_cache.at(it.cacheIndex)
- : 0;
-
- if (!cacheItem) {
- cacheItem = model->m_adaptorModel.createItem(
- model->m_cacheMetaType, it.modelIndex());
- if (!cacheItem)
- return QJSValue();
- cacheItem->groups = it->flags;
-
- model->m_cache.insert(it.cacheIndex, cacheItem);
- model->m_compositor.setFlags(it, 1, Compositor::CacheFlag);
- }
-
- if (model->m_cacheMetaType->modelItemProto.isUndefined())
- model->m_cacheMetaType->initializePrototype();
- QV4::ExecutionEngine *v4 = model->m_cacheMetaType->v4Engine;
- QV4::Scope scope(v4);
- 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());
-}
-
-bool QQmlDelegateModelGroupPrivate::parseIndex(const QV4::Value &value, int *index, Compositor::Group *group) const
-{
- if (value.isNumber()) {
- *index = value.toInt32();
- return true;
- }
-
- if (!value.isObject())
- return false;
-
- QV4::ExecutionEngine *v4 = value.as<QV4::Object>()->engine();
- QV4::Scope scope(v4);
- QV4::Scoped<QQmlDelegateModelItemObject> object(scope, value);
-
- if (object) {
- QQmlDelegateModelItem * const cacheItem = object->d()->item;
- if (QQmlDelegateModelPrivate *model = cacheItem->metaType->model
- ? QQmlDelegateModelPrivate::get(cacheItem->metaType->model)
- : nullptr) {
- *index = model->m_cache.indexOf(cacheItem);
- *group = Compositor::Cache;
- return true;
- }
- }
- return false;
-}
-
-/*!
- \qmlmethod QtQml.Models::DelegateModelGroup::insert(int index, jsdict data, array groups = undefined)
- \qmlmethod QtQml.Models::DelegateModelGroup::insert(jsdict data, var groups = undefined)
-
- Creates a new entry at \a index in a DelegateModel with the values from \a data that
- correspond to roles in the model assigned to DelegateModel::model.
-
- If no index is supplied the data is appended to the model.
-
- The optional \a groups parameter identifies the groups the new entry should belong to,
- if unspecified this is equal to the group insert was called on.
-
- Data inserted into a DelegateModel can later be merged with an existing entry in
- DelegateModel::model using the \l resolve() function. This can be used to create placeholder
- items that are later replaced by actual data.
-*/
-
-void QQmlDelegateModelGroup::insert(QQmlV4Function *args)
-{
- Q_D(QQmlDelegateModelGroup);
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
-
- int index = model->m_compositor.count(d->group);
- Compositor::Group group = d->group;
-
- if (args->length() == 0)
- return;
-
- int i = 0;
- QV4::Scope scope(args->v4engine());
- QV4::ScopedValue v(scope, (*args)[i]);
- if (d->parseIndex(v, &index, &group)) {
- if (index < 0 || index > model->m_compositor.count(group)) {
- qmlWarning(this) << tr("insert: index out of range");
- return;
- }
- if (++i == args->length())
- return;
- v = (*args)[i];
- }
-
- Compositor::insert_iterator before = index < model->m_compositor.count(group)
- ? model->m_compositor.findInsertPosition(group, index)
- : model->m_compositor.end();
-
- int groups = 1 << d->group;
- if (++i < args->length()) {
- QV4::ScopedValue val(scope, (*args)[i]);
- groups |= model->m_cacheMetaType->parseGroups(val);
- }
-
- if (v->as<QV4::ArrayObject>()) {
- return;
- } else if (v->as<QV4::Object>()) {
- model->insert(before, v, groups);
- model->emitChanges();
- }
-}
-
-/*!
- \qmlmethod QtQml.Models::DelegateModelGroup::create(int index)
- \qmlmethod QtQml.Models::DelegateModelGroup::create(int index, jsdict data, array groups = undefined)
- \qmlmethod QtQml.Models::DelegateModelGroup::create(jsdict data, array groups = undefined)
-
- Returns a reference to the instantiated item at \a index in the group.
-
- If a \a data object is provided it will be \l {insert}{inserted} at \a index and an item
- referencing this new entry will be returned. The optional \a groups parameter identifies
- the groups the new entry should belong to, if unspecified this is equal to the group create()
- was called on.
-
- All items returned by create are added to the
- \l {QtQml.Models::DelegateModel::persistedItems}{persistedItems} group. Items in this
- group remain instantiated when not referenced by any view.
-*/
-
-void QQmlDelegateModelGroup::create(QQmlV4Function *args)
-{
- Q_D(QQmlDelegateModelGroup);
- if (!d->model)
- return;
-
- if (args->length() == 0)
- return;
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
-
- int index = model->m_compositor.count(d->group);
- Compositor::Group group = d->group;
-
- int i = 0;
- QV4::Scope scope(args->v4engine());
- QV4::ScopedValue v(scope, (*args)[i]);
- if (d->parseIndex(v, &index, &group))
- ++i;
-
- if (i < args->length() && index >= 0 && index <= model->m_compositor.count(group)) {
- v = (*args)[i];
- if (v->as<QV4::Object>()) {
- int groups = 1 << d->group;
- if (++i < args->length()) {
- QV4::ScopedValue val(scope, (*args)[i]);
- groups |= model->m_cacheMetaType->parseGroups(val);
- }
-
- Compositor::insert_iterator before = index < model->m_compositor.count(group)
- ? model->m_compositor.findInsertPosition(group, index)
- : model->m_compositor.end();
-
- index = before.index[d->group];
- group = d->group;
-
- if (!model->insert(before, v, groups)) {
- return;
- }
- }
- }
- if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlWarning(this) << tr("create: index out of range");
- return;
- }
-
- QObject *object = model->object(group, index, QQmlIncubator::AsynchronousIfNested);
- if (object) {
- QVector<Compositor::Insert> inserts;
- Compositor::iterator it = model->m_compositor.find(group, index);
- model->m_compositor.setFlags(it, 1, d->group, Compositor::PersistedFlag, &inserts);
- model->itemsInserted(inserts);
- model->m_cache.at(it.cacheIndex)->releaseObject();
- }
-
- args->setReturnValue(QV4::QObjectWrapper::wrap(args->v4engine(), object));
- model->emitChanges();
-}
-
-/*!
- \qmlmethod QtQml.Models::DelegateModelGroup::resolve(int from, int to)
-
- Binds an unresolved item at \a from to an item in DelegateModel::model at index \a to.
-
- Unresolved items are entries whose data has been \l {insert()}{inserted} into a DelegateModelGroup
- instead of being derived from a DelegateModel::model index. Resolving an item will replace
- the item at the target index with the unresolved item. A resolved an item will reflect the data
- of the source model at its bound index and will move when that index moves like any other item.
-
- If a new item is replaced in the DelegateModelGroup onChanged() handler its insertion and
- replacement will be communicated to views as an atomic operation, creating the appearance
- that the model contents have not changed, or if the unresolved and model item are not adjacent
- that the previously unresolved item has simply moved.
-
-*/
-void QQmlDelegateModelGroup::resolve(QQmlV4Function *args)
-{
- Q_D(QQmlDelegateModelGroup);
- if (!d->model)
- return;
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
-
- if (args->length() < 2)
- return;
-
- int from = -1;
- int to = -1;
- Compositor::Group fromGroup = d->group;
- Compositor::Group toGroup = d->group;
-
- QV4::Scope scope(args->v4engine());
- QV4::ScopedValue v(scope, (*args)[0]);
- if (d->parseIndex(v, &from, &fromGroup)) {
- if (from < 0 || from >= model->m_compositor.count(fromGroup)) {
- qmlWarning(this) << tr("resolve: from index out of range");
- return;
- }
- } else {
- qmlWarning(this) << tr("resolve: from index invalid");
- return;
- }
-
- v = (*args)[1];
- if (d->parseIndex(v, &to, &toGroup)) {
- if (to < 0 || to >= model->m_compositor.count(toGroup)) {
- qmlWarning(this) << tr("resolve: to index out of range");
- return;
- }
- } else {
- qmlWarning(this) << tr("resolve: to index invalid");
- return;
- }
-
- Compositor::iterator fromIt = model->m_compositor.find(fromGroup, from);
- Compositor::iterator toIt = model->m_compositor.find(toGroup, to);
-
- if (!fromIt->isUnresolved()) {
- qmlWarning(this) << tr("resolve: from is not an unresolved item");
- return;
- }
- if (!toIt->list) {
- qmlWarning(this) << tr("resolve: to is not a model item");
- return;
- }
-
- const int unresolvedFlags = fromIt->flags;
- const int resolvedFlags = toIt->flags;
- const int resolvedIndex = toIt.modelIndex();
- void * const resolvedList = toIt->list;
-
- QQmlDelegateModelItem *cacheItem = model->m_cache.at(fromIt.cacheIndex);
- cacheItem->groups &= ~Compositor::UnresolvedFlag;
-
- if (toIt.cacheIndex > fromIt.cacheIndex)
- toIt.decrementIndexes(1, unresolvedFlags);
- if (!toIt->inGroup(fromGroup) || toIt.index[fromGroup] > from)
- from += 1;
-
- model->itemsMoved(
- QVector<Compositor::Remove>(1, Compositor::Remove(fromIt, 1, unresolvedFlags, 0)),
- QVector<Compositor::Insert>(1, Compositor::Insert(toIt, 1, unresolvedFlags, 0)));
- model->itemsInserted(
- QVector<Compositor::Insert>(1, Compositor::Insert(toIt, 1, (resolvedFlags & ~unresolvedFlags) | Compositor::CacheFlag)));
- toIt.incrementIndexes(1, resolvedFlags | unresolvedFlags);
- model->itemsRemoved(QVector<Compositor::Remove>(1, Compositor::Remove(toIt, 1, resolvedFlags)));
-
- model->m_compositor.setFlags(toGroup, to, 1, unresolvedFlags & ~Compositor::UnresolvedFlag);
- model->m_compositor.clearFlags(fromGroup, from, 1, unresolvedFlags);
-
- if (resolvedFlags & Compositor::CacheFlag)
- model->m_compositor.insert(Compositor::Cache, toIt.cacheIndex, resolvedList, resolvedIndex, 1, Compositor::CacheFlag);
-
- Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache));
-
- if (!cacheItem->isReferenced()) {
- Q_ASSERT(toIt.cacheIndex == model->m_cache.indexOf(cacheItem));
- model->m_cache.removeAt(toIt.cacheIndex);
- model->m_compositor.clearFlags(Compositor::Cache, toIt.cacheIndex, 1, Compositor::CacheFlag);
- delete cacheItem;
- Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache));
- } else {
- cacheItem->resolveIndex(model->m_adaptorModel, resolvedIndex);
- if (cacheItem->attached)
- cacheItem->attached->emitUnresolvedChanged();
- }
-
- model->emitChanges();
-}
-
-/*!
- \qmlmethod QtQml.Models::DelegateModelGroup::remove(int index, int count)
-
- Removes \a count items starting at \a index from the group.
-*/
-
-void QQmlDelegateModelGroup::remove(QQmlV4Function *args)
-{
- Q_D(QQmlDelegateModelGroup);
- if (!d->model)
- return;
- Compositor::Group group = d->group;
- int index = -1;
- int count = 1;
-
- if (args->length() == 0)
- return;
-
- int i = 0;
- QV4::Scope scope(args->v4engine());
- QV4::ScopedValue v(scope, (*args)[0]);
- if (!d->parseIndex(v, &index, &group)) {
- qmlWarning(this) << tr("remove: invalid index");
- return;
- }
-
- if (++i < args->length()) {
- v = (*args)[i];
- if (v->isNumber())
- count = v->toInt32();
- }
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
- if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlWarning(this) << tr("remove: index out of range");
- } else if (count != 0) {
- Compositor::iterator it = model->m_compositor.find(group, index);
- if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlWarning(this) << tr("remove: invalid count");
- } else {
- model->removeGroups(it, count, d->group, 1 << d->group);
- }
- }
-}
-
-bool QQmlDelegateModelGroupPrivate::parseGroupArgs(
- QQmlV4Function *args, Compositor::Group *group, int *index, int *count, int *groups) const
-{
- if (!model || !QQmlDelegateModelPrivate::get(model)->m_cacheMetaType)
- return false;
-
- if (args->length() < 2)
- return false;
-
- int i = 0;
- QV4::Scope scope(args->v4engine());
- QV4::ScopedValue v(scope, (*args)[i]);
- if (!parseIndex(v, index, group))
- return false;
-
- v = (*args)[++i];
- if (v->isNumber()) {
- *count = v->toInt32();
-
- if (++i == args->length())
- return false;
- v = (*args)[i];
- }
-
- *groups = QQmlDelegateModelPrivate::get(model)->m_cacheMetaType->parseGroups(v);
-
- return true;
-}
-
-/*!
- \qmlmethod QtQml.Models::DelegateModelGroup::addGroups(int index, int count, stringlist groups)
-
- Adds \a count items starting at \a index to \a groups.
-*/
-
-void QQmlDelegateModelGroup::addGroups(QQmlV4Function *args)
-{
- Q_D(QQmlDelegateModelGroup);
- Compositor::Group group = d->group;
- int index = -1;
- int count = 1;
- int groups = 0;
-
- if (!d->parseGroupArgs(args, &group, &index, &count, &groups))
- return;
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
- if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlWarning(this) << tr("addGroups: index out of range");
- } else if (count != 0) {
- Compositor::iterator it = model->m_compositor.find(group, index);
- if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlWarning(this) << tr("addGroups: invalid count");
- } else {
- model->addGroups(it, count, d->group, groups);
- }
- }
-}
-
-/*!
- \qmlmethod QtQml.Models::DelegateModelGroup::removeGroups(int index, int count, stringlist groups)
-
- Removes \a count items starting at \a index from \a groups.
-*/
-
-void QQmlDelegateModelGroup::removeGroups(QQmlV4Function *args)
-{
- Q_D(QQmlDelegateModelGroup);
- Compositor::Group group = d->group;
- int index = -1;
- int count = 1;
- int groups = 0;
-
- if (!d->parseGroupArgs(args, &group, &index, &count, &groups))
- return;
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
- if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlWarning(this) << tr("removeGroups: index out of range");
- } else if (count != 0) {
- Compositor::iterator it = model->m_compositor.find(group, index);
- if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlWarning(this) << tr("removeGroups: invalid count");
- } else {
- model->removeGroups(it, count, d->group, groups);
- }
- }
-}
-
-/*!
- \qmlmethod QtQml.Models::DelegateModelGroup::setGroups(int index, int count, stringlist groups)
-
- Sets the \a groups \a count items starting at \a index belong to.
-*/
-
-void QQmlDelegateModelGroup::setGroups(QQmlV4Function *args)
-{
- Q_D(QQmlDelegateModelGroup);
- Compositor::Group group = d->group;
- int index = -1;
- int count = 1;
- int groups = 0;
-
- if (!d->parseGroupArgs(args, &group, &index, &count, &groups))
- return;
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
- if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlWarning(this) << tr("setGroups: index out of range");
- } else if (count != 0) {
- Compositor::iterator it = model->m_compositor.find(group, index);
- if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlWarning(this) << tr("setGroups: invalid count");
- } else {
- model->setGroups(it, count, d->group, groups);
- }
- }
-}
-
-/*!
- \qmlmethod QtQml.Models::DelegateModelGroup::setGroups(int index, int count, stringlist groups)
-
- Sets the \a groups \a count items starting at \a index belong to.
-*/
-
-/*!
- \qmlmethod QtQml.Models::DelegateModelGroup::move(var from, var to, int count)
-
- Moves \a count at \a from in a group \a to a new position.
-
- \note The DelegateModel acts as a proxy model: it holds the delegates in a
- different order than the \l{dm-model-property}{underlying model} has them.
- Any subsequent changes to the underlying model will not undo whatever
- reordering you have done via this function.
-*/
-
-void QQmlDelegateModelGroup::move(QQmlV4Function *args)
-{
- Q_D(QQmlDelegateModelGroup);
-
- if (args->length() < 2)
- return;
-
- Compositor::Group fromGroup = d->group;
- Compositor::Group toGroup = d->group;
- int from = -1;
- int to = -1;
- int count = 1;
-
- QV4::Scope scope(args->v4engine());
- QV4::ScopedValue v(scope, (*args)[0]);
- if (!d->parseIndex(v, &from, &fromGroup)) {
- qmlWarning(this) << tr("move: invalid from index");
- return;
- }
-
- v = (*args)[1];
- if (!d->parseIndex(v, &to, &toGroup)) {
- qmlWarning(this) << tr("move: invalid to index");
- return;
- }
-
- if (args->length() > 2) {
- v = (*args)[2];
- if (v->isNumber())
- count = v->toInt32();
- }
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
-
- if (count < 0) {
- qmlWarning(this) << tr("move: invalid count");
- } else if (from < 0 || from + count > model->m_compositor.count(fromGroup)) {
- qmlWarning(this) << tr("move: from index out of range");
- } else if (!model->m_compositor.verifyMoveTo(fromGroup, from, toGroup, to, count, d->group)) {
- qmlWarning(this) << tr("move: to index out of range");
- } else if (count > 0) {
- QVector<Compositor::Remove> removes;
- QVector<Compositor::Insert> inserts;
-
- model->m_compositor.move(fromGroup, from, toGroup, to, count, d->group, &removes, &inserts);
- model->itemsMoved(removes, inserts);
- model->emitChanges();
- }
-
-}
-
-/*!
- \qmlsignal QtQml.Models::DelegateModelGroup::changed(array removed, array inserted)
-
- This signal is emitted when items have been removed from or inserted into the group.
-
- Each object in the \a removed and \a inserted arrays has two values; the \e index of the first
- item inserted or removed and a \e count of the number of consecutive items inserted or removed.
-
- Each index is adjusted for previous changes with all removed items preceding any inserted
- items.
-
- The corresponding handler is \c onChanged.
-*/
-
-//============================================================================
-
-QQmlPartsModel::QQmlPartsModel(QQmlDelegateModel *model, const QString &part, QObject *parent)
- : QQmlInstanceModel(*new QObjectPrivate, parent)
- , m_model(model)
- , m_part(part)
- , m_compositorGroup(Compositor::Cache)
- , m_inheritGroup(true)
-{
- QQmlDelegateModelPrivate *d = QQmlDelegateModelPrivate::get(m_model);
- if (d->m_cacheMetaType) {
- QQmlDelegateModelGroupPrivate::get(d->m_groups[1])->emitters.insert(this);
- m_compositorGroup = Compositor::Default;
- } else {
- d->m_pendingParts.insert(this);
- }
-}
-
-QQmlPartsModel::~QQmlPartsModel()
-{
-}
-
-QString QQmlPartsModel::filterGroup() const
-{
- if (m_inheritGroup)
- return m_model->filterGroup();
- return m_filterGroup;
-}
-
-void QQmlPartsModel::setFilterGroup(const QString &group)
-{
- if (QQmlDelegateModelPrivate::get(m_model)->m_transaction) {
- qmlWarning(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
- return;
- }
-
- if (m_filterGroup != group || m_inheritGroup) {
- m_filterGroup = group;
- m_inheritGroup = false;
- updateFilterGroup();
-
- emit filterGroupChanged();
- }
-}
-
-void QQmlPartsModel::resetFilterGroup()
-{
- if (!m_inheritGroup) {
- m_inheritGroup = true;
- updateFilterGroup();
- emit filterGroupChanged();
- }
-}
-
-void QQmlPartsModel::updateFilterGroup()
-{
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
- if (!model->m_cacheMetaType)
- return;
-
- if (m_inheritGroup) {
- if (m_filterGroup == model->m_filterGroup)
- return;
- m_filterGroup = model->m_filterGroup;
- }
-
- QQmlListCompositor::Group previousGroup = m_compositorGroup;
- m_compositorGroup = Compositor::Default;
- QQmlDelegateModelGroupPrivate::get(model->m_groups[Compositor::Default])->emitters.insert(this);
- for (int i = 1; i < model->m_groupCount; ++i) {
- if (m_filterGroup == model->m_cacheMetaType->groupNames.at(i - 1)) {
- m_compositorGroup = Compositor::Group(i);
- break;
- }
- }
-
- QQmlDelegateModelGroupPrivate::get(model->m_groups[m_compositorGroup])->emitters.insert(this);
- if (m_compositorGroup != previousGroup) {
- QVector<QQmlChangeSet::Change> removes;
- QVector<QQmlChangeSet::Change> inserts;
- model->m_compositor.transition(previousGroup, m_compositorGroup, &removes, &inserts);
-
- QQmlChangeSet changeSet;
- changeSet.move(removes, inserts);
- if (!changeSet.isEmpty())
- emit modelUpdated(changeSet, false);
-
- if (changeSet.difference() != 0)
- emit countChanged();
- }
-}
-
-void QQmlPartsModel::updateFilterGroup(
- Compositor::Group group, const QQmlChangeSet &changeSet)
-{
- if (!m_inheritGroup)
- return;
-
- m_compositorGroup = group;
- QQmlDelegateModelGroupPrivate::get(QQmlDelegateModelPrivate::get(m_model)->m_groups[m_compositorGroup])->emitters.insert(this);
-
- if (!changeSet.isEmpty())
- emit modelUpdated(changeSet, false);
-
- if (changeSet.difference() != 0)
- emit countChanged();
-
- emit filterGroupChanged();
-}
-
-int QQmlPartsModel::count() const
-{
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
- return model->m_delegate
- ? model->m_compositor.count(m_compositorGroup)
- : 0;
-}
-
-bool QQmlPartsModel::isValid() const
-{
- return m_model->isValid();
-}
-
-QObject *QQmlPartsModel::object(int index, QQmlIncubator::IncubationMode incubationMode)
-{
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
-
- if (!model->m_delegate || index < 0 || index >= model->m_compositor.count(m_compositorGroup)) {
- qWarning() << "DelegateModel::item: index out range" << index << model->m_compositor.count(m_compositorGroup);
- return nullptr;
- }
-
- QObject *object = model->object(m_compositorGroup, index, incubationMode);
-
- if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object)) {
- QObject *part = package->part(m_part);
- if (!part)
- return nullptr;
- m_packaged.insertMulti(part, package);
- return part;
- }
-
- model->release(object);
- if (!model->m_delegateValidated) {
- if (object)
- qmlWarning(model->m_delegate) << tr("Delegate component must be Package type.");
- model->m_delegateValidated = true;
- }
-
- return nullptr;
-}
-
-QQmlInstanceModel::ReleaseFlags QQmlPartsModel::release(QObject *item)
-{
- QQmlInstanceModel::ReleaseFlags flags = nullptr;
-
- QHash<QObject *, QQuickPackage *>::iterator it = m_packaged.find(item);
- if (it != m_packaged.end()) {
- QQuickPackage *package = *it;
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
- flags = model->release(package);
- m_packaged.erase(it);
- if (!m_packaged.contains(item))
- flags &= ~Referenced;
- if (flags & Destroyed)
- QQmlDelegateModelPrivate::get(m_model)->emitDestroyingPackage(package);
- }
- return flags;
-}
-
-QVariant QQmlPartsModel::variantValue(int index, const QString &role)
-{
- return QQmlDelegateModelPrivate::get(m_model)->variantValue(m_compositorGroup, index, role);
-}
-
-void QQmlPartsModel::setWatchedRoles(const QList<QByteArray> &roles)
-{
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
- model->m_adaptorModel.replaceWatchedRoles(m_watchedRoles, 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;
-
- if (auto incubationTask = model->m_cache.at(it.cacheIndex)->incubationTask)
- return incubationTask->status();
-
- return QQmlIncubator::Ready;
-}
-
-int QQmlPartsModel::indexOf(QObject *item, QObject *) const
-{
- QHash<QObject *, QQuickPackage *>::const_iterator it = m_packaged.find(item);
- if (it != m_packaged.end()) {
- if (QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(*it))
- return cacheItem->groupIndex(m_compositorGroup);
- }
- return -1;
-}
-
-void QQmlPartsModel::createdPackage(int index, QQuickPackage *package)
-{
- emit createdItem(index, package->part(m_part));
-}
-
-void QQmlPartsModel::initPackage(int index, QQuickPackage *package)
-{
- if (m_modelUpdatePending)
- m_pendingPackageInitializations << index;
- else
- emit initItem(index, package->part(m_part));
-}
-
-void QQmlPartsModel::destroyingPackage(QQuickPackage *package)
-{
- QObject *item = package->part(m_part);
- Q_ASSERT(!m_packaged.contains(item));
- emit destroyingItem(item);
-}
-
-void QQmlPartsModel::emitModelUpdated(const QQmlChangeSet &changeSet, bool reset)
-{
- m_modelUpdatePending = false;
- emit modelUpdated(changeSet, reset);
- if (changeSet.difference() != 0)
- emit countChanged();
-
- QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
- QVector<int> pendingPackageInitializations;
- qSwap(pendingPackageInitializations, m_pendingPackageInitializations);
- for (int index : pendingPackageInitializations) {
- if (!model->m_delegate || index < 0 || index >= model->m_compositor.count(m_compositorGroup))
- continue;
- QObject *object = model->object(m_compositorGroup, index, QQmlIncubator::Asynchronous);
- if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object))
- emit initItem(index, package->part(m_part));
- model->release(object);
- }
-}
-
-//============================================================================
-
-struct QQmlDelegateModelGroupChange : QV4::Object
-{
- V4_OBJECT2(QQmlDelegateModelGroupChange, QV4::Object)
-
- static QV4::Heap::QQmlDelegateModelGroupChange *create(QV4::ExecutionEngine *e) {
- return e->memoryManager->allocate<QQmlDelegateModelGroupChange>();
- }
-
- static QV4::ReturnedValue method_get_index(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
- QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, thisObject->as<QQmlDelegateModelGroupChange>());
- if (!that)
- THROW_TYPE_ERROR();
- return QV4::Encode(that->d()->change.index);
- }
- static QV4::ReturnedValue method_get_count(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
- QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, thisObject->as<QQmlDelegateModelGroupChange>());
- if (!that)
- THROW_TYPE_ERROR();
- return QV4::Encode(that->d()->change.count);
- }
- static QV4::ReturnedValue method_get_moveId(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
- QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, thisObject->as<QQmlDelegateModelGroupChange>());
- if (!that)
- THROW_TYPE_ERROR();
- if (that->d()->change.moveId < 0)
- RETURN_UNDEFINED();
- return QV4::Encode(that->d()->change.moveId);
- }
-};
-
-DEFINE_OBJECT_VTABLE(QQmlDelegateModelGroupChange);
-
-struct QQmlDelegateModelGroupChangeArray : public QV4::Object
-{
- V4_OBJECT2(QQmlDelegateModelGroupChangeArray, QV4::Object)
- V4_NEEDS_DESTROY
-public:
- static QV4::Heap::QQmlDelegateModelGroupChangeArray *create(QV4::ExecutionEngine *engine, const QVector<QQmlChangeSet::Change> &changes)
- {
- return engine->memoryManager->allocate<QQmlDelegateModelGroupChangeArray>(changes);
- }
-
- quint32 count() const { return d()->changes->count(); }
- const QQmlChangeSet::Change &at(int index) const { return d()->changes->at(index); }
-
- static QV4::ReturnedValue virtualGet(const QV4::Managed *m, QV4::PropertyKey id, const QV4::Value *receiver, bool *hasProperty)
- {
- if (id.isArrayIndex()) {
- uint index = id.asArrayIndex();
- Q_ASSERT(m->as<QQmlDelegateModelGroupChangeArray>());
- QV4::ExecutionEngine *v4 = static_cast<const QQmlDelegateModelGroupChangeArray *>(m)->engine();
- QV4::Scope scope(v4);
- QV4::Scoped<QQmlDelegateModelGroupChangeArray> array(scope, static_cast<const QQmlDelegateModelGroupChangeArray *>(m));
-
- if (index >= array->count()) {
- if (hasProperty)
- *hasProperty = false;
- return QV4::Value::undefinedValue().asReturnedValue();
- }
-
- const QQmlChangeSet::Change &change = array->at(index);
-
- QV4::ScopedObject changeProto(scope, engineData(v4)->changeProto.value());
- QV4::Scoped<QQmlDelegateModelGroupChange> object(scope, QQmlDelegateModelGroupChange::create(v4));
- object->setPrototypeOf(changeProto);
- object->d()->change = change;
-
- if (hasProperty)
- *hasProperty = true;
- return object.asReturnedValue();
- }
-
- Q_ASSERT(m->as<QQmlDelegateModelGroupChangeArray>());
- const QQmlDelegateModelGroupChangeArray *array = static_cast<const QQmlDelegateModelGroupChangeArray *>(m);
-
- if (id == array->engine()->id_length()->propertyKey()) {
- if (hasProperty)
- *hasProperty = true;
- return QV4::Encode(array->count());
- }
-
- return Object::virtualGet(m, id, receiver, hasProperty);
- }
-};
-
-void QV4::Heap::QQmlDelegateModelGroupChangeArray::init(const QVector<QQmlChangeSet::Change> &changes)
-{
- Object::init();
- this->changes = new QVector<QQmlChangeSet::Change>(changes);
- QV4::Scope scope(internalClass->engine);
- QV4::ScopedObject o(scope, this);
- o->setArrayType(QV4::Heap::ArrayData::Custom);
-}
-
-DEFINE_OBJECT_VTABLE(QQmlDelegateModelGroupChangeArray);
-
-QQmlDelegateModelEngineData::QQmlDelegateModelEngineData(QV4::ExecutionEngine *v4)
-{
- QV4::Scope scope(v4);
-
- QV4::ScopedObject proto(scope, v4->newObject());
- proto->defineAccessorProperty(QStringLiteral("index"), QQmlDelegateModelGroupChange::method_get_index, nullptr);
- proto->defineAccessorProperty(QStringLiteral("count"), QQmlDelegateModelGroupChange::method_get_count, nullptr);
- proto->defineAccessorProperty(QStringLiteral("moveId"), QQmlDelegateModelGroupChange::method_get_moveId, nullptr);
- changeProto.set(v4, proto);
-}
-
-QQmlDelegateModelEngineData::~QQmlDelegateModelEngineData()
-{
-}
-
-QV4::ReturnedValue QQmlDelegateModelEngineData::array(QV4::ExecutionEngine *v4,
- const QVector<QQmlChangeSet::Change> &changes)
-{
- QV4::Scope scope(v4);
- QV4::ScopedObject o(scope, QQmlDelegateModelGroupChangeArray::create(v4, changes));
- return o.asReturnedValue();
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qqmldelegatemodel_p.cpp"
diff --git a/src/qml/types/qqmldelegatemodel_p.h b/src/qml/types/qqmldelegatemodel_p.h
deleted file mode 100644
index 2684162514..0000000000
--- a/src/qml/types/qqmldelegatemodel_p.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLDATAMODEL_P_H
-#define QQMLDATAMODEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtqmlglobal_p.h>
-#include <private/qqmllistcompositor_p.h>
-#include <private/qqmlobjectmodel_p.h>
-#include <private/qqmlincubator_p.h>
-
-#include <QtCore/qabstractitemmodel.h>
-#include <QtCore/qstringlist.h>
-
-#include <private/qqmlglobal_p.h>
-
-QT_REQUIRE_CONFIG(qml_delegate_model);
-
-QT_BEGIN_NAMESPACE
-
-class QQmlChangeSet;
-class QQuickPackage;
-class QQmlV4Function;
-class QQmlDelegateModelGroup;
-class QQmlDelegateModelAttached;
-class QQmlDelegateModelPrivate;
-
-
-class Q_QML_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, public QQmlParserStatus
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QQmlDelegateModel)
-
- Q_PROPERTY(QVariant model READ model WRITE setModel)
- Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate)
- 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)
- Q_PROPERTY(QQmlListProperty<QQmlDelegateModelGroup> groups READ groups CONSTANT)
- Q_PROPERTY(QObject *parts READ parts CONSTANT)
- Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged)
- Q_CLASSINFO("DefaultProperty", "delegate")
- Q_INTERFACES(QQmlParserStatus)
-public:
- QQmlDelegateModel();
- QQmlDelegateModel(QQmlContext *, QObject *parent=nullptr);
- ~QQmlDelegateModel();
-
- void classBegin() override;
- void componentComplete() override;
-
- QVariant model() const;
- void setModel(const QVariant &);
-
- QQmlComponent *delegate() const;
- void setDelegate(QQmlComponent *);
-
- QVariant rootIndex() const;
- void setRootIndex(const QVariant &root);
-
- Q_INVOKABLE QVariant modelIndex(int idx) const;
- Q_INVOKABLE QVariant parentModelIndex() const;
-
- int count() const override;
- bool isValid() const override { return delegate() != nullptr; }
- QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
- ReleaseFlags release(QObject *object) override;
- void cancel(int index) override;
- QVariant variantValue(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;
-
- QString filterGroup() const;
- void setFilterGroup(const QString &group);
- void resetFilterGroup();
-
- QQmlDelegateModelGroup *items();
- QQmlDelegateModelGroup *persistedItems();
- QQmlListProperty<QQmlDelegateModelGroup> groups();
- QObject *parts();
-
- const QAbstractItemModel *abstractItemModel() const override;
-
- bool event(QEvent *) override;
-
- static QQmlDelegateModelAttached *qmlAttachedProperties(QObject *obj);
-
-Q_SIGNALS:
- void filterGroupChanged();
- void defaultGroupsChanged();
- void rootIndexChanged();
-
-private Q_SLOTS:
- void _q_itemsChanged(int index, int count, const QVector<int> &roles);
- void _q_itemsInserted(int index, int count);
- void _q_itemsRemoved(int index, int count);
- void _q_itemsMoved(int from, int to, int count);
- void _q_modelReset();
- void _q_rowsInserted(const QModelIndex &,int,int);
- void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
- void _q_rowsRemoved(const QModelIndex &,int,int);
- void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
- void _q_dataChanged(const QModelIndex&,const QModelIndex&,const QVector<int> &);
- void _q_layoutChanged(const QList<QPersistentModelIndex>&, QAbstractItemModel::LayoutChangeHint);
-
-private:
- bool isDescendantOf(const QPersistentModelIndex &desc, const QList<QPersistentModelIndex> &parents) const;
-
- Q_DISABLE_COPY(QQmlDelegateModel)
-};
-
-class QQmlDelegateModelGroupPrivate;
-class Q_QML_PRIVATE_EXPORT QQmlDelegateModelGroup : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(int count READ count NOTIFY countChanged)
- Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
- Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged)
-public:
- QQmlDelegateModelGroup(QObject *parent = nullptr);
- QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = nullptr);
- ~QQmlDelegateModelGroup();
-
- QString name() const;
- void setName(const QString &name);
-
- int count() const;
-
- bool defaultInclude() const;
- void setDefaultInclude(bool include);
-
- Q_INVOKABLE QJSValue get(int index);
-
-public Q_SLOTS:
- void insert(QQmlV4Function *);
- void create(QQmlV4Function *);
- void resolve(QQmlV4Function *);
- void remove(QQmlV4Function *);
- void addGroups(QQmlV4Function *);
- void removeGroups(QQmlV4Function *);
- void setGroups(QQmlV4Function *);
- void move(QQmlV4Function *);
-
-Q_SIGNALS:
- void countChanged();
- void nameChanged();
- void defaultIncludeChanged();
- void changed(const QJSValue &removed, const QJSValue &inserted);
-private:
- Q_DECLARE_PRIVATE(QQmlDelegateModelGroup)
-};
-
-class QQmlDelegateModelItem;
-class QQmlDelegateModelAttachedMetaObject;
-class QQmlDelegateModelAttached : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QQmlDelegateModel *model READ model CONSTANT)
- Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged)
- Q_PROPERTY(bool isUnresolved READ isUnresolved NOTIFY unresolvedChanged)
-public:
- QQmlDelegateModelAttached(QObject *parent);
- QQmlDelegateModelAttached(QQmlDelegateModelItem *cacheItem, QObject *parent);
- ~QQmlDelegateModelAttached() {}
-
- void resetCurrentIndex();
- void setCacheItem(QQmlDelegateModelItem *item);
-
- QQmlDelegateModel *model() const;
-
- QStringList groups() const;
- void setGroups(const QStringList &groups);
-
- bool isUnresolved() const;
-
- void emitChanges();
-
- void emitUnresolvedChanged() { Q_EMIT unresolvedChanged(); }
-
-Q_SIGNALS:
- void groupsChanged();
- void unresolvedChanged();
-
-public:
- QQmlDelegateModelItem *m_cacheItem;
- int m_previousGroups;
- int m_currentIndex[QQmlListCompositor::MaximumGroupCount];
- int m_previousIndex[QQmlListCompositor::MaximumGroupCount];
-
- friend class QQmlDelegateModelAttachedMetaObject;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQmlDelegateModel)
-QML_DECLARE_TYPEINFO(QQmlDelegateModel, QML_HAS_ATTACHED_PROPERTIES)
-QML_DECLARE_TYPE(QQmlDelegateModelGroup)
-
-#endif // QQMLDATAMODEL_P_H
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
deleted file mode 100644
index 7f10bbf370..0000000000
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ /dev/null
@@ -1,450 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLDATAMODEL_P_P_H
-#define QQMLDATAMODEL_P_P_H
-
-#include "qqmldelegatemodel_p.h"
-#include <private/qv4qobjectwrapper_p.h>
-
-#include <QtQml/qqmlcontext.h>
-#include <QtQml/qqmlincubator.h>
-
-#include <private/qqmladaptormodel_p.h>
-#include <private/qqmlopenmetaobject_p.h>
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-QT_REQUIRE_CONFIG(qml_delegate_model);
-
-QT_BEGIN_NAMESPACE
-
-typedef QQmlListCompositor Compositor;
-
-class QQmlDelegateModelAttachedMetaObject;
-class QQmlAbstractDelegateComponent;
-
-class Q_QML_PRIVATE_EXPORT QQmlDelegateModelItemMetaType : public QQmlRefCount
-{
-public:
- QQmlDelegateModelItemMetaType(QV4::ExecutionEngine *engine, QQmlDelegateModel *model, const QStringList &groupNames);
- ~QQmlDelegateModelItemMetaType();
-
- void initializeMetaObject();
- void initializePrototype();
-
- int parseGroups(const QStringList &groupNames) const;
- int parseGroups(const QV4::Value &groupNames) const;
-
- QPointer<QQmlDelegateModel> model;
- const int groupCount;
- QV4::ExecutionEngine * const v4Engine;
- QQmlDelegateModelAttachedMetaObject *metaObject;
- const QStringList groupNames;
- QV4::PersistentValue modelItemProto;
-};
-
-class QQmlAdaptorModel;
-class QQDMIncubationTask;
-
-class QQmlDelegateModelItem : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged)
- Q_PROPERTY(int row READ modelRow NOTIFY rowChanged REVISION 12)
- Q_PROPERTY(int column READ modelColumn NOTIFY columnChanged REVISION 12)
- Q_PROPERTY(QObject *model READ modelObject CONSTANT)
-public:
- QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType,
- QQmlAdaptorModel::Accessors *accessor, int modelIndex,
- int row, int column);
- ~QQmlDelegateModelItem();
-
- void referenceObject() { ++objectRef; }
- bool releaseObject() { return --objectRef == 0 && !(groups & Compositor::PersistedFlag); }
- bool isObjectReferenced() const { return objectRef != 0 || (groups & Compositor::PersistedFlag); }
- void childContextObjectDestroyed(QObject *childContextObject);
-
- bool isReferenced() const {
- return scriptRef
- || incubationTask
- || ((groups & Compositor::UnresolvedFlag) && (groups & Compositor::GroupMask));
- }
-
- void Dispose();
-
- QObject *modelObject() { return this; }
-
- void destroyObject();
-
- static QQmlDelegateModelItem *dataForObject(QObject *object);
-
- int groupIndex(Compositor::Group group);
-
- int modelRow() const { return row; }
- int modelColumn() const { return column; }
- int modelIndex() const { return index; }
- virtual void setModelIndex(int idx, int newRow, int newColumn);
-
- virtual QV4::ReturnedValue get() { return QV4::QObjectWrapper::wrap(v4, this); }
-
- virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
- virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; }
-
- static QV4::ReturnedValue get_model(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
- static QV4::ReturnedValue get_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
- static QV4::ReturnedValue set_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
- static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &);
- static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
- static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
-
- QV4::ExecutionEngine *v4;
- QQmlDelegateModelItemMetaType * const metaType;
- QQmlContextDataRef contextData;
- QPointer<QObject> object;
- QPointer<QQmlDelegateModelAttached> attached;
- QQDMIncubationTask *incubationTask;
- QQmlComponent *delegate;
- int poolTime;
- int objectRef;
- int scriptRef;
- int groups;
- int index;
-
-Q_SIGNALS:
- void modelIndexChanged();
- Q_REVISION(12) void rowChanged();
- Q_REVISION(12) void columnChanged();
-
-protected:
- void objectDestroyed(QObject *);
- int row;
- int column;
-};
-
-namespace QV4 {
-namespace Heap {
-struct QQmlDelegateModelItemObject : Object {
- inline void init(QQmlDelegateModelItem *item);
- void destroy();
- QQmlDelegateModelItem *item;
-};
-
-}
-}
-
-struct QQmlDelegateModelItemObject : QV4::Object
-{
- V4_OBJECT2(QQmlDelegateModelItemObject, QV4::Object)
- V4_NEEDS_DESTROY
-};
-
-void QV4::Heap::QQmlDelegateModelItemObject::init(QQmlDelegateModelItem *item)
-{
- Object::init();
- this->item = item;
-}
-
-
-
-class QQmlDelegateModelPrivate;
-class QQDMIncubationTask : public QQmlIncubator
-{
-public:
- QQDMIncubationTask(QQmlDelegateModelPrivate *l, IncubationMode mode)
- : QQmlIncubator(mode)
- , incubating(nullptr)
- , vdm(l) {}
-
- void statusChanged(Status) override;
- void setInitialState(QObject *) override;
-
- QQmlDelegateModelItem *incubating = nullptr;
- QQmlDelegateModelPrivate *vdm = nullptr;
- int index[QQmlListCompositor::MaximumGroupCount];
-};
-
-
-class QQmlDelegateModelGroupEmitter
-{
-public:
- virtual ~QQmlDelegateModelGroupEmitter() {}
- virtual void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) = 0;
- virtual void createdPackage(int, QQuickPackage *) {}
- virtual void initPackage(int, QQuickPackage *) {}
- virtual void destroyingPackage(QQuickPackage *) {}
-
- QIntrusiveListNode emitterNode;
-};
-
-typedef QIntrusiveList<QQmlDelegateModelGroupEmitter, &QQmlDelegateModelGroupEmitter::emitterNode> QQmlDelegateModelGroupEmitterList;
-
-class QQmlDelegateModelGroupPrivate : public QObjectPrivate
-{
-public:
- Q_DECLARE_PUBLIC(QQmlDelegateModelGroup)
-
- QQmlDelegateModelGroupPrivate() : group(Compositor::Cache), defaultInclude(false) {}
-
- static QQmlDelegateModelGroupPrivate *get(QQmlDelegateModelGroup *group) {
- return static_cast<QQmlDelegateModelGroupPrivate *>(QObjectPrivate::get(group)); }
-
- void setModel(QQmlDelegateModel *model, Compositor::Group group);
- bool isChangedConnected();
- void emitChanges(QV4::ExecutionEngine *engine);
- void emitModelUpdated(bool reset);
-
- void createdPackage(int index, QQuickPackage *package);
- void initPackage(int index, QQuickPackage *package);
- void destroyingPackage(QQuickPackage *package);
-
- bool parseIndex(const QV4::Value &value, int *index, Compositor::Group *group) const;
- bool parseGroupArgs(
- QQmlV4Function *args, Compositor::Group *group, int *index, int *count, int *groups) const;
-
- Compositor::Group group;
- QPointer<QQmlDelegateModel> model;
- QQmlDelegateModelGroupEmitterList emitters;
- QQmlChangeSet changeSet;
- QString name;
- bool defaultInclude;
-};
-
-class QQmlDelegateModelParts;
-
-class QQmlDelegateModelPrivate : public QObjectPrivate, public QQmlDelegateModelGroupEmitter
-{
- Q_DECLARE_PUBLIC(QQmlDelegateModel)
-public:
- QQmlDelegateModelPrivate(QQmlContext *);
- ~QQmlDelegateModelPrivate();
-
- static QQmlDelegateModelPrivate *get(QQmlDelegateModel *m) {
- return static_cast<QQmlDelegateModelPrivate *>(QObjectPrivate::get(m));
- }
-
- void init();
- void connectModel(QQmlAdaptorModel *model);
- void connectToAbstractItemModel();
- void disconnectFromAbstractItemModel();
-
- void requestMoreIfNecessary();
- QObject *object(Compositor::Group group, int index, QQmlIncubator::IncubationMode incubationMode);
- QQmlDelegateModel::ReleaseFlags release(QObject *object);
- QVariant variantValue(Compositor::Group group, int index, const QString &name);
- void emitCreatedPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
- void emitInitPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
- void emitCreatedItem(QQDMIncubationTask *incubationTask, QObject *item) {
- Q_EMIT q_func()->createdItem(incubationTask->index[m_compositorGroup], item); }
- void emitInitItem(QQDMIncubationTask *incubationTask, QObject *item) {
- Q_EMIT q_func()->initItem(incubationTask->index[m_compositorGroup], item); }
- void emitDestroyingPackage(QQuickPackage *package);
- void emitDestroyingItem(QObject *item) { Q_EMIT q_func()->destroyingItem(item); }
- void addCacheItem(QQmlDelegateModelItem *item, Compositor::iterator it);
- void removeCacheItem(QQmlDelegateModelItem *cacheItem);
-
- void updateFilterGroup();
-
- void addGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
- void removeGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
- void setGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
-
- void itemsInserted(
- const QVector<Compositor::Insert> &inserts,
- QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedInserts,
- QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = nullptr);
- void itemsInserted(const QVector<Compositor::Insert> &inserts);
- void itemsRemoved(
- const QVector<Compositor::Remove> &removes,
- QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedRemoves,
- QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = nullptr);
- void itemsRemoved(const QVector<Compositor::Remove> &removes);
- void itemsMoved(
- const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts);
- void itemsChanged(const QVector<Compositor::Change> &changes);
- void emitChanges();
- void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) override;
- void delegateChanged(bool add = true, bool remove = true);
-
- bool insert(Compositor::insert_iterator &before, const QV4::Value &object, int groups);
-
- int adaptorModelCount() const;
-
- static void group_append(QQmlListProperty<QQmlDelegateModelGroup> *property, QQmlDelegateModelGroup *group);
- static int group_count(QQmlListProperty<QQmlDelegateModelGroup> *property);
- static QQmlDelegateModelGroup *group_at(QQmlListProperty<QQmlDelegateModelGroup> *property, int index);
-
- void releaseIncubator(QQDMIncubationTask *incubationTask);
- void incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status);
- void setInitialState(QQDMIncubationTask *incubationTask, QObject *o);
-
- QQmlAdaptorModel m_adaptorModel;
- QQmlListCompositor m_compositor;
- QQmlStrongJSQObjectReference<QQmlComponent> m_delegate;
- QQmlAbstractDelegateComponent *m_delegateChooser;
- QMetaObject::Connection m_delegateChooserChanged;
- QQmlDelegateModelItemMetaType *m_cacheMetaType;
- QPointer<QQmlContext> m_context;
- QQmlDelegateModelParts *m_parts;
- QQmlDelegateModelGroupEmitterList m_pendingParts;
-
- QList<QQmlDelegateModelItem *> m_cache;
- QList<QQDMIncubationTask *> m_finishedIncubating;
- QList<QByteArray> m_watchedRoles;
-
- QString m_filterGroup;
-
- int m_count;
- int m_groupCount;
-
- QQmlListCompositor::Group m_compositorGroup;
- bool m_complete : 1;
- bool m_delegateValidated : 1;
- bool m_reset : 1;
- bool m_transaction : 1;
- bool m_incubatorCleanupScheduled : 1;
- bool m_waitingToFetchMore : 1;
-
- union {
- struct {
- QQmlDelegateModelGroup *m_cacheItems;
- QQmlDelegateModelGroup *m_items;
- QQmlDelegateModelGroup *m_persistedItems;
- };
- QQmlDelegateModelGroup *m_groups[Compositor::MaximumGroupCount];
- };
-};
-
-class QQmlPartsModel : public QQmlInstanceModel, public QQmlDelegateModelGroupEmitter
-{
- Q_OBJECT
- Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
-public:
- QQmlPartsModel(QQmlDelegateModel *model, const QString &part, QObject *parent = nullptr);
- ~QQmlPartsModel();
-
- QString filterGroup() const;
- void setFilterGroup(const QString &group);
- void resetFilterGroup();
- void updateFilterGroup();
- void updateFilterGroup(Compositor::Group group, const QQmlChangeSet &changeSet);
-
- int count() const override;
- bool isValid() const override;
- QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
- ReleaseFlags release(QObject *item) override;
- QVariant variantValue(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;
-
- void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) override;
-
- void createdPackage(int index, QQuickPackage *package) override;
- void initPackage(int index, QQuickPackage *package) override;
- void destroyingPackage(QQuickPackage *package) override;
-
-Q_SIGNALS:
- void filterGroupChanged();
-
-private:
- QQmlDelegateModel *m_model;
- QHash<QObject *, QQuickPackage *> m_packaged;
- QString m_part;
- QString m_filterGroup;
- QList<QByteArray> m_watchedRoles;
- QVector<int> m_pendingPackageInitializations; // vector holds model indices
- Compositor::Group m_compositorGroup;
- bool m_inheritGroup;
- bool m_modelUpdatePending = true;
-};
-
-class QMetaPropertyBuilder;
-
-class QQmlDelegateModelPartsMetaObject : public QQmlOpenMetaObject
-{
-public:
- QQmlDelegateModelPartsMetaObject(QObject *parent)
- : QQmlOpenMetaObject(parent) {}
-
- void propertyCreated(int, QMetaPropertyBuilder &) override;
- QVariant initialValue(int) override;
-};
-
-class QQmlDelegateModelParts : public QObject
-{
-Q_OBJECT
-public:
- QQmlDelegateModelParts(QQmlDelegateModel *parent);
-
- QQmlDelegateModel *model;
- QList<QQmlPartsModel *> models;
-};
-
-class QQmlDelegateModelAttachedMetaObject : public QAbstractDynamicMetaObject, public QQmlRefCount
-{
-public:
- QQmlDelegateModelAttachedMetaObject(
- QQmlDelegateModelItemMetaType *metaType, QMetaObject *metaObject);
- ~QQmlDelegateModelAttachedMetaObject();
-
- void objectDestroyed(QObject *) override;
- int metaCall(QObject *, QMetaObject::Call, int _id, void **) override;
-
-private:
- QQmlDelegateModelItemMetaType * const metaType;
- QMetaObject * const metaObject;
- const int memberPropertyOffset;
- const int indexPropertyOffset;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/types/qqmlinstantiator.cpp b/src/qml/types/qqmlinstantiator.cpp
deleted file mode 100644
index a23ec0f2b4..0000000000
--- a/src/qml/types/qqmlinstantiator.cpp
+++ /dev/null
@@ -1,509 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Research In Motion.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmlinstantiator_p.h"
-#include "qqmlinstantiator_p_p.h"
-#include <QtQml/QQmlContext>
-#include <QtQml/QQmlComponent>
-#include <QtQml/QQmlInfo>
-#include <QtQml/QQmlError>
-#include <QtQml/private/qqmlobjectmodel_p.h>
-#if QT_CONFIG(qml_delegate_model)
-#include <QtQml/private/qqmldelegatemodel_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QQmlInstantiatorPrivate::QQmlInstantiatorPrivate()
- : componentComplete(true)
- , effectiveReset(false)
- , active(true)
- , async(false)
-#if QT_CONFIG(qml_delegate_model)
- , ownModel(false)
-#endif
- , requestedIndex(-1)
- , model(QVariant(1))
- , instanceModel(nullptr)
- , delegate(nullptr)
-{
-}
-
-QQmlInstantiatorPrivate::~QQmlInstantiatorPrivate()
-{
- qDeleteAll(objects);
-}
-
-void QQmlInstantiatorPrivate::clear()
-{
- Q_Q(QQmlInstantiator);
- if (!instanceModel)
- return;
- if (!objects.count())
- return;
-
- for (int i=0; i < objects.count(); i++) {
- q->objectRemoved(i, objects[i]);
- instanceModel->release(objects[i]);
- }
- objects.clear();
- q->objectChanged();
-}
-
-QObject *QQmlInstantiatorPrivate::modelObject(int index, bool async)
-{
- requestedIndex = index;
- QObject *o = instanceModel->object(index, async ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
- requestedIndex = -1;
- return o;
-}
-
-
-void QQmlInstantiatorPrivate::regenerate()
-{
- Q_Q(QQmlInstantiator);
- if (!componentComplete)
- return;
-
- int prevCount = q->count();
-
- clear();
-
- if (!active || !instanceModel || !instanceModel->count() || !instanceModel->isValid()) {
- if (prevCount)
- q->countChanged();
- return;
- }
-
- for (int i = 0; i < instanceModel->count(); i++) {
- QObject *object = modelObject(i, async);
- // If the item was already created we won't get a createdItem
- if (object)
- _q_createdItem(i, object);
- }
- if (q->count() != prevCount)
- q->countChanged();
-}
-
-void QQmlInstantiatorPrivate::_q_createdItem(int idx, QObject* item)
-{
- Q_Q(QQmlInstantiator);
- if (objects.contains(item)) //Case when it was created synchronously in regenerate
- return;
- if (requestedIndex != idx) // Asynchronous creation, reference the object
- (void)instanceModel->object(idx);
- item->setParent(q);
- if (objects.size() < idx + 1) {
- int modelCount = instanceModel->count();
- if (objects.capacity() < modelCount)
- objects.reserve(modelCount);
- objects.resize(idx + 1);
- }
- if (QObject *o = objects.at(idx))
- instanceModel->release(o);
- objects.replace(idx, item);
- if (objects.count() == 1)
- q->objectChanged();
- q->objectAdded(idx, item);
-}
-
-void QQmlInstantiatorPrivate::_q_modelUpdated(const QQmlChangeSet &changeSet, bool reset)
-{
- Q_Q(QQmlInstantiator);
-
- if (!componentComplete || effectiveReset)
- return;
-
- if (reset) {
- regenerate();
- if (changeSet.difference() != 0)
- q->countChanged();
- return;
- }
-
- int difference = 0;
- QHash<int, QVector<QPointer<QObject> > > moved;
- const QVector<QQmlChangeSet::Change> &removes = changeSet.removes();
- for (const QQmlChangeSet::Change &remove : removes) {
- int index = qMin(remove.index, objects.count());
- int count = qMin(remove.index + remove.count, objects.count()) - index;
- if (remove.isMove()) {
- moved.insert(remove.moveId, objects.mid(index, count));
- objects.erase(
- objects.begin() + index,
- objects.begin() + index + count);
- } else while (count--) {
- QObject *obj = objects.at(index);
- objects.remove(index);
- q->objectRemoved(index, obj);
- if (obj)
- instanceModel->release(obj);
- }
-
- difference -= remove.count;
- }
-
- const QVector<QQmlChangeSet::Change> &inserts = changeSet.inserts();
- for (const QQmlChangeSet::Change &insert : inserts) {
- int index = qMin(insert.index, objects.count());
- if (insert.isMove()) {
- QVector<QPointer<QObject> > movedObjects = moved.value(insert.moveId);
- objects = objects.mid(0, index) + movedObjects + objects.mid(index);
- } else {
- if (insert.index <= objects.size())
- objects.insert(insert.index, insert.count, nullptr);
- for (int i = 0; i < insert.count; ++i) {
- int modelIndex = index + i;
- QObject* obj = modelObject(modelIndex, async);
- if (obj)
- _q_createdItem(modelIndex, obj);
- }
- }
- difference += insert.count;
- }
-
- if (difference != 0)
- q->countChanged();
-}
-
-#if QT_CONFIG(qml_delegate_model)
-void QQmlInstantiatorPrivate::makeModel()
-{
- Q_Q(QQmlInstantiator);
- QQmlDelegateModel* delegateModel = new QQmlDelegateModel(qmlContext(q), q);
- instanceModel = delegateModel;
- ownModel = true;
- delegateModel->setDelegate(delegate);
- delegateModel->classBegin(); //Pretend it was made in QML
- if (componentComplete)
- delegateModel->componentComplete();
-}
-#endif
-
-
-/*!
- \qmltype Instantiator
- \instantiates QQmlInstantiator
- \inqmlmodule QtQml
- \brief Dynamically creates objects.
-
- A Instantiator can be used to control the dynamic creation of objects, or to dynamically
- create multiple objects from a template.
-
- The Instantiator element will manage the objects it creates. Those objects are parented to the
- Instantiator and can also be deleted by the Instantiator if the Instantiator's properties change. Objects
- can also be destroyed dynamically through other means, and the Instantiator will not recreate
- them unless the properties of the Instantiator change.
-
-*/
-QQmlInstantiator::QQmlInstantiator(QObject *parent)
- : QObject(*(new QQmlInstantiatorPrivate), parent)
-{
-}
-
-QQmlInstantiator::~QQmlInstantiator()
-{
-}
-
-/*!
- \qmlsignal QtQml::Instantiator::objectAdded(int index, QtObject object)
-
- This signal is emitted when an object is added to the Instantiator. The \a index
- parameter holds the index which the object has been given, and the \a object
- parameter holds the \l QtObject that has been added.
-
- The corresponding handler is \c onObjectAdded.
-*/
-
-/*!
- \qmlsignal QtQml::Instantiator::objectRemoved(int index, QtObject object)
-
- This signal is emitted when an object is removed from the Instantiator. The \a index
- parameter holds the index which the object had been given, and the \a object
- parameter holds the \l QtObject that has been removed.
-
- Do not keep a reference to \a object if it was created by this Instantiator, as
- in these cases it will be deleted shortly after the signal is handled.
-
- The corresponding handler is \c onObjectRemoved.
-*/
-/*!
- \qmlproperty bool QtQml::Instantiator::active
-
- When active is true, and the delegate component is ready, the Instantiator will
- create objects according to the model. When active is false, no objects
- will be created and any previously created objects will be destroyed.
-
- Default is true.
-*/
-bool QQmlInstantiator::isActive() const
-{
- Q_D(const QQmlInstantiator);
- return d->active;
-}
-
-void QQmlInstantiator::setActive(bool newVal)
-{
- Q_D(QQmlInstantiator);
- if (newVal == d->active)
- return;
- d->active = newVal;
- emit activeChanged();
- d->regenerate();
-}
-
-/*!
- \qmlproperty bool QtQml::Instantiator::asynchronous
-
- When asynchronous is true the Instantiator will attempt to create objects
- asynchronously. This means that objects may not be available immediately,
- even if active is set to true.
-
- You can use the objectAdded signal to respond to items being created.
-
- Default is false.
-*/
-bool QQmlInstantiator::isAsync() const
-{
- Q_D(const QQmlInstantiator);
- return d->async;
-}
-
-void QQmlInstantiator::setAsync(bool newVal)
-{
- Q_D(QQmlInstantiator);
- if (newVal == d->async)
- return;
- d->async = newVal;
- emit asynchronousChanged();
-}
-
-
-/*!
- \qmlproperty int QtQml::Instantiator::count
-
- The number of objects the Instantiator is currently managing.
-*/
-
-int QQmlInstantiator::count() const
-{
- Q_D(const QQmlInstantiator);
- return d->objects.count();
-}
-
-/*!
- \qmlproperty QtQml::Component QtQml::Instantiator::delegate
- \default
-
- The component used to create all objects.
-
- Note that an extra variable, index, will be available inside instances of the
- delegate. This variable refers to the index of the instance inside the Instantiator,
- and can be used to obtain the object through the objectAt method of the Instantiator.
-
- If this property is changed, all instances using the old delegate will be destroyed
- and new instances will be created using the new delegate.
-*/
-QQmlComponent* QQmlInstantiator::delegate()
-{
- Q_D(QQmlInstantiator);
- return d->delegate;
-}
-
-void QQmlInstantiator::setDelegate(QQmlComponent* c)
-{
- Q_D(QQmlInstantiator);
- if (c == d->delegate)
- return;
-
- d->delegate = c;
- emit delegateChanged();
-
-#if QT_CONFIG(qml_delegate_model)
- if (!d->ownModel)
- return;
-
- if (QQmlDelegateModel *dModel = qobject_cast<QQmlDelegateModel*>(d->instanceModel))
- dModel->setDelegate(c);
- if (d->componentComplete)
- d->regenerate();
-#endif
-}
-
-/*!
- \qmlproperty variant QtQml::Instantiator::model
-
- This property can be set to any of the supported \l {qml-data-models}{data models}:
-
- \list
- \li A number that indicates the number of delegates to be created by the repeater
- \li A model (e.g. a ListModel item, or a QAbstractItemModel subclass)
- \li A string list
- \li An object list
- \endlist
-
- The type of model affects the properties that are exposed to the \l delegate.
-
- Default value is 1, which creates a single delegate instance.
-
- \sa {qml-data-models}{Data Models}
-*/
-
-QVariant QQmlInstantiator::model() const
-{
- Q_D(const QQmlInstantiator);
- return d->model;
-}
-
-void QQmlInstantiator::setModel(const QVariant &v)
-{
- Q_D(QQmlInstantiator);
- if (d->model == v)
- return;
-
- d->model = v;
- //Don't actually set model until componentComplete in case it wants to create its delegates immediately
- if (!d->componentComplete)
- return;
-
- QQmlInstanceModel *prevModel = d->instanceModel;
- QObject *object = qvariant_cast<QObject*>(v);
- QQmlInstanceModel *vim = nullptr;
- if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) {
-#if QT_CONFIG(qml_delegate_model)
- if (d->ownModel) {
- delete d->instanceModel;
- prevModel = nullptr;
- d->ownModel = false;
- }
-#endif
- d->instanceModel = vim;
-#if QT_CONFIG(qml_delegate_model)
- } else if (v != QVariant(0)){
- if (!d->ownModel)
- d->makeModel();
-
- if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel *>(d->instanceModel)) {
- d->effectiveReset = true;
- dataModel->setModel(v);
- d->effectiveReset = false;
- }
-#endif
- }
-
- if (d->instanceModel != prevModel) {
- if (prevModel) {
- disconnect(prevModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
- this, SLOT(_q_modelUpdated(QQmlChangeSet,bool)));
- disconnect(prevModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(_q_createdItem(int,QObject*)));
- //disconnect(prevModel, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
- }
-
- if (d->instanceModel) {
- connect(d->instanceModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
- this, SLOT(_q_modelUpdated(QQmlChangeSet,bool)));
- connect(d->instanceModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(_q_createdItem(int,QObject*)));
- //connect(d->instanceModel, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
- }
- }
-
- d->regenerate();
- emit modelChanged();
-}
-
-/*!
- \qmlproperty QtObject QtQml::Instantiator::object
-
- This is a reference to the first created object, intended as a convenience
- for the case where only one object has been created.
-*/
-QObject *QQmlInstantiator::object() const
-{
- Q_D(const QQmlInstantiator);
- if (d->objects.count())
- return d->objects[0];
- return nullptr;
-}
-
-/*!
- \qmlmethod QtObject QtQml::Instantiator::objectAt(int index)
-
- Returns a reference to the object with the given \a index.
-*/
-QObject *QQmlInstantiator::objectAt(int index) const
-{
- Q_D(const QQmlInstantiator);
- if (index >= 0 && index < d->objects.count())
- return d->objects[index];
- return nullptr;
-}
-
-/*!
- \internal
-*/
-void QQmlInstantiator::classBegin()
-{
- Q_D(QQmlInstantiator);
- d->componentComplete = false;
-}
-
-/*!
- \internal
-*/
-void QQmlInstantiator::componentComplete()
-{
- Q_D(QQmlInstantiator);
- d->componentComplete = true;
-#if QT_CONFIG(qml_delegate_model)
- if (d->ownModel) {
- static_cast<QQmlDelegateModel*>(d->instanceModel)->componentComplete();
- d->regenerate();
- } else
-#endif
- {
- QVariant realModel = d->model;
- d->model = QVariant(0);
- setModel(realModel); //If realModel == d->model this won't do anything, but that's fine since the model's 0
- //setModel calls regenerate
- }
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qqmlinstantiator_p.cpp"
diff --git a/src/qml/types/qqmlinstantiator_p.h b/src/qml/types/qqmlinstantiator_p.h
deleted file mode 100644
index ca371adc23..0000000000
--- a/src/qml/types/qqmlinstantiator_p.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Research In Motion.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLINSTANTIATOR_P_H
-#define QQMLINSTANTIATOR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtQml/qqmlcomponent.h>
-#include <QtQml/qqmlparserstatus.h>
-#include <QtQml/private/qtqmlglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlInstantiatorPrivate;
-class Q_QML_PRIVATE_EXPORT QQmlInstantiator : public QObject, public QQmlParserStatus
-{
- Q_OBJECT
- Q_INTERFACES(QQmlParserStatus)
-
- Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged)
- Q_PROPERTY(bool asynchronous READ isAsync WRITE setAsync NOTIFY asynchronousChanged)
- Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
- Q_PROPERTY(int count READ count NOTIFY countChanged)
- Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
- Q_PROPERTY(QObject *object READ object NOTIFY objectChanged)
- Q_CLASSINFO("DefaultProperty", "delegate")
-
-public:
- QQmlInstantiator(QObject *parent = nullptr);
- ~QQmlInstantiator();
-
- bool isActive() const;
- void setActive(bool newVal);
-
- bool isAsync() const;
- void setAsync(bool newVal);
-
- int count() const;
-
- QQmlComponent* delegate();
- void setDelegate(QQmlComponent* c);
-
- QVariant model() const;
- void setModel(const QVariant &v);
-
- QObject *object() const;
-
- Q_INVOKABLE QObject *objectAt(int index) const;
-
- void classBegin() override;
- void componentComplete() override;
-
-Q_SIGNALS:
- void modelChanged();
- void delegateChanged();
- void countChanged();
- void objectChanged();
- void activeChanged();
- void asynchronousChanged();
-
- void objectAdded(int index, QObject* object);
- void objectRemoved(int index, QObject* object);
-
-private:
- Q_DISABLE_COPY(QQmlInstantiator)
- Q_DECLARE_PRIVATE(QQmlInstantiator)
- Q_PRIVATE_SLOT(d_func(), void _q_createdItem(int, QObject *))
- Q_PRIVATE_SLOT(d_func(), void _q_modelUpdated(const QQmlChangeSet &, bool))
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLCREATOR_P_H
diff --git a/src/qml/types/qqmlinstantiator_p_p.h b/src/qml/types/qqmlinstantiator_p_p.h
deleted file mode 100644
index 4c76d5c689..0000000000
--- a/src/qml/types/qqmlinstantiator_p_p.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Research In Motion.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLINSTANTIATOR_P_P_H
-#define QQMLINSTANTIATOR_P_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qqmlinstantiator_p.h"
-#include <QObject>
-#include <private/qobject_p.h>
-#include <private/qqmlchangeset_p.h>
-#include <private/qqmlobjectmodel_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_QML_PRIVATE_EXPORT QQmlInstantiatorPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQmlInstantiator)
-
-public:
- QQmlInstantiatorPrivate();
- ~QQmlInstantiatorPrivate();
-
- void clear();
- void regenerate();
-#if QT_CONFIG(qml_delegate_model)
- void makeModel();
-#endif
- void _q_createdItem(int, QObject *);
- void _q_modelUpdated(const QQmlChangeSet &, bool);
- QObject *modelObject(int index, bool async);
-
- static QQmlInstantiatorPrivate *get(QQmlInstantiator *instantiator) { return instantiator->d_func(); }
- static const QQmlInstantiatorPrivate *get(const QQmlInstantiator *instantiator) { return instantiator->d_func(); }
-
- bool componentComplete:1;
- bool effectiveReset:1;
- bool active:1;
- bool async:1;
-#if QT_CONFIG(qml_delegate_model)
- bool ownModel:1;
-#endif
- int requestedIndex;
- QVariant model;
- QQmlInstanceModel *instanceModel;
- QQmlComponent *delegate;
- QVector<QPointer<QObject> > objects;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLCREATOR_P_P_H
diff --git a/src/qml/types/qqmlitemmodels.qdoc b/src/qml/types/qqmlitemmodels.qdoc
deleted file mode 100644
index f6e1b0b1b9..0000000000
--- a/src/qml/types/qqmlitemmodels.qdoc
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \page qmodelindex-and-related-classes-in-qml.html
- \title QModelIndex and related Classes in QML
-
- Since Qt 5.5, QModelIndex and QPersistentModelIndex are exposed in QML as
- value-based types. Also exposed in a similar fashion are QModelIndexList,
- QItemSelectionRange and QItemSelection. All objects from these types can
- be passed back and forth between QML and C++ as \c var properties or plain
- JavaScript variables.
-
- Below you will find an overview of the API exposed to QML for these classes.
- For more information, refer to their C++ documentation.
-
- \note Since all these types are exposed as \l{Q_GADGET}{gadgets}, there are no property
- change notification signals emitted. Therefore binding to their properties
- may not give the expected results. This is especially true for QPersistentModelIndex.
-
- \section1 QModelIndex and QPersistentModelIndex Types
-
- \list
- \li \b row : int
- \li \b column : int
- \li \b parent : QModelIndex
- \li \b valid : bool
- \li \b model : QAbstractItemModel
- \li \b internalId : quint64
- \endlist
-
- All these properties are read-only, as are their C++ counterparts.
-
- \note The usual caveats apply to QModelIndex in QML. If the underlying model changes
- or gets deleted, it may become dangerous to access its properties. Therefore, you
- should not store any QModelIndex objects. You can, however, store QPersistentModelIndexe
- objects in a safe way.
-
- \section1 QModelIndexList Type
-
- \l QModelIndexList is exposed in QML as a JavaScript array. Conversions are
- automatically made from and to C++. In fact, any JavaScript array can be
- converted back to QModelIndexList, with non-QModelIndex objects replaced by
- invalid \l{QModelIndex}es.
-
- \note QModelIndex to QPersistentModelIndex conversion happens when accessing
- the array elements because any QModelIndexList property retains reference
- semantics when exposed this way.
-
- \section1 \l QItemSelectionRange Type
-
- \list
- \li \b top : int
- \li \b left : int
- \li \b bottom : int
- \li \b right : int
- \li \b width : int
- \li \b height : int
- \li \b topLeft : QPersistentModelIndex
- \li \b bottomRight : QPersistentModelIndex
- \li \b parent : QModelIndex
- \li \b valid : bool
- \li \b empty : bool
- \li \b model : QAbstractItemModel
- \endlist
-
- All these properties are read-only, as are their C++ counterparts. In addition,
- we also expose the following functions:
-
- \list
- \li bool \b{contains}(QModelIndex \e index)
- \li bool \b{contains}(int \e row, int \e column, QModelIndex \e parentIndex)
- \li bool \b{intersects}(QItemSelectionRange \e other)
- \li QItemSelectionRange \b{intersected}(QItemSelectionRange \e other)
- \endlist
-
- \section1 QItemSelection Type
-
- Similarly to QModelIndexList, \l QItemSelection is exposed in QML as a JavaScript
- array of QItemSelectionRange objects. Conversions are automatically made from and to C++.
- In fact, any JavaScript array can be converted back to QItemSelection, with
- non-QItemSelectionRange objects replaced by empty \l {QItemSelectionRange}s.
-
-
- \sa ItemSelectionModel
-*/
diff --git a/src/qml/types/qqmlitemselectionmodel.qdoc b/src/qml/types/qqmlitemselectionmodel.qdoc
deleted file mode 100644
index 43da4f7a55..0000000000
--- a/src/qml/types/qqmlitemselectionmodel.qdoc
+++ /dev/null
@@ -1,239 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \qmltype ItemSelectionModel
- \instantiates QItemSelectionModel
- \inqmlmodule QtQml.Models
- \since 5.5
- \ingroup qtquick-models
-
- \brief Instantiates a QItemSelectionModel to be used in conjunction
- with a QAbstractItemModel and any view supporting it.
-
- \sa QItemSelectionModel, {Models and Views in Qt Quick}
-*/
-
-
-/*!
- \qmlproperty QAbstractItemModel ItemSelectionModel::model
-
- This property's value must match the view's model.
-*/
-
-/*!
- \qmlproperty bool ItemSelectionModel::hasSelection
- \readonly
-
- It will trigger property binding updates every time \l selectionChanged()
- is emitted, even though its value hasn't changed.
-
- \sa selection, selectedIndexes, select(), selectionChanged()
-*/
-
-/*!
- \qmlproperty QModelIndex ItemSelectionModel::currentIndex
- \readonly
-
- Use \l setCurrentIndex() to set its value.
-
- \sa setCurrentIndex(), currentChanged()
-*/
-
-/*!
- \qmlproperty QModelIndexList ItemSelectionModel::selectedIndexes
- \readonly
-
- Contains the list of all the indexes in the selection model.
-*/
-
-/*!
- \qmlmethod bool ItemSelectionModel::isSelected(QModelIndex index)
-
- Returns \c true if the given model item \a index is selected.
-*/
-
-/*!
- \qmlmethod bool ItemSelectionModel::isRowSelected(int row, QModelIndex parent)
-
- Returns \c true if all items are selected in the \a row with the given
- \a parent.
-
- Note that this function is usually faster than calling isSelected()
- on all items in the same row, and that unselectable items are ignored.
-*/
-
-/*!
- \qmlmethod bool ItemSelectionModel::isColumnSelected(int column, QModelIndex parent)
-
- Returns \c true if all items are selected in the \a column with the given
- \a parent.
-
- Note that this function is usually faster than calling isSelected()
- on all items in the same column, and that unselectable items are ignored.
-*/
-
-/*!
- \qmlmethod bool ItemSelectionModel::rowIntersectsSelection(int row, QModelIndex parent)
-
- Returns \c true if there are any items selected in the \a row with the
- given \a parent.
-*/
-
-/*!
- \qmlmethod bool ItemSelectionModel::columnIntersectsSelection(int column, QModelIndex parent)
-
- Returns \c true if there are any items selected in the \a column with the
- given \a parent.
-*/
-
-/*!
- \qmlmethod QModelIndexList ItemSelectionModel::selectedRows(int column)
-
- Returns the indexes in the given \a column for the rows where all columns
- are selected.
-
- \sa selectedColumns()
-*/
-
-/*!
- \qmlmethod QModelIndexList ItemSelectionModel::selectedColumns(int row)
-
- Returns the indexes in the given \a row for columns where all rows are
- selected.
-
- \sa selectedRows()
-*/
-
-/*!
- \qmlproperty object ItemSelectionModel::selection
- \readonly
-
- Holds the selection ranges stored in the selection model.
-*/
-
-/*!
- \qmlmethod void ItemSelectionModel::setCurrentIndex(QModelIndex index, SelectionFlags command)
-
- Sets the model item \a index to be the current item, and emits
- currentChanged(). The current item is used for keyboard navigation and
- focus indication; it is independent of any selected items, although a
- selected item can also be the current item.
-
- Depending on the specified \a command, the \a index can also become part
- of the current selection.
-
- Valid \a command values are described in \l {itemselectionmodelselectindex}
- {select(\e index, \e command)}.
-
- \sa select()
-*/
-
-/*!
- \qmlmethod void ItemSelectionModel::select(QModelIndex index, SelectionFlags command)
- \keyword itemselectionmodelselectindex
-
- Selects the model item \a index using the specified \a command, and emits
- selectionChanged().
-
- Valid values for the \a command parameter, are:
-
- \value NoUpdate No selection will be made.
- \value Clear The complete selection will be cleared.
- \value Select All specified indexes will be selected.
- \value Deselect All specified indexes will be deselected.
- \value Toggle All specified indexes will be selected or
- deselected depending on their current state.
- \value Current The current selection will be updated.
- \value Rows All indexes will be expanded to span rows.
- \value Columns All indexes will be expanded to span columns.
- \value SelectCurrent A combination of Select and Current, provided for
- convenience.
- \value ToggleCurrent A combination of Toggle and Current, provided for
- convenience.
- \value ClearAndSelect A combination of Clear and Select, provided for
- convenience.
-*/
-
-/*!
- \qmlmethod void ItemSelectionModel::select(QItemSelection selection, SelectionFlags command)
-
- Selects the item \a selection using the specified \a command, and emits
- selectionChanged().
-
- Valid \a command values are described in \l {itemselectionmodelselectindex}
- {select(\e index, \e command)}.
-*/
-
-/*!
- \qmlmethod void ItemSelectionModel::clear()
-
- Clears the selection model. Emits selectionChanged() and currentChanged().
-*/
-
-/*!
- \qmlmethod void ItemSelectionModel::reset()
-
- Clears the selection model. Does not emit any signals.
-*/
-
-/*!
- \qmlmethod void ItemSelectionModel::clearSelection()
-
- Clears the selection in the selection model. Emits selectionChanged().
-*/
-
-/*!
- \qmlmethod void ItemSelectionModel::clearCurrentIndex()
-
- Clears the current index. Emits currentChanged().
-*/
-
-/*!
- \qmlsignal ItemSelectionModel::selectionChanged(QItemSelection selected, QItemSelection deselected)
-
- This signal is emitted whenever the selection changes. The change in the
- selection is represented as an item selection of \a deselected items and
- an item selection of \a selected items.
-
- Note the that the current index changes independently from the selection.
- Also note that this signal will not be emitted when the item model is reset.
-
- \sa select(), currentChanged()
-*/
-
-/*!
- \qmlsignal ItemSelectionModel::currentChanged(QModelIndex current, QModelIndex previous)
-
- This signal is emitted whenever the current item changes. The \a previous
- model item index is replaced by the \a current index as the selection's
- current item.
-
- Note that this signal will not be emitted when the item model is reset.
-
- \sa currentIndex, setCurrentIndex(), selectionChanged()
-*/
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
deleted file mode 100644
index 5b5bcd8464..0000000000
--- a/src/qml/types/qqmllistmodel.cpp
+++ /dev/null
@@ -1,2900 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmllistmodel_p_p.h"
-#include "qqmllistmodelworkeragent_p.h"
-#include <private/qqmlopenmetaobject_p.h>
-#include <private/qqmljsast_p.h>
-#include <private/qqmljsengine_p.h>
-#include <private/qjsvalue_p.h>
-
-#include <private/qqmlcustomparser_p.h>
-#include <private/qqmlengine_p.h>
-#include <private/qqmlnotifier_p.h>
-
-#include <private/qv4object_p.h>
-#include <private/qv4dateobject_p.h>
-#include <private/qv4objectiterator_p.h>
-#include <private/qv4alloca_p.h>
-#include <private/qv4lookup_p.h>
-
-#include <qqmlcontext.h>
-#include <qqmlinfo.h>
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qstack.h>
-#include <QXmlStreamReader>
-#include <QtCore/qdatetime.h>
-#include <QScopedValueRollback>
-
-Q_DECLARE_METATYPE(const QV4::CompiledData::Binding*);
-
-QT_BEGIN_NAMESPACE
-
-// Set to 1024 as a debugging aid - easier to distinguish uids from indices of elements/models.
-enum { MIN_LISTMODEL_UID = 1024 };
-
-static QAtomicInt uidCounter(MIN_LISTMODEL_UID);
-
-template <typename T>
-static bool isMemoryUsed(const char *mem)
-{
- for (size_t i=0 ; i < sizeof(T) ; ++i) {
- if (mem[i] != 0)
- return true;
- }
-
- return false;
-}
-
-static QString roleTypeName(ListLayout::Role::DataType t)
-{
- static const QString roleTypeNames[] = {
- QStringLiteral("String"), QStringLiteral("Number"), QStringLiteral("Bool"),
- QStringLiteral("List"), QStringLiteral("QObject"), QStringLiteral("VariantMap"),
- QStringLiteral("DateTime"), QStringLiteral("Function")
- };
-
- if (t > ListLayout::Role::Invalid && t < ListLayout::Role::MaxDataType)
- return roleTypeNames[t];
-
- return QString();
-}
-
-const ListLayout::Role &ListLayout::getRoleOrCreate(const QString &key, Role::DataType type)
-{
- QStringHash<Role *>::Node *node = roleHash.findNode(key);
- if (node) {
- const Role &r = *node->value;
- if (type != r.type)
- qmlWarning(nullptr) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
- return r;
- }
-
- return createRole(key, type);
-}
-
-const ListLayout::Role &ListLayout::getRoleOrCreate(QV4::String *key, Role::DataType type)
-{
- QStringHash<Role *>::Node *node = roleHash.findNode(key);
- if (node) {
- const Role &r = *node->value;
- if (type != r.type)
- qmlWarning(nullptr) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
- return r;
- }
-
- QString qkey = key->toQString();
-
- return createRole(qkey, type);
-}
-
-const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::Role::DataType type)
-{
- const int dataSizes[] = { sizeof(StringOrTranslation), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QPointer<QObject>), sizeof(QVariantMap), sizeof(QDateTime), sizeof(QJSValue) };
- const int dataAlignments[] = { sizeof(StringOrTranslation), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QObject *), sizeof(QVariantMap), sizeof(QDateTime), sizeof(QJSValue) };
-
- Role *r = new Role;
- r->name = key;
- r->type = type;
-
- if (type == Role::List) {
- r->subLayout = new ListLayout;
- } else {
- r->subLayout = nullptr;
- }
-
- int dataSize = dataSizes[type];
- int dataAlignment = dataAlignments[type];
-
- int dataOffset = (currentBlockOffset + dataAlignment-1) & ~(dataAlignment-1);
- if (dataOffset + dataSize > ListElement::BLOCK_SIZE) {
- r->blockIndex = ++currentBlock;
- r->blockOffset = 0;
- currentBlockOffset = dataSize;
- } else {
- r->blockIndex = currentBlock;
- r->blockOffset = dataOffset;
- currentBlockOffset = dataOffset + dataSize;
- }
-
- int roleIndex = roles.count();
- r->index = roleIndex;
-
- roles.append(r);
- roleHash.insert(key, r);
-
- return *r;
-}
-
-ListLayout::ListLayout(const ListLayout *other) : currentBlock(0), currentBlockOffset(0)
-{
- const int otherRolesCount = other->roles.count();
- roles.reserve(otherRolesCount);
- for (int i=0 ; i < otherRolesCount; ++i) {
- Role *role = new Role(other->roles[i]);
- roles.append(role);
- roleHash.insert(role->name, role);
- }
- currentBlockOffset = other->currentBlockOffset;
- currentBlock = other->currentBlock;
-}
-
-ListLayout::~ListLayout()
-{
- qDeleteAll(roles);
-}
-
-void ListLayout::sync(ListLayout *src, ListLayout *target)
-{
- int roleOffset = target->roles.count();
- int newRoleCount = src->roles.count() - roleOffset;
-
- for (int i=0 ; i < newRoleCount ; ++i) {
- Role *role = new Role(src->roles[roleOffset + i]);
- target->roles.append(role);
- target->roleHash.insert(role->name, role);
- }
-
- target->currentBlockOffset = src->currentBlockOffset;
- target->currentBlock = src->currentBlock;
-}
-
-ListLayout::Role::Role(const Role *other)
-{
- name = other->name;
- type = other->type;
- blockIndex = other->blockIndex;
- blockOffset = other->blockOffset;
- index = other->index;
- if (other->subLayout)
- subLayout = new ListLayout(other->subLayout);
- else
- subLayout = nullptr;
-}
-
-ListLayout::Role::~Role()
-{
- delete subLayout;
-}
-
-const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QVariant &data)
-{
- Role::DataType type;
-
- switch (data.type()) {
- case QVariant::Double: type = Role::Number; break;
- case QVariant::Int: type = Role::Number; break;
- case QVariant::Bool: type = Role::Bool; break;
- case QVariant::String: type = Role::String; break;
- case QVariant::Map: type = Role::VariantMap; break;
- case QVariant::DateTime: type = Role::DateTime; break;
- case QVariant::UserType: {
- if (data.userType() == qMetaTypeId<QJSValue>() &&
- data.value<QJSValue>().isCallable()) {
- type = Role::Function;
- break;
- } else if (data.userType() == qMetaTypeId<const QV4::CompiledData::Binding*>()
- && data.value<const QV4::CompiledData::Binding*>()->isTranslationBinding()) {
- type = Role::String;
- break;
- } else {
- type = Role::List;
- break;
- }
- }
- default: type = Role::Invalid; break;
- }
-
- if (type == Role::Invalid) {
- qmlWarning(nullptr) << "Can't create role for unsupported data type";
- return nullptr;
- }
-
- return &getRoleOrCreate(key, type);
-}
-
-const ListLayout::Role *ListLayout::getExistingRole(const QString &key) const
-{
- Role *r = nullptr;
- QStringHash<Role *>::Node *node = roleHash.findNode(key);
- if (node)
- r = node->value;
- return r;
-}
-
-const ListLayout::Role *ListLayout::getExistingRole(QV4::String *key) const
-{
- Role *r = nullptr;
- QStringHash<Role *>::Node *node = roleHash.findNode(key);
- if (node)
- r = node->value;
- return r;
-}
-
-StringOrTranslation::StringOrTranslation(const QString &s)
-{
- d.setFlag();
- setString(s);
-}
-
-StringOrTranslation::StringOrTranslation(const QV4::CompiledData::Binding *binding)
-{
- d.setFlag();
- clear();
- d = binding;
-}
-
-StringOrTranslation::~StringOrTranslation()
-{
- clear();
-}
-
-void StringOrTranslation::setString(const QString &s)
-{
- d.setFlag();
- clear();
- QStringData *stringData = const_cast<QString &>(s).data_ptr();
- d = stringData;
- if (stringData)
- stringData->ref.ref();
-}
-
-void StringOrTranslation::setTranslation(const QV4::CompiledData::Binding *binding)
-{
- d.setFlag();
- clear();
- d = binding;
-}
-
-QString StringOrTranslation::toString(const QQmlListModel *owner) const
-{
- if (d.isNull())
- return QString();
- if (d.isT1()) {
- QStringDataPtr holder = { d.asT1() };
- holder.ptr->ref.ref();
- return QString(holder);
- }
- if (!owner)
- return QString();
- return d.asT2()->valueAsString(owner->m_compilationUnit.data());
-}
-
-QString StringOrTranslation::asString() const
-{
- if (d.isNull())
- return QString();
- if (!d.isT1())
- return QString();
- QStringDataPtr holder = { d.asT1() };
- holder.ptr->ref.ref();
- return QString(holder);
-}
-
-void StringOrTranslation::clear()
-{
- if (QStringData *strData = d.isT1() ? d.asT1() : nullptr) {
- if (!strData->ref.deref())
- QStringData::deallocate(strData);
- }
- d = static_cast<QStringData *>(nullptr);
-}
-
-QObject *ListModel::getOrCreateModelObject(QQmlListModel *model, int elementIndex)
-{
- ListElement *e = elements[elementIndex];
- if (e->m_objectCache == nullptr) {
- void *memory = operator new(sizeof(QObject) + sizeof(QQmlData));
- void *ddataMemory = ((char *)memory) + sizeof(QObject);
- e->m_objectCache = new (memory) QObject;
- QQmlData *ddata = new (ddataMemory) QQmlData;
- ddata->ownMemory = false;
- QObjectPrivate::get(e->m_objectCache)->declarativeData = ddata;
- (void)new ModelNodeMetaObject(e->m_objectCache, model, elementIndex);
- }
- return e->m_objectCache;
-}
-
-bool ListModel::sync(ListModel *src, ListModel *target)
-{
- // Sanity check
-
- bool hasChanges = false;
-
- // Build hash of elements <-> uid for each of the lists
- QHash<int, ElementSync> elementHash;
- for (int i = 0; i < target->elements.count(); ++i) {
- ListElement *e = target->elements.at(i);
- int uid = e->getUid();
- ElementSync sync;
- sync.target = e;
- sync.targetIndex = i;
- elementHash.insert(uid, sync);
- }
- for (int i = 0; i < src->elements.count(); ++i) {
- ListElement *e = src->elements.at(i);
- int uid = e->getUid();
-
- QHash<int, ElementSync>::iterator it = elementHash.find(uid);
- if (it == elementHash.end()) {
- ElementSync sync;
- sync.src = e;
- sync.srcIndex = i;
- elementHash.insert(uid, sync);
- } else {
- ElementSync &sync = it.value();
- sync.src = e;
- sync.srcIndex = i;
- }
- }
-
- QQmlListModel *targetModel = target->m_modelCache;
-
- // Get list of elements that are in the target but no longer in the source. These get deleted first.
- int rowsRemoved = 0;
- for (int i = 0 ; i < target->elements.count() ; ++i) {
- ListElement *element = target->elements.at(i);
- ElementSync &s = elementHash.find(element->getUid()).value();
- Q_ASSERT(s.targetIndex >= 0);
- // need to update the targetIndex, to keep it correct after removals
- s.targetIndex -= rowsRemoved;
- if (s.src == nullptr) {
- Q_ASSERT(s.targetIndex == i);
- hasChanges = true;
- if (targetModel)
- targetModel->beginRemoveRows(QModelIndex(), i, i);
- s.target->destroy(target->m_layout);
- target->elements.removeOne(s.target);
- delete s.target;
- if (targetModel)
- targetModel->endRemoveRows();
- ++rowsRemoved;
- --i;
- continue;
- }
- }
-
- // Sync the layouts
- ListLayout::sync(src->m_layout, target->m_layout);
-
- // Clear the target list, and append in correct order from the source
- target->elements.clear();
- for (int i = 0; i < src->elements.count(); ++i) {
- ListElement *srcElement = src->elements.at(i);
- ElementSync &s = elementHash.find(srcElement->getUid()).value();
- Q_ASSERT(s.srcIndex >= 0);
- ListElement *targetElement = s.target;
- if (targetElement == nullptr) {
- targetElement = new ListElement(srcElement->getUid());
- }
- s.changedRoles = ListElement::sync(srcElement, src->m_layout, targetElement, target->m_layout);
- target->elements.append(targetElement);
- }
-
- target->updateCacheIndices();
-
- // Update values stored in target meta objects
- for (int i=0 ; i < target->elements.count() ; ++i) {
- ListElement *e = target->elements[i];
- if (ModelNodeMetaObject *mo = e->objectCache())
- mo->updateValues();
- }
-
- // now emit the change notifications required. This can be safely done, as we're only emitting changes, moves and inserts,
- // so the model indices can't be out of bounds
- //
- // to ensure things are kept in the correct order, emit inserts and moves first. This shouls ensure all persistent
- // model indices are updated correctly
- int rowsInserted = 0;
- for (int i = 0 ; i < target->elements.count() ; ++i) {
- ListElement *element = target->elements.at(i);
- ElementSync &s = elementHash.find(element->getUid()).value();
- Q_ASSERT(s.srcIndex >= 0);
- s.srcIndex += rowsInserted;
- if (s.srcIndex != s.targetIndex) {
- if (targetModel) {
- if (s.targetIndex == -1) {
- targetModel->beginInsertRows(QModelIndex(), i, i);
- targetModel->endInsertRows();
- } else {
- targetModel->beginMoveRows(QModelIndex(), i, i, QModelIndex(), s.srcIndex);
- targetModel->endMoveRows();
- }
- }
- hasChanges = true;
- ++rowsInserted;
- }
- if (s.targetIndex != -1 && !s.changedRoles.isEmpty()) {
- QModelIndex idx = targetModel->createIndex(i, 0);
- if (targetModel)
- targetModel->dataChanged(idx, idx, s.changedRoles);
- hasChanges = true;
- }
- }
- return hasChanges;
-}
-
-ListModel::ListModel(ListLayout *layout, QQmlListModel *modelCache) : m_layout(layout), m_modelCache(modelCache)
-{
-}
-
-void ListModel::destroy()
-{
- for (const auto &destroyer : remove(0, elements.count()))
- destroyer();
-
- m_layout = nullptr;
- if (m_modelCache && m_modelCache->m_primary == false)
- delete m_modelCache;
- m_modelCache = nullptr;
-}
-
-int ListModel::appendElement()
-{
- int elementIndex = elements.count();
- newElement(elementIndex);
- return elementIndex;
-}
-
-void ListModel::insertElement(int index)
-{
- newElement(index);
- updateCacheIndices(index);
-}
-
-void ListModel::move(int from, int to, int n)
-{
- if (from > to) {
- // Only move forwards - flip if backwards moving
- int tfrom = from;
- int tto = to;
- from = tto;
- to = tto+n;
- n = tfrom-tto;
- }
-
- QPODVector<ListElement *, 4> store;
- for (int i=0 ; i < (to-from) ; ++i)
- store.append(elements[from+n+i]);
- for (int i=0 ; i < n ; ++i)
- store.append(elements[from+i]);
- for (int i=0 ; i < store.count() ; ++i)
- elements[from+i] = store[i];
-
- updateCacheIndices(from, to + n);
-}
-
-void ListModel::newElement(int index)
-{
- ListElement *e = new ListElement;
- elements.insert(index, e);
-}
-
-void ListModel::updateCacheIndices(int start, int end)
-{
- int count = elements.count();
-
- if (end < 0 || end > count)
- end = count;
-
- for (int i = start; i < end; ++i) {
- ListElement *e = elements.at(i);
- if (ModelNodeMetaObject *mo = e->objectCache())
- mo->m_elementIndex = i;
- }
-}
-
-QVariant ListModel::getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV4::ExecutionEngine *eng)
-{
- if (roleIndex >= m_layout->roleCount())
- return QVariant();
- ListElement *e = elements[elementIndex];
- const ListLayout::Role &r = m_layout->getExistingRole(roleIndex);
- return e->getProperty(r, owner, eng);
-}
-
-ListModel *ListModel::getListProperty(int elementIndex, const ListLayout::Role &role)
-{
- ListElement *e = elements[elementIndex];
- return e->getListProperty(role);
-}
-
-void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles)
-{
- ListElement *e = elements[elementIndex];
-
- QV4::ExecutionEngine *v4 = object->engine();
- QV4::Scope scope(v4);
- QV4::ScopedObject o(scope);
-
- QV4::ObjectIterator it(scope, object, QV4::ObjectIterator::EnumerableOnly);
- QV4::ScopedString propertyName(scope);
- QV4::ScopedValue propertyValue(scope);
- while (1) {
- propertyName = it.nextPropertyNameAsString(propertyValue);
- if (!propertyName)
- break;
-
- // Check if this key exists yet
- int roleIndex = -1;
-
- // Add the value now
- if (const QV4::String *s = propertyValue->as<QV4::String>()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String);
- roleIndex = e->setStringProperty(r, s->toQString());
- } else if (propertyValue->isNumber()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number);
- roleIndex = e->setDoubleProperty(r, propertyValue->asDouble());
- } else if (QV4::ArrayObject *a = propertyValue->as<QV4::ArrayObject>()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
- ListModel *subModel = new ListModel(r.subLayout, nullptr);
-
- int arrayLength = a->getLength();
- for (int j=0 ; j < arrayLength ; ++j) {
- o = a->get(j);
- subModel->append(o);
- }
-
- roleIndex = e->setListProperty(r, subModel);
- } else if (propertyValue->isBoolean()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool);
- roleIndex = e->setBoolProperty(r, propertyValue->booleanValue());
- } else if (QV4::DateObject *dd = propertyValue->as<QV4::DateObject>()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
- QDateTime dt = dd->toQDateTime();
- roleIndex = e->setDateTimeProperty(r, dt);
- } else if (QV4::FunctionObject *f = propertyValue->as<QV4::FunctionObject>()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Function);
- QV4::ScopedFunctionObject func(scope, f);
- QJSValue jsv;
- QJSValuePrivate::setValue(&jsv, v4, func);
- roleIndex = e->setFunctionProperty(r, jsv);
- } else if (QV4::Object *o = propertyValue->as<QV4::Object>()) {
- if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
- QObject *o = wrapper->object();
- const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject);
- if (role.type == ListLayout::Role::QObject)
- roleIndex = e->setQObjectProperty(role, o);
- } else {
- const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap);
- if (role.type == ListLayout::Role::VariantMap) {
- QV4::ScopedObject obj(scope, o);
- roleIndex = e->setVariantMapProperty(role, obj);
- }
- }
- } else if (propertyValue->isNullOrUndefined()) {
- const ListLayout::Role *r = m_layout->getExistingRole(propertyName);
- if (r)
- e->clearProperty(*r);
- }
-
- if (roleIndex != -1)
- roles->append(roleIndex);
- }
-
- if (ModelNodeMetaObject *mo = e->objectCache())
- mo->updateValues(*roles);
-}
-
-void ListModel::set(int elementIndex, QV4::Object *object)
-{
- if (!object)
- return;
-
- ListElement *e = elements[elementIndex];
-
- QV4::ExecutionEngine *v4 = object->engine();
- QV4::Scope scope(v4);
-
- QV4::ObjectIterator it(scope, object, QV4::ObjectIterator::EnumerableOnly);
- QV4::ScopedString propertyName(scope);
- QV4::ScopedValue propertyValue(scope);
- QV4::ScopedObject o(scope);
- while (1) {
- propertyName = it.nextPropertyNameAsString(propertyValue);
- if (!propertyName)
- break;
-
- // Add the value now
- if (QV4::String *s = propertyValue->stringValue()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String);
- if (r.type == ListLayout::Role::String)
- e->setStringPropertyFast(r, s->toQString());
- } else if (propertyValue->isNumber()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number);
- if (r.type == ListLayout::Role::Number) {
- e->setDoublePropertyFast(r, propertyValue->asDouble());
- }
- } else if (QV4::ArrayObject *a = propertyValue->as<QV4::ArrayObject>()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
- if (r.type == ListLayout::Role::List) {
- ListModel *subModel = new ListModel(r.subLayout, nullptr);
-
- int arrayLength = a->getLength();
- for (int j=0 ; j < arrayLength ; ++j) {
- o = a->get(j);
- subModel->append(o);
- }
-
- e->setListPropertyFast(r, subModel);
- }
- } else if (propertyValue->isBoolean()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool);
- if (r.type == ListLayout::Role::Bool) {
- e->setBoolPropertyFast(r, propertyValue->booleanValue());
- }
- } else if (QV4::DateObject *date = propertyValue->as<QV4::DateObject>()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
- if (r.type == ListLayout::Role::DateTime) {
- QDateTime dt = date->toQDateTime();;
- e->setDateTimePropertyFast(r, dt);
- }
- } else if (QV4::Object *o = propertyValue->as<QV4::Object>()) {
- if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
- QObject *o = wrapper->object();
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject);
- if (r.type == ListLayout::Role::QObject)
- e->setQObjectPropertyFast(r, o);
- } else {
- const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap);
- if (role.type == ListLayout::Role::VariantMap)
- e->setVariantMapFast(role, o);
- }
- } else if (propertyValue->isNullOrUndefined()) {
- const ListLayout::Role *r = m_layout->getExistingRole(propertyName);
- if (r)
- e->clearProperty(*r);
- }
- }
-}
-
-QVector<std::function<void()>> ListModel::remove(int index, int count)
-{
- QVector<std::function<void()>> toDestroy;
- auto layout = m_layout;
- for (int i=0 ; i < count ; ++i) {
- auto element = elements[index+i];
- toDestroy.append([element, layout](){
- element->destroy(layout);
- delete element;
- });
- }
- elements.remove(index, count);
- updateCacheIndices(index);
- return toDestroy;
-}
-
-void ListModel::insert(int elementIndex, QV4::Object *object)
-{
- insertElement(elementIndex);
- set(elementIndex, object);
-}
-
-int ListModel::append(QV4::Object *object)
-{
- int elementIndex = appendElement();
- set(elementIndex, object);
- return elementIndex;
-}
-
-int ListModel::setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data)
-{
- int roleIndex = -1;
-
- if (elementIndex >= 0 && elementIndex < elements.count()) {
- ListElement *e = elements[elementIndex];
-
- const ListLayout::Role *r = m_layout->getRoleOrCreate(key, data);
- if (r) {
- roleIndex = e->setVariantProperty(*r, data);
-
- ModelNodeMetaObject *cache = e->objectCache();
-
- if (roleIndex != -1 && cache)
- cache->updateValues(QVector<int>(1, roleIndex));
- }
- }
-
- return roleIndex;
-}
-
-int ListModel::setExistingProperty(int elementIndex, const QString &key, const QV4::Value &data, QV4::ExecutionEngine *eng)
-{
- int roleIndex = -1;
-
- if (elementIndex >= 0 && elementIndex < elements.count()) {
- ListElement *e = elements[elementIndex];
- const ListLayout::Role *r = m_layout->getExistingRole(key);
- if (r)
- roleIndex = e->setJsProperty(*r, data, eng);
- }
-
- return roleIndex;
-}
-
-inline char *ListElement::getPropertyMemory(const ListLayout::Role &role)
-{
- ListElement *e = this;
- int blockIndex = 0;
- while (blockIndex < role.blockIndex) {
- if (e->next == nullptr) {
- e->next = new ListElement;
- e->next->uid = uid;
- }
- e = e->next;
- ++blockIndex;
- }
-
- char *mem = &e->data[role.blockOffset];
- return mem;
-}
-
-ModelNodeMetaObject *ListElement::objectCache()
-{
- if (!m_objectCache)
- return nullptr;
- return ModelNodeMetaObject::get(m_objectCache);
-}
-
-StringOrTranslation *ListElement::getStringProperty(const ListLayout::Role &role)
-{
- char *mem = getPropertyMemory(role);
- StringOrTranslation *s = reinterpret_cast<StringOrTranslation *>(mem);
- return s;
-}
-
-QObject *ListElement::getQObjectProperty(const ListLayout::Role &role)
-{
- char *mem = getPropertyMemory(role);
- QPointer<QObject> *o = reinterpret_cast<QPointer<QObject> *>(mem);
- return o->data();
-}
-
-QVariantMap *ListElement::getVariantMapProperty(const ListLayout::Role &role)
-{
- QVariantMap *map = nullptr;
-
- char *mem = getPropertyMemory(role);
- if (isMemoryUsed<QVariantMap>(mem))
- map = reinterpret_cast<QVariantMap *>(mem);
-
- return map;
-}
-
-QDateTime *ListElement::getDateTimeProperty(const ListLayout::Role &role)
-{
- QDateTime *dt = nullptr;
-
- char *mem = getPropertyMemory(role);
- if (isMemoryUsed<QDateTime>(mem))
- dt = reinterpret_cast<QDateTime *>(mem);
-
- return dt;
-}
-
-QJSValue *ListElement::getFunctionProperty(const ListLayout::Role &role)
-{
- QJSValue *f = nullptr;
-
- char *mem = getPropertyMemory(role);
- if (isMemoryUsed<QJSValue>(mem))
- f = reinterpret_cast<QJSValue *>(mem);
-
- return f;
-}
-
-QPointer<QObject> *ListElement::getGuardProperty(const ListLayout::Role &role)
-{
- char *mem = getPropertyMemory(role);
-
- bool existingGuard = false;
- for (size_t i=0 ; i < sizeof(QPointer<QObject>) ; ++i) {
- if (mem[i] != 0) {
- existingGuard = true;
- break;
- }
- }
-
- QPointer<QObject> *o = nullptr;
-
- if (existingGuard)
- o = reinterpret_cast<QPointer<QObject> *>(mem);
-
- return o;
-}
-
-ListModel *ListElement::getListProperty(const ListLayout::Role &role)
-{
- char *mem = getPropertyMemory(role);
- ListModel **value = reinterpret_cast<ListModel **>(mem);
- return *value;
-}
-
-QVariant ListElement::getProperty(const ListLayout::Role &role, const QQmlListModel *owner, QV4::ExecutionEngine *eng)
-{
- char *mem = getPropertyMemory(role);
-
- QVariant data;
-
- switch (role.type) {
- case ListLayout::Role::Number:
- {
- double *value = reinterpret_cast<double *>(mem);
- data = *value;
- }
- break;
- case ListLayout::Role::String:
- {
- StringOrTranslation *value = reinterpret_cast<StringOrTranslation *>(mem);
- if (value->isSet())
- data = value->toString(owner);
- }
- break;
- case ListLayout::Role::Bool:
- {
- bool *value = reinterpret_cast<bool *>(mem);
- data = *value;
- }
- break;
- case ListLayout::Role::List:
- {
- ListModel **value = reinterpret_cast<ListModel **>(mem);
- ListModel *model = *value;
-
- if (model) {
- if (model->m_modelCache == nullptr) {
- model->m_modelCache = new QQmlListModel(owner, model, eng);
- QQmlEngine::setContextForObject(model->m_modelCache, QQmlEngine::contextForObject(owner));
- }
-
- QObject *object = model->m_modelCache;
- data = QVariant::fromValue(object);
- }
- }
- break;
- case ListLayout::Role::QObject:
- {
- QPointer<QObject> *guard = reinterpret_cast<QPointer<QObject> *>(mem);
- QObject *object = guard->data();
- if (object)
- data = QVariant::fromValue(object);
- }
- break;
- case ListLayout::Role::VariantMap:
- {
- if (isMemoryUsed<QVariantMap>(mem)) {
- QVariantMap *map = reinterpret_cast<QVariantMap *>(mem);
- data = *map;
- }
- }
- break;
- case ListLayout::Role::DateTime:
- {
- if (isMemoryUsed<QDateTime>(mem)) {
- QDateTime *dt = reinterpret_cast<QDateTime *>(mem);
- data = *dt;
- }
- }
- break;
- case ListLayout::Role::Function:
- {
- if (isMemoryUsed<QJSValue>(mem)) {
- QJSValue *func = reinterpret_cast<QJSValue *>(mem);
- data = QVariant::fromValue(*func);
- }
- }
- break;
- default:
- break;
- }
-
- return data;
-}
-
-int ListElement::setStringProperty(const ListLayout::Role &role, const QString &s)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::String) {
- char *mem = getPropertyMemory(role);
- StringOrTranslation *c = reinterpret_cast<StringOrTranslation *>(mem);
- bool changed;
- if (!c->isSet() || c->isTranslation())
- changed = true;
- else
- changed = c->asString().compare(s) != 0;
- c->setString(s);
- if (changed)
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-int ListElement::setDoubleProperty(const ListLayout::Role &role, double d)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::Number) {
- char *mem = getPropertyMemory(role);
- double *value = reinterpret_cast<double *>(mem);
- bool changed = *value != d;
- *value = d;
- if (changed)
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-int ListElement::setBoolProperty(const ListLayout::Role &role, bool b)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::Bool) {
- char *mem = getPropertyMemory(role);
- bool *value = reinterpret_cast<bool *>(mem);
- bool changed = *value != b;
- *value = b;
- if (changed)
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-int ListElement::setListProperty(const ListLayout::Role &role, ListModel *m)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::List) {
- char *mem = getPropertyMemory(role);
- ListModel **value = reinterpret_cast<ListModel **>(mem);
- if (*value && *value != m) {
- (*value)->destroy();
- delete *value;
- }
- *value = m;
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-int ListElement::setQObjectProperty(const ListLayout::Role &role, QObject *o)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::QObject) {
- char *mem = getPropertyMemory(role);
- QPointer<QObject> *g = reinterpret_cast<QPointer<QObject> *>(mem);
- bool existingGuard = false;
- for (size_t i=0 ; i < sizeof(QPointer<QObject>) ; ++i) {
- if (mem[i] != 0) {
- existingGuard = true;
- break;
- }
- }
- bool changed;
- if (existingGuard) {
- changed = g->data() != o;
- g->~QPointer();
- } else {
- changed = true;
- }
- new (mem) QPointer<QObject>(o);
- if (changed)
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-int ListElement::setVariantMapProperty(const ListLayout::Role &role, QV4::Object *o)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::VariantMap) {
- char *mem = getPropertyMemory(role);
- if (isMemoryUsed<QVariantMap>(mem)) {
- QVariantMap *map = reinterpret_cast<QVariantMap *>(mem);
- map->~QMap();
- }
- new (mem) QVariantMap(o->engine()->variantMapFromJS(o));
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-int ListElement::setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::VariantMap) {
- char *mem = getPropertyMemory(role);
- if (isMemoryUsed<QVariantMap>(mem)) {
- QVariantMap *map = reinterpret_cast<QVariantMap *>(mem);
- if (m && map->isSharedWith(*m))
- return roleIndex;
- map->~QMap();
- } else if (!m) {
- return roleIndex;
- }
- if (m)
- new (mem) QVariantMap(*m);
- else
- new (mem) QVariantMap;
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-int ListElement::setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::DateTime) {
- char *mem = getPropertyMemory(role);
- if (isMemoryUsed<QDateTime>(mem)) {
- QDateTime *dt = reinterpret_cast<QDateTime *>(mem);
- dt->~QDateTime();
- }
- new (mem) QDateTime(dt);
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-int ListElement::setFunctionProperty(const ListLayout::Role &role, const QJSValue &f)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::Function) {
- char *mem = getPropertyMemory(role);
- if (isMemoryUsed<QJSValue>(mem)) {
- QJSValue *f = reinterpret_cast<QJSValue *>(mem);
- f->~QJSValue();
- }
- new (mem) QJSValue(f);
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-int ListElement::setTranslationProperty(const ListLayout::Role &role, const QV4::CompiledData::Binding *b)
-{
- int roleIndex = -1;
-
- if (role.type == ListLayout::Role::String) {
- char *mem = getPropertyMemory(role);
- StringOrTranslation *s = reinterpret_cast<StringOrTranslation *>(mem);
- s->setTranslation(b);
- roleIndex = role.index;
- }
-
- return roleIndex;
-}
-
-
-void ListElement::setStringPropertyFast(const ListLayout::Role &role, const QString &s)
-{
- char *mem = getPropertyMemory(role);
- new (mem) StringOrTranslation(s);
-}
-
-void ListElement::setDoublePropertyFast(const ListLayout::Role &role, double d)
-{
- char *mem = getPropertyMemory(role);
- double *value = new (mem) double;
- *value = d;
-}
-
-void ListElement::setBoolPropertyFast(const ListLayout::Role &role, bool b)
-{
- char *mem = getPropertyMemory(role);
- bool *value = new (mem) bool;
- *value = b;
-}
-
-void ListElement::setQObjectPropertyFast(const ListLayout::Role &role, QObject *o)
-{
- char *mem = getPropertyMemory(role);
- new (mem) QPointer<QObject>(o);
-}
-
-void ListElement::setListPropertyFast(const ListLayout::Role &role, ListModel *m)
-{
- char *mem = getPropertyMemory(role);
- ListModel **value = new (mem) ListModel *;
- *value = m;
-}
-
-void ListElement::setVariantMapFast(const ListLayout::Role &role, QV4::Object *o)
-{
- char *mem = getPropertyMemory(role);
- QVariantMap *map = new (mem) QVariantMap;
- *map = o->engine()->variantMapFromJS(o);
-}
-
-void ListElement::setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt)
-{
- char *mem = getPropertyMemory(role);
- new (mem) QDateTime(dt);
-}
-
-void ListElement::setFunctionPropertyFast(const ListLayout::Role &role, const QJSValue &f)
-{
- char *mem = getPropertyMemory(role);
- new (mem) QJSValue(f);
-}
-
-void ListElement::clearProperty(const ListLayout::Role &role)
-{
- switch (role.type) {
- case ListLayout::Role::String:
- setStringProperty(role, QString());
- break;
- case ListLayout::Role::Number:
- setDoubleProperty(role, 0.0);
- break;
- case ListLayout::Role::Bool:
- setBoolProperty(role, false);
- break;
- case ListLayout::Role::List:
- setListProperty(role, nullptr);
- break;
- case ListLayout::Role::QObject:
- setQObjectProperty(role, nullptr);
- break;
- case ListLayout::Role::DateTime:
- setDateTimeProperty(role, QDateTime());
- break;
- case ListLayout::Role::VariantMap:
- setVariantMapProperty(role, (QVariantMap *)nullptr);
- break;
- case ListLayout::Role::Function:
- setFunctionProperty(role, QJSValue());
- break;
- default:
- break;
- }
-}
-
-ListElement::ListElement()
-{
- m_objectCache = nullptr;
- uid = uidCounter.fetchAndAddOrdered(1);
- next = nullptr;
- memset(data, 0, sizeof(data));
-}
-
-ListElement::ListElement(int existingUid)
-{
- m_objectCache = nullptr;
- uid = existingUid;
- next = nullptr;
- memset(data, 0, sizeof(data));
-}
-
-ListElement::~ListElement()
-{
- delete next;
-}
-
-QVector<int> ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout)
-{
- QVector<int> changedRoles;
- for (int i=0 ; i < srcLayout->roleCount() ; ++i) {
- const ListLayout::Role &srcRole = srcLayout->getExistingRole(i);
- const ListLayout::Role &targetRole = targetLayout->getExistingRole(i);
-
- int roleIndex = -1;
- switch (srcRole.type) {
- case ListLayout::Role::List:
- {
- ListModel *srcSubModel = src->getListProperty(srcRole);
- ListModel *targetSubModel = target->getListProperty(targetRole);
-
- if (srcSubModel) {
- if (targetSubModel == nullptr) {
- targetSubModel = new ListModel(targetRole.subLayout, nullptr);
- target->setListPropertyFast(targetRole, targetSubModel);
- }
- if (ListModel::sync(srcSubModel, targetSubModel))
- roleIndex = targetRole.index;
- }
- }
- break;
- case ListLayout::Role::QObject:
- {
- QObject *object = src->getQObjectProperty(srcRole);
- roleIndex = target->setQObjectProperty(targetRole, object);
- }
- break;
- case ListLayout::Role::String:
- case ListLayout::Role::Number:
- case ListLayout::Role::Bool:
- case ListLayout::Role::DateTime:
- case ListLayout::Role::Function:
- {
- QVariant v = src->getProperty(srcRole, nullptr, nullptr);
- roleIndex = target->setVariantProperty(targetRole, v);
- }
- break;
- case ListLayout::Role::VariantMap:
- {
- QVariantMap *map = src->getVariantMapProperty(srcRole);
- roleIndex = target->setVariantMapProperty(targetRole, map);
- }
- break;
- default:
- break;
- }
- if (roleIndex >= 0)
- changedRoles << roleIndex;
- }
-
- return changedRoles;
-}
-
-void ListElement::destroy(ListLayout *layout)
-{
- if (layout) {
- for (int i=0 ; i < layout->roleCount() ; ++i) {
- const ListLayout::Role &r = layout->getExistingRole(i);
-
- switch (r.type) {
- case ListLayout::Role::String:
- {
- StringOrTranslation *string = getStringProperty(r);
- if (string)
- string->~StringOrTranslation();
- }
- break;
- case ListLayout::Role::List:
- {
- ListModel *model = getListProperty(r);
- if (model) {
- model->destroy();
- delete model;
- }
- }
- break;
- case ListLayout::Role::QObject:
- {
- QPointer<QObject> *guard = getGuardProperty(r);
- if (guard)
- guard->~QPointer();
- }
- break;
- case ListLayout::Role::VariantMap:
- {
- QVariantMap *map = getVariantMapProperty(r);
- if (map)
- map->~QMap();
- }
- break;
- case ListLayout::Role::DateTime:
- {
- QDateTime *dt = getDateTimeProperty(r);
- if (dt)
- dt->~QDateTime();
- }
- break;
- case ListLayout::Role::Function:
- {
- QJSValue *f = getFunctionProperty(r);
- if (f)
- f->~QJSValue();
- }
- break;
- default:
- // other types don't need explicit cleanup.
- break;
- }
- }
-
- if (m_objectCache) {
- m_objectCache->~QObject();
- operator delete(m_objectCache);
- }
- }
-
- if (next)
- next->destroy(nullptr);
- uid = -1;
-}
-
-int ListElement::setVariantProperty(const ListLayout::Role &role, const QVariant &d)
-{
- int roleIndex = -1;
-
- switch (role.type) {
- case ListLayout::Role::Number:
- roleIndex = setDoubleProperty(role, d.toDouble());
- break;
- case ListLayout::Role::String:
- if (d.userType() == qMetaTypeId<const QV4::CompiledData::Binding *>())
- roleIndex = setTranslationProperty(role, d.value<const QV4::CompiledData::Binding*>());
- else
- roleIndex = setStringProperty(role, d.toString());
- break;
- case ListLayout::Role::Bool:
- roleIndex = setBoolProperty(role, d.toBool());
- break;
- case ListLayout::Role::List:
- roleIndex = setListProperty(role, d.value<ListModel *>());
- break;
- case ListLayout::Role::VariantMap: {
- QVariantMap map = d.toMap();
- roleIndex = setVariantMapProperty(role, &map);
- }
- break;
- case ListLayout::Role::DateTime:
- roleIndex = setDateTimeProperty(role, d.toDateTime());
- break;
- case ListLayout::Role::Function:
- roleIndex = setFunctionProperty(role, d.value<QJSValue>());
- break;
- default:
- break;
- }
-
- return roleIndex;
-}
-
-int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d, QV4::ExecutionEngine *eng)
-{
- // Check if this key exists yet
- int roleIndex = -1;
-
- QV4::Scope scope(eng);
-
- // Add the value now
- if (d.isString()) {
- QString qstr = d.toQString();
- roleIndex = setStringProperty(role, qstr);
- } else if (d.isNumber()) {
- roleIndex = setDoubleProperty(role, d.asDouble());
- } else if (d.as<QV4::ArrayObject>()) {
- QV4::ScopedArrayObject a(scope, d);
- if (role.type == ListLayout::Role::List) {
- QV4::Scope scope(a->engine());
- QV4::ScopedObject o(scope);
-
- ListModel *subModel = new ListModel(role.subLayout, nullptr);
- int arrayLength = a->getLength();
- for (int j=0 ; j < arrayLength ; ++j) {
- o = a->get(j);
- subModel->append(o);
- }
- roleIndex = setListProperty(role, subModel);
- } else {
- qmlWarning(nullptr) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List));
- }
- } else if (d.isBoolean()) {
- roleIndex = setBoolProperty(role, d.booleanValue());
- } else if (d.as<QV4::DateObject>()) {
- QV4::Scoped<QV4::DateObject> dd(scope, d);
- QDateTime dt = dd->toQDateTime();
- roleIndex = setDateTimeProperty(role, dt);
- } else if (d.as<QV4::FunctionObject>()) {
- QV4::ScopedFunctionObject f(scope, d);
- QJSValue jsv;
- QJSValuePrivate::setValue(&jsv, eng, f);
- roleIndex = setFunctionProperty(role, jsv);
- } else if (d.isObject()) {
- QV4::ScopedObject o(scope, d);
- QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>();
- if (role.type == ListLayout::Role::QObject && wrapper) {
- QObject *o = wrapper->object();
- roleIndex = setQObjectProperty(role, o);
- } else if (role.type == ListLayout::Role::VariantMap) {
- roleIndex = setVariantMapProperty(role, o);
- }
- } else if (d.isNullOrUndefined()) {
- clearProperty(role);
- }
-
- return roleIndex;
-}
-
-ModelNodeMetaObject::ModelNodeMetaObject(QObject *object, QQmlListModel *model, int elementIndex)
-: QQmlOpenMetaObject(object), m_enabled(false), m_model(model), m_elementIndex(elementIndex), m_initialized(false)
-{}
-
-void ModelNodeMetaObject::initialize()
-{
- const int roleCount = m_model->m_listModel->roleCount();
- QVector<QByteArray> properties;
- properties.reserve(roleCount);
- for (int i = 0 ; i < roleCount ; ++i) {
- const ListLayout::Role &role = m_model->m_listModel->getExistingRole(i);
- QByteArray name = role.name.toUtf8();
- properties << name;
- }
- type()->createProperties(properties);
- updateValues();
- m_enabled = true;
-}
-
-ModelNodeMetaObject::~ModelNodeMetaObject()
-{
-}
-
-QAbstractDynamicMetaObject *ModelNodeMetaObject::toDynamicMetaObject(QObject *object)
-{
- if (!m_initialized) {
- m_initialized = true;
- initialize();
- }
- return QQmlOpenMetaObject::toDynamicMetaObject(object);
-}
-
-ModelNodeMetaObject *ModelNodeMetaObject::get(QObject *obj)
-{
- QObjectPrivate *op = QObjectPrivate::get(obj);
- return static_cast<ModelNodeMetaObject*>(op->metaObject);
-}
-
-void ModelNodeMetaObject::updateValues()
-{
- const int roleCount = m_model->m_listModel->roleCount();
- if (!m_initialized) {
- if (roleCount) {
- Q_ALLOCA_VAR(int, changedRoles, roleCount * sizeof(int));
- for (int i = 0; i < roleCount; ++i)
- changedRoles[i] = i;
- emitDirectNotifies(changedRoles, roleCount);
- }
- return;
- }
- for (int i=0 ; i < roleCount ; ++i) {
- const ListLayout::Role &role = m_model->m_listModel->getExistingRole(i);
- QByteArray name = role.name.toUtf8();
- const QVariant &data = m_model->data(m_elementIndex, i);
- setValue(name, data, role.type == ListLayout::Role::List);
- }
-}
-
-void ModelNodeMetaObject::updateValues(const QVector<int> &roles)
-{
- if (!m_initialized) {
- emitDirectNotifies(roles.constData(), roles.count());
- return;
- }
- int roleCount = roles.count();
- for (int i=0 ; i < roleCount ; ++i) {
- int roleIndex = roles.at(i);
- const ListLayout::Role &role = m_model->m_listModel->getExistingRole(roleIndex);
- QByteArray name = role.name.toUtf8();
- const QVariant &data = m_model->data(m_elementIndex, roleIndex);
- setValue(name, data, role.type == ListLayout::Role::List);
- }
-}
-
-void ModelNodeMetaObject::propertyWritten(int index)
-{
- if (!m_enabled)
- return;
-
- QString propName = QString::fromUtf8(name(index));
- const QVariant value = this->value(index);
-
- QV4::Scope scope(m_model->engine());
- QV4::ScopedValue v(scope, scope.engine->fromVariant(value));
-
- int roleIndex = m_model->m_listModel->setExistingProperty(m_elementIndex, propName, v, scope.engine);
- if (roleIndex != -1)
- m_model->emitItemsChanged(m_elementIndex, 1, QVector<int>(1, roleIndex));
-}
-
-// Does the emission of the notifiers when we haven't created the meta-object yet
-void ModelNodeMetaObject::emitDirectNotifies(const int *changedRoles, int roleCount)
-{
- Q_ASSERT(!m_initialized);
- QQmlData *ddata = QQmlData::get(object(), /*create*/false);
- if (!ddata)
- return;
- // There's nothing to emit if we're a list model in a worker thread.
- if (!qmlEngine(m_model))
- return;
- for (int i = 0; i < roleCount; ++i) {
- const int changedRole = changedRoles[i];
- QQmlNotifier::notify(ddata, changedRole);
- }
-}
-
-namespace QV4 {
-
-bool ModelObject::virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver)
-{
- if (!id.isString())
- return Object::virtualPut(m, id, value, receiver);
- QString propName = id.toQString();
-
- ModelObject *that = static_cast<ModelObject*>(m);
-
- ExecutionEngine *eng = that->engine();
- const int elementIndex = that->d()->elementIndex();
- int roleIndex = that->d()->m_model->m_listModel->setExistingProperty(elementIndex, propName, value, eng);
- if (roleIndex != -1)
- that->d()->m_model->emitItemsChanged(elementIndex, 1, QVector<int>(1, roleIndex));
-
- ModelNodeMetaObject *mo = ModelNodeMetaObject::get(that->object());
- if (mo->initialized())
- mo->emitPropertyNotification(propName.toUtf8());
- return true;
-}
-
-ReturnedValue ModelObject::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
-{
- if (!id.isString())
- return QObjectWrapper::virtualGet(m, id, receiver, hasProperty);
-
- const ModelObject *that = static_cast<const ModelObject*>(m);
- Scope scope(that);
- ScopedString name(scope, id.asStringOrSymbol());
- const ListLayout::Role *role = that->d()->m_model->m_listModel->getExistingRole(name);
- if (!role)
- return QObjectWrapper::virtualGet(m, id, receiver, hasProperty);
- if (hasProperty)
- *hasProperty = true;
-
- if (QQmlEngine *qmlEngine = that->engine()->qmlEngine()) {
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine);
- if (ep && ep->propertyCapture)
- ep->propertyCapture->captureProperty(that->object(), -1, role->index, /*doNotify=*/ false);
- }
-
- const int elementIndex = that->d()->elementIndex();
- QVariant value = that->d()->m_model->data(elementIndex, role->index);
- return that->engine()->fromVariant(value);
-}
-
-ReturnedValue ModelObject::virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup)
-{
- lookup->getter = Lookup::getterFallback;
- return lookup->getter(lookup, engine, *object);
-}
-
-struct ModelObjectOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
-{
- int roleNameIndex = 0;
- ~ModelObjectOwnPropertyKeyIterator() override = default;
- PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;
-
-};
-
-PropertyKey ModelObjectOwnPropertyKeyIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs)
-{
- const ModelObject *that = static_cast<const ModelObject *>(o);
-
- ExecutionEngine *v4 = that->engine();
- if (roleNameIndex < that->listModel()->roleCount()) {
- Scope scope(that->engine());
- const ListLayout::Role &role = that->listModel()->getExistingRole(roleNameIndex);
- ++roleNameIndex;
- ScopedString roleName(scope, v4->newString(role.name));
- if (attrs)
- *attrs = QV4::Attr_Data;
- if (pd) {
- QVariant value = that->d()->m_model->data(that->d()->elementIndex(), role.index);
- pd->value = v4->fromVariant(value);
- }
- return roleName->toPropertyKey();
- }
-
- // Fall back to QV4::Object as opposed to QV4::QObjectWrapper otherwise it will add
- // unnecessary entries that relate to the roles used. These just create extra work
- // later on as they will just be ignored.
- return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
-}
-
-OwnPropertyKeyIterator *ModelObject::virtualOwnPropertyKeys(const Object *m, Value *target)
-{
- *target = *m;
- return new ModelObjectOwnPropertyKeyIterator;
-}
-
-DEFINE_OBJECT_VTABLE(ModelObject);
-
-} // namespace QV4
-
-DynamicRoleModelNode::DynamicRoleModelNode(QQmlListModel *owner, int uid) : m_owner(owner), m_uid(uid), m_meta(new DynamicRoleModelNodeMetaObject(this))
-{
- setNodeUpdatesEnabled(true);
-}
-
-DynamicRoleModelNode *DynamicRoleModelNode::create(const QVariantMap &obj, QQmlListModel *owner)
-{
- DynamicRoleModelNode *object = new DynamicRoleModelNode(owner, uidCounter.fetchAndAddOrdered(1));
- QVector<int> roles;
- object->updateValues(obj, roles);
- return object;
-}
-
-QVector<int> DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target)
-{
- QVector<int> changedRoles;
- for (int i = 0; i < src->m_meta->count(); ++i) {
- const QByteArray &name = src->m_meta->name(i);
- QVariant value = src->m_meta->value(i);
-
- QQmlListModel *srcModel = qobject_cast<QQmlListModel *>(value.value<QObject *>());
- QQmlListModel *targetModel = qobject_cast<QQmlListModel *>(target->m_meta->value(i).value<QObject *>());
-
- bool modelHasChanges = false;
- if (srcModel) {
- if (targetModel == nullptr)
- targetModel = QQmlListModel::createWithOwner(target->m_owner);
-
- modelHasChanges = QQmlListModel::sync(srcModel, targetModel);
-
- QObject *targetModelObject = targetModel;
- value = QVariant::fromValue(targetModelObject);
- } else if (targetModel) {
- delete targetModel;
- }
-
- if (target->setValue(name, value) || modelHasChanges)
- changedRoles << target->m_owner->m_roles.indexOf(QString::fromUtf8(name));
- }
- return changedRoles;
-}
-
-void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int> &roles)
-{
- for (auto it = object.cbegin(), end = object.cend(); it != end; ++it) {
- const QString &key = it.key();
-
- int roleIndex = m_owner->m_roles.indexOf(key);
- if (roleIndex == -1) {
- roleIndex = m_owner->m_roles.count();
- m_owner->m_roles.append(key);
- }
-
- QVariant value = it.value();
-
- // A JS array/object is translated into a (hierarchical) QQmlListModel,
- // so translate to a variant map/list first with toVariant().
- if (value.userType() == qMetaTypeId<QJSValue>())
- value = value.value<QJSValue>().toVariant();
-
- if (value.type() == QVariant::List) {
- QQmlListModel *subModel = QQmlListModel::createWithOwner(m_owner);
-
- QVariantList subArray = value.toList();
- QVariantList::const_iterator subIt = subArray.cbegin();
- QVariantList::const_iterator subEnd = subArray.cend();
- while (subIt != subEnd) {
- const QVariantMap &subObject = subIt->toMap();
- subModel->m_modelObjects.append(DynamicRoleModelNode::create(subObject, subModel));
- ++subIt;
- }
-
- QObject *subModelObject = subModel;
- value = QVariant::fromValue(subModelObject);
- }
-
- const QByteArray &keyUtf8 = key.toUtf8();
-
- QQmlListModel *existingModel = qobject_cast<QQmlListModel *>(m_meta->value(keyUtf8).value<QObject *>());
- delete existingModel;
-
- if (m_meta->setValue(keyUtf8, value))
- roles << roleIndex;
- }
-}
-
-DynamicRoleModelNodeMetaObject::DynamicRoleModelNodeMetaObject(DynamicRoleModelNode *object)
- : QQmlOpenMetaObject(object), m_enabled(false), m_owner(object)
-{
-}
-
-DynamicRoleModelNodeMetaObject::~DynamicRoleModelNodeMetaObject()
-{
- for (int i=0 ; i < count() ; ++i) {
- QQmlListModel *subModel = qobject_cast<QQmlListModel *>(value(i).value<QObject *>());
- delete subModel;
- }
-}
-
-void DynamicRoleModelNodeMetaObject::propertyWrite(int index)
-{
- if (!m_enabled)
- return;
-
- QVariant v = value(index);
- QQmlListModel *model = qobject_cast<QQmlListModel *>(v.value<QObject *>());
- delete model;
-}
-
-void DynamicRoleModelNodeMetaObject::propertyWritten(int index)
-{
- if (!m_enabled)
- return;
-
- QQmlListModel *parentModel = m_owner->m_owner;
-
- QVariant v = value(index);
-
- // A JS array/object is translated into a (hierarchical) QQmlListModel,
- // so translate to a variant map/list first with toVariant().
- if (v.userType() == qMetaTypeId<QJSValue>())
- v= v.value<QJSValue>().toVariant();
-
- if (v.type() == QVariant::List) {
- QQmlListModel *subModel = QQmlListModel::createWithOwner(parentModel);
-
- QVariantList subArray = v.toList();
- QVariantList::const_iterator subIt = subArray.cbegin();
- QVariantList::const_iterator subEnd = subArray.cend();
- while (subIt != subEnd) {
- const QVariantMap &subObject = subIt->toMap();
- subModel->m_modelObjects.append(DynamicRoleModelNode::create(subObject, subModel));
- ++subIt;
- }
-
- QObject *subModelObject = subModel;
- v = QVariant::fromValue(subModelObject);
-
- setValue(index, v);
- }
-
- int elementIndex = parentModel->m_modelObjects.indexOf(m_owner);
- if (elementIndex != -1) {
- int roleIndex = parentModel->m_roles.indexOf(QString::fromLatin1(name(index).constData()));
- if (roleIndex != -1)
- parentModel->emitItemsChanged(elementIndex, 1, QVector<int>(1, roleIndex));
- }
-}
-
-/*!
- \qmltype ListModel
- \instantiates QQmlListModel
- \inqmlmodule QtQml.Models
- \ingroup qtquick-models
- \brief Defines a free-form list data source.
-
- The ListModel is a simple container of ListElement definitions, each
- containing data roles. The contents can be defined dynamically, or
- explicitly in QML.
-
- The number of elements in the model can be obtained from its \l count property.
- A number of familiar methods are also provided to manipulate the contents of the
- model, including append(), insert(), move(), remove() and set(). These methods
- accept dictionaries as their arguments; these are translated to ListElement objects
- by the model.
-
- Elements can be manipulated via the model using the setProperty() method, which
- allows the roles of the specified element to be set and changed.
-
- \section1 Example Usage
-
- The following example shows a ListModel containing three elements, with the roles
- "name" and "cost".
-
- \div {class="float-right"}
- \inlineimage listmodel.png
- \enddiv
-
- \snippet qml/listmodel/listmodel.qml 0
-
- Roles (properties) in each element must begin with a lower-case letter and
- should be common to all elements in a model. The ListElement documentation
- provides more guidelines for how elements should be defined.
-
- Since the example model contains an \c id property, it can be referenced
- by views, such as the ListView in this example:
-
- \snippet qml/listmodel/listmodel-simple.qml 0
- \dots 8
- \snippet qml/listmodel/listmodel-simple.qml 1
-
- It is possible for roles to contain list data. In the following example we
- create a list of fruit attributes:
-
- \snippet qml/listmodel/listmodel-nested.qml model
-
- The delegate displays all the fruit attributes:
-
- \div {class="float-right"}
- \inlineimage listmodel-nested.png
- \enddiv
-
- \snippet qml/listmodel/listmodel-nested.qml delegate
-
- \section1 Modifying List Models
-
- The content of a ListModel may be created and modified using the clear(),
- append(), set(), insert() and setProperty() methods. For example:
-
- \snippet qml/listmodel/listmodel-modify.qml delegate
-
- Note that when creating content dynamically the set of available properties
- cannot be changed once set. Whatever properties are first added to the model
- are the only permitted properties in the model.
-
- \section1 Using Threaded List Models with WorkerScript
-
- ListModel can be used together with WorkerScript access a list model
- from multiple threads. This is useful if list modifications are
- synchronous and take some time: the list operations can be moved to a
- different thread to avoid blocking of the main GUI thread.
-
- Here is an example that uses WorkerScript to periodically append the
- current time to a list model:
-
- \snippet ../quick/threading/threadedlistmodel/timedisplay.qml 0
-
- The included file, \tt dataloader.mjs, looks like this:
-
- \snippet ../quick/threading/threadedlistmodel/dataloader.mjs 0
-
- The timer in the main example sends messages to the worker script by calling
- \l WorkerScript::sendMessage(). When this message is received,
- \c WorkerScript.onMessage() is invoked in \c dataloader.mjs,
- which appends the current time to the list model.
-
- Note the call to sync() from the external thread.
- You must call sync() or else the changes made to the list from that
- thread will not be reflected in the list model in the main thread.
-
- \sa {qml-data-models}{Data Models}, {Qt Quick Examples - Threading}, {Qt QML}
-*/
-
-QQmlListModel::QQmlListModel(QObject *parent)
-: QAbstractListModel(parent)
-{
- m_mainThread = true;
- m_primary = true;
- m_agent = nullptr;
- m_dynamicRoles = false;
-
- m_layout = new ListLayout;
- m_listModel = new ListModel(m_layout, this);
-
- m_engine = nullptr;
-}
-
-QQmlListModel::QQmlListModel(const QQmlListModel *owner, ListModel *data, QV4::ExecutionEngine *engine, QObject *parent)
-: QAbstractListModel(parent)
-{
- m_mainThread = owner->m_mainThread;
- m_primary = false;
- m_agent = owner->m_agent;
-
- Q_ASSERT(owner->m_dynamicRoles == false);
- m_dynamicRoles = false;
- m_layout = nullptr;
- m_listModel = data;
-
- m_engine = engine;
- m_compilationUnit = owner->m_compilationUnit;
-}
-
-QQmlListModel::QQmlListModel(QQmlListModel *orig, QQmlListModelWorkerAgent *agent)
-: QAbstractListModel(agent)
-{
- m_mainThread = false;
- m_primary = true;
- m_agent = agent;
- m_dynamicRoles = orig->m_dynamicRoles;
-
- m_layout = new ListLayout(orig->m_layout);
- m_listModel = new ListModel(m_layout, this);
-
- if (m_dynamicRoles)
- sync(orig, this);
- else
- ListModel::sync(orig->m_listModel, m_listModel);
-
- m_engine = nullptr;
- m_compilationUnit = orig->m_compilationUnit;
-}
-
-QQmlListModel::~QQmlListModel()
-{
- qDeleteAll(m_modelObjects);
-
- if (m_primary) {
- m_listModel->destroy();
- delete m_listModel;
-
- if (m_mainThread && m_agent) {
- m_agent->modelDestroyed();
- m_agent->release();
- }
- }
-
- m_listModel = nullptr;
-
- delete m_layout;
- m_layout = nullptr;
-}
-
-QQmlListModel *QQmlListModel::createWithOwner(QQmlListModel *newOwner)
-{
- QQmlListModel *model = new QQmlListModel;
-
- model->m_mainThread = newOwner->m_mainThread;
- model->m_engine = newOwner->m_engine;
- model->m_agent = newOwner->m_agent;
- model->m_dynamicRoles = newOwner->m_dynamicRoles;
-
- if (model->m_mainThread && model->m_agent)
- model->m_agent->addref();
-
- QQmlEngine::setContextForObject(model, QQmlEngine::contextForObject(newOwner));
-
- return model;
-}
-
-QV4::ExecutionEngine *QQmlListModel::engine() const
-{
- if (m_engine == nullptr) {
- m_engine = qmlEngine(this)->handle();
- }
-
- return m_engine;
-}
-
-bool QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target)
-{
- Q_ASSERT(src->m_dynamicRoles && target->m_dynamicRoles);
-
- bool hasChanges = false;
-
- target->m_roles = src->m_roles;
-
- // Build hash of elements <-> uid for each of the lists
- QHash<int, ElementSync> elementHash;
- for (int i = 0 ; i < target->m_modelObjects.count(); ++i) {
- DynamicRoleModelNode *e = target->m_modelObjects.at(i);
- int uid = e->getUid();
- ElementSync sync;
- sync.target = e;
- sync.targetIndex = i;
- elementHash.insert(uid, sync);
- }
- for (int i = 0 ; i < src->m_modelObjects.count(); ++i) {
- DynamicRoleModelNode *e = src->m_modelObjects.at(i);
- int uid = e->getUid();
-
- QHash<int, ElementSync>::iterator it = elementHash.find(uid);
- if (it == elementHash.end()) {
- ElementSync sync;
- sync.src = e;
- sync.srcIndex = i;
- elementHash.insert(uid, sync);
- } else {
- ElementSync &sync = it.value();
- sync.src = e;
- sync.srcIndex = i;
- }
- }
-
- // Get list of elements that are in the target but no longer in the source. These get deleted first.
- int rowsRemoved = 0;
- for (int i = 0 ; i < target->m_modelObjects.count() ; ++i) {
- DynamicRoleModelNode *element = target->m_modelObjects.at(i);
- ElementSync &s = elementHash.find(element->getUid()).value();
- Q_ASSERT(s.targetIndex >= 0);
- // need to update the targetIndex, to keep it correct after removals
- s.targetIndex -= rowsRemoved;
- if (s.src == nullptr) {
- Q_ASSERT(s.targetIndex == i);
- hasChanges = true;
- target->beginRemoveRows(QModelIndex(), i, i);
- target->m_modelObjects.remove(i, 1);
- target->endRemoveRows();
- delete s.target;
- ++rowsRemoved;
- --i;
- continue;
- }
- }
-
- // Clear the target list, and append in correct order from the source
- target->m_modelObjects.clear();
- for (int i = 0 ; i < src->m_modelObjects.count() ; ++i) {
- DynamicRoleModelNode *element = src->m_modelObjects.at(i);
- ElementSync &s = elementHash.find(element->getUid()).value();
- Q_ASSERT(s.srcIndex >= 0);
- DynamicRoleModelNode *targetElement = s.target;
- if (targetElement == nullptr) {
- targetElement = new DynamicRoleModelNode(target, element->getUid());
- }
- s.changedRoles = DynamicRoleModelNode::sync(element, targetElement);
- target->m_modelObjects.append(targetElement);
- }
-
- // now emit the change notifications required. This can be safely done, as we're only emitting changes, moves and inserts,
- // so the model indices can't be out of bounds
- //
- // to ensure things are kept in the correct order, emit inserts and moves first. This shouls ensure all persistent
- // model indices are updated correctly
- int rowsInserted = 0;
- for (int i = 0 ; i < target->m_modelObjects.count() ; ++i) {
- DynamicRoleModelNode *element = target->m_modelObjects.at(i);
- ElementSync &s = elementHash.find(element->getUid()).value();
- Q_ASSERT(s.srcIndex >= 0);
- s.srcIndex += rowsInserted;
- if (s.srcIndex != s.targetIndex) {
- if (s.targetIndex == -1) {
- target->beginInsertRows(QModelIndex(), i, i);
- target->endInsertRows();
- } else {
- target->beginMoveRows(QModelIndex(), i, i, QModelIndex(), s.srcIndex);
- target->endMoveRows();
- }
- hasChanges = true;
- ++rowsInserted;
- }
- if (s.targetIndex != -1 && !s.changedRoles.isEmpty()) {
- QModelIndex idx = target->createIndex(i, 0);
- emit target->dataChanged(idx, idx, s.changedRoles);
- hasChanges = true;
- }
- }
- return hasChanges;
-}
-
-void QQmlListModel::emitItemsChanged(int index, int count, const QVector<int> &roles)
-{
- if (count <= 0)
- return;
-
- if (m_mainThread)
- emit dataChanged(createIndex(index, 0), createIndex(index + count - 1, 0), roles);;
-}
-
-void QQmlListModel::emitItemsAboutToBeInserted(int index, int count)
-{
- Q_ASSERT(index >= 0 && count >= 0);
- if (m_mainThread)
- beginInsertRows(QModelIndex(), index, index + count - 1);
-}
-
-void QQmlListModel::emitItemsInserted()
-{
- if (m_mainThread) {
- endInsertRows();
- emit countChanged();
- }
-}
-
-QQmlListModelWorkerAgent *QQmlListModel::agent()
-{
- if (m_agent)
- return m_agent;
-
- m_agent = new QQmlListModelWorkerAgent(this);
- return m_agent;
-}
-
-QModelIndex QQmlListModel::index(int row, int column, const QModelIndex &parent) const
-{
- return row >= 0 && row < count() && column == 0 && !parent.isValid()
- ? createIndex(row, column)
- : QModelIndex();
-}
-
-int QQmlListModel::rowCount(const QModelIndex &parent) const
-{
- return !parent.isValid() ? count() : 0;
-}
-
-QVariant QQmlListModel::data(const QModelIndex &index, int role) const
-{
- return data(index.row(), role);
-}
-
-bool QQmlListModel::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- const int row = index.row();
- if (row >= count() || row < 0)
- return false;
-
- if (m_dynamicRoles) {
- const QByteArray property = m_roles.at(role).toUtf8();
- if (m_modelObjects[row]->setValue(property, value)) {
- emitItemsChanged(row, 1, QVector<int>(1, role));
- return true;
- }
- } else {
- const ListLayout::Role &r = m_listModel->getExistingRole(role);
- const int roleIndex = m_listModel->setOrCreateProperty(row, r.name, value);
- if (roleIndex != -1) {
- emitItemsChanged(row, 1, QVector<int>(1, role));
- return true;
- }
- }
-
- return false;
-}
-
-QVariant QQmlListModel::data(int index, int role) const
-{
- QVariant v;
-
- if (index >= count() || index < 0)
- return v;
-
- if (m_dynamicRoles)
- v = m_modelObjects[index]->getValue(m_roles[role]);
- else
- v = m_listModel->getProperty(index, role, this, engine());
-
- return v;
-}
-
-QHash<int, QByteArray> QQmlListModel::roleNames() const
-{
- QHash<int, QByteArray> roleNames;
-
- if (m_dynamicRoles) {
- for (int i = 0 ; i < m_roles.count() ; ++i)
- roleNames.insert(i, m_roles.at(i).toUtf8());
- } else {
- for (int i = 0 ; i < m_listModel->roleCount() ; ++i) {
- const ListLayout::Role &r = m_listModel->getExistingRole(i);
- roleNames.insert(i, r.name.toUtf8());
- }
- }
-
- return roleNames;
-}
-
-/*!
- \qmlproperty bool ListModel::dynamicRoles
-
- By default, the type of a role is fixed the first time
- the role is used. For example, if you create a role called
- "data" and assign a number to it, you can no longer assign
- a string to the "data" role. However, when the dynamicRoles
- property is enabled, the type of a given role is not fixed
- and can be different between elements.
-
- The dynamicRoles property must be set before any data is
- added to the ListModel, and must be set from the main
- thread.
-
- A ListModel that has data statically defined (via the
- ListElement QML syntax) cannot have the dynamicRoles
- property enabled.
-
- There is a significant performance cost to using a
- ListModel with dynamic roles enabled. The cost varies
- from platform to platform but is typically somewhere
- between 4-6x slower than using static role types.
-
- Due to the performance cost of using dynamic roles,
- they are disabled by default.
-*/
-void QQmlListModel::setDynamicRoles(bool enableDynamicRoles)
-{
- if (m_mainThread && m_agent == nullptr) {
- if (enableDynamicRoles) {
- if (m_layout->roleCount())
- qmlWarning(this) << tr("unable to enable dynamic roles as this model is not empty");
- else
- m_dynamicRoles = true;
- } else {
- if (m_roles.count()) {
- qmlWarning(this) << tr("unable to enable static roles as this model is not empty");
- } else {
- m_dynamicRoles = false;
- }
- }
- } else {
- qmlWarning(this) << tr("dynamic role setting must be made from the main thread, before any worker scripts are created");
- }
-}
-
-/*!
- \qmlproperty int ListModel::count
- The number of data entries in the model.
-*/
-int QQmlListModel::count() const
-{
- return m_dynamicRoles ? m_modelObjects.count() : m_listModel->elementCount();
-}
-
-/*!
- \qmlmethod ListModel::clear()
-
- Deletes all content from the model.
-
- \sa append(), remove()
-*/
-void QQmlListModel::clear()
-{
- removeElements(0, count());
-}
-
-/*!
- \qmlmethod ListModel::remove(int index, int count = 1)
-
- Deletes the content at \a index from the model.
-
- \sa clear()
-*/
-void QQmlListModel::remove(QQmlV4Function *args)
-{
- int argLength = args->length();
-
- if (argLength == 1 || argLength == 2) {
- QV4::Scope scope(args->v4engine());
- int index = QV4::ScopedValue(scope, (*args)[0])->toInt32();
- int removeCount = (argLength == 2 ? QV4::ScopedValue(scope, (*args)[1])->toInt32() : 1);
-
- if (index < 0 || index+removeCount > count() || removeCount <= 0) {
- qmlWarning(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+removeCount).arg(count());
- return;
- }
-
- removeElements(index, removeCount);
- } else {
- qmlWarning(this) << tr("remove: incorrect number of arguments");
- }
-}
-
-void QQmlListModel::removeElements(int index, int removeCount)
-{
- Q_ASSERT(index >= 0 && removeCount >= 0);
-
- if (!removeCount)
- return;
-
- if (m_mainThread)
- beginRemoveRows(QModelIndex(), index, index + removeCount - 1);
-
- QVector<std::function<void()>> toDestroy;
- if (m_dynamicRoles) {
- for (int i=0 ; i < removeCount ; ++i) {
- auto modelObject = m_modelObjects[index+i];
- toDestroy.append([modelObject](){
- delete modelObject;
- });
- }
- m_modelObjects.remove(index, removeCount);
- } else {
- toDestroy = m_listModel->remove(index, removeCount);
- }
-
- if (m_mainThread) {
- endRemoveRows();
- emit countChanged();
- }
- for (const auto &destroyer : toDestroy)
- destroyer();
-}
-
-/*!
- \qmlmethod ListModel::insert(int index, jsobject dict)
-
- Adds a new item to the list model at position \a index, with the
- values in \a dict.
-
- \code
- fruitModel.insert(2, {"cost": 5.95, "name":"Pizza"})
- \endcode
-
- The \a index must be to an existing item in the list, or one past
- the end of the list (equivalent to append).
-
- \sa set(), append()
-*/
-
-void QQmlListModel::insert(QQmlV4Function *args)
-{
- if (args->length() == 2) {
- QV4::Scope scope(args->v4engine());
- QV4::ScopedValue arg0(scope, (*args)[0]);
- int index = arg0->toInt32();
-
- if (index < 0 || index > count()) {
- qmlWarning(this) << tr("insert: index %1 out of range").arg(index);
- return;
- }
-
- QV4::ScopedObject argObject(scope, (*args)[1]);
- QV4::ScopedArrayObject objectArray(scope, (*args)[1]);
- if (objectArray) {
- QV4::ScopedObject argObject(scope);
-
- int objectArrayLength = objectArray->getLength();
- emitItemsAboutToBeInserted(index, objectArrayLength);
- for (int i=0 ; i < objectArrayLength ; ++i) {
- argObject = objectArray->get(i);
-
- if (m_dynamicRoles) {
- m_modelObjects.insert(index+i, DynamicRoleModelNode::create(scope.engine->variantMapFromJS(argObject), this));
- } else {
- m_listModel->insert(index+i, argObject);
- }
- }
- emitItemsInserted();
- } else if (argObject) {
- emitItemsAboutToBeInserted(index, 1);
-
- if (m_dynamicRoles) {
- m_modelObjects.insert(index, DynamicRoleModelNode::create(scope.engine->variantMapFromJS(argObject), this));
- } else {
- m_listModel->insert(index, argObject);
- }
-
- emitItemsInserted();
- } else {
- qmlWarning(this) << tr("insert: value is not an object");
- }
- } else {
- qmlWarning(this) << tr("insert: value is not an object");
- }
-}
-
-/*!
- \qmlmethod ListModel::move(int from, int to, int n)
-
- Moves \a n items \a from one position \a to another.
-
- The from and to ranges must exist; for example, to move the first 3 items
- to the end of the list:
-
- \code
- fruitModel.move(0, fruitModel.count - 3, 3)
- \endcode
-
- \sa append()
-*/
-void QQmlListModel::move(int from, int to, int n)
-{
- if (n == 0 || from == to)
- return;
- if (!canMove(from, to, n)) {
- qmlWarning(this) << tr("move: out of range");
- return;
- }
-
- if (m_mainThread)
- beginMoveRows(QModelIndex(), from, from + n - 1, QModelIndex(), to > from ? to + n : to);
-
- if (m_dynamicRoles) {
-
- int realFrom = from;
- int realTo = to;
- int realN = n;
-
- if (from > to) {
- // Only move forwards - flip if backwards moving
- int tfrom = from;
- int tto = to;
- realFrom = tto;
- realTo = tto+n;
- realN = tfrom-tto;
- }
-
- QPODVector<DynamicRoleModelNode *, 4> store;
- for (int i=0 ; i < (realTo-realFrom) ; ++i)
- store.append(m_modelObjects[realFrom+realN+i]);
- for (int i=0 ; i < realN ; ++i)
- store.append(m_modelObjects[realFrom+i]);
- for (int i=0 ; i < store.count() ; ++i)
- m_modelObjects[realFrom+i] = store[i];
-
- } else {
- m_listModel->move(from, to, n);
- }
-
- if (m_mainThread)
- endMoveRows();
-}
-
-/*!
- \qmlmethod ListModel::append(jsobject dict)
-
- Adds a new item to the end of the list model, with the
- values in \a dict.
-
- \code
- fruitModel.append({"cost": 5.95, "name":"Pizza"})
- \endcode
-
- \sa set(), remove()
-*/
-void QQmlListModel::append(QQmlV4Function *args)
-{
- if (args->length() == 1) {
- QV4::Scope scope(args->v4engine());
- QV4::ScopedObject argObject(scope, (*args)[0]);
- QV4::ScopedArrayObject objectArray(scope, (*args)[0]);
-
- if (objectArray) {
- QV4::ScopedObject argObject(scope);
-
- int objectArrayLength = objectArray->getLength();
- if (objectArrayLength > 0) {
- int index = count();
- emitItemsAboutToBeInserted(index, objectArrayLength);
-
- for (int i=0 ; i < objectArrayLength ; ++i) {
- argObject = objectArray->get(i);
-
- if (m_dynamicRoles) {
- m_modelObjects.append(DynamicRoleModelNode::create(scope.engine->variantMapFromJS(argObject), this));
- } else {
- m_listModel->append(argObject);
- }
- }
-
- emitItemsInserted();
- }
- } else if (argObject) {
- int index;
-
- if (m_dynamicRoles) {
- index = m_modelObjects.count();
- emitItemsAboutToBeInserted(index, 1);
- m_modelObjects.append(DynamicRoleModelNode::create(scope.engine->variantMapFromJS(argObject), this));
- } else {
- index = m_listModel->elementCount();
- emitItemsAboutToBeInserted(index, 1);
- m_listModel->append(argObject);
- }
-
- emitItemsInserted();
- } else {
- qmlWarning(this) << tr("append: value is not an object");
- }
- } else {
- qmlWarning(this) << tr("append: value is not an object");
- }
-}
-
-/*!
- \qmlmethod object ListModel::get(int index)
-
- Returns the item at \a index in the list model. This allows the item
- data to be accessed or modified from JavaScript:
-
- \code
- Component.onCompleted: {
- fruitModel.append({"cost": 5.95, "name":"Jackfruit"});
- console.log(fruitModel.get(0).cost);
- fruitModel.get(0).cost = 10.95;
- }
- \endcode
-
- The \a index must be an element in the list.
-
- Note that properties of the returned object that are themselves objects
- will also be models, and this get() method is used to access elements:
-
- \code
- fruitModel.append(..., "attributes":
- [{"name":"spikes","value":"7mm"},
- {"name":"color","value":"green"}]);
- fruitModel.get(0).attributes.get(1).value; // == "green"
- \endcode
-
- \warning The returned object is not guaranteed to remain valid. It
- should not be used in \l{Property Binding}{property bindings}.
-
- \sa append()
-*/
-QJSValue QQmlListModel::get(int index) const
-{
- QV4::Scope scope(engine());
- QV4::ScopedValue result(scope, QV4::Value::undefinedValue());
-
- if (index >= 0 && index < count()) {
-
- if (m_dynamicRoles) {
- DynamicRoleModelNode *object = m_modelObjects[index];
- result = QV4::QObjectWrapper::wrap(scope.engine, object);
- } else {
- QObject *object = m_listModel->getOrCreateModelObject(const_cast<QQmlListModel *>(this), index);
- QQmlData *ddata = QQmlData::get(object);
- if (ddata->jsWrapper.isNullOrUndefined()) {
- result = scope.engine->memoryManager->allocate<QV4::ModelObject>(object, const_cast<QQmlListModel *>(this));
- // Keep track of the QObjectWrapper in persistent value storage
- ddata->jsWrapper.set(scope.engine, result);
- } else {
- result = ddata->jsWrapper.value();
- }
- }
- }
-
- return QJSValue(engine(), result->asReturnedValue());
-}
-
-/*!
- \qmlmethod ListModel::set(int index, jsobject dict)
-
- Changes the item at \a index in the list model with the
- values in \a dict. Properties not appearing in \a dict
- are left unchanged.
-
- \code
- fruitModel.set(3, {"cost": 5.95, "name":"Pizza"})
- \endcode
-
- If \a index is equal to count() then a new item is appended to the
- list. Otherwise, \a index must be an element in the list.
-
- \sa append()
-*/
-void QQmlListModel::set(int index, const QJSValue &value)
-{
- QV4::Scope scope(engine());
- QV4::ScopedObject object(scope, QJSValuePrivate::getValue(&value));
-
- if (!object) {
- qmlWarning(this) << tr("set: value is not an object");
- return;
- }
- if (index > count() || index < 0) {
- qmlWarning(this) << tr("set: index %1 out of range").arg(index);
- return;
- }
-
-
- if (index == count()) {
- emitItemsAboutToBeInserted(index, 1);
-
- if (m_dynamicRoles) {
- m_modelObjects.append(DynamicRoleModelNode::create(scope.engine->variantMapFromJS(object), this));
- } else {
- m_listModel->insert(index, object);
- }
-
- emitItemsInserted();
- } else {
-
- QVector<int> roles;
-
- if (m_dynamicRoles) {
- m_modelObjects[index]->updateValues(scope.engine->variantMapFromJS(object), roles);
- } else {
- m_listModel->set(index, object, &roles);
- }
-
- if (roles.count())
- emitItemsChanged(index, 1, roles);
- }
-}
-
-/*!
- \qmlmethod ListModel::setProperty(int index, string property, variant value)
-
- Changes the \a property of the item at \a index in the list model to \a value.
-
- \code
- fruitModel.setProperty(3, "cost", 5.95)
- \endcode
-
- The \a index must be an element in the list.
-
- \sa append()
-*/
-void QQmlListModel::setProperty(int index, const QString& property, const QVariant& value)
-{
- if (count() == 0 || index >= count() || index < 0) {
- qmlWarning(this) << tr("set: index %1 out of range").arg(index);
- return;
- }
-
- if (m_dynamicRoles) {
- int roleIndex = m_roles.indexOf(property);
- if (roleIndex == -1) {
- roleIndex = m_roles.count();
- m_roles.append(property);
- }
- if (m_modelObjects[index]->setValue(property.toUtf8(), value))
- emitItemsChanged(index, 1, QVector<int>(1, roleIndex));
- } else {
- int roleIndex = m_listModel->setOrCreateProperty(index, property, value);
- if (roleIndex != -1)
- emitItemsChanged(index, 1, QVector<int>(1, roleIndex));
- }
-}
-
-/*!
- \qmlmethod ListModel::sync()
-
- Writes any unsaved changes to the list model after it has been modified
- from a worker script.
-*/
-void QQmlListModel::sync()
-{
- // This is just a dummy method to make it look like sync() exists in
- // ListModel (and not just QQmlListModelWorkerAgent) and to let
- // us document sync().
- qmlWarning(this) << "List sync() can only be called from a WorkerScript";
-}
-
-bool QQmlListModelParser::verifyProperty(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding)
-{
- if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
- const quint32 targetObjectIndex = binding->value.objectIndex;
- const QV4::CompiledData::Object *target = compilationUnit->objectAt(targetObjectIndex);
- QString objName = compilationUnit->stringAt(target->inheritedTypeNameIndex);
- if (objName != listElementTypeName) {
- const QMetaObject *mo = resolveType(objName);
- if (mo != &QQmlListElement::staticMetaObject) {
- error(target, QQmlListModel::tr("ListElement: cannot contain nested elements"));
- return false;
- }
- listElementTypeName = objName; // cache right name for next time
- }
-
- if (!compilationUnit->stringAt(target->idNameIndex).isEmpty()) {
- error(target->locationOfIdProperty, QQmlListModel::tr("ListElement: cannot use reserved \"id\" property"));
- return false;
- }
-
- const QV4::CompiledData::Binding *binding = target->bindingTable();
- for (quint32 i = 0; i < target->nBindings; ++i, ++binding) {
- QString propName = compilationUnit->stringAt(binding->propertyNameIndex);
- if (propName.isEmpty()) {
- error(binding, QQmlListModel::tr("ListElement: cannot contain nested elements"));
- return false;
- }
- if (!verifyProperty(compilationUnit, binding))
- return false;
- }
- } else if (binding->type == QV4::CompiledData::Binding::Type_Script) {
- QString scriptStr = binding->valueAsScriptString(compilationUnit.data());
- if (!binding->isFunctionExpression() && !definesEmptyList(scriptStr)) {
- QByteArray script = scriptStr.toUtf8();
- bool ok;
- evaluateEnum(script, &ok);
- if (!ok) {
- error(binding, QQmlListModel::tr("ListElement: cannot use script for property value"));
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool QQmlListModelParser::applyProperty(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding, ListModel *model, int outterElementIndex)
-{
- const QString elementName = compilationUnit->stringAt(binding->propertyNameIndex);
-
- bool roleSet = false;
- if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
- const quint32 targetObjectIndex = binding->value.objectIndex;
- const QV4::CompiledData::Object *target = compilationUnit->objectAt(targetObjectIndex);
-
- ListModel *subModel = nullptr;
- if (outterElementIndex == -1) {
- subModel = model;
- } else {
- const ListLayout::Role &role = model->getOrCreateListRole(elementName);
- if (role.type == ListLayout::Role::List) {
- subModel = model->getListProperty(outterElementIndex, role);
- if (subModel == nullptr) {
- subModel = new ListModel(role.subLayout, nullptr);
- QVariant vModel = QVariant::fromValue(subModel);
- model->setOrCreateProperty(outterElementIndex, elementName, vModel);
- }
- }
- }
-
- int elementIndex = subModel ? subModel->appendElement() : -1;
-
- const QV4::CompiledData::Binding *subBinding = target->bindingTable();
- for (quint32 i = 0; i < target->nBindings; ++i, ++subBinding) {
- roleSet |= applyProperty(compilationUnit, subBinding, subModel, elementIndex);
- }
-
- } else {
- QVariant value;
-
- if (binding->isTranslationBinding()) {
- value = QVariant::fromValue<const QV4::CompiledData::Binding*>(binding);
- } else if (binding->evaluatesToString()) {
- value = binding->valueAsString(compilationUnit.data());
- } else if (binding->type == QV4::CompiledData::Binding::Type_Number) {
- value = binding->valueAsNumber(compilationUnit->constants);
- } else if (binding->type == QV4::CompiledData::Binding::Type_Boolean) {
- value = binding->valueAsBoolean();
- } else if (binding->type == QV4::CompiledData::Binding::Type_Null) {
- value = QVariant::fromValue(nullptr);
- } else if (binding->type == QV4::CompiledData::Binding::Type_Script) {
- QString scriptStr = binding->valueAsScriptString(compilationUnit.data());
- if (definesEmptyList(scriptStr)) {
- const ListLayout::Role &role = model->getOrCreateListRole(elementName);
- ListModel *emptyModel = new ListModel(role.subLayout, nullptr);
- value = QVariant::fromValue(emptyModel);
- } else if (binding->isFunctionExpression()) {
- QQmlBinding::Identifier id = binding->value.compiledScriptIndex;
- Q_ASSERT(id != QQmlBinding::Invalid);
-
- auto v4 = compilationUnit->engine;
- QV4::Scope scope(v4);
- // for now we do not provide a context object; data from the ListElement must be passed to the function
- QV4::ScopedContext context(scope, QV4::QmlContext::create(v4->rootContext(), QQmlContextData::get(qmlContext(model->m_modelCache)), nullptr));
- QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createScriptFunction(context, compilationUnit->runtimeFunctions[id]));
-
- QV4::ReturnedValue result = function->call(v4->globalObject, nullptr, 0);
-
- QJSValue v;
- QJSValuePrivate::setValue(&v, v4, result);
- value.setValue<QJSValue>(v);
- } else {
- QByteArray script = scriptStr.toUtf8();
- bool ok;
- value = evaluateEnum(script, &ok);
- }
- } else {
- Q_UNREACHABLE();
- }
-
- model->setOrCreateProperty(outterElementIndex, elementName, value);
- roleSet = true;
- }
- return roleSet;
-}
-
-void QQmlListModelParser::verifyBindings(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
-{
- listElementTypeName = QString(); // unknown
-
- for (const QV4::CompiledData::Binding *binding : bindings) {
- QString propName = compilationUnit->stringAt(binding->propertyNameIndex);
- if (!propName.isEmpty()) { // isn't default property
- error(binding, QQmlListModel::tr("ListModel: undefined property '%1'").arg(propName));
- return;
- }
- if (!verifyProperty(compilationUnit, binding))
- return;
- }
-}
-
-void QQmlListModelParser::applyBindings(QObject *obj, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
-{
- QQmlListModel *rv = static_cast<QQmlListModel *>(obj);
-
- rv->m_engine = qmlEngine(rv)->handle();
- rv->m_compilationUnit = compilationUnit;
-
- bool setRoles = false;
-
- for (const QV4::CompiledData::Binding *binding : bindings) {
- if (binding->type != QV4::CompiledData::Binding::Type_Object)
- continue;
- setRoles |= applyProperty(compilationUnit, binding, rv->m_listModel, /*outter element index*/-1);
- }
-
- if (setRoles == false)
- qmlWarning(obj) << "All ListElement declarations are empty, no roles can be created unless dynamicRoles is set.";
-}
-
-bool QQmlListModelParser::definesEmptyList(const QString &s)
-{
- if (s.startsWith(QLatin1Char('[')) && s.endsWith(QLatin1Char(']'))) {
- for (int i=1; i<s.length()-1; i++) {
- if (!s[i].isSpace())
- return false;
- }
- return true;
- }
- return false;
-}
-
-
-/*!
- \qmltype ListElement
- \instantiates QQmlListElement
- \inqmlmodule QtQml.Models
- \brief Defines a data item in a ListModel.
- \ingroup qtquick-models
-
- List elements are defined inside ListModel definitions, and represent items in a
- list that will be displayed using ListView or \l Repeater items.
-
- List elements are defined like other QML elements except that they contain
- a collection of \e role definitions instead of properties. Using the same
- syntax as property definitions, roles both define how the data is accessed
- and include the data itself.
-
- The names used for roles must begin with a lower-case letter and should be
- common to all elements in a given model. Values must be simple constants; either
- strings (quoted and optionally within a call to QT_TR_NOOP), boolean values
- (true, false), numbers, or enumeration values (such as AlignText.AlignHCenter).
-
- Beginning with Qt 5.11 ListElement also allows assigning a function declaration to
- a role. This allows the definition of ListElements with callable actions.
-
- \section1 Referencing Roles
-
- The role names are used by delegates to obtain data from list elements.
- Each role name is accessible in the delegate's scope, and refers to the
- corresponding role in the current element. Where a role name would be
- ambiguous to use, it can be accessed via the \l{ListView::}{model}
- property (e.g., \c{model.cost} instead of \c{cost}).
-
- \section1 Example Usage
-
- The following model defines a series of list elements, each of which
- contain "name" and "cost" roles and their associated values.
-
- \snippet qml/listmodel/listelements.qml model
-
- The delegate obtains the name and cost for each element by simply referring
- to \c name and \c cost:
-
- \snippet qml/listmodel/listelements.qml view
-
- \sa ListModel
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qqmllistmodel_p.cpp"
diff --git a/src/qml/types/qqmllistmodel_p.h b/src/qml/types/qqmllistmodel_p.h
deleted file mode 100644
index 471e33aa5a..0000000000
--- a/src/qml/types/qqmllistmodel_p.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLLISTMODEL_H
-#define QQMLLISTMODEL_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qqml.h>
-#include <private/qqmlcustomparser_p.h>
-
-#include <QtCore/QObject>
-#include <QtCore/QStringList>
-#include <QtCore/QHash>
-#include <QtCore/QList>
-#include <QtCore/QVariant>
-#include <QtCore/qabstractitemmodel.h>
-
-#include <private/qv4engine_p.h>
-#include <private/qpodvector_p.h>
-
-QT_REQUIRE_CONFIG(qml_list_model);
-
-QT_BEGIN_NAMESPACE
-
-
-class QQmlListModelWorkerAgent;
-class ListModel;
-class ListLayout;
-
-namespace QV4 {
-struct ModelObject;
-}
-
-class Q_QML_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel
-{
- Q_OBJECT
- Q_PROPERTY(int count READ count NOTIFY countChanged)
- Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles)
-
-public:
- QQmlListModel(QObject *parent=nullptr);
- ~QQmlListModel();
-
- QModelIndex index(int row, int column, const QModelIndex &parent) const override;
- int rowCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
- QHash<int,QByteArray> roleNames() const override;
-
- QVariant data(int index, int role) const;
- int count() const;
-
- Q_INVOKABLE void clear();
- Q_INVOKABLE void remove(QQmlV4Function *args);
- Q_INVOKABLE void append(QQmlV4Function *args);
- Q_INVOKABLE void insert(QQmlV4Function *args);
- Q_INVOKABLE QJSValue get(int index) const;
- Q_INVOKABLE void set(int index, const QJSValue &value);
- Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value);
- Q_INVOKABLE void move(int from, int to, int count);
- Q_INVOKABLE void sync();
-
- QQmlListModelWorkerAgent *agent();
-
- bool dynamicRoles() const { return m_dynamicRoles; }
- void setDynamicRoles(bool enableDynamicRoles);
-
-Q_SIGNALS:
- void countChanged();
-
-private:
- friend class QQmlListModelParser;
- friend class QQmlListModelWorkerAgent;
- friend class ModelObject;
- friend struct QV4::ModelObject;
- friend class ModelNodeMetaObject;
- friend class ListModel;
- friend class ListElement;
- friend class DynamicRoleModelNode;
- friend class DynamicRoleModelNodeMetaObject;
- friend struct StringOrTranslation;
-
- // Constructs a flat list model for a worker agent
- QQmlListModel(QQmlListModel *orig, QQmlListModelWorkerAgent *agent);
- QQmlListModel(const QQmlListModel *owner, ListModel *data, QV4::ExecutionEngine *engine, QObject *parent=nullptr);
-
- QV4::ExecutionEngine *engine() const;
-
- inline bool canMove(int from, int to, int n) const { return !(from+n > count() || to+n > count() || from < 0 || to < 0 || n < 0); }
-
- QQmlListModelWorkerAgent *m_agent;
- mutable QV4::ExecutionEngine *m_engine;
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> m_compilationUnit;
- bool m_mainThread;
- bool m_primary;
-
- bool m_dynamicRoles;
-
- ListLayout *m_layout;
- ListModel *m_listModel;
-
- QVector<class DynamicRoleModelNode *> m_modelObjects;
- QVector<QString> m_roles;
-
- struct ElementSync
- {
- DynamicRoleModelNode *src = nullptr;
- DynamicRoleModelNode *target = nullptr;
- int srcIndex = -1;
- int targetIndex = -1;
- QVector<int> changedRoles;
- };
-
- static bool sync(QQmlListModel *src, QQmlListModel *target);
- static QQmlListModel *createWithOwner(QQmlListModel *newOwner);
-
- void emitItemsChanged(int index, int count, const QVector<int> &roles);
- void emitItemsAboutToBeInserted(int index, int count);
- void emitItemsInserted();
-
- void removeElements(int index, int removeCount);
-};
-
-// ### FIXME
-class QQmlListElement : public QObject
-{
-Q_OBJECT
-};
-
-class QQmlListModelParser : public QQmlCustomParser
-{
-public:
- enum PropertyType {
- Invalid,
- Boolean,
- Number,
- String,
- Script
- };
-
-
- QQmlListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {}
-
- void verifyBindings(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
- void applyBindings(QObject *obj, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
-
-private:
- bool verifyProperty(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding);
- // returns true if a role was set
- bool applyProperty(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding, ListModel *model, int outterElementIndex);
-
- static bool definesEmptyList(const QString &);
-
- QString listElementTypeName;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQmlListModel)
-QML_DECLARE_TYPE(QQmlListElement)
-
-#endif // QQMLLISTMODEL_H
diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h
deleted file mode 100644
index 2876c71de6..0000000000
--- a/src/qml/types/qqmllistmodel_p_p.h
+++ /dev/null
@@ -1,428 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLLISTMODEL_P_P_H
-#define QQMLLISTMODEL_P_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qqmllistmodel_p.h"
-#include <private/qqmlengine_p.h>
-#include <private/qqmlopenmetaobject_p.h>
-#include <private/qv4qobjectwrapper_p.h>
-#include <qqml.h>
-
-QT_REQUIRE_CONFIG(qml_list_model);
-
-QT_BEGIN_NAMESPACE
-
-
-class DynamicRoleModelNode;
-
-class DynamicRoleModelNodeMetaObject : public QQmlOpenMetaObject
-{
-public:
- DynamicRoleModelNodeMetaObject(DynamicRoleModelNode *object);
- ~DynamicRoleModelNodeMetaObject();
-
- bool m_enabled;
-
-protected:
- void propertyWrite(int index) override;
- void propertyWritten(int index) override;
-
-private:
- DynamicRoleModelNode *m_owner;
-};
-
-class DynamicRoleModelNode : public QObject
-{
- Q_OBJECT
-public:
- DynamicRoleModelNode(QQmlListModel *owner, int uid);
-
- static DynamicRoleModelNode *create(const QVariantMap &obj, QQmlListModel *owner);
-
- void updateValues(const QVariantMap &object, QVector<int> &roles);
-
- QVariant getValue(const QString &name) const
- {
- return m_meta->value(name.toUtf8());
- }
-
- bool setValue(const QByteArray &name, const QVariant &val)
- {
- return m_meta->setValue(name, val);
- }
-
- void setNodeUpdatesEnabled(bool enable)
- {
- m_meta->m_enabled = enable;
- }
-
- int getUid() const
- {
- return m_uid;
- }
-
- static QVector<int> sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target);
-
-private:
- QQmlListModel *m_owner;
- int m_uid;
- DynamicRoleModelNodeMetaObject *m_meta;
-
- friend class DynamicRoleModelNodeMetaObject;
-};
-
-class ModelNodeMetaObject : public QQmlOpenMetaObject
-{
-public:
- ModelNodeMetaObject(QObject *object, QQmlListModel *model, int elementIndex);
- ~ModelNodeMetaObject();
-
- QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *object) override;
-
- static ModelNodeMetaObject *get(QObject *obj);
-
- bool m_enabled;
- QQmlListModel *m_model;
- int m_elementIndex;
-
- void updateValues();
- void updateValues(const QVector<int> &roles);
-
- bool initialized() const { return m_initialized; }
-
-protected:
- void propertyWritten(int index) override;
-
-private:
- using QQmlOpenMetaObject::setValue;
-
- void emitDirectNotifies(const int *changedRoles, int roleCount);
-
- void initialize();
- bool m_initialized;
-};
-
-namespace QV4 {
-
-namespace Heap {
-
-struct ModelObject : public QObjectWrapper {
- void init(QObject *object, QQmlListModel *model)
- {
- QObjectWrapper::init(object);
- m_model = model;
- QObjectPrivate *op = QObjectPrivate::get(object);
- m_nodeModelMetaObject = static_cast<ModelNodeMetaObject *>(op->metaObject);
- }
- void destroy() { QObjectWrapper::destroy(); }
- int elementIndex() const { return m_nodeModelMetaObject->m_elementIndex; }
- QQmlListModel *m_model;
- ModelNodeMetaObject *m_nodeModelMetaObject;
-};
-
-}
-
-struct ModelObject : public QObjectWrapper
-{
- V4_OBJECT2(ModelObject, QObjectWrapper)
- V4_NEEDS_DESTROY
-
- ListModel *listModel() const { return d()->m_model->m_listModel; }
-
-protected:
- static bool virtualPut(Managed *m, PropertyKey id, const Value& value, Value *receiver);
- static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
- static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup);
- static ReturnedValue lookupGetter(Lookup *l, ExecutionEngine *engine, const Value &object);
- static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
-};
-
-} // namespace QV4
-
-class ListLayout
-{
-public:
- ListLayout() : currentBlock(0), currentBlockOffset(0) {}
- ListLayout(const ListLayout *other);
- ~ListLayout();
-
- class Role
- {
- public:
-
- Role() : type(Invalid), blockIndex(-1), blockOffset(-1), index(-1), subLayout(0) {}
- explicit Role(const Role *other);
- ~Role();
-
- // This enum must be kept in sync with the roleTypeNames variable in qqmllistmodel.cpp
- enum DataType
- {
- Invalid = -1,
-
- String,
- Number,
- Bool,
- List,
- QObject,
- VariantMap,
- DateTime,
- Function,
-
- MaxDataType
- };
-
- QString name;
- DataType type;
- int blockIndex;
- int blockOffset;
- int index;
- ListLayout *subLayout;
- };
-
- const Role *getRoleOrCreate(const QString &key, const QVariant &data);
- const Role &getRoleOrCreate(QV4::String *key, Role::DataType type);
- const Role &getRoleOrCreate(const QString &key, Role::DataType type);
-
- const Role &getExistingRole(int index) const { return *roles.at(index); }
- const Role *getExistingRole(const QString &key) const;
- const Role *getExistingRole(QV4::String *key) const;
-
- int roleCount() const { return roles.count(); }
-
- static void sync(ListLayout *src, ListLayout *target);
-
-private:
- const Role &createRole(const QString &key, Role::DataType type);
-
- int currentBlock;
- int currentBlockOffset;
- QVector<Role *> roles;
- QStringHash<Role *> roleHash;
-};
-
-struct StringOrTranslation
-{
- explicit StringOrTranslation(const QString &s);
- explicit StringOrTranslation(const QV4::CompiledData::Binding *binding);
- ~StringOrTranslation();
- bool isSet() const { return d.flag(); }
- bool isTranslation() const { return d.isT2(); }
- void setString(const QString &s);
- void setTranslation(const QV4::CompiledData::Binding *binding);
- QString toString(const QQmlListModel *owner) const;
- QString asString() const;
-private:
- void clear();
- QBiPointer<QStringData, const QV4::CompiledData::Binding> d;
-};
-
-/*!
-\internal
-*/
-class ListElement
-{
-public:
-
- ListElement();
- ListElement(int existingUid);
- ~ListElement();
-
- static QVector<int> sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout);
-
- enum
- {
- BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelNodeMetaObject *)
- };
-
-private:
-
- void destroy(ListLayout *layout);
-
- int setVariantProperty(const ListLayout::Role &role, const QVariant &d);
-
- int setJsProperty(const ListLayout::Role &role, const QV4::Value &d, QV4::ExecutionEngine *eng);
-
- int setStringProperty(const ListLayout::Role &role, const QString &s);
- int setDoubleProperty(const ListLayout::Role &role, double n);
- int setBoolProperty(const ListLayout::Role &role, bool b);
- int setListProperty(const ListLayout::Role &role, ListModel *m);
- int setQObjectProperty(const ListLayout::Role &role, QObject *o);
- int setVariantMapProperty(const ListLayout::Role &role, QV4::Object *o);
- int setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m);
- int setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt);
- int setFunctionProperty(const ListLayout::Role &role, const QJSValue &f);
- int setTranslationProperty(const ListLayout::Role &role, const QV4::CompiledData::Binding *b);
-
- void setStringPropertyFast(const ListLayout::Role &role, const QString &s);
- void setDoublePropertyFast(const ListLayout::Role &role, double n);
- void setBoolPropertyFast(const ListLayout::Role &role, bool b);
- void setQObjectPropertyFast(const ListLayout::Role &role, QObject *o);
- void setListPropertyFast(const ListLayout::Role &role, ListModel *m);
- void setVariantMapFast(const ListLayout::Role &role, QV4::Object *o);
- void setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt);
- void setFunctionPropertyFast(const ListLayout::Role &role, const QJSValue &f);
-
- void clearProperty(const ListLayout::Role &role);
-
- QVariant getProperty(const ListLayout::Role &role, const QQmlListModel *owner, QV4::ExecutionEngine *eng);
- ListModel *getListProperty(const ListLayout::Role &role);
- StringOrTranslation *getStringProperty(const ListLayout::Role &role);
- QObject *getQObjectProperty(const ListLayout::Role &role);
- QPointer<QObject> *getGuardProperty(const ListLayout::Role &role);
- QVariantMap *getVariantMapProperty(const ListLayout::Role &role);
- QDateTime *getDateTimeProperty(const ListLayout::Role &role);
- QJSValue *getFunctionProperty(const ListLayout::Role &role);
-
- inline char *getPropertyMemory(const ListLayout::Role &role);
-
- int getUid() const { return uid; }
-
- ModelNodeMetaObject *objectCache();
-
- char data[BLOCK_SIZE];
- ListElement *next;
-
- int uid;
- QObject *m_objectCache;
-
- friend class ListModel;
-};
-
-/*!
-\internal
-*/
-class ListModel
-{
-public:
-
- ListModel(ListLayout *layout, QQmlListModel *modelCache);
- ~ListModel() {}
-
- void destroy();
-
- int setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data);
- int setExistingProperty(int uid, const QString &key, const QV4::Value &data, QV4::ExecutionEngine *eng);
-
- QVariant getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV4::ExecutionEngine *eng);
- ListModel *getListProperty(int elementIndex, const ListLayout::Role &role);
-
- int roleCount() const
- {
- return m_layout->roleCount();
- }
-
- const ListLayout::Role &getExistingRole(int index) const
- {
- return m_layout->getExistingRole(index);
- }
-
- const ListLayout::Role *getExistingRole(QV4::String *key) const
- {
- return m_layout->getExistingRole(key);
- }
-
- const ListLayout::Role &getOrCreateListRole(const QString &name)
- {
- return m_layout->getRoleOrCreate(name, ListLayout::Role::List);
- }
-
- int elementCount() const
- {
- return elements.count();
- }
-
- void set(int elementIndex, QV4::Object *object, QVector<int> *roles);
- void set(int elementIndex, QV4::Object *object);
-
- int append(QV4::Object *object);
- void insert(int elementIndex, QV4::Object *object);
-
- Q_REQUIRED_RESULT QVector<std::function<void()>> remove(int index, int count);
-
- int appendElement();
- void insertElement(int index);
-
- void move(int from, int to, int n);
-
- static bool sync(ListModel *src, ListModel *target);
-
- QObject *getOrCreateModelObject(QQmlListModel *model, int elementIndex);
-
-private:
- QPODVector<ListElement *, 4> elements;
- ListLayout *m_layout;
-
- QQmlListModel *m_modelCache;
-
- struct ElementSync
- {
- ListElement *src = nullptr;
- ListElement *target = nullptr;
- int srcIndex = -1;
- int targetIndex = -1;
- QVector<int> changedRoles;
- };
-
- void newElement(int index);
-
- void updateCacheIndices(int start = 0, int end = -1);
-
- friend class ListElement;
- friend class QQmlListModelWorkerAgent;
- friend class QQmlListModelParser;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(ListModel *);
-
-#endif // QQUICKLISTMODEL_P_P_H
diff --git a/src/qml/types/qqmllistmodelworkeragent.cpp b/src/qml/types/qqmllistmodelworkeragent.cpp
deleted file mode 100644
index f7cb08dcf4..0000000000
--- a/src/qml/types/qqmllistmodelworkeragent.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmllistmodelworkeragent_p.h"
-#include "qqmllistmodel_p_p.h"
-#include <private/qqmldata_p.h>
-#include <private/qqmlengine_p.h>
-#include <qqmlinfo.h>
-
-#include <QtCore/qcoreevent.h>
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qdebug.h>
-
-
-QT_BEGIN_NAMESPACE
-
-QQmlListModelWorkerAgent::Sync::~Sync()
-{
-}
-
-QQmlListModelWorkerAgent::QQmlListModelWorkerAgent(QQmlListModel *model)
-: m_ref(1), m_orig(model), m_copy(new QQmlListModel(model, this))
-{
-}
-
-QQmlListModelWorkerAgent::~QQmlListModelWorkerAgent()
-{
- mutex.lock();
- syncDone.wakeAll();
- mutex.unlock();
-}
-
-void QQmlListModelWorkerAgent::setEngine(QV4::ExecutionEngine *eng)
-{
- m_copy->m_engine = eng;
-}
-
-void QQmlListModelWorkerAgent::addref()
-{
- m_ref.ref();
-}
-
-void QQmlListModelWorkerAgent::release()
-{
- bool del = !m_ref.deref();
-
- if (del)
- deleteLater();
-}
-
-void QQmlListModelWorkerAgent::modelDestroyed()
-{
- m_orig = nullptr;
-}
-
-int QQmlListModelWorkerAgent::count() const
-{
- return m_copy->count();
-}
-
-void QQmlListModelWorkerAgent::clear()
-{
- m_copy->clear();
-}
-
-void QQmlListModelWorkerAgent::remove(QQmlV4Function *args)
-{
- m_copy->remove(args);
-}
-
-void QQmlListModelWorkerAgent::append(QQmlV4Function *args)
-{
- m_copy->append(args);
-}
-
-void QQmlListModelWorkerAgent::insert(QQmlV4Function *args)
-{
- m_copy->insert(args);
-}
-
-QJSValue QQmlListModelWorkerAgent::get(int index) const
-{
- return m_copy->get(index);
-}
-
-void QQmlListModelWorkerAgent::set(int index, const QJSValue &value)
-{
- m_copy->set(index, value);
-}
-
-void QQmlListModelWorkerAgent::setProperty(int index, const QString& property, const QVariant& value)
-{
- m_copy->setProperty(index, property, value);
-}
-
-void QQmlListModelWorkerAgent::move(int from, int to, int count)
-{
- m_copy->move(from, to, count);
-}
-
-void QQmlListModelWorkerAgent::sync()
-{
- Sync *s = new Sync(m_copy);
-
- mutex.lock();
- QCoreApplication::postEvent(this, s);
- syncDone.wait(&mutex);
- mutex.unlock();
-}
-
-bool QQmlListModelWorkerAgent::event(QEvent *e)
-{
- if (e->type() == QEvent::User) {
- bool cc = false;
- QMutexLocker locker(&mutex);
- if (m_orig) {
- Sync *s = static_cast<Sync *>(e);
-
- cc = (m_orig->count() != s->list->count());
-
- Q_ASSERT(m_orig->m_dynamicRoles == s->list->m_dynamicRoles);
- if (m_orig->m_dynamicRoles)
- QQmlListModel::sync(s->list, m_orig);
- else
- ListModel::sync(s->list->m_listModel, m_orig->m_listModel);
- }
-
- syncDone.wakeAll();
- locker.unlock();
-
- if (cc)
- emit m_orig->countChanged();
- return true;
- }
-
- return QObject::event(e);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qqmllistmodelworkeragent_p.cpp"
diff --git a/src/qml/types/qqmllistmodelworkeragent_p.h b/src/qml/types/qqmllistmodelworkeragent_p.h
deleted file mode 100644
index 69d1785618..0000000000
--- a/src/qml/types/qqmllistmodelworkeragent_p.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKLISTMODELWORKERAGENT_P_H
-#define QQUICKLISTMODELWORKERAGENT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qqml.h>
-
-#include <QEvent>
-#include <QMutex>
-#include <QWaitCondition>
-
-#include <private/qv8engine_p.h>
-
-QT_REQUIRE_CONFIG(qml_list_model);
-
-QT_BEGIN_NAMESPACE
-
-
-class QQmlListModel;
-
-class QQmlListModelWorkerAgent : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(int count READ count)
-
-public:
- QQmlListModelWorkerAgent(QQmlListModel *);
- ~QQmlListModelWorkerAgent();
- void setEngine(QV4::ExecutionEngine *eng);
-
- void addref();
- void release();
-
- int count() const;
-
- Q_INVOKABLE void clear();
- Q_INVOKABLE void remove(QQmlV4Function *args);
- Q_INVOKABLE void append(QQmlV4Function *args);
- Q_INVOKABLE void insert(QQmlV4Function *args);
- Q_INVOKABLE QJSValue get(int index) const;
- Q_INVOKABLE void set(int index, const QJSValue &value);
- Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value);
- Q_INVOKABLE void move(int from, int to, int count);
- Q_INVOKABLE void sync();
-
- struct VariantRef
- {
- VariantRef() : a(nullptr) {}
- VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); }
- VariantRef(QQmlListModelWorkerAgent *_a) : a(_a) { if (a) a->addref(); }
- ~VariantRef() { if (a) a->release(); }
-
- VariantRef &operator=(const VariantRef &o) {
- if (o.a) o.a->addref();
- if (a) a->release();
- a = o.a;
- return *this;
- }
-
- QQmlListModelWorkerAgent *a;
- };
-
- void modelDestroyed();
-protected:
- bool event(QEvent *) override;
-
-private:
- friend class QQuickWorkerScriptEnginePrivate;
- friend class QQmlListModel;
-
- struct Sync : public QEvent {
- Sync(QQmlListModel *l)
- : QEvent(QEvent::User)
- , list(l)
- {}
- ~Sync();
- QQmlListModel *list;
- };
-
- QAtomicInt m_ref;
- QQmlListModel *m_orig;
- QQmlListModel *m_copy;
- QMutex mutex;
- QWaitCondition syncDone;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QQmlListModelWorkerAgent::VariantRef)
-
-#endif // QQUICKLISTMODELWORKERAGENT_P_H
-
diff --git a/src/qml/types/qqmlmodelsmodule.cpp b/src/qml/types/qqmlmodelsmodule.cpp
deleted file mode 100644
index 840b435d18..0000000000
--- a/src/qml/types/qqmlmodelsmodule.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Research In Motion.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmlmodelsmodule_p.h"
-#include <QtCore/qitemselectionmodel.h>
-#if QT_CONFIG(qml_list_model)
-#include <private/qqmllistmodel_p.h>
-#endif
-#if QT_CONFIG(qml_delegate_model)
-#include <private/qqmldelegatemodel_p.h>
-#include <private/qqmldelegatecomponent_p.h>
-#endif
-#include <private/qqmlobjectmodel_p.h>
-#include <private/qqmltablemodel_p.h>
-#include <private/qqmltablemodelcolumn_p.h>
-#include <private/qqmlinstantiator_p.h>
-#include <private/qquickpackage_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-
-void QQmlModelsModule::registerQmlTypes()
-{
- // Don't add anything here. These are only for backwards compatibility.
- qmlRegisterType<QQmlInstantiator>("QtQml", 2, 1, "Instantiator"); // Only available in >= 2.1
- qmlRegisterType<QQmlInstanceModel>();
-}
-
-void QQmlModelsModule::registerQuickTypes()
-{
- // Don't add anything here. These are only for backwards compatibility.
-
- const char uri[] = "QtQuick";
-
- qmlRegisterType<QQmlInstantiator>(uri, 2, 1, "Instantiator");
- qmlRegisterType<QQmlInstanceModel>();
-#if QT_CONFIG(qml_list_model)
- qmlRegisterType<QQmlListElement>(uri, 2, 0, "ListElement");
- qmlRegisterCustomType<QQmlListModel>(uri, 2, 0, "ListModel", new QQmlListModelParser);
-#endif
- qmlRegisterType<QQuickPackage>(uri, 2, 0, "Package");
-#if QT_CONFIG(qml_delegate_model)
- qmlRegisterType<QQmlDelegateModel>(uri, 2, 0, "VisualDataModel");
- qmlRegisterType<QQmlDelegateModelGroup>(uri, 2, 0, "VisualDataGroup");
-#endif
- qmlRegisterType<QQmlObjectModel>(uri, 2, 0, "VisualItemModel");
-}
-
-#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-
-void QQmlModelsModule::defineModule()
-{
- const char uri[] = "QtQml.Models";
-
-#if QT_CONFIG(qml_list_model)
- qmlRegisterType<QQmlListElement>(uri, 2, 1, "ListElement");
- qmlRegisterCustomType<QQmlListModel>(uri, 2, 1, "ListModel", new QQmlListModelParser);
-#endif
-#if QT_CONFIG(qml_delegate_model)
- qmlRegisterType<QQmlDelegateModel>(uri, 2, 1, "DelegateModel");
- qmlRegisterType<QQmlDelegateModelGroup>(uri, 2, 1, "DelegateModelGroup");
-#endif
- qmlRegisterType<QQmlObjectModel>(uri, 2, 1, "ObjectModel");
- qmlRegisterType<QQmlObjectModel,3>(uri, 2, 3, "ObjectModel");
-
- qmlRegisterType<QItemSelectionModel>(uri, 2, 2, "ItemSelectionModel");
-
- qmlRegisterType<QQuickPackage>(uri, 2, 14, "Package");
- qmlRegisterType<QQmlInstantiator>(uri, 2, 14, "Instantiator");
- qmlRegisterType<QQmlInstanceModel>();
-}
-
-void QQmlModelsModule::defineLabsModule()
-{
- const char uri[] = "Qt.labs.qmlmodels";
-
-#if QT_CONFIG(qml_delegate_model)
- qmlRegisterUncreatableType<QQmlAbstractDelegateComponent>(uri, 1, 0, "AbstractDelegateComponent", QQmlAbstractDelegateComponent::tr("Cannot create instance of abstract class AbstractDelegateComponent."));
- qmlRegisterType<QQmlDelegateChooser>(uri, 1, 0, "DelegateChooser");
- qmlRegisterType<QQmlDelegateChoice>(uri, 1, 0, "DelegateChoice");
-#endif
- qmlRegisterType<QQmlTableModel>(uri, 1, 0, "TableModel");
- qmlRegisterType<QQmlTableModelColumn>(uri, 1, 0, "TableModelColumn");
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/types/qqmlmodelsmodule_p.h b/src/qml/types/qqmlmodelsmodule_p.h
deleted file mode 100644
index 2bb04f1e11..0000000000
--- a/src/qml/types/qqmlmodelsmodule_p.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Research In Motion.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLMODELSMODULE_H
-#define QQMLMODELSMODULE_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtqmlglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_QML_PRIVATE_EXPORT QQmlModelsModule
-{
-public:
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- static void registerQmlTypes();
- static void registerQuickTypes();
-#endif
-
- static void defineModule();
- static void defineLabsModule();
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp
deleted file mode 100644
index b6330b4295..0000000000
--- a/src/qml/types/qqmlobjectmodel.cpp
+++ /dev/null
@@ -1,431 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmlobjectmodel_p.h"
-
-#include <QtCore/qcoreapplication.h>
-#include <QtQml/qqmlcontext.h>
-#include <QtQml/qqmlengine.h>
-#include <QtQml/qqmlinfo.h>
-
-#include <private/qqmlchangeset_p.h>
-#include <private/qqmlglobal_p.h>
-#include <private/qobject_p.h>
-#include <private/qpodvector_p.h>
-
-#include <QtCore/qhash.h>
-#include <QtCore/qlist.h>
-
-QT_BEGIN_NAMESPACE
-
-QHash<QObject*, QQmlObjectModelAttached*> QQmlObjectModelAttached::attachedProperties;
-
-
-class QQmlObjectModelPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQmlObjectModel)
-public:
- class Item {
- public:
- Item(QObject *i) : item(i), ref(0) {}
-
- void addRef() { ++ref; }
- bool deref() { return --ref == 0; }
-
- QObject *item;
- int ref;
- };
-
- QQmlObjectModelPrivate() : QObjectPrivate(), moveId(0) {}
-
- static void children_append(QQmlListProperty<QObject> *prop, QObject *item) {
- int index = static_cast<QQmlObjectModelPrivate *>(prop->data)->children.count();
- static_cast<QQmlObjectModelPrivate *>(prop->data)->insert(index, item);
- }
-
- static int children_count(QQmlListProperty<QObject> *prop) {
- return static_cast<QQmlObjectModelPrivate *>(prop->data)->children.count();
- }
-
- static QObject *children_at(QQmlListProperty<QObject> *prop, int index) {
- return static_cast<QQmlObjectModelPrivate *>(prop->data)->children.at(index).item;
- }
-
- static void children_clear(QQmlListProperty<QObject> *prop) {
- static_cast<QQmlObjectModelPrivate *>(prop->data)->clear();
- }
-
- void insert(int index, QObject *item) {
- Q_Q(QQmlObjectModel);
- children.insert(index, Item(item));
- for (int i = index; i < children.count(); ++i) {
- QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(i).item);
- attached->setIndex(i);
- }
- QQmlChangeSet changeSet;
- changeSet.insert(index, 1);
- emit q->modelUpdated(changeSet, false);
- emit q->countChanged();
- emit q->childrenChanged();
- }
-
- void move(int from, int to, int n) {
- Q_Q(QQmlObjectModel);
- if (from > to) {
- // Only move forwards - flip if backwards moving
- int tfrom = from;
- int tto = to;
- from = tto;
- to = tto+n;
- n = tfrom-tto;
- }
-
- QPODVector<QQmlObjectModelPrivate::Item, 4> store;
- for (int i = 0; i < to - from; ++i)
- store.append(children[from + n + i]);
- for (int i = 0; i < n; ++i)
- store.append(children[from + i]);
-
- for (int i = 0; i < store.count(); ++i) {
- children[from + i] = store[i];
- QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(from + i).item);
- attached->setIndex(from + i);
- }
-
- QQmlChangeSet changeSet;
- changeSet.move(from, to, n, ++moveId);
- emit q->modelUpdated(changeSet, false);
- emit q->childrenChanged();
- }
-
- void remove(int index, int n) {
- Q_Q(QQmlObjectModel);
- for (int i = index; i < index + n; ++i) {
- QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(i).item);
- attached->setIndex(-1);
- }
- children.erase(children.begin() + index, children.begin() + index + n);
- for (int i = index; i < children.count(); ++i) {
- QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(i).item);
- attached->setIndex(i);
- }
- QQmlChangeSet changeSet;
- changeSet.remove(index, n);
- emit q->modelUpdated(changeSet, false);
- emit q->countChanged();
- emit q->childrenChanged();
- }
-
- void clear() {
- Q_Q(QQmlObjectModel);
- for (const Item &child : qAsConst(children))
- emit q->destroyingItem(child.item);
- remove(0, children.count());
- }
-
- int indexOf(QObject *item) const {
- for (int i = 0; i < children.count(); ++i)
- if (children.at(i).item == item)
- return i;
- return -1;
- }
-
- uint moveId;
- QList<Item> children;
-};
-
-
-/*!
- \qmltype ObjectModel
- \instantiates QQmlObjectModel
- \inqmlmodule QtQml.Models
- \ingroup qtquick-models
- \brief Defines a set of items to be used as a model.
-
- An ObjectModel contains the visual items to be used in a view.
- When an ObjectModel is used in a view, the view does not require
- a delegate since the ObjectModel already contains the visual
- delegate (items).
-
- An item can determine its index within the
- model via the \l{ObjectModel::index}{index} attached property.
-
- The example below places three colored rectangles in a ListView.
- \code
- import QtQuick 2.0
- import QtQml.Models 2.1
-
- Rectangle {
- ObjectModel {
- id: itemModel
- Rectangle { height: 30; width: 80; color: "red" }
- Rectangle { height: 30; width: 80; color: "green" }
- Rectangle { height: 30; width: 80; color: "blue" }
- }
-
- ListView {
- anchors.fill: parent
- model: itemModel
- }
- }
- \endcode
-
- \image objectmodel.png
-
- \sa {Qt Quick Examples - Views}
-*/
-
-QQmlObjectModel::QQmlObjectModel(QObject *parent)
- : QQmlInstanceModel(*(new QQmlObjectModelPrivate), parent)
-{
-}
-
-/*!
- \qmlattachedproperty int QtQml.Models::ObjectModel::index
- This attached property holds the index of this delegate's item within the model.
-
- It is attached to each instance of the delegate.
-*/
-
-QQmlListProperty<QObject> QQmlObjectModel::children()
-{
- Q_D(QQmlObjectModel);
- return QQmlListProperty<QObject>(this,
- d,
- d->children_append,
- d->children_count,
- d->children_at,
- d->children_clear);
-}
-
-/*!
- \qmlproperty int QtQml.Models::ObjectModel::count
-
- The number of items in the model. This property is readonly.
-*/
-int QQmlObjectModel::count() const
-{
- Q_D(const QQmlObjectModel);
- return d->children.count();
-}
-
-bool QQmlObjectModel::isValid() const
-{
- return true;
-}
-
-QObject *QQmlObjectModel::object(int index, QQmlIncubator::IncubationMode)
-{
- Q_D(QQmlObjectModel);
- QQmlObjectModelPrivate::Item &item = d->children[index];
- item.addRef();
- if (item.ref == 1) {
- emit initItem(index, item.item);
- emit createdItem(index, item.item);
- }
- return item.item;
-}
-
-QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item)
-{
- Q_D(QQmlObjectModel);
- int idx = d->indexOf(item);
- if (idx >= 0) {
- if (!d->children[idx].deref())
- return QQmlInstanceModel::Referenced;
- }
- return nullptr;
-}
-
-QVariant QQmlObjectModel::variantValue(int index, const QString &role)
-{
- Q_D(QQmlObjectModel);
- if (index < 0 || index >= d->children.count())
- return QString();
- return QQmlEngine::contextForObject(d->children.at(index).item)->contextProperty(role);
-}
-
-QQmlIncubator::Status QQmlObjectModel::incubationStatus(int)
-{
- return QQmlIncubator::Ready;
-}
-
-int QQmlObjectModel::indexOf(QObject *item, QObject *) const
-{
- Q_D(const QQmlObjectModel);
- return d->indexOf(item);
-}
-
-QQmlObjectModelAttached *QQmlObjectModel::qmlAttachedProperties(QObject *obj)
-{
- return QQmlObjectModelAttached::properties(obj);
-}
-
-/*!
- \qmlmethod object QtQml.Models::ObjectModel::get(int index)
- \since 5.6
-
- Returns the item at \a index in the model. This allows the item
- to be accessed or modified from JavaScript:
-
- \code
- Component.onCompleted: {
- objectModel.append(objectComponent.createObject())
- console.log(objectModel.get(0).objectName);
- objectModel.get(0).objectName = "first";
- }
- \endcode
-
- The \a index must be an element in the list.
-
- \sa append()
-*/
-QObject *QQmlObjectModel::get(int index) const
-{
- Q_D(const QQmlObjectModel);
- if (index < 0 || index >= d->children.count())
- return nullptr;
- return d->children.at(index).item;
-}
-
-/*!
- \qmlmethod QtQml.Models::ObjectModel::append(object item)
- \since 5.6
-
- Appends a new item to the end of the model.
-
- \code
- objectModel.append(objectComponent.createObject())
- \endcode
-
- \sa insert(), remove()
-*/
-void QQmlObjectModel::append(QObject *object)
-{
- Q_D(QQmlObjectModel);
- d->insert(count(), object);
-}
-
-/*!
- \qmlmethod QtQml.Models::ObjectModel::insert(int index, object item)
- \since 5.6
-
- Inserts a new item to the model at position \a index.
-
- \code
- objectModel.insert(2, objectComponent.createObject())
- \endcode
-
- The \a index must be to an existing item in the list, or one past
- the end of the list (equivalent to append).
-
- \sa append(), remove()
-*/
-void QQmlObjectModel::insert(int index, QObject *object)
-{
- Q_D(QQmlObjectModel);
- if (index < 0 || index > count()) {
- qmlWarning(this) << tr("insert: index %1 out of range").arg(index);
- return;
- }
- d->insert(index, object);
-}
-
-/*!
- \qmlmethod QtQml.Models::ObjectModel::move(int from, int to, int n = 1)
- \since 5.6
-
- Moves \a n items \a from one position \a to another.
-
- The from and to ranges must exist; for example, to move the first 3 items
- to the end of the model:
-
- \code
- objectModel.move(0, objectModel.count - 3, 3)
- \endcode
-
- \sa append()
-*/
-void QQmlObjectModel::move(int from, int to, int n)
-{
- Q_D(QQmlObjectModel);
- if (n <= 0 || from == to)
- return;
- if (from < 0 || to < 0 || from + n > count() || to + n > count()) {
- qmlWarning(this) << tr("move: out of range");
- return;
- }
- d->move(from, to, n);
-}
-
-/*!
- \qmlmethod QtQml.Models::ObjectModel::remove(int index, int n = 1)
- \since 5.6
-
- Removes the items at \a index from the model.
-
- \sa clear()
-*/
-void QQmlObjectModel::remove(int index, int n)
-{
- Q_D(QQmlObjectModel);
- if (index < 0 || n <= 0 || index + n > count()) {
- qmlWarning(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+n).arg(count());
- return;
- }
- d->remove(index, n);
-}
-
-/*!
- \qmlmethod QtQml.Models::ObjectModel::clear()
- \since 5.6
-
- Clears all items from the model.
-
- \sa append(), remove()
-*/
-void QQmlObjectModel::clear()
-{
- Q_D(QQmlObjectModel);
- d->clear();
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qqmlobjectmodel_p.cpp"
diff --git a/src/qml/types/qqmlobjectmodel_p.h b/src/qml/types/qqmlobjectmodel_p.h
deleted file mode 100644
index 1284ba1780..0000000000
--- a/src/qml/types/qqmlobjectmodel_p.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLINSTANCEMODEL_P_H
-#define QQMLINSTANCEMODEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtqmlglobal_p.h>
-#include <private/qqmlincubator_p.h>
-#include <QtQml/qqml.h>
-#include <QtCore/qobject.h>
-
-QT_BEGIN_NAMESPACE
-
-class QObject;
-class QQmlChangeSet;
-class QAbstractItemModel;
-
-class Q_QML_PRIVATE_EXPORT QQmlInstanceModel : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(int count READ count NOTIFY countChanged)
-
-public:
- virtual ~QQmlInstanceModel() {}
-
- enum ReleaseFlag { Referenced = 0x01, Destroyed = 0x02 };
- Q_DECLARE_FLAGS(ReleaseFlags, ReleaseFlag)
-
- virtual int count() const = 0;
- virtual bool isValid() const = 0;
- virtual QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) = 0;
- virtual ReleaseFlags release(QObject *object) = 0;
- virtual void cancel(int) {}
- QString stringValue(int index, const QString &role) { return variantValue(index, role).toString(); }
- virtual QVariant variantValue(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;
- virtual const QAbstractItemModel *abstractItemModel() const { return nullptr; }
-
-Q_SIGNALS:
- void countChanged();
- void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
- void createdItem(int index, QObject *object);
- void initItem(int index, QObject *object);
- void destroyingItem(QObject *object);
-
-protected:
- QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = nullptr)
- : QObject(dd, parent) {}
-
-private:
- Q_DISABLE_COPY(QQmlInstanceModel)
-};
-
-class QQmlObjectModelAttached;
-class QQmlObjectModelPrivate;
-class Q_QML_PRIVATE_EXPORT QQmlObjectModel : public QQmlInstanceModel
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QQmlObjectModel)
-
- Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged DESIGNABLE false)
- Q_CLASSINFO("DefaultProperty", "children")
-
-public:
- QQmlObjectModel(QObject *parent=nullptr);
- ~QQmlObjectModel() {}
-
- int count() const override;
- bool isValid() const override;
- QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
- ReleaseFlags release(QObject *object) override;
- QVariant variantValue(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;
-
- QQmlListProperty<QObject> children();
-
- static QQmlObjectModelAttached *qmlAttachedProperties(QObject *obj);
-
- Q_REVISION(3) Q_INVOKABLE QObject *get(int index) const;
- Q_REVISION(3) Q_INVOKABLE void append(QObject *object);
- Q_REVISION(3) Q_INVOKABLE void insert(int index, QObject *object);
- Q_REVISION(3) Q_INVOKABLE void move(int from, int to, int n = 1);
- Q_REVISION(3) Q_INVOKABLE void remove(int index, int n = 1);
-
-public Q_SLOTS:
- Q_REVISION(3) void clear();
-
-Q_SIGNALS:
- void childrenChanged();
-
-private:
- Q_DISABLE_COPY(QQmlObjectModel)
-};
-
-class QQmlObjectModelAttached : public QObject
-{
- Q_OBJECT
-
-public:
- QQmlObjectModelAttached(QObject *parent)
- : QObject(parent), m_index(-1) {}
- ~QQmlObjectModelAttached() {
- attachedProperties.remove(parent());
- }
-
- Q_PROPERTY(int index READ index NOTIFY indexChanged)
- int index() const { return m_index; }
- void setIndex(int idx) {
- if (m_index != idx) {
- m_index = idx;
- Q_EMIT indexChanged();
- }
- }
-
- static QQmlObjectModelAttached *properties(QObject *obj) {
- QQmlObjectModelAttached *rv = attachedProperties.value(obj);
- if (!rv) {
- rv = new QQmlObjectModelAttached(obj);
- attachedProperties.insert(obj, rv);
- }
- return rv;
- }
-
-Q_SIGNALS:
- void indexChanged();
-
-public:
- int m_index;
-
- static QHash<QObject*, QQmlObjectModelAttached*> attachedProperties;
-};
-
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQmlInstanceModel)
-QML_DECLARE_TYPE(QQmlObjectModel)
-QML_DECLARE_TYPEINFO(QQmlObjectModel, QML_HAS_ATTACHED_PROPERTIES)
-
-#endif // QQMLINSTANCEMODEL_P_H
diff --git a/src/qml/types/qqmltableinstancemodel.cpp b/src/qml/types/qqmltableinstancemodel.cpp
deleted file mode 100644
index 2170e2daec..0000000000
--- a/src/qml/types/qqmltableinstancemodel.cpp
+++ /dev/null
@@ -1,547 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmltableinstancemodel_p.h"
-#include "qqmldelegatecomponent_p.h"
-
-#include <QtCore/QTimer>
-
-#include <QtQml/private/qqmlincubator_p.h>
-#include <QtQml/private/qqmlchangeset_p.h>
-#include <QtQml/private/qqmlcomponent_p.h>
-
-QT_BEGIN_NAMESPACE
-
-const char* kModelItemTag = "_tableinstancemodel_modelItem";
-
-bool QQmlTableInstanceModel::isDoneIncubating(QQmlDelegateModelItem *modelItem)
-{
- if (!modelItem->incubationTask)
- return true;
-
- const auto status = modelItem->incubationTask->status();
- return (status == QQmlIncubator::Ready) || (status == QQmlIncubator::Error);
-}
-
-void QQmlTableInstanceModel::deleteModelItemLater(QQmlDelegateModelItem *modelItem)
-{
- Q_ASSERT(modelItem);
-
- delete modelItem->object;
- modelItem->object = nullptr;
-
- if (modelItem->contextData) {
- modelItem->contextData->invalidate();
- Q_ASSERT(modelItem->contextData->refCount == 1);
- modelItem->contextData = nullptr;
- }
-
- modelItem->deleteLater();
-}
-
-QQmlTableInstanceModel::QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent)
- : QQmlInstanceModel(*(new QObjectPrivate()), parent)
- , m_qmlContext(qmlContext)
- , m_metaType(new QQmlDelegateModelItemMetaType(m_qmlContext->engine()->handle(), nullptr, QStringList()))
-{
-}
-
-void QQmlTableInstanceModel::useImportVersion(int minorVersion)
-{
- m_adaptorModel.useImportVersion(minorVersion);
-}
-
-QQmlTableInstanceModel::~QQmlTableInstanceModel()
-{
- for (const auto modelItem : m_modelItems) {
- // No item in m_modelItems should be referenced at this point. The view
- // should release all its items before it deletes this model. Only model items
- // that are still being incubated should be left for us to delete.
- Q_ASSERT(modelItem->objectRef == 0);
- Q_ASSERT(modelItem->incubationTask);
- // Check that we are not being deleted while we're
- // in the process of e.g emitting a created signal.
- Q_ASSERT(modelItem->scriptRef == 0);
-
- if (modelItem->object) {
- delete modelItem->object;
- modelItem->object = nullptr;
- modelItem->contextData->invalidate();
- modelItem->contextData = nullptr;
- }
- }
-
- deleteAllFinishedIncubationTasks();
- qDeleteAll(m_modelItems);
- drainReusableItemsPool(0);
-}
-
-QQmlComponent *QQmlTableInstanceModel::resolveDelegate(int index)
-{
- if (m_delegateChooser) {
- const int row = m_adaptorModel.rowAt(index);
- const int column = m_adaptorModel.columnAt(index);
- QQmlComponent *delegate = nullptr;
- QQmlAbstractDelegateComponent *chooser = m_delegateChooser;
- do {
- delegate = chooser->delegate(&m_adaptorModel, row, column);
- chooser = qobject_cast<QQmlAbstractDelegateComponent *>(delegate);
- } while (chooser);
- return delegate;
- }
-
- return m_delegate;
-}
-
-QQmlDelegateModelItem *QQmlTableInstanceModel::resolveModelItem(int index)
-{
- // Check if an item for the given index is already loaded and ready
- QQmlDelegateModelItem *modelItem = m_modelItems.value(index, nullptr);
- if (modelItem)
- return modelItem;
-
- QQmlComponent *delegate = resolveDelegate(index);
- if (!delegate)
- return nullptr;
-
- // Check if the pool contains an item that can be reused
- modelItem = takeFromReusableItemsPool(delegate);
- if (modelItem) {
- reuseItem(modelItem, index);
- m_modelItems.insert(index, modelItem);
- return modelItem;
- }
-
- // Create a new item from scratch
- modelItem = m_adaptorModel.createItem(m_metaType, index);
- if (modelItem) {
- modelItem->delegate = delegate;
- m_modelItems.insert(index, modelItem);
- return modelItem;
- }
-
- qWarning() << Q_FUNC_INFO << "failed creating a model item for index: " << index;
- return nullptr;
-}
-
-QObject *QQmlTableInstanceModel::object(int index, QQmlIncubator::IncubationMode incubationMode)
-{
- Q_ASSERT(m_delegate);
- Q_ASSERT(index >= 0 && index < m_adaptorModel.count());
- Q_ASSERT(m_qmlContext && m_qmlContext->isValid());
-
- QQmlDelegateModelItem *modelItem = resolveModelItem(index);
- if (!modelItem)
- return nullptr;
-
- if (modelItem->object) {
- // The model item has already been incubated. So
- // just bump the ref-count and return it.
- modelItem->referenceObject();
- return modelItem->object;
- }
-
- // The object is not ready, and needs to be incubated
- incubateModelItem(modelItem, incubationMode);
- if (!isDoneIncubating(modelItem))
- return nullptr;
-
- // Incubation is done, so the task should be removed
- Q_ASSERT(!modelItem->incubationTask);
-
- if (!modelItem->object) {
- // The object was incubated synchronously (otherwise we would return above). But since
- // we have no object, the incubation must have failed. And when we have no object, there
- // should be no object references either. And there should also not be any internal script
- // refs at this point. So we delete the model item.
- Q_ASSERT(!modelItem->isObjectReferenced());
- Q_ASSERT(!modelItem->isReferenced());
- m_modelItems.remove(modelItem->index);
- delete modelItem;
- return nullptr;
- }
-
- // Incubation was completed sync and successful
- modelItem->referenceObject();
- return modelItem->object;
-}
-
-QQmlInstanceModel::ReleaseFlags QQmlTableInstanceModel::release(QObject *object, ReusableFlag reusable)
-{
- Q_ASSERT(object);
- auto modelItem = qvariant_cast<QQmlDelegateModelItem *>(object->property(kModelItemTag));
- Q_ASSERT(modelItem);
-
- if (!modelItem->releaseObject())
- return QQmlDelegateModel::Referenced;
-
- if (modelItem->isReferenced()) {
- // We still have an internal reference to this object, which means that we are told to release an
- // object while the createdItem signal for it is still on the stack. This can happen when objects
- // are e.g delivered async, and the user flicks back and forth quicker than the loading can catch
- // up with. The view might then find that the object is no longer visible and should be released.
- // We detect this case in incubatorStatusChanged(), and delete it there instead. But from the callers
- // point of view, it should consider it destroyed.
- return QQmlDelegateModel::Destroyed;
- }
-
- // The item is not referenced by anyone
- m_modelItems.remove(modelItem->index);
-
- if (reusable == Reusable) {
- insertIntoReusableItemsPool(modelItem);
- return QQmlInstanceModel::Referenced;
- }
-
- // The item is not reused or referenced by anyone, so just delete it
- modelItem->destroyObject();
- emit destroyingItem(object);
-
- delete modelItem;
- return QQmlInstanceModel::Destroyed;
-}
-
-void QQmlTableInstanceModel::cancel(int index)
-{
- auto modelItem = m_modelItems.value(index);
- Q_ASSERT(modelItem);
-
- // Since the view expects the item to be incubating, there should be
- // an incubation task. And since the incubation is not done, no-one
- // should yet have received, and therfore hold a reference to, the object.
- Q_ASSERT(modelItem->incubationTask);
- Q_ASSERT(!modelItem->isObjectReferenced());
-
- m_modelItems.remove(index);
-
- if (modelItem->object)
- delete modelItem->object;
-
- // modelItem->incubationTask will be deleted from the modelItems destructor
- delete modelItem;
-}
-
-void QQmlTableInstanceModel::insertIntoReusableItemsPool(QQmlDelegateModelItem *modelItem)
-{
- // Currently, the only way for a view to reuse items is to call QQmlTableInstanceModel::release()
- // with the second argument explicitly set to QQmlTableInstanceModel::Reusable. If the released
- // item is no longer referenced, it will be added to the pool. Reusing of items can be specified
- // per item, in case certain items cannot be recycled.
- // A QQmlDelegateModelItem knows which delegate its object was created from. So when we are
- // about to create a new item, we first check if the pool contains an item based on the same
- // delegate from before. If so, we take it out of the pool (instead of creating a new item), and
- // update all its context-, and attached properties.
- // When a view is recycling items, it should call QQmlTableInstanceModel::drainReusableItemsPool()
- // regularly. As there is currently no logic to 'hibernate' items in the pool, they are only
- // meant to rest there for a short while, ideally only from the time e.g a row is unloaded
- // on one side of the view, and until a new row is loaded on the opposite side. In-between
- // this time, the application will see the item as fully functional and 'alive' (just not
- // visible on screen). Since this time is supposed to be short, we don't take any action to
- // notify the application about it, since we don't want to trigger any bindings that can
- // disturb performance.
- // A recommended time for calling drainReusableItemsPool() is each time a view has finished
- // loading e.g a new row or column. If there are more items in the pool after that, it means
- // that the view most likely doesn't need them anytime soon. Those items should be destroyed to
- // not consume resources.
- // Depending on if a view is a list or a table, it can sometimes be performant to keep
- // items in the pool for a bit longer than one "row out/row in" cycle. E.g for a table, if the
- // number of visible rows in a view is much larger than the number of visible columns.
- // In that case, if you flick out a row, and then flick in a column, you would throw away a lot
- // of items in the pool if completely draining it. The reason is that unloading a row places more
- // items in the pool than what ends up being recycled when loading a new column. And then, when you
- // next flick in a new row, you would need to load all those drained items again from scratch. For
- // that reason, you can specify a maxPoolTime to the drainReusableItemsPool() that allows you to keep
- // items in the pool for a bit longer, effectively keeping more items in circulation.
- // A recommended maxPoolTime would be equal to the number of dimenstions in the view, which
- // means 1 for a list view and 2 for a table view. If you specify 0, all items will be drained.
- Q_ASSERT(!modelItem->incubationTask);
- Q_ASSERT(!modelItem->isObjectReferenced());
- Q_ASSERT(!modelItem->isReferenced());
- Q_ASSERT(modelItem->object);
-
- modelItem->poolTime = 0;
- m_reusableItemsPool.append(modelItem);
- emit itemPooled(modelItem->index, modelItem->object);
-}
-
-QQmlDelegateModelItem *QQmlTableInstanceModel::takeFromReusableItemsPool(const QQmlComponent *delegate)
-{
- // Find the oldest item in the pool that was made from the same delegate as
- // the given argument, remove it from the pool, and return it.
- if (m_reusableItemsPool.isEmpty())
- return nullptr;
-
- for (auto it = m_reusableItemsPool.begin(); it != m_reusableItemsPool.end(); ++it) {
- if ((*it)->delegate != delegate)
- continue;
- auto modelItem = *it;
- m_reusableItemsPool.erase(it);
- return modelItem;
- }
-
- return nullptr;
-}
-
-void QQmlTableInstanceModel::drainReusableItemsPool(int maxPoolTime)
-{
- // Rather than releasing all pooled items upon a call to this function, each
- // item has a poolTime. The poolTime specifies for how many loading cycles an item
- // has been resting in the pool. And for each invocation of this function, poolTime
- // will increase. If poolTime is equal to, or exceeds, maxPoolTime, it will be removed
- // from the pool and released. This way, the view can tweak a bit for how long
- // items should stay in "circulation", even if they are not recycled right away.
- for (auto it = m_reusableItemsPool.begin(); it != m_reusableItemsPool.end();) {
- auto modelItem = *it;
- modelItem->poolTime++;
- if (modelItem->poolTime <= maxPoolTime) {
- ++it;
- } else {
- it = m_reusableItemsPool.erase(it);
- release(modelItem->object, NotReusable);
- }
- }
-}
-
-void QQmlTableInstanceModel::reuseItem(QQmlDelegateModelItem *item, int newModelIndex)
-{
- // Update the context properties index, row and column on
- // the delegate item, and inform the application about it.
- const int newRow = m_adaptorModel.rowAt(newModelIndex);
- const int newColumn = m_adaptorModel.columnAt(newModelIndex);
- item->setModelIndex(newModelIndex, newRow, newColumn);
-
- // Notify the application that all 'dynamic'/role-based context data has
- // changed as well (their getter function will use the updated index).
- auto const itemAsList = QList<QQmlDelegateModelItem *>() << item;
- auto const updateAllRoles = QVector<int>();
- m_adaptorModel.notify(itemAsList, newModelIndex, 1, updateAllRoles);
-
- // Inform the view that the item is recycled. This will typically result
- // in the view updating its own attached delegate item properties.
- emit itemReused(newModelIndex, item->object);
-}
-
-void QQmlTableInstanceModel::incubateModelItem(QQmlDelegateModelItem *modelItem, QQmlIncubator::IncubationMode incubationMode)
-{
- // Guard the model item temporarily so that it's not deleted from
- // incubatorStatusChanged(), in case the incubation is done synchronously.
- modelItem->scriptRef++;
-
- if (modelItem->incubationTask) {
- // We're already incubating the model item from a previous request. If the previous call requested
- // the item async, but the current request needs it sync, we need to force-complete the incubation.
- const bool sync = (incubationMode == QQmlIncubator::Synchronous || incubationMode == QQmlIncubator::AsynchronousIfNested);
- if (sync && modelItem->incubationTask->incubationMode() == QQmlIncubator::Asynchronous)
- modelItem->incubationTask->forceCompletion();
- } else {
- modelItem->incubationTask = new QQmlTableInstanceModelIncubationTask(this, modelItem, incubationMode);
-
- QQmlContextData *ctxt = new QQmlContextData;
- QQmlContext *creationContext = modelItem->delegate->creationContext();
- ctxt->setParent(QQmlContextData::get(creationContext ? creationContext : m_qmlContext.data()));
- ctxt->contextObject = modelItem;
- modelItem->contextData = ctxt;
-
- QQmlComponentPrivate::get(modelItem->delegate)->incubateObject(
- modelItem->incubationTask,
- modelItem->delegate,
- m_qmlContext->engine(),
- ctxt,
- QQmlContextData::get(m_qmlContext));
- }
-
- // Remove the temporary guard
- modelItem->scriptRef--;
-}
-
-void QQmlTableInstanceModel::incubatorStatusChanged(QQmlTableInstanceModelIncubationTask *incubationTask, QQmlIncubator::Status status)
-{
- QQmlDelegateModelItem *modelItem = incubationTask->modelItemToIncubate;
- Q_ASSERT(modelItem->incubationTask);
-
- modelItem->incubationTask = nullptr;
- incubationTask->modelItemToIncubate = nullptr;
-
- if (status == QQmlIncubator::Ready) {
- // Tag the incubated object with the model item for easy retrieval upon release etc.
- modelItem->object->setProperty(kModelItemTag, QVariant::fromValue(modelItem));
-
- // Emit that the item has been created. What normally happens next is that the view
- // upon receiving the signal asks for the model item once more. And since the item is
- // now in the map, it will be returned directly.
- Q_ASSERT(modelItem->object);
- modelItem->scriptRef++;
- emit createdItem(modelItem->index, modelItem->object);
- modelItem->scriptRef--;
- } else if (status == QQmlIncubator::Error) {
- qWarning() << "Error incubating delegate:" << incubationTask->errors();
- }
-
- if (!modelItem->isReferenced() && !modelItem->isObjectReferenced()) {
- // We have no internal reference to the model item, and the view has no
- // reference to the incubated object. So just delete the model item.
- // Note that being here means that the object was incubated _async_
- // (otherwise modelItem->isReferenced() would be true).
- m_modelItems.remove(modelItem->index);
-
- if (modelItem->object) {
- modelItem->scriptRef++;
- emit destroyingItem(modelItem->object);
- modelItem->scriptRef--;
- Q_ASSERT(!modelItem->isReferenced());
- }
-
- deleteModelItemLater(modelItem);
- }
-
- deleteIncubationTaskLater(incubationTask);
-}
-
-QQmlIncubator::Status QQmlTableInstanceModel::incubationStatus(int index) {
- const auto modelItem = m_modelItems.value(index, nullptr);
- if (!modelItem)
- return QQmlIncubator::Null;
-
- if (modelItem->incubationTask)
- return modelItem->incubationTask->status();
-
- // Since we clear the incubation task when we're done
- // incubating, it means that the status is Ready.
- return QQmlIncubator::Ready;
-}
-
-void QQmlTableInstanceModel::deleteIncubationTaskLater(QQmlIncubator *incubationTask)
-{
- // We often need to post-delete incubation tasks, since we cannot
- // delete them while we're in the middle of an incubation change callback.
- Q_ASSERT(!m_finishedIncubationTasks.contains(incubationTask));
- m_finishedIncubationTasks.append(incubationTask);
- if (m_finishedIncubationTasks.count() == 1)
- QTimer::singleShot(1, this, &QQmlTableInstanceModel::deleteAllFinishedIncubationTasks);
-}
-
-void QQmlTableInstanceModel::deleteAllFinishedIncubationTasks()
-{
- qDeleteAll(m_finishedIncubationTasks);
- m_finishedIncubationTasks.clear();
-}
-
-QVariant QQmlTableInstanceModel::model() const
-{
- return m_adaptorModel.model();
-}
-
-void QQmlTableInstanceModel::setModel(const QVariant &model)
-{
- // Pooled items are still accessible/alive for the application, and
- // needs to stay in sync with the model. So we need to drain the pool
- // completely when the model changes.
- drainReusableItemsPool(0);
- if (auto const aim = abstractItemModel())
- disconnect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback);
- m_adaptorModel.setModel(model, this, m_qmlContext->engine());
- if (auto const aim = abstractItemModel())
- connect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback);
-}
-
-void QQmlTableInstanceModel::dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
-{
- // This function is called when model data has changed. In that case, we tell the adaptor model
- // to go through all the items we have created, find the ones that are affected, and notify that
- // their model data has changed. This will in turn update QML bindings inside the delegate items.
- int numberOfRowsChanged = end.row() - begin.row() + 1;
- int numberOfColumnsChanged = end.column() - begin.column() + 1;
-
- for (int column = 0; column < numberOfColumnsChanged; ++column) {
- const int columnIndex = begin.column() + column;
- const int rowIndex = begin.row() + (columnIndex * rows());
- m_adaptorModel.notify(m_modelItems.values(), rowIndex, numberOfRowsChanged, roles);
- }
-}
-
-QQmlComponent *QQmlTableInstanceModel::delegate() const
-{
- return m_delegate;
-}
-
-void QQmlTableInstanceModel::setDelegate(QQmlComponent *delegate)
-{
- if (m_delegate == delegate)
- return;
-
- m_delegateChooser = nullptr;
- if (delegate) {
- QQmlAbstractDelegateComponent *adc =
- qobject_cast<QQmlAbstractDelegateComponent *>(delegate);
- if (adc)
- m_delegateChooser = adc;
- }
-
- m_delegate = delegate;
-}
-
-const QAbstractItemModel *QQmlTableInstanceModel::abstractItemModel() const
-{
- return m_adaptorModel.adaptsAim() ? m_adaptorModel.aim() : nullptr;
-}
-
-// --------------------------------------------------------
-
-void QQmlTableInstanceModelIncubationTask::setInitialState(QObject *object)
-{
- modelItemToIncubate->object = object;
- emit tableInstanceModel->initItem(modelItemToIncubate->index, object);
-}
-
-void QQmlTableInstanceModelIncubationTask::statusChanged(QQmlIncubator::Status status)
-{
- if (!QQmlTableInstanceModel::isDoneIncubating(modelItemToIncubate))
- return;
-
- // We require the view to cancel any ongoing load
- // requests before the tableInstanceModel is destructed.
- Q_ASSERT(tableInstanceModel);
-
- tableInstanceModel->incubatorStatusChanged(this, status);
-}
-
-#include "moc_qqmltableinstancemodel_p.cpp"
-
-QT_END_NAMESPACE
-
diff --git a/src/qml/types/qqmltableinstancemodel_p.h b/src/qml/types/qqmltableinstancemodel_p.h
deleted file mode 100644
index 39ec66d136..0000000000
--- a/src/qml/types/qqmltableinstancemodel_p.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLTABLEINSTANCEMODEL_P_H
-#define QQMLTABLEINSTANCEMODEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtQml/private/qqmldelegatemodel_p.h>
-#include <QtQml/private/qqmldelegatemodel_p_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlTableInstanceModel;
-class QQmlAbstractDelegateComponent;
-
-class QQmlTableInstanceModelIncubationTask : public QQDMIncubationTask
-{
-public:
- QQmlTableInstanceModelIncubationTask(
- QQmlTableInstanceModel *tableInstanceModel
- , QQmlDelegateModelItem* modelItemToIncubate
- , IncubationMode mode)
- : QQDMIncubationTask(nullptr, mode)
- , modelItemToIncubate(modelItemToIncubate)
- , tableInstanceModel(tableInstanceModel) {
- clear();
- }
-
- void statusChanged(Status status) override;
- void setInitialState(QObject *object) override;
-
- QQmlDelegateModelItem *modelItemToIncubate = nullptr;
- QQmlTableInstanceModel *tableInstanceModel = nullptr;
-};
-
-class Q_QML_PRIVATE_EXPORT QQmlTableInstanceModel : public QQmlInstanceModel
-{
- Q_OBJECT
-
-public:
-
- enum ReusableFlag {
- NotReusable,
- Reusable
- };
-
- QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent = nullptr);
- ~QQmlTableInstanceModel() override;
-
- void useImportVersion(int minorVersion);
-
- int count() const override { return m_adaptorModel.count(); }
- int rows() const { return m_adaptorModel.rowCount(); }
- int columns() const { return m_adaptorModel.columnCount(); }
-
- bool isValid() const override { return true; }
-
- QVariant model() const;
- void setModel(const QVariant &model);
-
- QQmlComponent *delegate() const;
- void setDelegate(QQmlComponent *);
-
- const QAbstractItemModel *abstractItemModel() const override;
-
- QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
- ReleaseFlags release(QObject *object) override { return release(object, NotReusable); }
- ReleaseFlags release(QObject *object, ReusableFlag reusable);
- void cancel(int) override;
-
- void insertIntoReusableItemsPool(QQmlDelegateModelItem *modelItem);
- QQmlDelegateModelItem *takeFromReusableItemsPool(const QQmlComponent *delegate);
- void drainReusableItemsPool(int maxPoolTime);
- int poolSize() { return m_reusableItemsPool.size(); }
- void reuseItem(QQmlDelegateModelItem *item, int newModelIndex);
-
- QQmlIncubator::Status incubationStatus(int index) override;
-
- QVariant variantValue(int, const QString &) override { Q_UNREACHABLE(); return QVariant(); }
- void setWatchedRoles(const QList<QByteArray> &) override { Q_UNREACHABLE(); }
- int indexOf(QObject *, QObject *) const override { Q_UNREACHABLE(); return 0; }
-
-Q_SIGNALS:
- void itemPooled(int index, QObject *object);
- void itemReused(int index, QObject *object);
-
-private:
- QQmlComponent *resolveDelegate(int index);
-
- QQmlAdaptorModel m_adaptorModel;
- QQmlAbstractDelegateComponent *m_delegateChooser = nullptr;
- QQmlComponent *m_delegate = nullptr;
- QPointer<QQmlContext> m_qmlContext;
- QQmlDelegateModelItemMetaType *m_metaType;
-
- QHash<int, QQmlDelegateModelItem *> m_modelItems;
- QList<QQmlDelegateModelItem *> m_reusableItemsPool;
- QList<QQmlIncubator *> m_finishedIncubationTasks;
-
- void incubateModelItem(QQmlDelegateModelItem *modelItem, QQmlIncubator::IncubationMode incubationMode);
- void incubatorStatusChanged(QQmlTableInstanceModelIncubationTask *dmIncubationTask, QQmlIncubator::Status status);
- void deleteIncubationTaskLater(QQmlIncubator *incubationTask);
- void deleteAllFinishedIncubationTasks();
- QQmlDelegateModelItem *resolveModelItem(int index);
-
- void dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles);
-
- static bool isDoneIncubating(QQmlDelegateModelItem *modelItem);
- static void deleteModelItemLater(QQmlDelegateModelItem *modelItem);
-
- friend class QQmlTableInstanceModelIncubationTask;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLTABLEINSTANCEMODEL_P_H
diff --git a/src/qml/types/qqmltablemodel.cpp b/src/qml/types/qqmltablemodel.cpp
deleted file mode 100644
index 4a96e7a46b..0000000000
--- a/src/qml/types/qqmltablemodel.cpp
+++ /dev/null
@@ -1,1059 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmltablemodel_p.h"
-
-#include <QtCore/qloggingcategory.h>
-#include <QtQml/qqmlinfo.h>
-#include <QtQml/qqmlengine.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcTableModel, "qt.qml.tablemodel")
-
-/*!
- \qmltype TableModel
- \instantiates QQmlTableModel
- \inqmlmodule Qt.labs.qmlmodels
- \brief Encapsulates a simple table model.
- \since 5.14
-
- The TableModel type stores JavaScript/JSON objects as data for a table
- model that can be used with \l TableView. It is intended to support
- very simple models without requiring the creation of a custom
- QAbstractTableModel subclass in C++.
-
- \snippet qml/tablemodel/fruit-example-simpledelegate.qml file
-
- The model's initial row data is set with either the \l rows property or by
- calling \l appendRow(). Each column in the model is specified by declaring
- a \l TableModelColumn instance, where the order of each instance determines
- its column index. Once the model's \l Component.completed() signal has been
- emitted, the columns and roles will have been established and are then
- fixed for the lifetime of the model.
-
- To access a specific row, the \l getRow() function can be used.
- It's also possible to access the model's JavaScript data
- directly via the \l rows property, but it is not possible to
- modify the model data this way.
-
- To add new rows, use \l appendRow() and \l insertRow(). To modify
- existing rows, use \l setRow(), \l moveRow(), \l removeRow(), and
- \l clear().
-
- It is also possible to modify the model's data via the delegate,
- as shown in the example above:
-
- \snippet qml/tablemodel/fruit-example-simpledelegate.qml delegate
-
- If the type of the data at the modified role does not match the type of the
- data that is set, it will be automatically converted via
- \l {QVariant::canConvert()}{QVariant}.
-
- \section1 Supported Row Data Structures
-
- TableModel is designed to work with JavaScript/JSON data, where each row
- is a simple key-pair object:
-
- \code
- {
- // Each property is one cell/column.
- checked: false,
- amount: 1,
- fruitType: "Apple",
- fruitName: "Granny Smith",
- fruitPrice: 1.50
- },
- // ...
- \endcode
-
- As model manipulation in Qt is done via row and column indices,
- and because object keys are unordered, each column must be specified via
- TableModelColumn. This allows mapping Qt's built-in roles to any property
- in each row object.
-
- Complex row structures are supported, but with limited functionality.
- As TableModel has no way of knowing how each row is structured,
- it cannot manipulate it. As a consequence of this, the copy of the
- model data that TableModel has stored in \l rows is not kept in sync
- with the source data that was set in QML. For these reasons, TableModel
- relies on the user to handle simple data manipulation.
-
- For example, suppose you wanted to have several roles per column. One way
- of doing this is to use a data source where each row is an array and each
- cell is an object. To use this data source with TableModel, define a
- getter and setter:
-
- \code
- TableModel {
- TableModelColumn {
- display: function(modelIndex) { return rows[modelIndex.row][0].checked }
- setDisplay: function(modelIndex, cellData) { rows[modelIndex.row][0].checked = cellData }
- }
- // ...
-
- rows: [
- [
- { checked: false, checkable: true },
- { amount: 1 },
- { fruitType: "Apple" },
- { fruitName: "Granny Smith" },
- { fruitPrice: 1.50 }
- ]
- // ...
- ]
- }
- \endcode
-
- The row above is one example of a complex row.
-
- \note Row manipulation functions such as \l appendRow(), \l removeRow(),
- etc. are not supported when using complex rows.
-
- \section1 Using DelegateChooser with TableModel
-
- For most real world use cases, it is recommended to use DelegateChooser
- as the delegate of a TableView that uses TableModel. This allows you to
- use specific roles in the relevant delegates. For example, the snippet
- above can be rewritten to use DelegateChooser like so:
-
- \snippet qml/tablemodel/fruit-example-delegatechooser.qml file
-
- The most specific delegates are declared first: the columns at index \c 0
- and \c 1 have \c bool and \c integer data types, so they use a
- \l [QtQuickControls2]{CheckBox} and \l [QtQuickControls2]{SpinBox},
- respectively. The remaining columns can simply use a
- \l [QtQuickControls2]{TextField}, and so that delegate is declared
- last as a fallback.
-
- \sa TableModelColumn, TableView, QAbstractTableModel
-*/
-
-QQmlTableModel::QQmlTableModel(QObject *parent)
- : QAbstractTableModel(parent)
-{
-}
-
-QQmlTableModel::~QQmlTableModel()
-{
-}
-
-/*!
- \qmlproperty object TableModel::rows
-
- This property holds the model data in the form of an array of rows:
-
- \snippet qml/tablemodel/fruit-example-simpledelegate.qml rows
-
- \sa getRow(), setRow(), moveRow(), appendRow(), insertRow(), clear(), rowCount, columnCount
-*/
-QVariant QQmlTableModel::rows() const
-{
- return mRows;
-}
-
-void QQmlTableModel::setRows(const QVariant &rows)
-{
- if (rows.userType() != qMetaTypeId<QJSValue>()) {
- qmlWarning(this) << "setRows(): \"rows\" must be an array; actual type is " << rows.typeName();
- return;
- }
-
- const QJSValue rowsAsJSValue = rows.value<QJSValue>();
- const QVariantList rowsAsVariantList = rowsAsJSValue.toVariant().toList();
- if (rowsAsVariantList == mRows) {
- // No change.
- return;
- }
-
- if (!componentCompleted) {
- // Store the rows until we can call doSetRows() after component completion.
- mRows = rowsAsVariantList;
- return;
- }
-
- doSetRows(rowsAsVariantList);
-}
-
-void QQmlTableModel::doSetRows(const QVariantList &rowsAsVariantList)
-{
- Q_ASSERT(componentCompleted);
-
- // By now, all TableModelColumns should have been set.
- if (mColumns.isEmpty()) {
- qmlWarning(this) << "No TableModelColumns were set; model will be empty";
- return;
- }
-
- const bool firstTimeValidRowsHaveBeenSet = mColumnMetadata.isEmpty();
- if (!firstTimeValidRowsHaveBeenSet) {
- // This is not the first time rows have been set; validate each one.
- for (int rowIndex = 0; rowIndex < rowsAsVariantList.size(); ++rowIndex) {
- // validateNewRow() expects a QVariant wrapping a QJSValue, so to
- // simplify the code, just create one here.
- const QVariant row = QVariant::fromValue(rowsAsVariantList.at(rowIndex));
- if (!validateNewRow("setRows()", row, rowIndex, SetRowsOperation))
- return;
- }
- }
-
- const int oldRowCount = mRowCount;
- const int oldColumnCount = mColumnCount;
-
- beginResetModel();
-
- // We don't clear the column or role data, because a TableModel should not be reused in that way.
- // Once it has valid data, its columns and roles are fixed.
- mRows = rowsAsVariantList;
- mRowCount = mRows.size();
-
- // Gather metadata the first time rows is set.
- if (firstTimeValidRowsHaveBeenSet && !mRows.isEmpty())
- fetchColumnMetadata();
-
- endResetModel();
-
- emit rowsChanged();
-
- if (mRowCount != oldRowCount)
- emit rowCountChanged();
- if (mColumnCount != oldColumnCount)
- emit columnCountChanged();
-}
-
-QQmlTableModel::ColumnRoleMetadata QQmlTableModel::fetchColumnRoleData(const QString &roleNameKey,
- QQmlTableModelColumn *tableModelColumn, int columnIndex) const
-{
- const QVariant firstRow = mRows.first();
- ColumnRoleMetadata roleData;
-
- QJSValue columnRoleGetter = tableModelColumn->getterAtRole(roleNameKey);
- if (columnRoleGetter.isUndefined()) {
- // This role is not defined, which is fine; just skip it.
- return roleData;
- }
-
- if (columnRoleGetter.isString()) {
- // The role is set as a string, so we assume the row is a simple object.
- if (firstRow.type() != QVariant::Map) {
- qmlWarning(this).quote() << "expected row for role "
- << roleNameKey << " of TableModelColumn at index "
- << columnIndex << " to be a simple object, but it's "
- << firstRow.typeName() << " instead: " << firstRow;
- return roleData;
- }
- const QVariantMap firstRowAsMap = firstRow.toMap();
- const QString rolePropertyName = columnRoleGetter.toString();
- const QVariant roleProperty = firstRowAsMap.value(rolePropertyName);
-
- roleData.isStringRole = true;
- roleData.name = rolePropertyName;
- roleData.type = roleProperty.type();
- roleData.typeName = QString::fromLatin1(roleProperty.typeName());
- } else if (columnRoleGetter.isCallable()) {
- // The role is provided via a function, which means the row is complex and
- // the user needs to provide the data for it.
- const auto modelIndex = index(0, columnIndex);
- const auto args = QJSValueList() << qmlEngine(this)->toScriptValue(modelIndex);
- const QVariant cellData = columnRoleGetter.call(args).toVariant();
-
- // We don't know the property name since it's provided through the function.
- // roleData.name = ???
- roleData.isStringRole = false;
- roleData.type = cellData.type();
- roleData.typeName = QString::fromLatin1(cellData.typeName());
- } else {
- // Invalid role.
- qmlWarning(this) << "TableModelColumn role for column at index "
- << columnIndex << " must be either a string or a function; actual type is: "
- << columnRoleGetter.toString();
- }
-
- return roleData;
-}
-
-void QQmlTableModel::fetchColumnMetadata()
-{
- qCDebug(lcTableModel) << "gathering metadata for" << mColumnCount << "columns from first row:";
-
- static const auto supportedRoleNames = QQmlTableModelColumn::supportedRoleNames();
-
- // Since we support different data structures at the row level, we require that there
- // is a TableModelColumn for each column.
- // Collect and cache metadata for each column. This makes data lookup faster.
- for (int columnIndex = 0; columnIndex < mColumns.size(); ++columnIndex) {
- QQmlTableModelColumn *column = mColumns.at(columnIndex);
- qCDebug(lcTableModel).nospace() << "- column " << columnIndex << ":";
-
- ColumnMetadata metaData;
- const auto builtInRoleKeys = supportedRoleNames.keys();
- for (const int builtInRoleKey : builtInRoleKeys) {
- const QString builtInRoleName = supportedRoleNames.value(builtInRoleKey);
- ColumnRoleMetadata roleData = fetchColumnRoleData(builtInRoleName, column, columnIndex);
- if (roleData.type == QVariant::Invalid) {
- // This built-in role was not specified in this column.
- continue;
- }
-
- qCDebug(lcTableModel).nospace() << " - added metadata for built-in role "
- << builtInRoleName << " at column index " << columnIndex
- << ": name=" << roleData.name << " typeName=" << roleData.typeName
- << " type=" << roleData.type;
-
- // This column now supports this specific built-in role.
- metaData.roles.insert(builtInRoleName, roleData);
- // Add it if it doesn't already exist.
- mRoleNames[builtInRoleKey] = builtInRoleName.toLatin1();
- }
- mColumnMetadata.insert(columnIndex, metaData);
- }
-}
-
-/*!
- \qmlmethod TableModel::appendRow(object row)
-
- Adds a new row to the end of the model, with the
- values (cells) in \a row.
-
- \code
- model.appendRow({
- checkable: true,
- amount: 1,
- fruitType: "Pear",
- fruitName: "Williams",
- fruitPrice: 1.50,
- })
- \endcode
-
- \sa insertRow(), setRow(), removeRow()
-*/
-void QQmlTableModel::appendRow(const QVariant &row)
-{
- if (!validateNewRow("appendRow()", row, -1, AppendOperation))
- return;
-
- doInsert(mRowCount, row);
-}
-
-/*!
- \qmlmethod TableModel::clear()
-
- Removes all rows from the model.
-
- \sa removeRow()
-*/
-void QQmlTableModel::clear()
-{
- QQmlEngine *engine = qmlEngine(this);
- Q_ASSERT(engine);
- setRows(QVariant::fromValue(engine->newArray()));
-}
-
-/*!
- \qmlmethod object TableModel::getRow(int rowIndex)
-
- Returns the row at \a rowIndex in the model.
-
- Note that this equivalent to accessing the row directly
- through the \l rows property:
-
- \code
- Component.onCompleted: {
- // These two lines are equivalent.
- console.log(model.getRow(0).display);
- console.log(model.rows[0].fruitName);
- }
- \endcode
-
- \note the returned object cannot be used to modify the contents of the
- model; use setRow() instead.
-
- \sa setRow(), appendRow(), insertRow(), removeRow(), moveRow()
-*/
-QVariant QQmlTableModel::getRow(int rowIndex)
-{
- if (!validateRowIndex("getRow()", "rowIndex", rowIndex))
- return QVariant();
-
- return mRows.at(rowIndex);
-}
-
-/*!
- \qmlmethod TableModel::insertRow(int rowIndex, object row)
-
- Adds a new row to the list model at position \a rowIndex, with the
- values (cells) in \a row.
-
- \code
- model.insertRow(2, {
- checkable: true, checked: false,
- amount: 1,
- fruitType: "Pear",
- fruitName: "Williams",
- fruitPrice: 1.50,
- })
- \endcode
-
- The \a rowIndex must be to an existing item in the list, or one past
- the end of the list (equivalent to \l appendRow()).
-
- \sa appendRow(), setRow(), removeRow(), rowCount
-*/
-void QQmlTableModel::insertRow(int rowIndex, const QVariant &row)
-{
- if (!validateNewRow("insertRow()", row, rowIndex))
- return;
-
- doInsert(rowIndex, row);
-}
-
-void QQmlTableModel::doInsert(int rowIndex, const QVariant &row)
-{
- beginInsertRows(QModelIndex(), rowIndex, rowIndex);
-
- // Adding rowAsVariant.toList() will add each invidual variant in the list,
- // which is definitely not what we want.
- const QVariant rowAsVariant = row.value<QJSValue>().toVariant();
- mRows.insert(rowIndex, rowAsVariant);
- ++mRowCount;
-
- qCDebug(lcTableModel).nospace() << "inserted the following row to the model at index "
- << rowIndex << ":\n" << rowAsVariant.toMap();
-
- // Gather metadata the first time a row is added.
- if (mColumnMetadata.isEmpty())
- fetchColumnMetadata();
-
- endInsertRows();
- emit rowCountChanged();
-}
-
-void QQmlTableModel::classBegin()
-{
-}
-
-void QQmlTableModel::componentComplete()
-{
- componentCompleted = true;
-
- mColumnCount = mColumns.size();
- if (mColumnCount > 0)
- emit columnCountChanged();
-
- doSetRows(mRows);
-}
-
-/*!
- \qmlmethod TableModel::moveRow(int fromRowIndex, int toRowIndex, int rows)
-
- Moves \a rows from the index at \a fromRowIndex to the index at
- \a toRowIndex.
-
- The from and to ranges must exist; for example, to move the first 3 items
- to the end of the list:
-
- \code
- model.moveRow(0, model.rowCount - 3, 3)
- \endcode
-
- \sa appendRow(), insertRow(), removeRow(), rowCount
-*/
-void QQmlTableModel::moveRow(int fromRowIndex, int toRowIndex, int rows)
-{
- if (fromRowIndex == toRowIndex) {
- qmlWarning(this) << "moveRow(): \"fromRowIndex\" cannot be equal to \"toRowIndex\"";
- return;
- }
-
- if (rows <= 0) {
- qmlWarning(this) << "moveRow(): \"rows\" is less than or equal to 0";
- return;
- }
-
- if (!validateRowIndex("moveRow()", "fromRowIndex", fromRowIndex))
- return;
-
- if (!validateRowIndex("moveRow()", "toRowIndex", toRowIndex))
- return;
-
- if (fromRowIndex + rows > mRowCount) {
- qmlWarning(this) << "moveRow(): \"fromRowIndex\" (" << fromRowIndex
- << ") + \"rows\" (" << rows << ") = " << (fromRowIndex + rows)
- << ", which is greater than rowCount() of " << mRowCount;
- return;
- }
-
- if (toRowIndex + rows > mRowCount) {
- qmlWarning(this) << "moveRow(): \"toRowIndex\" (" << toRowIndex
- << ") + \"rows\" (" << rows << ") = " << (toRowIndex + rows)
- << ", which is greater than rowCount() of " << mRowCount;
- return;
- }
-
- qCDebug(lcTableModel).nospace() << "moving " << rows
- << " row(s) from index " << fromRowIndex
- << " to index " << toRowIndex;
-
- // Based on the same call in QQmlListModel::moveRow().
- beginMoveRows(QModelIndex(), fromRowIndex, fromRowIndex + rows - 1, QModelIndex(),
- toRowIndex > fromRowIndex ? toRowIndex + rows : toRowIndex);
-
- // Based on ListModel::moveRow().
- if (fromRowIndex > toRowIndex) {
- // Only move forwards - flip if moving backwards.
- const int from = fromRowIndex;
- const int to = toRowIndex;
- fromRowIndex = to;
- toRowIndex = to + rows;
- rows = from - to;
- }
-
- QVector<QVariant> store;
- store.reserve(rows);
- for (int i = 0; i < (toRowIndex - fromRowIndex); ++i)
- store.append(mRows.at(fromRowIndex + rows + i));
- for (int i = 0; i < rows; ++i)
- store.append(mRows.at(fromRowIndex + i));
- for (int i = 0; i < store.size(); ++i)
- mRows[fromRowIndex + i] = store[i];
-
- qCDebug(lcTableModel).nospace() << "after moving, rows are:\n" << mRows;
-
- endMoveRows();
-}
-
-/*!
- \qmlmethod TableModel::removeRow(int rowIndex, int rows = 1)
-
- Removes the row at \a rowIndex from the model.
-
- \sa clear(), rowCount
-*/
-void QQmlTableModel::removeRow(int rowIndex, int rows)
-{
- if (!validateRowIndex("removeRow()", "rowIndex", rowIndex))
- return;
-
- if (rows <= 0) {
- qmlWarning(this) << "removeRow(): \"rows\" is less than or equal to zero";
- return;
- }
-
- if (rowIndex + rows - 1 >= mRowCount) {
- qmlWarning(this) << "removeRow(): \"rows\" " << rows
- << " exceeds available rowCount() of " << mRowCount
- << " when removing from \"rowIndex\" " << rowIndex;
- return;
- }
-
- beginRemoveRows(QModelIndex(), rowIndex, rowIndex + rows - 1);
-
- auto firstIterator = mRows.begin() + rowIndex;
- // The "last" argument to erase() is exclusive, so we go one past the last item.
- auto lastIterator = firstIterator + rows;
- mRows.erase(firstIterator, lastIterator);
- mRowCount -= rows;
-
- endRemoveRows();
- emit rowCountChanged();
-
- qCDebug(lcTableModel).nospace() << "removed " << rows
- << " items from the model, starting at index " << rowIndex;
-}
-
-/*!
- \qmlmethod TableModel::setRow(int rowIndex, object row)
-
- Changes the row at \a rowIndex in the model with \a row.
-
- All columns/cells must be present in \c row, and in the correct order.
-
- \code
- model.setRow(0, {
- checkable: true,
- amount: 1,
- fruitType: "Pear",
- fruitName: "Williams",
- fruitPrice: 1.50,
- })
- \endcode
-
- If \a rowIndex is equal to \c rowCount(), then a new row is appended to the
- model. Otherwise, \a rowIndex must point to an existing row in the model.
-
- \sa appendRow(), insertRow(), rowCount
-*/
-void QQmlTableModel::setRow(int rowIndex, const QVariant &row)
-{
- if (!validateNewRow("setRow()", row, rowIndex))
- return;
-
- if (rowIndex != mRowCount) {
- // Setting an existing row.
- mRows[rowIndex] = row;
-
- // For now we just assume the whole row changed, as it's simpler.
- const QModelIndex topLeftModelIndex(createIndex(rowIndex, 0));
- const QModelIndex bottomRightModelIndex(createIndex(rowIndex, mColumnCount - 1));
- emit dataChanged(topLeftModelIndex, bottomRightModelIndex);
- } else {
- // Appending a row.
- doInsert(rowIndex, row);
- }
-}
-
-QQmlListProperty<QQmlTableModelColumn> QQmlTableModel::columns()
-{
- return QQmlListProperty<QQmlTableModelColumn>(this, nullptr,
- &QQmlTableModel::columns_append,
- &QQmlTableModel::columns_count,
- &QQmlTableModel::columns_at,
- &QQmlTableModel::columns_clear);
-}
-
-void QQmlTableModel::columns_append(QQmlListProperty<QQmlTableModelColumn> *property,
- QQmlTableModelColumn *value)
-{
- QQmlTableModel *model = static_cast<QQmlTableModel*>(property->object);
- QQmlTableModelColumn *column = qobject_cast<QQmlTableModelColumn*>(value);
- if (column)
- model->mColumns.append(column);
-}
-
-int QQmlTableModel::columns_count(QQmlListProperty<QQmlTableModelColumn> *property)
-{
- const QQmlTableModel *model = static_cast<QQmlTableModel*>(property->object);
- return model->mColumns.count();
-}
-
-QQmlTableModelColumn *QQmlTableModel::columns_at(QQmlListProperty<QQmlTableModelColumn> *property, int index)
-{
- const QQmlTableModel *model = static_cast<QQmlTableModel*>(property->object);
- return model->mColumns.at(index);
-}
-
-void QQmlTableModel::columns_clear(QQmlListProperty<QQmlTableModelColumn> *property)
-{
- QQmlTableModel *model = static_cast<QQmlTableModel*>(property->object);
- return model->mColumns.clear();
-}
-
-/*!
- \qmlmethod QModelIndex TableModel::index(int row, int column)
-
- Returns a \l QModelIndex object referencing the given \a row and \a column,
- which can be passed to the data() function to get the data from that cell,
- or to setData() to edit the contents of that cell.
-
- \code
- import QtQml 2.14
- import Qt.labs.qmlmodels 1.0
-
- TableModel {
- id: model
-
- TableModelColumn { display: "fruitType" }
- TableModelColumn { display: "fruitPrice" }
-
- rows: [
- { fruitType: "Apple", fruitPrice: 1.50 },
- { fruitType: "Orange", fruitPrice: 2.50 }
- ]
-
- Component.onCompleted: {
- for (var r = 0; r < model.rowCount; ++r) {
- console.log("An " + model.data(model.index(r, 0)).display +
- " costs " + model.data(model.index(r, 1)).display.toFixed(2))
- }
- }
- }
- \endcode
-
- \sa {QModelIndex and related Classes in QML}, data()
-*/
-// Note: we don't document the parent argument, because you never need it, because
-// cells in a TableModel don't have parents. But it is there because this function is an override.
-QModelIndex QQmlTableModel::index(int row, int column, const QModelIndex &parent) const
-{
- return row >= 0 && row < rowCount() && column >= 0 && column < columnCount() && !parent.isValid()
- ? createIndex(row, column)
- : QModelIndex();
-}
-
-/*!
- \qmlproperty int TableModel::rowCount
- \readonly
-
- This read-only property holds the number of rows in the model.
-
- This value changes whenever rows are added or removed from the model.
-*/
-int QQmlTableModel::rowCount(const QModelIndex &parent) const
-{
- if (parent.isValid())
- return 0;
-
- return mRowCount;
-}
-
-/*!
- \qmlproperty int TableModel::columnCount
- \readonly
-
- This read-only property holds the number of columns in the model.
-
- The number of columns is fixed for the lifetime of the model
- after the \l rows property is set or \l appendRow() is called for the first
- time.
-*/
-int QQmlTableModel::columnCount(const QModelIndex &parent) const
-{
- if (parent.isValid())
- return 0;
-
- return mColumnCount;
-}
-
-/*!
- \qmlmethod variant TableModel::data(QModelIndex index, string role)
-
- Returns the data from the table cell at the given \a index belonging to the
- given \a role.
-
- \sa index()
-*/
-QVariant QQmlTableModel::data(const QModelIndex &index, const QString &role) const
-{
- const int iRole = mRoleNames.key(role.toUtf8(), -1);
- if (iRole >= 0)
- return data(index, iRole);
- return QVariant();
-}
-
-QVariant QQmlTableModel::data(const QModelIndex &index, int role) const
-{
- const int row = index.row();
- if (row < 0 || row >= rowCount())
- return QVariant();
-
- const int column = index.column();
- if (column < 0 || column >= columnCount())
- return QVariant();
-
- const ColumnMetadata columnMetadata = mColumnMetadata.at(index.column());
- const QString roleName = QString::fromUtf8(mRoleNames.value(role));
- if (!columnMetadata.roles.contains(roleName)) {
- qmlWarning(this) << "setData(): no role named " << roleName
- << " at column index " << column << ". The available roles for that column are: "
- << columnMetadata.roles.keys();
- return QVariant();
- }
-
- const ColumnRoleMetadata roleData = columnMetadata.roles.value(roleName);
- if (roleData.isStringRole) {
- // We know the data structure, so we can get the data for the user.
- const QVariantMap rowData = mRows.at(row).toMap();
- const QString propertyName = columnMetadata.roles.value(roleName).name;
- const QVariant value = rowData.value(propertyName);
- return value;
- }
-
- // We don't know the data structure, so the user has to modify their data themselves.
- // First, find the getter for this column and role.
- QJSValue getter = mColumns.at(column)->getterAtRole(roleName);
-
- // Then, call it and return what it returned.
- const auto args = QJSValueList() << qmlEngine(this)->toScriptValue(index);
- return getter.call(args).toVariant();
-}
-
-/*!
- \qmlmethod bool TableModel::setData(QModelIndex index, string role, variant value)
-
- Inserts or updates the data field named by \a role in the table cell at the
- given \a index with \a value. Returns true if sucessful, false if not.
-
- \sa index()
-*/
-bool QQmlTableModel::setData(const QModelIndex &index, const QString &role, const QVariant &value)
-{
- const int intRole = mRoleNames.key(role.toUtf8(), -1);
- if (intRole >= 0)
- return setData(index, value, intRole);
- return false;
-}
-
-bool QQmlTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- const int row = index.row();
- if (row < 0 || row >= rowCount())
- return false;
-
- const int column = index.column();
- if (column < 0 || column >= columnCount())
- return false;
-
- const QString roleName = QString::fromUtf8(mRoleNames.value(role));
-
- qCDebug(lcTableModel).nospace() << "setData() called with index "
- << index << ", value " << value << " and role " << roleName;
-
- // Verify that the role exists for this column.
- const ColumnMetadata columnMetadata = mColumnMetadata.at(index.column());
- if (!columnMetadata.roles.contains(roleName)) {
- qmlWarning(this) << "setData(): no role named \"" << roleName
- << "\" at column index " << column << ". The available roles for that column are: "
- << columnMetadata.roles.keys();
- return false;
- }
-
- // Verify that the type of the value is what we expect.
- // If the value set is not of the expected type, we can try to convert it automatically.
- const ColumnRoleMetadata roleData = columnMetadata.roles.value(roleName);
- QVariant effectiveValue = value;
- if (value.type() != roleData.type) {
- if (!value.canConvert(int(roleData.type))) {
- qmlWarning(this).nospace() << "setData(): the value " << value
- << " set at row " << row << " column " << column << " with role " << roleName
- << " cannot be converted to " << roleData.typeName;
- return false;
- }
-
- if (!effectiveValue.convert(int(roleData.type))) {
- qmlWarning(this).nospace() << "setData(): failed converting value " << value
- << " set at row " << row << " column " << column << " with role " << roleName
- << " to " << roleData.typeName;
- return false;
- }
- }
-
- if (roleData.isStringRole) {
- // We know the data structure, so we can set it for the user.
- QVariantMap modifiedRow = mRows.at(row).toMap();
- modifiedRow[roleData.name] = value;
-
- mRows[row] = modifiedRow;
- } else {
- // We don't know the data structure, so the user has to modify their data themselves.
- auto engine = qmlEngine(this);
- auto args = QJSValueList()
- // arg 0: modelIndex.
- << engine->toScriptValue(index)
- // arg 1: cellData.
- << engine->toScriptValue(value);
- // Do the actual setting.
- QJSValue setter = mColumns.at(column)->setterAtRole(roleName);
- setter.call(args);
-
- /*
- The chain of events so far:
-
- - User did e.g.: model.edit = textInput.text
- - setData() is called
- - setData() calls the setter
- (remember that we need to emit the dataChanged() signal,
- which is why the user can't just set the data directly in the delegate)
-
- Now the user's setter function has modified *their* copy of the
- data, but *our* copy of the data is old. Imagine the getters and setters looked like this:
-
- display: function(modelIndex) { return rows[modelIndex.row][1].amount }
- setDisplay: function(modelIndex, cellData) { rows[modelIndex.row][1].amount = cellData }
-
- We don't know the structure of the user's data, so we can't just do
- what we do above for the isStringRole case:
-
- modifiedRow[column][roleName] = value
-
- This means that, besides getting the implicit row count when rows is initially set,
- our copy of the data is unused when it comes to complex columns.
-
- Another point to note is that we can't pass rowData in to the getter as a convenience,
- because we would be passing in *our* copy of the row, which is not up-to-date.
- Since the user already has access to the data, it's not a big deal for them to do:
-
- display: function(modelIndex) { return rows[modelIndex.row][1].amount }
-
- instead of:
-
- display: function(modelIndex, rowData) { return rowData[1].amount }
- */
- }
-
- QVector<int> rolesChanged;
- rolesChanged.append(role);
- emit dataChanged(index, index, rolesChanged);
-
- return true;
-}
-
-QHash<int, QByteArray> QQmlTableModel::roleNames() const
-{
- return mRoleNames;
-}
-
-QQmlTableModel::ColumnRoleMetadata::ColumnRoleMetadata()
-{
-}
-
-QQmlTableModel::ColumnRoleMetadata::ColumnRoleMetadata(
- bool isStringRole, const QString &name, QVariant::Type type, const QString &typeName) :
- isStringRole(isStringRole),
- name(name),
- type(type),
- typeName(typeName)
-{
-}
-
-bool QQmlTableModel::ColumnRoleMetadata::isValid() const
-{
- return !name.isEmpty();
-}
-
-bool QQmlTableModel::validateRowType(const char *functionName, const QVariant &row) const
-{
- if (!row.canConvert<QJSValue>()) {
- qmlWarning(this) << functionName << ": expected \"row\" argument to be a QJSValue,"
- << " but got " << row.typeName() << " instead:\n" << row;
- return false;
- }
-
- const QJSValue rowAsJSValue = row.value<QJSValue>();
- if (!rowAsJSValue.isObject() && !rowAsJSValue.isArray()) {
- qmlWarning(this) << functionName << ": expected \"row\" argument "
- << "to be an object or array, but got:\n" << rowAsJSValue.toString();
- return false;
- }
-
- return true;
-}
-
-bool QQmlTableModel::validateNewRow(const char *functionName, const QVariant &row,
- int rowIndex, NewRowOperationFlag operation) const
-{
- if (mColumnMetadata.isEmpty()) {
- // There is no column metadata, so we have nothing to validate the row against.
- // Rows have to be added before we can gather metadata from them, so just this
- // once we'll return true to allow the rows to be added.
- return true;
- }
-
- // Don't require each row to be a QJSValue when setting all rows,
- // as they won't be; they'll be QVariantMap.
- if (operation != SetRowsOperation && !validateRowType(functionName, row))
- return false;
-
- if (operation == OtherOperation) {
- // Inserting/setting.
- if (rowIndex < 0) {
- qmlWarning(this) << functionName << ": \"rowIndex\" cannot be negative";
- return false;
- }
-
- if (rowIndex > mRowCount) {
- qmlWarning(this) << functionName << ": \"rowIndex\" " << rowIndex
- << " is greater than rowCount() of " << mRowCount;
- return false;
- }
- }
-
- const QVariant rowAsVariant = operation == SetRowsOperation
- ? row : row.value<QJSValue>().toVariant();
- if (rowAsVariant.type() != QVariant::Map) {
- qmlWarning(this) << functionName << ": row manipulation functions "
- << "do not support complex rows (row index: " << rowIndex << ")";
- return false;
- }
-
- const QVariantMap rowAsMap = rowAsVariant.toMap();
- const int columnCount = rowAsMap.size();
- if (columnCount < mColumnCount) {
- qmlWarning(this) << functionName << ": expected " << mColumnCount
- << " columns, but only got " << columnCount;
- return false;
- }
-
- // We can't validate complex structures, but we can make sure that
- // each simple string-based role in each column is correct.
- for (int columnIndex = 0; columnIndex < mColumns.size(); ++columnIndex) {
- QQmlTableModelColumn *column = mColumns.at(columnIndex);
- const QHash<QString, QJSValue> getters = column->getters();
- const auto roleNames = getters.keys();
- const ColumnMetadata columnMetadata = mColumnMetadata.at(columnIndex);
- for (const QString &roleName : roleNames) {
- const ColumnRoleMetadata roleData = columnMetadata.roles.value(roleName);
- if (!roleData.isStringRole)
- continue;
-
- if (!rowAsMap.contains(roleData.name)) {
- qmlWarning(this).quote() << functionName << ": expected a property named "
- << roleData.name << " in row at index " << rowIndex << ", but couldn't find one";
- return false;
- }
-
- const QVariant rolePropertyValue = rowAsMap.value(roleData.name);
- if (rolePropertyValue.type() != roleData.type) {
- qmlWarning(this).quote() << functionName << ": expected the property named "
- << roleData.name << " to be of type " << roleData.typeName
- << ", but got " << QString::fromLatin1(rolePropertyValue.typeName()) << " instead";
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool QQmlTableModel::validateRowIndex(const char *functionName, const char *argumentName, int rowIndex) const
-{
- if (rowIndex < 0) {
- qmlWarning(this) << functionName << ": \"" << argumentName << "\" cannot be negative";
- return false;
- }
-
- if (rowIndex >= mRowCount) {
- qmlWarning(this) << functionName << ": \"" << argumentName
- << "\" " << rowIndex << " is greater than or equal to rowCount() of " << mRowCount;
- return false;
- }
-
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/types/qqmltablemodel_p.h b/src/qml/types/qqmltablemodel_p.h
deleted file mode 100644
index a1bb97e7d4..0000000000
--- a/src/qml/types/qqmltablemodel_p.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLTABLEMODEL_P_H
-#define QQMLTABLEMODEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/QObject>
-#include <QtCore/QAbstractTableModel>
-#include <QtQml/qqml.h>
-#include <QtQml/private/qtqmlglobal_p.h>
-#include <QtQml/private/qqmltablemodelcolumn_p.h>
-#include <QtQml/QJSValue>
-#include <QtQml/QQmlListProperty>
-
-QT_BEGIN_NAMESPACE
-
-class Q_QML_PRIVATE_EXPORT QQmlTableModel : public QAbstractTableModel, public QQmlParserStatus
-{
- Q_OBJECT
- Q_PROPERTY(int columnCount READ columnCount NOTIFY columnCountChanged FINAL)
- Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged FINAL)
- Q_PROPERTY(QVariant rows READ rows WRITE setRows NOTIFY rowsChanged FINAL)
- Q_PROPERTY(QQmlListProperty<QQmlTableModelColumn> columns READ columns CONSTANT FINAL)
- Q_INTERFACES(QQmlParserStatus)
- Q_CLASSINFO("DefaultProperty", "columns")
-
-public:
- QQmlTableModel(QObject *parent = nullptr);
- ~QQmlTableModel() override;
-
- QVariant rows() const;
- void setRows(const QVariant &rows);
-
- Q_INVOKABLE void appendRow(const QVariant &row);
- Q_INVOKABLE void clear();
- Q_INVOKABLE QVariant getRow(int rowIndex);
- Q_INVOKABLE void insertRow(int rowIndex, const QVariant &row);
- Q_INVOKABLE void moveRow(int fromRowIndex, int toRowIndex, int rows = 1);
- Q_INVOKABLE void removeRow(int rowIndex, int rows = 1);
- Q_INVOKABLE void setRow(int rowIndex, const QVariant &row);
-
- QQmlListProperty<QQmlTableModelColumn> columns();
-
- static void columns_append(QQmlListProperty<QQmlTableModelColumn> *property, QQmlTableModelColumn *value);
- static int columns_count(QQmlListProperty<QQmlTableModelColumn> *property);
- static QQmlTableModelColumn *columns_at(QQmlListProperty<QQmlTableModelColumn> *property, int index);
- static void columns_clear(QQmlListProperty<QQmlTableModelColumn> *property);
-
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- Q_INVOKABLE QVariant data(const QModelIndex &index, const QString &role) const;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- Q_INVOKABLE bool setData(const QModelIndex &index, const QString &role, const QVariant &value);
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole) override;
- QHash<int, QByteArray> roleNames() const override;
-
-Q_SIGNALS:
- void columnCountChanged();
- void rowCountChanged();
- void rowsChanged();
-
-private:
- class ColumnRoleMetadata
- {
- public:
- ColumnRoleMetadata();
- ColumnRoleMetadata(bool isStringRole, const QString &name, QVariant::Type type, const QString &typeName);
-
- bool isValid() const;
-
- // If this is false, it's a function role.
- bool isStringRole = false;
- QString name;
- QVariant::Type type = QVariant::Invalid;
- QString typeName;
- };
-
- struct ColumnMetadata
- {
- // Key = role name that will be made visible to the delegate
- // Value = metadata about that role, including actual name in the model data, type, etc.
- QHash<QString, ColumnRoleMetadata> roles;
- };
-
- enum NewRowOperationFlag {
- OtherOperation, // insert(), set(), etc.
- SetRowsOperation,
- AppendOperation
- };
-
- void doSetRows(const QVariantList &rowsAsVariantList);
- ColumnRoleMetadata fetchColumnRoleData(const QString &roleNameKey,
- QQmlTableModelColumn *tableModelColumn, int columnIndex) const;
- void fetchColumnMetadata();
-
- bool validateRowType(const char *functionName, const QVariant &row) const;
- bool validateNewRow(const char *functionName, const QVariant &row,
- int rowIndex, NewRowOperationFlag operation = OtherOperation) const;
- bool validateRowIndex(const char *functionName, const char *argumentName, int rowIndex) const;
-
- void doInsert(int rowIndex, const QVariant &row);
-
- void classBegin() override;
- void componentComplete() override;
-
- bool componentCompleted = false;
- QVariantList mRows;
- QList<QQmlTableModelColumn *> mColumns;
- int mRowCount = 0;
- int mColumnCount = 0;
- // Each entry contains information about the properties of the column at that index.
- QVector<ColumnMetadata> mColumnMetadata;
- // key = property index (0 to number of properties across all columns)
- // value = role name
- QHash<int, QByteArray> mRoleNames;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQmlTableModel)
-
-#endif // QQMLTABLEMODEL_P_H
diff --git a/src/qml/types/qqmltablemodelcolumn.cpp b/src/qml/types/qqmltablemodelcolumn.cpp
deleted file mode 100644
index 93da0642de..0000000000
--- a/src/qml/types/qqmltablemodelcolumn.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmltablemodelcolumn_p.h"
-
-#include <QtQml/qqmlinfo.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype TableModelColumn
- \instantiates QQmlTableModelColumn
- \inqmlmodule Qt.labs.qmlmodels
- \brief Represents a column in a model.
- \since 5.14
-
- \section1 Supported Roles
-
- TableModelColumn supports all of \l {Qt::ItemDataRole}{Qt's roles},
- with the exception of \c Qt::InitialSortOrderRole.
-
- \sa TableModel, TableView
-*/
-
-static const QString displayRoleName = QStringLiteral("display");
-static const QString decorationRoleName = QStringLiteral("decoration");
-static const QString editRoleName = QStringLiteral("edit");
-static const QString toolTipRoleName = QStringLiteral("toolTip");
-static const QString statusTipRoleName = QStringLiteral("statusTip");
-static const QString whatsThisRoleName = QStringLiteral("whatsThis");
-
-static const QString fontRoleName = QStringLiteral("font");
-static const QString textAlignmentRoleName = QStringLiteral("textAlignment");
-static const QString backgroundRoleName = QStringLiteral("background");
-static const QString foregroundRoleName = QStringLiteral("foreground");
-static const QString checkStateRoleName = QStringLiteral("checkState");
-
-static const QString accessibleTextRoleName = QStringLiteral("accessibleText");
-static const QString accessibleDescriptionRoleName = QStringLiteral("accessibleDescription");
-
-static const QString sizeHintRoleName = QStringLiteral("sizeHint");
-
-
-QQmlTableModelColumn::QQmlTableModelColumn(QObject *parent)
- : QObject(parent)
-{
-}
-
-QQmlTableModelColumn::~QQmlTableModelColumn()
-{
-}
-
-#define DEFINE_ROLE_PROPERTIES(getterGetterName, getterSetterName, getterSignal, setterGetterName, setterSetterName, setterSignal, roleName) \
-QJSValue QQmlTableModelColumn::getterGetterName() const \
-{ \
- return mGetters.value(roleName); \
-} \
-\
-void QQmlTableModelColumn::getterSetterName(const QJSValue &stringOrFunction) \
-{ \
- if (!stringOrFunction.isString() && !stringOrFunction.isCallable()) { \
- qmlWarning(this).quote() << "getter for " << roleName << " must be a function"; \
- return; \
- } \
- if (stringOrFunction.strictlyEquals(decoration())) \
- return; \
-\
- mGetters[roleName] = stringOrFunction; \
- emit decorationChanged(); \
-} \
-\
-QJSValue QQmlTableModelColumn::setterGetterName() const \
-{ \
- return mSetters.value(roleName); \
-} \
-\
-void QQmlTableModelColumn::setterSetterName(const QJSValue &function) \
-{ \
- if (!function.isCallable()) { \
- qmlWarning(this).quote() << "setter for " << roleName << " must be a function"; \
- return; \
- } \
-\
- if (function.strictlyEquals(getSetDisplay())) \
- return; \
-\
- mSetters[roleName] = function; \
- emit setDisplayChanged(); \
-}
-
-DEFINE_ROLE_PROPERTIES(display, setDisplay, displayChanged,
- getSetDisplay, setSetDisplay, setDisplayChanged, displayRoleName)
-DEFINE_ROLE_PROPERTIES(decoration, setDecoration, decorationChanged,
- getSetDecoration, setSetDecoration, setDecorationChanged, decorationRoleName)
-DEFINE_ROLE_PROPERTIES(edit, setEdit, editChanged,
- getSetEdit, setSetEdit, setEditChanged, editRoleName)
-DEFINE_ROLE_PROPERTIES(toolTip, setToolTip, toolTipChanged,
- getSetToolTip, setSetToolTip, setToolTipChanged, toolTipRoleName)
-DEFINE_ROLE_PROPERTIES(statusTip, setStatusTip, statusTipChanged,
- getSetStatusTip, setSetStatusTip, setStatusTipChanged, statusTipRoleName)
-DEFINE_ROLE_PROPERTIES(whatsThis, setWhatsThis, whatsThisChanged,
- getSetWhatsThis, setSetWhatsThis, setWhatsThisChanged, whatsThisRoleName)
-
-DEFINE_ROLE_PROPERTIES(font, setFont, fontChanged,
- getSetFont, setSetFont, setFontChanged, fontRoleName)
-DEFINE_ROLE_PROPERTIES(textAlignment, setTextAlignment, textAlignmentChanged,
- getSetTextAlignment, setSetTextAlignment, setTextAlignmentChanged, textAlignmentRoleName)
-DEFINE_ROLE_PROPERTIES(background, setBackground, backgroundChanged,
- getSetBackground, setSetBackground, setBackgroundChanged, backgroundRoleName)
-DEFINE_ROLE_PROPERTIES(foreground, setForeground, foregroundChanged,
- getSetForeground, setSetForeground, setForegroundChanged, foregroundRoleName)
-DEFINE_ROLE_PROPERTIES(checkState, setCheckState, checkStateChanged,
- getSetCheckState, setSetCheckState, setCheckStateChanged, checkStateRoleName)
-
-DEFINE_ROLE_PROPERTIES(accessibleText, setAccessibleText, accessibleTextChanged,
- getSetAccessibleText, setSetAccessibleText, setAccessibleTextChanged, accessibleTextRoleName)
-DEFINE_ROLE_PROPERTIES(accessibleDescription, setAccessibleDescription, accessibleDescriptionChanged,
- getSetAccessibleDescription, setSetAccessibleDescription, setAccessibleDescriptionChanged, accessibleDescriptionRoleName)
-
-DEFINE_ROLE_PROPERTIES(sizeHint, setSizeHint, sizeHintChanged,
- getSetSizeHint, setSetSizeHint, setSizeHintChanged, sizeHintRoleName)
-
-QJSValue QQmlTableModelColumn::getterAtRole(const QString &roleName)
-{
- auto it = mGetters.find(roleName);
- if (it == mGetters.end())
- return QJSValue();
- return *it;
-}
-
-QJSValue QQmlTableModelColumn::setterAtRole(const QString &roleName)
-{
- auto it = mSetters.find(roleName);
- if (it == mSetters.end())
- return QJSValue();
- return *it;
-}
-
-const QHash<QString, QJSValue> QQmlTableModelColumn::getters() const
-{
- return mGetters;
-}
-
-const QHash<int, QString> QQmlTableModelColumn::supportedRoleNames()
-{
- QHash<int, QString> names;
- names[Qt::DisplayRole] = QLatin1String("display");
- names[Qt::DecorationRole] = QLatin1String("decoration");
- names[Qt::EditRole] = QLatin1String("edit");
- names[Qt::ToolTipRole] = QLatin1String("toolTip");
- names[Qt::StatusTipRole] = QLatin1String("statusTip");
- names[Qt::WhatsThisRole] = QLatin1String("whatsThis");
- names[Qt::FontRole] = QLatin1String("font");
- names[Qt::TextAlignmentRole] = QLatin1String("textAlignment");
- names[Qt::BackgroundRole] = QLatin1String("background");
- names[Qt::ForegroundRole] = QLatin1String("foreground");
- names[Qt::CheckStateRole] = QLatin1String("checkState");
- names[Qt::AccessibleTextRole] = QLatin1String("accessibleText");
- names[Qt::AccessibleDescriptionRole] = QLatin1String("accessibleDescription");
- names[Qt::SizeHintRole] = QLatin1String("sizeHint");
- return names;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/types/qqmltablemodelcolumn_p.h b/src/qml/types/qqmltablemodelcolumn_p.h
deleted file mode 100644
index 41c02482c0..0000000000
--- a/src/qml/types/qqmltablemodelcolumn_p.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLTABLEMODELCOLUMN_P_H
-#define QQMLTABLEMODELCOLUMN_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/QObject>
-#include <QtQml/qqml.h>
-#include <QtQml/private/qtqmlglobal_p.h>
-#include <QtQml/qjsvalue.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_QML_AUTOTEST_EXPORT QQmlTableModelColumn : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QJSValue display READ display WRITE setDisplay NOTIFY displayChanged FINAL)
- Q_PROPERTY(QJSValue setDisplay READ getSetDisplay WRITE setSetDisplay NOTIFY setDisplayChanged)
- Q_PROPERTY(QJSValue decoration READ decoration WRITE setDecoration NOTIFY decorationChanged FINAL)
- Q_PROPERTY(QJSValue setDecoration READ getSetDecoration WRITE setSetDecoration NOTIFY setDecorationChanged FINAL)
- Q_PROPERTY(QJSValue edit READ edit WRITE setEdit NOTIFY editChanged FINAL)
- Q_PROPERTY(QJSValue setEdit READ getSetEdit WRITE setSetEdit NOTIFY setEditChanged FINAL)
- Q_PROPERTY(QJSValue toolTip READ toolTip WRITE setToolTip NOTIFY toolTipChanged FINAL)
- Q_PROPERTY(QJSValue setToolTip READ getSetToolTip WRITE setSetToolTip NOTIFY setToolTipChanged FINAL)
- Q_PROPERTY(QJSValue statusTip READ statusTip WRITE setStatusTip NOTIFY statusTipChanged FINAL)
- Q_PROPERTY(QJSValue setStatusTip READ getSetStatusTip WRITE setSetStatusTip NOTIFY setStatusTipChanged FINAL)
- Q_PROPERTY(QJSValue whatsThis READ whatsThis WRITE setWhatsThis NOTIFY whatsThisChanged FINAL)
- Q_PROPERTY(QJSValue setWhatsThis READ getSetWhatsThis WRITE setSetWhatsThis NOTIFY setWhatsThisChanged FINAL)
-
- Q_PROPERTY(QJSValue font READ font WRITE setFont NOTIFY fontChanged FINAL)
- Q_PROPERTY(QJSValue setFont READ getSetFont WRITE setSetFont NOTIFY setFontChanged FINAL)
- Q_PROPERTY(QJSValue textAlignment READ textAlignment WRITE setTextAlignment NOTIFY textAlignmentChanged FINAL)
- Q_PROPERTY(QJSValue setTextAlignment READ getSetTextAlignment WRITE setSetTextAlignment NOTIFY setTextAlignmentChanged FINAL)
- Q_PROPERTY(QJSValue background READ background WRITE setBackground NOTIFY backgroundChanged FINAL)
- Q_PROPERTY(QJSValue setBackground READ getSetBackground WRITE setSetBackground NOTIFY setBackgroundChanged FINAL)
- Q_PROPERTY(QJSValue foreground READ foreground WRITE setForeground NOTIFY foregroundChanged FINAL)
- Q_PROPERTY(QJSValue setForeground READ getSetForeground WRITE setSetForeground NOTIFY setForegroundChanged FINAL)
- Q_PROPERTY(QJSValue checkState READ checkState WRITE setCheckState NOTIFY checkStateChanged FINAL)
- Q_PROPERTY(QJSValue setCheckState READ getSetCheckState WRITE setSetCheckState NOTIFY setCheckStateChanged FINAL)
-
- Q_PROPERTY(QJSValue accessibleText READ accessibleText WRITE setAccessibleText NOTIFY accessibleTextChanged FINAL)
- Q_PROPERTY(QJSValue setAccessibleText READ getSetAccessibleText WRITE setSetAccessibleText NOTIFY setAccessibleTextChanged FINAL)
- Q_PROPERTY(QJSValue accessibleDescription READ accessibleDescription
- WRITE setAccessibleDescription NOTIFY accessibleDescriptionChanged FINAL)
- Q_PROPERTY(QJSValue setAccessibleDescription READ getSetAccessibleDescription
- WRITE setSetAccessibleDescription NOTIFY setAccessibleDescriptionChanged FINAL)
-
- Q_PROPERTY(QJSValue sizeHint READ sizeHint WRITE setSizeHint NOTIFY sizeHintChanged FINAL)
- Q_PROPERTY(QJSValue setSizeHint READ getSetSizeHint WRITE setSetSizeHint NOTIFY setSizeHintChanged FINAL)
-
-public:
- QQmlTableModelColumn(QObject *parent = nullptr);
- ~QQmlTableModelColumn() override;
-
- QJSValue display() const;
- void setDisplay(const QJSValue &stringOrFunction);
- QJSValue getSetDisplay() const;
- void setSetDisplay(const QJSValue &function);
-
- QJSValue decoration() const;
- void setDecoration(const QJSValue &stringOrFunction);
- QJSValue getSetDecoration() const;
- void setSetDecoration(const QJSValue &function);
-
- QJSValue edit() const;
- void setEdit(const QJSValue &stringOrFunction);
- QJSValue getSetEdit() const;
- void setSetEdit(const QJSValue &function);
-
- QJSValue toolTip() const;
- void setToolTip(const QJSValue &stringOrFunction);
- QJSValue getSetToolTip() const;
- void setSetToolTip(const QJSValue &function);
-
- QJSValue statusTip() const;
- void setStatusTip(const QJSValue &stringOrFunction);
- QJSValue getSetStatusTip() const;
- void setSetStatusTip(const QJSValue &function);
-
- QJSValue whatsThis() const;
- void setWhatsThis(const QJSValue &stringOrFunction);
- QJSValue getSetWhatsThis() const;
- void setSetWhatsThis(const QJSValue &function);
-
- QJSValue font() const;
- void setFont(const QJSValue &stringOrFunction);
- QJSValue getSetFont() const;
- void setSetFont(const QJSValue &function);
-
- QJSValue textAlignment() const;
- void setTextAlignment(const QJSValue &stringOrFunction);
- QJSValue getSetTextAlignment() const;
- void setSetTextAlignment(const QJSValue &function);
-
- QJSValue background() const;
- void setBackground(const QJSValue &stringOrFunction);
- QJSValue getSetBackground() const;
- void setSetBackground(const QJSValue &function);
-
- QJSValue foreground() const;
- void setForeground(const QJSValue &stringOrFunction);
- QJSValue getSetForeground() const;
- void setSetForeground(const QJSValue &function);
-
- QJSValue checkState() const;
- void setCheckState(const QJSValue &stringOrFunction);
- QJSValue getSetCheckState() const;
- void setSetCheckState(const QJSValue &function);
-
- QJSValue accessibleText() const;
- void setAccessibleText(const QJSValue &stringOrFunction);
- QJSValue getSetAccessibleText() const;
- void setSetAccessibleText(const QJSValue &function);
-
- QJSValue accessibleDescription() const;
- void setAccessibleDescription(const QJSValue &stringOrFunction);
- QJSValue getSetAccessibleDescription() const;
- void setSetAccessibleDescription(const QJSValue &function);
-
- QJSValue sizeHint() const;
- void setSizeHint(const QJSValue &stringOrFunction);
- QJSValue getSetSizeHint() const;
- void setSetSizeHint(const QJSValue &function);
-
- QJSValue getterAtRole(const QString &roleName);
- QJSValue setterAtRole(const QString &roleName);
-
- const QHash<QString, QJSValue> getters() const;
-
- static const QHash<int, QString> supportedRoleNames();
-
-Q_SIGNALS:
- void indexChanged();
- void displayChanged();
- void setDisplayChanged();
- void decorationChanged();
- void setDecorationChanged();
- void editChanged();
- void setEditChanged();
- void toolTipChanged();
- void setToolTipChanged();
- void statusTipChanged();
- void setStatusTipChanged();
- void whatsThisChanged();
- void setWhatsThisChanged();
-
- void fontChanged();
- void setFontChanged();
- void textAlignmentChanged();
- void setTextAlignmentChanged();
- void backgroundChanged();
- void setBackgroundChanged();
- void foregroundChanged();
- void setForegroundChanged();
- void checkStateChanged();
- void setCheckStateChanged();
-
- void accessibleTextChanged();
- void setAccessibleTextChanged();
- void accessibleDescriptionChanged();
- void setAccessibleDescriptionChanged();
- void sizeHintChanged();
- void setSizeHintChanged();
-
-private:
- int mIndex = -1;
-
- // We store these in hashes because QQuickTableModel needs string-based lookup in certain situations.
- QHash<QString, QJSValue> mGetters;
- QHash<QString, QJSValue> mSetters;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQmlTableModelColumn)
-
-#endif // QQMLTABLEMODELCOLUMN_P_H
diff --git a/src/qml/types/qquickpackage.cpp b/src/qml/types/qquickpackage.cpp
deleted file mode 100644
index 03539d8737..0000000000
--- a/src/qml/types/qquickpackage.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpackage_p.h"
-
-#include <private/qobject_p.h>
-#include <private/qqmlguard_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype Package
- \instantiates QQuickPackage
- \inqmlmodule QtQuick
- \ingroup qtquick-views
- \brief Specifies a collection of named items.
-
- The Package type is used in conjunction with
- DelegateModel to enable delegates with a shared context
- to be provided to multiple views.
-
- Any item within a Package may be assigned a name via the
- \l{Package::name}{Package.name} attached property.
-
- The example below creates a Package containing two named items;
- \e list and \e grid. The third item in the package (the \l Rectangle) is parented to whichever
- delegate it should appear in. This allows an item to move
- between views.
-
- \snippet package/Delegate.qml 0
-
- These named items are used as the delegates by the two views who
- reference the special \l{DelegateModel::parts} property to select
- a model which provides the chosen delegate.
-
- \snippet package/view.qml 0
-
- \sa {Qt Quick Examples - Views}, {Qt Quick Demo - Photo Viewer}, {Qt QML}
-*/
-
-/*!
- \qmlattachedproperty string QtQuick::Package::name
- This attached property holds the name of an item within a Package.
-*/
-
-
-class QQuickPackagePrivate : public QObjectPrivate
-{
-public:
- QQuickPackagePrivate() {}
-
- struct DataGuard : public QQmlGuard<QObject>
- {
- DataGuard(QObject *obj, QList<DataGuard> *l) : list(l) { (QQmlGuard<QObject>&)*this = obj; }
- QList<DataGuard> *list;
- void objectDestroyed(QObject *) override {
- // we assume priv will always be destroyed after objectDestroyed calls
- list->removeOne(*this);
- }
- };
-
- QList<DataGuard> dataList;
- static void data_append(QQmlListProperty<QObject> *prop, QObject *o) {
- QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
- list->append(DataGuard(o, list));
- }
- static void data_clear(QQmlListProperty<QObject> *prop) {
- QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
- list->clear();
- }
- static QObject *data_at(QQmlListProperty<QObject> *prop, int index) {
- QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
- return list->at(index);
- }
- static int data_count(QQmlListProperty<QObject> *prop) {
- QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
- return list->count();
- }
-};
-
-QHash<QObject *, QQuickPackageAttached *> QQuickPackageAttached::attached;
-
-QQuickPackageAttached::QQuickPackageAttached(QObject *parent)
-: QObject(parent)
-{
- attached.insert(parent, this);
-}
-
-QQuickPackageAttached::~QQuickPackageAttached()
-{
- attached.remove(parent());
-}
-
-QString QQuickPackageAttached::name() const
-{
- return _name;
-}
-
-void QQuickPackageAttached::setName(const QString &n)
-{
- _name = n;
-}
-
-QQuickPackage::QQuickPackage(QObject *parent)
- : QObject(*(new QQuickPackagePrivate), parent)
-{
-}
-
-QQuickPackage::~QQuickPackage()
-{
-}
-
-QQmlListProperty<QObject> QQuickPackage::data()
-{
- Q_D(QQuickPackage);
- return QQmlListProperty<QObject>(this, &d->dataList, QQuickPackagePrivate::data_append,
- QQuickPackagePrivate::data_count,
- QQuickPackagePrivate::data_at,
- QQuickPackagePrivate::data_clear);
-}
-
-bool QQuickPackage::hasPart(const QString &name)
-{
- Q_D(QQuickPackage);
- for (int ii = 0; ii < d->dataList.count(); ++ii) {
- QObject *obj = d->dataList.at(ii);
- QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj);
- if (a && a->name() == name)
- return true;
- }
- return false;
-}
-
-QObject *QQuickPackage::part(const QString &name)
-{
- Q_D(QQuickPackage);
- if (name.isEmpty() && !d->dataList.isEmpty())
- return d->dataList.at(0);
-
- for (int ii = 0; ii < d->dataList.count(); ++ii) {
- QObject *obj = d->dataList.at(ii);
- QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj);
- if (a && a->name() == name)
- return obj;
- }
-
- if (name == QLatin1String("default") && !d->dataList.isEmpty())
- return d->dataList.at(0);
-
- return nullptr;
-}
-
-QQuickPackageAttached *QQuickPackage::qmlAttachedProperties(QObject *o)
-{
- return new QQuickPackageAttached(o);
-}
-
-
-
-QT_END_NAMESPACE
-
-#include "moc_qquickpackage_p.cpp"
diff --git a/src/qml/types/qquickpackage_p.h b/src/qml/types/qquickpackage_p.h
deleted file mode 100644
index 122c7fcb30..0000000000
--- a/src/qml/types/qquickpackage_p.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPACKAGE_H
-#define QQUICKPACKAGE_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qqml.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPackagePrivate;
-class QQuickPackageAttached;
-class Q_AUTOTEST_EXPORT QQuickPackage : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QQuickPackage)
-
- Q_CLASSINFO("DefaultProperty", "data")
- Q_PROPERTY(QQmlListProperty<QObject> data READ data)
-
-public:
- QQuickPackage(QObject *parent=nullptr);
- virtual ~QQuickPackage();
-
- QQmlListProperty<QObject> data();
-
- QObject *part(const QString & = QString());
- bool hasPart(const QString &);
-
- static QQuickPackageAttached *qmlAttachedProperties(QObject *);
-};
-
-class QQuickPackageAttached : public QObject
-{
-Q_OBJECT
-Q_PROPERTY(QString name READ name WRITE setName)
-public:
- QQuickPackageAttached(QObject *parent);
- virtual ~QQuickPackageAttached();
-
- QString name() const;
- void setName(const QString &n);
-
- static QHash<QObject *, QQuickPackageAttached *> attached;
-private:
- QString _name;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickPackage)
-QML_DECLARE_TYPEINFO(QQuickPackage, QML_HAS_ATTACHED_PROPERTIES)
-
-#endif // QQUICKPACKAGE_H
diff --git a/src/qml/types/types.pri b/src/qml/types/types.pri
index 5a56208dc4..ba11271d66 100644
--- a/src/qml/types/types.pri
+++ b/src/qml/types/types.pri
@@ -1,27 +1,12 @@
SOURCES += \
$$PWD/qqmlbind.cpp \
$$PWD/qqmlconnections.cpp \
- $$PWD/qqmlmodelsmodule.cpp \
- $$PWD/qqmlmodelindexvaluetype.cpp \
- $$PWD/qqmlobjectmodel.cpp \
- $$PWD/qquickpackage.cpp \
- $$PWD/qqmlinstantiator.cpp \
- $$PWD/qqmltableinstancemodel.cpp \
- $$PWD/qqmltablemodel.cpp \
- $$PWD/qqmltablemodelcolumn.cpp
+ $$PWD/qqmlmodelindexvaluetype.cpp
HEADERS += \
$$PWD/qqmlbind_p.h \
$$PWD/qqmlconnections_p.h \
- $$PWD/qqmlmodelsmodule_p.h \
- $$PWD/qqmlmodelindexvaluetype_p.h \
- $$PWD/qqmlobjectmodel_p.h \
- $$PWD/qquickpackage_p.h \
- $$PWD/qqmlinstantiator_p.h \
- $$PWD/qqmlinstantiator_p_p.h \
- $$PWD/qqmltableinstancemodel_p.h \
- $$PWD/qqmltablemodel_p.h \
- $$PWD/qqmltablemodelcolumn_p.h
+ $$PWD/qqmlmodelindexvaluetype_p.h
qtConfig(qml-worker-script) {
SOURCES += \
@@ -30,28 +15,6 @@ qtConfig(qml-worker-script) {
$$PWD/qquickworkerscript_p.h
}
-qtConfig(qml-list-model) {
- SOURCES += \
- $$PWD/qqmllistmodel.cpp \
- $$PWD/qqmllistmodelworkeragent.cpp
-
- HEADERS += \
- $$PWD/qqmllistmodel_p.h \
- $$PWD/qqmllistmodel_p_p.h \
- $$PWD/qqmllistmodelworkeragent_p.h
-}
-
-qtConfig(qml-delegate-model) {
- SOURCES += \
- $$PWD/qqmldelegatemodel.cpp \
- $$PWD/qqmldelegatecomponent.cpp
-
- HEADERS += \
- $$PWD/qqmldelegatemodel_p.h \
- $$PWD/qqmldelegatemodel_p_p.h \
- $$PWD/qqmldelegatecomponent_p.h
-}
-
qtConfig(qml-animation) {
SOURCES += \
$$PWD/qqmltimer.cpp
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
deleted file mode 100644
index f991ae0a69..0000000000
--- a/src/qml/util/qqmladaptormodel.cpp
+++ /dev/null
@@ -1,1037 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmladaptormodel_p.h"
-
-#include <private/qqmldelegatemodel_p_p.h>
-#include <private/qmetaobjectbuilder_p.h>
-#include <private/qqmlproperty_p.h>
-
-#include <private/qv4value_p.h>
-#include <private/qv4functionobject_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlAdaptorModelEngineData : public QV8Engine::Deletable
-{
-public:
- QQmlAdaptorModelEngineData(QV4::ExecutionEngine *v4);
- ~QQmlAdaptorModelEngineData();
-
- QV4::ExecutionEngine *v4;
- QV4::PersistentValue listItemProto;
-};
-
-V4_DEFINE_EXTENSION(QQmlAdaptorModelEngineData, engineData)
-
-static QV4::ReturnedValue get_index(const QV4::FunctionObject *f, const QV4::Value *thisObject, const QV4::Value *, int)
-{
- QV4::Scope scope(f);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
- if (!o)
- RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid DelegateModel object")));
-
- RETURN_RESULT(QV4::Encode(o->d()->item->index));
-}
-
-template <typename T, typename M> static void setModelDataType(QMetaObjectBuilder *builder, M *metaType)
-{
- builder->setFlags(QMetaObjectBuilder::DynamicMetaObject);
- builder->setClassName(T::staticMetaObject.className());
- builder->setSuperClass(&T::staticMetaObject);
- metaType->propertyOffset = T::staticMetaObject.propertyCount();
- metaType->signalOffset = T::staticMetaObject.methodCount();
-}
-
-static void addProperty(QMetaObjectBuilder *builder, int propertyId, const QByteArray &propertyName, const QByteArray &propertyType)
-{
- builder->addSignal("__" + QByteArray::number(propertyId) + "()");
- QMetaPropertyBuilder property = builder->addProperty(
- propertyName, propertyType, propertyId);
- property.setWritable(true);
-}
-
-class VDMModelDelegateDataType;
-
-class QQmlDMCachedModelData : public QQmlDelegateModelItem
-{
-public:
- QQmlDMCachedModelData(
- QQmlDelegateModelItemMetaType *metaType,
- VDMModelDelegateDataType *dataType,
- int index, int row, int column);
-
- int metaCall(QMetaObject::Call call, int id, void **arguments);
-
- virtual QVariant value(int role) const = 0;
- virtual void setValue(int role, const QVariant &value) = 0;
-
- void setValue(const QString &role, const QVariant &value) override;
- bool resolveIndex(const QQmlAdaptorModel &model, int idx) override;
-
- static QV4::ReturnedValue get_property(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
- static QV4::ReturnedValue set_property(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
-
- VDMModelDelegateDataType *type;
- QVector<QVariant> cachedData;
-};
-
-class VDMModelDelegateDataType
- : public QQmlRefCount
- , public QQmlAdaptorModel::Accessors
- , public QAbstractDynamicMetaObject
-{
-public:
- VDMModelDelegateDataType(QQmlAdaptorModel *model)
- : model(model)
- , propertyOffset(0)
- , signalOffset(0)
- , hasModelData(false)
- {
- }
-
- bool notify(
- const QQmlAdaptorModel &,
- const QList<QQmlDelegateModelItem *> &items,
- int index,
- int count,
- const QVector<int> &roles) const override
- {
- bool changed = roles.isEmpty() && !watchedRoles.isEmpty();
- if (!changed && !watchedRoles.isEmpty() && watchedRoleIds.isEmpty()) {
- QList<int> roleIds;
- for (const QByteArray &r : watchedRoles) {
- QHash<QByteArray, int>::const_iterator it = roleNames.find(r);
- if (it != roleNames.end())
- roleIds << it.value();
- }
- const_cast<VDMModelDelegateDataType *>(this)->watchedRoleIds = roleIds;
- }
-
- QVector<int> signalIndexes;
- for (int i = 0; i < roles.count(); ++i) {
- const int role = roles.at(i);
- if (!changed && watchedRoleIds.contains(role))
- changed = true;
-
- int propertyId = propertyRoles.indexOf(role);
- if (propertyId != -1)
- signalIndexes.append(propertyId + signalOffset);
- }
- if (roles.isEmpty()) {
- const int propertyRolesCount = propertyRoles.count();
- signalIndexes.reserve(propertyRolesCount);
- for (int propertyId = 0; propertyId < propertyRolesCount; ++propertyId)
- signalIndexes.append(propertyId + signalOffset);
- }
-
- for (int i = 0, c = items.count(); i < c; ++i) {
- QQmlDelegateModelItem *item = items.at(i);
- const int idx = item->modelIndex();
- if (idx >= index && idx < index + count) {
- for (int i = 0; i < signalIndexes.count(); ++i)
- QMetaObject::activate(item, signalIndexes.at(i), nullptr);
- }
- }
- return changed;
- }
-
- void replaceWatchedRoles(
- QQmlAdaptorModel &,
- const QList<QByteArray> &oldRoles,
- const QList<QByteArray> &newRoles) const override
- {
- VDMModelDelegateDataType *dataType = const_cast<VDMModelDelegateDataType *>(this);
-
- dataType->watchedRoleIds.clear();
- for (const QByteArray &oldRole : oldRoles)
- dataType->watchedRoles.removeOne(oldRole);
- dataType->watchedRoles += newRoles;
- }
-
- static QV4::ReturnedValue get_hasModelChildren(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
- {
- QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
- if (!o)
- RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid DelegateModel object")));
-
- const QQmlAdaptorModel *const model = static_cast<QQmlDMCachedModelData *>(o->d()->item)->type->model;
- if (o->d()->item->index >= 0 && *model) {
- const QAbstractItemModel * const aim = model->aim();
- RETURN_RESULT(QV4::Encode(aim->hasChildren(aim->index(o->d()->item->index, 0, model->rootIndex))));
- } else {
- RETURN_RESULT(QV4::Encode(false));
- }
- }
-
-
- void initializeConstructor(QQmlAdaptorModelEngineData *const data)
- {
- QV4::ExecutionEngine *v4 = data->v4;
- QV4::Scope scope(v4);
- QV4::ScopedObject proto(scope, v4->newObject());
- proto->defineAccessorProperty(QStringLiteral("index"), get_index, nullptr);
- proto->defineAccessorProperty(QStringLiteral("hasModelChildren"), get_hasModelChildren, nullptr);
- QV4::ScopedProperty p(scope);
-
- typedef QHash<QByteArray, int>::const_iterator iterator;
- for (iterator it = roleNames.constBegin(), end = roleNames.constEnd(); it != end; ++it) {
- const int propertyId = propertyRoles.indexOf(it.value());
- const QByteArray &propertyName = it.key();
-
- QV4::ScopedString name(scope, v4->newString(QString::fromUtf8(propertyName)));
- QV4::ExecutionContext *global = v4->rootContext();
- QV4::ScopedFunctionObject g(scope, v4->memoryManager->allocate<QV4::IndexedBuiltinFunction>(global, propertyId, QQmlDMCachedModelData::get_property));
- QV4::ScopedFunctionObject s(scope, v4->memoryManager->allocate<QV4::IndexedBuiltinFunction>(global, propertyId, QQmlDMCachedModelData::set_property));
- p->setGetter(g);
- p->setSetter(s);
- proto->insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable);
- }
- prototype.set(v4, proto);
- }
-
- // QAbstractDynamicMetaObject
-
- void objectDestroyed(QObject *) override
- {
- release();
- }
-
- int metaCall(QObject *object, QMetaObject::Call call, int id, void **arguments) override
- {
- return static_cast<QQmlDMCachedModelData *>(object)->metaCall(call, id, arguments);
- }
-
- QV4::PersistentValue prototype;
- QList<int> propertyRoles;
- QList<int> watchedRoleIds;
- QList<QByteArray> watchedRoles;
- QHash<QByteArray, int> roleNames;
- QQmlAdaptorModel *model;
- int propertyOffset;
- int signalOffset;
- bool hasModelData;
-};
-
-QQmlDMCachedModelData::QQmlDMCachedModelData(QQmlDelegateModelItemMetaType *metaType, VDMModelDelegateDataType *dataType, int index, int row, int column)
- : QQmlDelegateModelItem(metaType, dataType, index, row, column)
- , type(dataType)
-{
- if (index == -1)
- cachedData.resize(type->hasModelData ? 1 : type->propertyRoles.count());
-
- QObjectPrivate::get(this)->metaObject = type;
-
- type->addref();
-}
-
-int QQmlDMCachedModelData::metaCall(QMetaObject::Call call, int id, void **arguments)
-{
- if (call == QMetaObject::ReadProperty && id >= type->propertyOffset) {
- const int propertyIndex = id - type->propertyOffset;
- if (index == -1) {
- if (!cachedData.isEmpty()) {
- *static_cast<QVariant *>(arguments[0]) = cachedData.at(
- type->hasModelData ? 0 : propertyIndex);
- }
- } else if (*type->model) {
- *static_cast<QVariant *>(arguments[0]) = value(type->propertyRoles.at(propertyIndex));
- }
- return -1;
- } else if (call == QMetaObject::WriteProperty && id >= type->propertyOffset) {
- const int propertyIndex = id - type->propertyOffset;
- if (index == -1) {
- const QMetaObject *meta = metaObject();
- if (cachedData.count() > 1) {
- cachedData[propertyIndex] = *static_cast<QVariant *>(arguments[0]);
- QMetaObject::activate(this, meta, propertyIndex, nullptr);
- } else if (cachedData.count() == 1) {
- cachedData[0] = *static_cast<QVariant *>(arguments[0]);
- QMetaObject::activate(this, meta, 0, nullptr);
- QMetaObject::activate(this, meta, 1, nullptr);
- }
- } else if (*type->model) {
- setValue(type->propertyRoles.at(propertyIndex), *static_cast<QVariant *>(arguments[0]));
- }
- return -1;
- } else {
- return qt_metacall(call, id, arguments);
- }
-}
-
-void QQmlDMCachedModelData::setValue(const QString &role, const QVariant &value)
-{
- QHash<QByteArray, int>::iterator it = type->roleNames.find(role.toUtf8());
- if (it != type->roleNames.end()) {
- for (int i = 0; i < type->propertyRoles.count(); ++i) {
- if (type->propertyRoles.at(i) == *it) {
- cachedData[i] = value;
- return;
- }
- }
- }
-}
-
-bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &adaptorModel, int idx)
-{
- if (index == -1) {
- Q_ASSERT(idx >= 0);
- cachedData.clear();
- setModelIndex(idx, adaptorModel.rowAt(idx), adaptorModel.columnAt(idx));
- const QMetaObject *meta = metaObject();
- const int propertyCount = type->propertyRoles.count();
- for (int i = 0; i < propertyCount; ++i)
- QMetaObject::activate(this, meta, i, nullptr);
- return true;
- } else {
- return false;
- }
-}
-
-QV4::ReturnedValue QQmlDMCachedModelData::get_property(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
-{
- QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
- if (!o)
- return scope.engine->throwTypeError(QStringLiteral("Not a valid DelegateModel object"));
-
- uint propertyId = static_cast<const QV4::IndexedBuiltinFunction *>(b)->d()->index;
-
- QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
- if (o->d()->item->index == -1) {
- if (!modelData->cachedData.isEmpty()) {
- return scope.engine->fromVariant(
- modelData->cachedData.at(modelData->type->hasModelData ? 0 : propertyId));
- }
- } else if (*modelData->type->model) {
- return scope.engine->fromVariant(
- modelData->value(modelData->type->propertyRoles.at(propertyId)));
- }
- return QV4::Encode::undefined();
-}
-
-QV4::ReturnedValue QQmlDMCachedModelData::set_property(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
-{
- QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
- if (!o)
- return scope.engine->throwTypeError(QStringLiteral("Not a valid DelegateModel object"));
- if (!argc)
- return scope.engine->throwTypeError();
-
- uint propertyId = static_cast<const QV4::IndexedBuiltinFunction *>(b)->d()->index;
-
- if (o->d()->item->index == -1) {
- QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
- if (!modelData->cachedData.isEmpty()) {
- if (modelData->cachedData.count() > 1) {
- modelData->cachedData[propertyId] = scope.engine->toVariant(argv[0], QVariant::Invalid);
- QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), propertyId, nullptr);
- } else if (modelData->cachedData.count() == 1) {
- modelData->cachedData[0] = scope.engine->toVariant(argv[0], QVariant::Invalid);
- QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 0, nullptr);
- QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 1, nullptr);
- }
- }
- }
- return QV4::Encode::undefined();
-}
-
-//-----------------------------------------------------------------
-// QAbstractItemModel
-//-----------------------------------------------------------------
-
-class QQmlDMAbstractItemModelData : public QQmlDMCachedModelData
-{
- Q_OBJECT
- Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT)
-
-public:
- QQmlDMAbstractItemModelData(
- QQmlDelegateModelItemMetaType *metaType,
- VDMModelDelegateDataType *dataType,
- int index, int row, int column)
- : QQmlDMCachedModelData(metaType, dataType, index, row, column)
- {
- }
-
- bool hasModelChildren() const
- {
- if (index >= 0 && *type->model) {
- const QAbstractItemModel * const model = type->model->aim();
- return model->hasChildren(model->index(row, column, type->model->rootIndex));
- } else {
- return false;
- }
- }
-
- QVariant value(int role) const override
- {
- return type->model->aim()->index(row, column, type->model->rootIndex).data(role);
- }
-
- void setValue(int role, const QVariant &value) override
- {
- type->model->aim()->setData(
- type->model->aim()->index(row, column, type->model->rootIndex), value, role);
- }
-
- QV4::ReturnedValue get() override
- {
- if (type->prototype.isUndefined()) {
- QQmlAdaptorModelEngineData * const data = engineData(v4);
- type->initializeConstructor(data);
- }
- QV4::Scope scope(v4);
- QV4::ScopedObject proto(scope, type->prototype.value());
- QV4::ScopedObject o(scope, proto->engine()->memoryManager->allocate<QQmlDelegateModelItemObject>(this));
- o->setPrototypeOf(proto);
- ++scriptRef;
- return o.asReturnedValue();
- }
-};
-
-class VDMAbstractItemModelDataType : public VDMModelDelegateDataType
-{
-public:
- VDMAbstractItemModelDataType(QQmlAdaptorModel *model)
- : VDMModelDelegateDataType(model)
- {
- }
-
- int rowCount(const QQmlAdaptorModel &model) const override
- {
- return model.aim()->rowCount(model.rootIndex);
- }
-
- int columnCount(const QQmlAdaptorModel &model) const override
- {
- return model.aim()->columnCount(model.rootIndex);
- }
-
- void cleanup(QQmlAdaptorModel &) const override
- {
- const_cast<VDMAbstractItemModelDataType *>(this)->release();
- }
-
- QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const override
- {
- QHash<QByteArray, int>::const_iterator it = roleNames.find(role.toUtf8());
- if (it != roleNames.end()) {
- return model.aim()->index(model.rowAt(index), model.columnAt(index), model.rootIndex).data(*it);
- } else if (role == QLatin1String("hasModelChildren")) {
- return QVariant(model.aim()->hasChildren(model.aim()->index(model.rowAt(index), model.columnAt(index), model.rootIndex)));
- } else {
- return QVariant();
- }
- }
-
- QVariant parentModelIndex(const QQmlAdaptorModel &model) const override
- {
- return model
- ? QVariant::fromValue(model.aim()->parent(model.rootIndex))
- : QVariant();
- }
-
- QVariant modelIndex(const QQmlAdaptorModel &model, int index) const override
- {
- return model
- ? QVariant::fromValue(model.aim()->index(model.rowAt(index), model.columnAt(index), model.rootIndex))
- : QVariant();
- }
-
- bool canFetchMore(const QQmlAdaptorModel &model) const override
- {
- return model && model.aim()->canFetchMore(model.rootIndex);
- }
-
- void fetchMore(QQmlAdaptorModel &model) const override
- {
- if (model)
- model.aim()->fetchMore(model.rootIndex);
- }
-
- QQmlDelegateModelItem *createItem(
- QQmlAdaptorModel &model,
- QQmlDelegateModelItemMetaType *metaType,
- int index, int row, int column) const override
- {
- VDMAbstractItemModelDataType *dataType = const_cast<VDMAbstractItemModelDataType *>(this);
- if (!metaObject)
- dataType->initializeMetaType(model);
- return new QQmlDMAbstractItemModelData(metaType, dataType, index, row, column);
- }
-
- void initializeMetaType(QQmlAdaptorModel &model)
- {
- QMetaObjectBuilder builder;
- setModelDataType<QQmlDMAbstractItemModelData>(&builder, this);
-
- const QByteArray propertyType = QByteArrayLiteral("QVariant");
- const QHash<int, QByteArray> names = model.aim()->roleNames();
- for (QHash<int, QByteArray>::const_iterator it = names.begin(), cend = names.end(); it != cend; ++it) {
- const int propertyId = propertyRoles.count();
- propertyRoles.append(it.key());
- roleNames.insert(it.value(), it.key());
- addProperty(&builder, propertyId, it.value(), propertyType);
- }
- if (propertyRoles.count() == 1) {
- hasModelData = true;
- const int role = names.begin().key();
- const QByteArray propertyName = QByteArrayLiteral("modelData");
-
- propertyRoles.append(role);
- roleNames.insert(propertyName, role);
- addProperty(&builder, 1, propertyName, propertyType);
- }
-
- metaObject.reset(builder.toMetaObject());
- *static_cast<QMetaObject *>(this) = *metaObject;
- propertyCache.adopt(new QQmlPropertyCache(metaObject.data(), model.modelItemRevision));
- }
-};
-
-//-----------------------------------------------------------------
-// QQmlListAccessor
-//-----------------------------------------------------------------
-
-class QQmlDMListAccessorData : public QQmlDelegateModelItem
-{
- Q_OBJECT
- Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
-public:
- QQmlDMListAccessorData(QQmlDelegateModelItemMetaType *metaType,
- QQmlAdaptorModel::Accessors *accessor,
- int index, int row, int column, const QVariant &value)
- : QQmlDelegateModelItem(metaType, accessor, index, row, column)
- , cachedData(value)
- {
- }
-
- QVariant modelData() const
- {
- return cachedData;
- }
-
- void setModelData(const QVariant &data)
- {
- if (data == cachedData)
- return;
-
- cachedData = data;
- emit modelDataChanged();
- }
-
- static QV4::ReturnedValue get_modelData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
- {
- QV4::ExecutionEngine *v4 = b->engine();
- const QQmlDelegateModelItemObject *o = thisObject->as<QQmlDelegateModelItemObject>();
- if (!o)
- return v4->throwTypeError(QStringLiteral("Not a valid DelegateModel object"));
-
- return v4->fromVariant(static_cast<QQmlDMListAccessorData *>(o->d()->item)->cachedData);
- }
-
- static QV4::ReturnedValue set_modelData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
- {
- QV4::ExecutionEngine *v4 = b->engine();
- const QQmlDelegateModelItemObject *o = thisObject->as<QQmlDelegateModelItemObject>();
- if (!o)
- return v4->throwTypeError(QStringLiteral("Not a valid DelegateModel object"));
- if (!argc)
- return v4->throwTypeError();
-
- static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(v4->toVariant(argv[0], QVariant::Invalid));
- return QV4::Encode::undefined();
- }
-
- QV4::ReturnedValue get() override
- {
- QQmlAdaptorModelEngineData *data = engineData(v4);
- QV4::Scope scope(v4);
- QV4::ScopedObject o(scope, v4->memoryManager->allocate<QQmlDelegateModelItemObject>(this));
- QV4::ScopedObject p(scope, data->listItemProto.value());
- o->setPrototypeOf(p);
- ++scriptRef;
- return o.asReturnedValue();
- }
-
- void setValue(const QString &role, const QVariant &value) override
- {
- if (role == QLatin1String("modelData"))
- cachedData = value;
- }
-
- bool resolveIndex(const QQmlAdaptorModel &model, int idx) override
- {
- if (index == -1) {
- index = idx;
- cachedData = model.list.at(idx);
- emit modelIndexChanged();
- emit modelDataChanged();
- return true;
- } else {
- return false;
- }
- }
-
-
-Q_SIGNALS:
- void modelDataChanged();
-
-private:
- QVariant cachedData;
-};
-
-
-class VDMListDelegateDataType : public QQmlRefCount, public QQmlAdaptorModel::Accessors
-{
-public:
- VDMListDelegateDataType()
- : QQmlRefCount()
- , QQmlAdaptorModel::Accessors()
- {}
-
- void cleanup(QQmlAdaptorModel &) const override
- {
- const_cast<VDMListDelegateDataType *>(this)->release();
- }
-
- int rowCount(const QQmlAdaptorModel &model) const override
- {
- return model.list.count();
- }
-
- int columnCount(const QQmlAdaptorModel &) const override
- {
- return 1;
- }
-
- QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const override
- {
- return role == QLatin1String("modelData")
- ? model.list.at(index)
- : QVariant();
- }
-
- QQmlDelegateModelItem *createItem(
- QQmlAdaptorModel &model,
- QQmlDelegateModelItemMetaType *metaType,
- int index, int row, int column) const override
- {
- VDMListDelegateDataType *dataType = const_cast<VDMListDelegateDataType *>(this);
- if (!propertyCache) {
- dataType->propertyCache.adopt(new QQmlPropertyCache(
- &QQmlDMListAccessorData::staticMetaObject, model.modelItemRevision));
- }
-
- return new QQmlDMListAccessorData(
- metaType,
- dataType,
- index, row, column,
- index >= 0 && index < model.list.count() ? model.list.at(index) : QVariant());
- }
-
- bool notify(const QQmlAdaptorModel &model, const QList<QQmlDelegateModelItem *> &items, int index, int count, const QVector<int> &) const override
- {
- for (auto modelItem : items) {
- const int modelItemIndex = modelItem->index;
- if (modelItemIndex < index || modelItemIndex >= index + count)
- continue;
-
- auto listModelItem = static_cast<QQmlDMListAccessorData *>(modelItem);
- QVariant updatedModelData = model.list.at(listModelItem->index);
- listModelItem->setModelData(updatedModelData);
- }
- return true;
- }
-};
-
-//-----------------------------------------------------------------
-// QObject
-//-----------------------------------------------------------------
-
-class VDMObjectDelegateDataType;
-class QQmlDMObjectData : public QQmlDelegateModelItem, public QQmlAdaptorModelProxyInterface
-{
- Q_OBJECT
- Q_PROPERTY(QObject *modelData READ modelData NOTIFY modelDataChanged)
- Q_INTERFACES(QQmlAdaptorModelProxyInterface)
-public:
- QQmlDMObjectData(
- QQmlDelegateModelItemMetaType *metaType,
- VDMObjectDelegateDataType *dataType,
- int index, int row, int column,
- QObject *object);
-
- void setModelData(QObject *modelData)
- {
- if (modelData == object)
- return;
-
- object = modelData;
- emit modelDataChanged();
- }
-
- QObject *modelData() const { return object; }
- QObject *proxiedObject() override { return object; }
-
- QPointer<QObject> object;
-
-Q_SIGNALS:
- void modelDataChanged();
-};
-
-class VDMObjectDelegateDataType : public QQmlRefCount, public QQmlAdaptorModel::Accessors
-{
-public:
- int propertyOffset;
- int signalOffset;
- bool shared;
- QMetaObjectBuilder builder;
-
- VDMObjectDelegateDataType()
- : propertyOffset(0)
- , signalOffset(0)
- , shared(true)
- {
- }
-
- VDMObjectDelegateDataType(const VDMObjectDelegateDataType &type)
- : QQmlRefCount()
- , QQmlAdaptorModel::Accessors()
- , propertyOffset(type.propertyOffset)
- , signalOffset(type.signalOffset)
- , shared(false)
- , builder(type.metaObject.data(), QMetaObjectBuilder::Properties
- | QMetaObjectBuilder::Signals
- | QMetaObjectBuilder::SuperClass
- | QMetaObjectBuilder::ClassName)
- {
- builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
- }
-
- int rowCount(const QQmlAdaptorModel &model) const override
- {
- return model.list.count();
- }
-
- int columnCount(const QQmlAdaptorModel &) const override
- {
- return 1;
- }
-
- QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const override
- {
- if (QObject *object = model.list.at(index).value<QObject *>())
- return object->property(role.toUtf8());
- return QVariant();
- }
-
- QQmlDelegateModelItem *createItem(
- QQmlAdaptorModel &model,
- QQmlDelegateModelItemMetaType *metaType,
- int index, int row, int column) const override
- {
- VDMObjectDelegateDataType *dataType = const_cast<VDMObjectDelegateDataType *>(this);
- if (!metaObject)
- dataType->initializeMetaType(model);
- return index >= 0 && index < model.list.count()
- ? new QQmlDMObjectData(metaType, dataType, index, row, column, qvariant_cast<QObject *>(model.list.at(index)))
- : nullptr;
- }
-
- void initializeMetaType(QQmlAdaptorModel &model)
- {
- Q_UNUSED(model);
- setModelDataType<QQmlDMObjectData>(&builder, this);
-
- metaObject.reset(builder.toMetaObject());
- // Note: ATM we cannot create a shared property cache for this class, since each model
- // object can have different properties. And to make those properties available to the
- // delegate, QQmlDMObjectData makes use of a QAbstractDynamicMetaObject subclass
- // (QQmlDMObjectDataMetaObject), which we cannot represent in a QQmlPropertyCache.
- // By not having a shared property cache, revisioned properties in QQmlDelegateModelItem
- // will always be available to the delegate, regardless of the import version.
- }
-
- void cleanup(QQmlAdaptorModel &) const override
- {
- const_cast<VDMObjectDelegateDataType *>(this)->release();
- }
-
- bool notify(const QQmlAdaptorModel &model, const QList<QQmlDelegateModelItem *> &items, int index, int count, const QVector<int> &) const override
- {
- for (auto modelItem : items) {
- const int modelItemIndex = modelItem->index;
- if (modelItemIndex < index || modelItemIndex >= index + count)
- continue;
-
- auto objectModelItem = static_cast<QQmlDMObjectData *>(modelItem);
- QObject *updatedModelData = qvariant_cast<QObject *>(model.list.at(objectModelItem->index));
- objectModelItem->setModelData(updatedModelData);
- }
- return true;
- }
-};
-
-class QQmlDMObjectDataMetaObject : public QAbstractDynamicMetaObject
-{
-public:
- QQmlDMObjectDataMetaObject(QQmlDMObjectData *data, VDMObjectDelegateDataType *type)
- : m_data(data)
- , m_type(type)
- {
- QObjectPrivate *op = QObjectPrivate::get(m_data);
- *static_cast<QMetaObject *>(this) = *type->metaObject;
- op->metaObject = this;
- m_type->addref();
- }
-
- ~QQmlDMObjectDataMetaObject()
- {
- m_type->release();
- }
-
- int metaCall(QObject *o, QMetaObject::Call call, int id, void **arguments) override
- {
- Q_ASSERT(o == m_data);
- Q_UNUSED(o);
-
- static const int objectPropertyOffset = QObject::staticMetaObject.propertyCount();
- if (id >= m_type->propertyOffset
- && (call == QMetaObject::ReadProperty
- || call == QMetaObject::WriteProperty
- || call == QMetaObject::ResetProperty)) {
- if (m_data->object)
- QMetaObject::metacall(m_data->object, call, id - m_type->propertyOffset + objectPropertyOffset, arguments);
- return -1;
- } else if (id >= m_type->signalOffset && call == QMetaObject::InvokeMetaMethod) {
- QMetaObject::activate(m_data, this, id - m_type->signalOffset, nullptr);
- return -1;
- } else {
- return m_data->qt_metacall(call, id, arguments);
- }
- }
-
- int createProperty(const char *name, const char *) override
- {
- if (!m_data->object)
- return -1;
- const QMetaObject *metaObject = m_data->object->metaObject();
- static const int objectPropertyOffset = QObject::staticMetaObject.propertyCount();
-
- const int previousPropertyCount = propertyCount() - propertyOffset();
- int propertyIndex = metaObject->indexOfProperty(name);
- if (propertyIndex == -1)
- return -1;
- if (previousPropertyCount + objectPropertyOffset == metaObject->propertyCount())
- return propertyIndex + m_type->propertyOffset - objectPropertyOffset;
-
- if (m_type->shared) {
- VDMObjectDelegateDataType *type = m_type;
- m_type = new VDMObjectDelegateDataType(*m_type);
- type->release();
- }
-
- const int previousMethodCount = methodCount();
- int notifierId = previousMethodCount - methodOffset();
- for (int propertyId = previousPropertyCount; propertyId < metaObject->propertyCount() - objectPropertyOffset; ++propertyId) {
- QMetaProperty property = metaObject->property(propertyId + objectPropertyOffset);
- QMetaPropertyBuilder propertyBuilder;
- if (property.hasNotifySignal()) {
- m_type->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
- propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName(), notifierId);
- ++notifierId;
- } else {
- propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName());
- }
- propertyBuilder.setWritable(property.isWritable());
- propertyBuilder.setResettable(property.isResettable());
- propertyBuilder.setConstant(property.isConstant());
- }
-
- m_type->metaObject.reset(m_type->builder.toMetaObject());
- *static_cast<QMetaObject *>(this) = *m_type->metaObject;
-
- notifierId = previousMethodCount;
- for (int i = previousPropertyCount; i < metaObject->propertyCount() - objectPropertyOffset; ++i) {
- QMetaProperty property = metaObject->property(i + objectPropertyOffset);
- if (property.hasNotifySignal()) {
- QQmlPropertyPrivate::connect(
- m_data->object, property.notifySignalIndex(), m_data, notifierId);
- ++notifierId;
- }
- }
- return propertyIndex + m_type->propertyOffset - objectPropertyOffset;
- }
-
- QQmlDMObjectData *m_data;
- VDMObjectDelegateDataType *m_type;
-};
-
-QQmlDMObjectData::QQmlDMObjectData(QQmlDelegateModelItemMetaType *metaType,
- VDMObjectDelegateDataType *dataType,
- int index, int row, int column,
- QObject *object)
- : QQmlDelegateModelItem(metaType, dataType, index, row, column)
- , object(object)
-{
- new QQmlDMObjectDataMetaObject(this, dataType);
-}
-
-//-----------------------------------------------------------------
-// QQmlAdaptorModel
-//-----------------------------------------------------------------
-
-static const QQmlAdaptorModel::Accessors qt_vdm_null_accessors;
-
-QQmlAdaptorModel::Accessors::~Accessors()
-{
-}
-
-QQmlAdaptorModel::QQmlAdaptorModel()
- : accessors(&qt_vdm_null_accessors)
-{
-}
-
-QQmlAdaptorModel::~QQmlAdaptorModel()
-{
- accessors->cleanup(*this);
-}
-
-void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *parent, QQmlEngine *engine)
-{
- accessors->cleanup(*this);
-
- list.setList(variant, engine);
-
- if (QObject *object = qvariant_cast<QObject *>(list.list())) {
- setObject(object, parent);
- if (qobject_cast<QAbstractItemModel *>(object))
- accessors = new VDMAbstractItemModelDataType(this);
- else
- accessors = new VDMObjectDelegateDataType;
- } else if (list.type() == QQmlListAccessor::ListProperty) {
- setObject(static_cast<const QQmlListReference *>(variant.constData())->object(), parent);
- accessors = new VDMObjectDelegateDataType;
- } else if (list.type() != QQmlListAccessor::Invalid
- && list.type() != QQmlListAccessor::Instance) { // Null QObject
- setObject(nullptr, parent);
- accessors = new VDMListDelegateDataType;
- } else {
- setObject(nullptr, parent);
- accessors = &qt_vdm_null_accessors;
- }
-}
-
-void QQmlAdaptorModel::invalidateModel()
-{
- accessors->cleanup(*this);
- accessors = &qt_vdm_null_accessors;
- // Don't clear the model object as we still need the guard to clear the list variant if the
- // object is destroyed.
-}
-
-bool QQmlAdaptorModel::isValid() const
-{
- return accessors != &qt_vdm_null_accessors;
-}
-
-int QQmlAdaptorModel::count() const
-{
- return rowCount() * columnCount();
-}
-
-int QQmlAdaptorModel::rowCount() const
-{
- return qMax(0, accessors->rowCount(*this));
-}
-
-int QQmlAdaptorModel::columnCount() const
-{
- return qMax(0, accessors->columnCount(*this));
-}
-
-int QQmlAdaptorModel::rowAt(int index) const
-{
- int count = rowCount();
- return count <= 0 ? -1 : index % count;
-}
-
-int QQmlAdaptorModel::columnAt(int index) const
-{
- int count = rowCount();
- return count <= 0 ? -1 : index / count;
-}
-
-int QQmlAdaptorModel::indexAt(int row, int column) const
-{
- return column * rowCount() + row;
-}
-
-void QQmlAdaptorModel::useImportVersion(int minorVersion)
-{
- modelItemRevision = minorVersion;
-}
-
-void QQmlAdaptorModel::objectDestroyed(QObject *)
-{
- setModel(QVariant(), nullptr, nullptr);
-}
-
-QQmlAdaptorModelEngineData::QQmlAdaptorModelEngineData(QV4::ExecutionEngine *v4)
- : v4(v4)
-{
- QV4::Scope scope(v4);
- QV4::ScopedObject proto(scope, v4->newObject());
- proto->defineAccessorProperty(QStringLiteral("index"), get_index, nullptr);
- proto->defineAccessorProperty(QStringLiteral("modelData"),
- QQmlDMListAccessorData::get_modelData, QQmlDMListAccessorData::set_modelData);
- listItemProto.set(v4, proto);
-}
-
-QQmlAdaptorModelEngineData::~QQmlAdaptorModelEngineData()
-{
-}
-
-QT_END_NAMESPACE
-
-#include <qqmladaptormodel.moc>
diff --git a/src/qml/util/qqmladaptormodel_p.h b/src/qml/util/qqmladaptormodel_p.h
deleted file mode 100644
index 8c18466ab5..0000000000
--- a/src/qml/util/qqmladaptormodel_p.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLADAPTORMODEL_P_H
-#define QQMLADAPTORMODEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qabstractitemmodel.h>
-
-#include "private/qqmllistaccessor_p.h"
-#include <private/qqmlglobal_p.h>
-#include <private/qqmlguard_p.h>
-#include <private/qqmlnullablevalue_p.h>
-
-QT_REQUIRE_CONFIG(qml_delegate_model);
-
-QT_BEGIN_NAMESPACE
-
-class QQmlEngine;
-
-class QQmlDelegateModel;
-class QQmlDelegateModelItem;
-class QQmlDelegateModelItemMetaType;
-
-class Q_QML_PRIVATE_EXPORT QQmlAdaptorModel : public QQmlStrongJSQObjectReference<QObject>
-{
-public:
- class Accessors
- {
- public:
- inline Accessors() {}
- virtual ~Accessors();
- virtual int rowCount(const QQmlAdaptorModel &) const { return 0; }
- virtual int columnCount(const QQmlAdaptorModel &) const { return 0; }
- virtual void cleanup(QQmlAdaptorModel &) const {}
-
- virtual QVariant value(const QQmlAdaptorModel &, int, const QString &) const {
- return QVariant(); }
-
- virtual QQmlDelegateModelItem *createItem(
- QQmlAdaptorModel &,
- QQmlDelegateModelItemMetaType *,
- int, int, int) const { return nullptr; }
-
- virtual bool notify(
- const QQmlAdaptorModel &,
- const QList<QQmlDelegateModelItem *> &,
- int,
- int,
- const QVector<int> &) const { return false; }
- virtual void replaceWatchedRoles(
- QQmlAdaptorModel &,
- const QList<QByteArray> &,
- const QList<QByteArray> &) const {}
- virtual QVariant parentModelIndex(const QQmlAdaptorModel &) const {
- return QVariant(); }
- virtual QVariant modelIndex(const QQmlAdaptorModel &, int) const {
- return QVariant(); }
- virtual bool canFetchMore(const QQmlAdaptorModel &) const { return false; }
- virtual void fetchMore(QQmlAdaptorModel &) const {}
-
- QScopedPointer<QMetaObject, QScopedPointerPodDeleter> metaObject;
- QQmlRefPointer<QQmlPropertyCache> propertyCache;
- };
-
- const Accessors *accessors;
- QPersistentModelIndex rootIndex;
- QQmlListAccessor list;
-
- int modelItemRevision = 0;
-
- QQmlAdaptorModel();
- ~QQmlAdaptorModel();
-
- inline QVariant model() const { return list.list(); }
- void setModel(const QVariant &variant, QObject *parent, QQmlEngine *engine);
- void invalidateModel();
-
- bool isValid() const;
- int count() const;
- int rowCount() const;
- int columnCount() const;
- int rowAt(int index) const;
- int columnAt(int index) const;
- int indexAt(int row, int column) const;
-
- void useImportVersion(int minorVersion);
-
- inline bool adaptsAim() const { return qobject_cast<QAbstractItemModel *>(object()); }
- inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); }
- inline const QAbstractItemModel *aim() const { return static_cast<const QAbstractItemModel *>(object()); }
-
- inline QVariant value(int index, const QString &role) const {
- return accessors->value(*this, index, role); }
- inline QQmlDelegateModelItem *createItem(QQmlDelegateModelItemMetaType *metaType, int index) {
- return accessors->createItem(*this, metaType, index, rowAt(index), columnAt(index)); }
- inline bool hasProxyObject() const {
- return list.type() == QQmlListAccessor::Instance || list.type() == QQmlListAccessor::ListProperty; }
-
- inline bool notify(
- const QList<QQmlDelegateModelItem *> &items,
- int index,
- int count,
- const QVector<int> &roles) const {
- return accessors->notify(*this, items, index, count, roles); }
- inline void replaceWatchedRoles(
- const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles) {
- accessors->replaceWatchedRoles(*this, oldRoles, newRoles); }
-
- inline QVariant modelIndex(int index) const { return accessors->modelIndex(*this, index); }
- inline QVariant parentModelIndex() const { return accessors->parentModelIndex(*this); }
- inline bool canFetchMore() const { return accessors->canFetchMore(*this); }
- inline void fetchMore() { return accessors->fetchMore(*this); }
-
-protected:
- void objectDestroyed(QObject *) override;
-};
-
-class QQmlAdaptorModelProxyInterface
-{
-public:
- virtual ~QQmlAdaptorModelProxyInterface() {}
-
- virtual QObject *proxiedObject() = 0;
-};
-
-#define QQmlAdaptorModelProxyInterface_iid "org.qt-project.Qt.QQmlAdaptorModelProxyInterface"
-
-Q_DECLARE_INTERFACE(QQmlAdaptorModelProxyInterface, QQmlAdaptorModelProxyInterface_iid)
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/util/qqmlchangeset.cpp b/src/qml/util/qqmlchangeset.cpp
deleted file mode 100644
index ba876b42e2..0000000000
--- a/src/qml/util/qqmlchangeset.cpp
+++ /dev/null
@@ -1,583 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmlchangeset_p.h"
-
-QT_BEGIN_NAMESPACE
-
-
-/*!
- \class QQmlChangeSet
- \brief The QQmlChangeSet class stores an ordered list of notifications about
- changes to a linear data set.
- \internal
-
- QQmlChangeSet can be used to record a series of notifications about items in an indexed list
- being inserted, removed, moved, and changed. Notifications in the set are re-ordered so that
- all notifications of a single type are grouped together and sorted in order of ascending index,
- with remove notifications preceding all others, followed by insert notification, and then
- change notifications.
-
- Moves in a change set are represented by a remove notification paired with an insert
- notification by way of a shared unique moveId. Re-ordering may result in one or both of the
- paired notifications being divided, when this happens the offset member of the notification
- will indicate the relative offset of the divided notification from the beginning of the
- original.
-*/
-
-/*!
- Constructs an empty change set.
-*/
-
-QQmlChangeSet::QQmlChangeSet()
- : m_difference(0)
-{
-}
-
-/*!
- Constructs a copy of a \a changeSet.
-*/
-
-QQmlChangeSet::QQmlChangeSet(const QQmlChangeSet &changeSet)
- : m_removes(changeSet.m_removes)
- , m_inserts(changeSet.m_inserts)
- , m_changes(changeSet.m_changes)
- , m_difference(changeSet.m_difference)
-{
-}
-
-/*!
- Destroys a change set.
-*/
-
-QQmlChangeSet::~QQmlChangeSet()
-{
-}
-
-/*!
- Assigns the value of a \a changeSet to another.
-*/
-
-QQmlChangeSet &QQmlChangeSet::operator =(const QQmlChangeSet &changeSet)
-{
- m_removes = changeSet.m_removes;
- m_inserts = changeSet.m_inserts;
- m_changes = changeSet.m_changes;
- m_difference = changeSet.m_difference;
- return *this;
-}
-
-/*!
- Appends a notification that \a count items were inserted at \a index.
-*/
-
-void QQmlChangeSet::insert(int index, int count)
-{
- insert(QVector<Change>() << Change(index, count));
-}
-
-/*!
- Appends a notification that \a count items were removed at \a index.
-*/
-
-void QQmlChangeSet::remove(int index, int count)
-{
- QVector<Change> removes;
- removes.append(Change(index, count));
- remove(&removes, nullptr);
-}
-
-/*!
- Appends a notification that \a count items were moved \a from one index \a to another.
-
- The \a moveId must be unique across the lifetime of the change set and any related
- change sets.
-*/
-
-void QQmlChangeSet::move(int from, int to, int count, int moveId)
-{
- QVector<Change> removes;
- removes.append(Change(from, count, moveId));
- QVector<Change> inserts;
- inserts.append(Change(to, count, moveId));
- remove(&removes, &inserts);
- insert(inserts);
-}
-
-/*!
- Appends a notification that \a count items were changed at \a index.
-*/
-
-void QQmlChangeSet::change(int index, int count)
-{
- QVector<Change> changes;
- changes.append(Change(index, count));
- change(changes);
-}
-
-/*!
- Applies the changes in a \a changeSet to another.
-*/
-
-void QQmlChangeSet::apply(const QQmlChangeSet &changeSet)
-{
- QVector<Change> r = changeSet.m_removes;
- QVector<Change> i = changeSet.m_inserts;
- QVector<Change> c = changeSet.m_changes;
- remove(&r, &i);
- insert(i);
- change(c);
-}
-
-/*!
- Applies a list of \a removes to a change set.
-
- If a remove contains a moveId then any intersecting insert in the set will replace the
- corresponding intersection in the optional \a inserts list.
-*/
-
-void QQmlChangeSet::remove(const QVector<Change> &removes, QVector<Change> *inserts)
-{
- QVector<Change> r = removes;
- remove(&r, inserts);
-}
-
-void QQmlChangeSet::remove(QVector<Change> *removes, QVector<Change> *inserts)
-{
- int removeCount = 0;
- int insertCount = 0;
- QVector<Change>::iterator insert = m_inserts.begin();
- QVector<Change>::iterator change = m_changes.begin();
- QVector<Change>::iterator rit = removes->begin();
- for (; rit != removes->end(); ++rit) {
- int index = rit->index + removeCount;
- int count = rit->count;
-
- // Decrement the accumulated remove count from the indexes of any changes prior to the
- // current remove.
- for (; change != m_changes.end() && change->end() < rit->index; ++change)
- change->index -= removeCount;
- // Remove any portion of a change notification that intersects the current remove.
- for (; change != m_changes.end() && change->index > rit->end(); ++change) {
- change->count -= qMin(change->end(), rit->end()) - qMax(change->index, rit->index);
- if (change->count == 0) {
- change = m_changes.erase(change);
- } else if (rit->index < change->index) {
- change->index = rit->index;
- }
- }
-
- // Decrement the accumulated remove count from the indexes of any inserts prior to the
- // current remove.
- for (; insert != m_inserts.end() && insert->end() <= index; ++insert) {
- insertCount += insert->count;
- insert->index -= removeCount;
- }
-
- rit->index -= insertCount;
-
- // Remove any portion of a insert notification that intersects the current remove.
- while (insert != m_inserts.end() && insert->index < index + count) {
- int offset = index - insert->index;
- const int difference = qMin(insert->end(), index + count) - qMax(insert->index, index);
-
- // If part of the remove or insert that precedes the intersection has a moveId create
- // a new delta for that portion and subtract the size of that delta from the current
- // one.
- if (offset < 0 && rit->moveId != -1) {
- rit = removes->insert(rit, Change(
- rit->index, -offset, rit->moveId, rit->offset));
- ++rit;
- rit->count -= -offset;
- rit->offset += -offset;
- index += -offset;
- count -= -offset;
- removeCount += -offset;
- offset = 0;
- } else if (offset > 0 && insert->moveId != -1) {
- insert = m_inserts.insert(insert, Change(
- insert->index - removeCount, offset, insert->moveId, insert->offset));
- ++insert;
- insert->index += offset;
- insert->count -= offset;
- insert->offset += offset;
- rit->index -= offset;
- insertCount += offset;
- }
-
- // If the current remove has a move id, find any inserts with the same move id and
- // replace the corresponding sections with the insert removed from the change set.
- if (rit->moveId != -1 && difference > 0 && inserts) {
- for (QVector<Change>::iterator iit = inserts->begin(); iit != inserts->end(); ++iit) {
- if (iit->moveId != rit->moveId
- || rit->offset > iit->offset + iit->count
- || iit->offset > rit->offset + difference) {
- continue;
- }
- // If the intersecting insert starts before the replacement one create
- // a new insert for the portion prior to the replacement insert.
- const int overlapOffset = rit->offset - iit->offset;
- if (overlapOffset > 0) {
- iit = inserts->insert(iit, Change(
- iit->index, overlapOffset, iit->moveId, iit->offset));
- ++iit;
- iit->index += overlapOffset;
- iit->count -= overlapOffset;
- iit->offset += overlapOffset;
- }
- if (iit->offset >= rit->offset
- && iit->offset + iit->count <= rit->offset + difference) {
- // If the replacement insert completely encapsulates the existing
- // one just change the moveId.
- iit->moveId = insert->moveId;
- iit->offset = insert->offset + qMax(0, -overlapOffset);
- } else {
- // Create a new insertion before the intersecting one with the number of intersecting
- // items and remove that number from that insert.
- const int count
- = qMin(iit->offset + iit->count, rit->offset + difference)
- - qMax(iit->offset, rit->offset);
- iit = inserts->insert(iit, Change(
- iit->index,
- count,
- insert->moveId,
- insert->offset + qMax(0, -overlapOffset)));
- ++iit;
- iit->index += count;
- iit->count -= count;
- iit->offset += count;
- }
- }
- }
-
- // Subtract the number of intersecting items from the current remove and insert.
- insert->count -= difference;
- insert->offset += difference;
- rit->count -= difference;
- rit->offset += difference;
-
- index += difference;
- count -= difference;
- removeCount += difference;
-
- if (insert->count == 0) {
- insert = m_inserts.erase(insert);
- } else if (rit->count == -offset || rit->count == 0) {
- insert->index += difference;
- break;
- } else {
- insert->index -= removeCount - difference;
- rit->index -= insert->count;
- insertCount += insert->count;
- ++insert;
- }
- }
- removeCount += rit->count;
- }
- for (; insert != m_inserts.end(); ++insert)
- insert->index -= removeCount;
-
- removeCount = 0;
- QVector<Change>::iterator remove = m_removes.begin();
- for (rit = removes->begin(); rit != removes->end(); ++rit) {
- if (rit->count == 0)
- continue;
- // Accumulate consecutive removes into a single delta before attempting to apply.
- for (QVector<Change>::iterator next = rit + 1; next != removes->end()
- && next->index == rit->index
- && next->moveId == -1
- && rit->moveId == -1; ++next) {
- next->count += rit->count;
- rit = next;
- }
- int index = rit->index + removeCount;
- // Decrement the accumulated remove count from the indexes of any inserts prior to the
- // current remove.
- for (; remove != m_removes.end() && index > remove->index; ++remove)
- remove->index -= removeCount;
- while (remove != m_removes.end() && index + rit->count >= remove->index) {
- int count = 0;
- const int offset = remove->index - index;
- QVector<Change>::iterator rend = remove;
- for (; rend != m_removes.end()
- && rit->moveId == -1
- && rend->moveId == -1
- && index + rit->count >= rend->index; ++rend) {
- count += rend->count;
- }
- if (remove != rend) {
- // Accumulate all existing non-move removes that are encapsulated by or immediately
- // follow the current remove into it.
- int difference = 0;
- if (rend == m_removes.end()) {
- difference = rit->count;
- } else if (rit->index + rit->count < rend->index - removeCount) {
- difference = rit->count;
- } else if (rend->moveId != -1) {
- difference = rend->index - removeCount - rit->index;
- index += difference;
- }
- count += difference;
-
- rit->count -= difference;
- removeCount += difference;
- remove->index = rit->index;
- remove->count = count;
- remove = m_removes.erase(++remove, rend);
- } else {
- // Insert a remove for the portion of the unmergable current remove prior to the
- // point of intersection.
- if (offset > 0) {
- remove = m_removes.insert(remove, Change(
- rit->index, offset, rit->moveId, rit->offset));
- ++remove;
- rit->count -= offset;
- rit->offset += offset;
- removeCount += offset;
- index += offset;
- }
- remove->index = rit->index;
-
- ++remove;
- }
- }
-
- if (rit->count > 0) {
- remove = m_removes.insert(remove, *rit);
- ++remove;
- }
- removeCount += rit->count;
- }
- for (; remove != m_removes.end(); ++remove)
- remove->index -= removeCount;
- m_difference -= removeCount;
-}
-
-/*!
- Applies a list of \a inserts to a change set.
-*/
-
-void QQmlChangeSet::insert(const QVector<Change> &inserts)
-{
- int insertCount = 0;
- QVector<Change>::iterator insert = m_inserts.begin();
- QVector<Change>::iterator change = m_changes.begin();
- for (QVector<Change>::const_iterator iit = inserts.begin(); iit != inserts.end(); ++iit) {
- if (iit->count == 0)
- continue;
- int index = iit->index - insertCount;
-
- Change current = *iit;
- // Accumulate consecutive inserts into a single delta before attempting to insert.
- for (QVector<Change>::const_iterator next = iit + 1; next != inserts.end()
- && next->index == iit->index + iit->count
- && next->moveId == -1
- && iit->moveId == -1; ++next) {
- current.count += next->count;
- iit = next;
- }
-
- // Increment the index of any changes before the current insert by the accumlated insert
- // count.
- for (; change != m_changes.end() && change->index >= index; ++change)
- change->index += insertCount;
- // If the current insert index is in the middle of a change split it in two at that
- // point and increment the index of the latter half.
- if (change != m_changes.end() && change->index < index + iit->count) {
- int offset = index - change->index;
- change = m_changes.insert(change, Change(change->index + insertCount, offset));
- ++change;
- change->index += iit->count + offset;
- change->count -= offset;
- }
-
- // Increment the index of any inserts before the current insert by the accumlated insert
- // count.
- for (; insert != m_inserts.end() && index > insert->index + insert->count; ++insert)
- insert->index += insertCount;
- if (insert == m_inserts.end()) {
- insert = m_inserts.insert(insert, current);
- ++insert;
- } else {
- const int offset = index - insert->index;
-
- if (offset < 0) {
- // If the current insert is before an existing insert and not adjacent just insert
- // it into the list.
- insert = m_inserts.insert(insert, current);
- ++insert;
- } else if (iit->moveId == -1 && insert->moveId == -1) {
- // If neither the current nor existing insert has a moveId add the current insert
- // to the existing one.
- if (offset < insert->count) {
- insert->index -= current.count;
- insert->count += current.count;
- } else {
- insert->index += insertCount;
- insert->count += current.count;
- ++insert;
- }
- } else if (offset < insert->count) {
- // If either insert has a moveId then split the existing insert and insert the
- // current one in the middle.
- if (offset > 0) {
- insert = m_inserts.insert(insert, Change(
- insert->index + insertCount, offset, insert->moveId, insert->offset));
- ++insert;
- insert->index += offset;
- insert->count -= offset;
- insert->offset += offset;
- }
- insert = m_inserts.insert(insert, current);
- ++insert;
- } else {
- insert->index += insertCount;
- ++insert;
- insert = m_inserts.insert(insert, current);
- ++insert;
- }
- }
- insertCount += current.count;
- }
- for (; insert != m_inserts.end(); ++insert)
- insert->index += insertCount;
- m_difference += insertCount;
-}
-
-/*!
- Applies a combined list of \a removes and \a inserts to a change set. This is equivalent
- calling \l remove() followed by \l insert() with the same lists.
-*/
-
-void QQmlChangeSet::move(const QVector<Change> &removes, const QVector<Change> &inserts)
-{
- QVector<Change> r = removes;
- QVector<Change> i = inserts;
- remove(&r, &i);
- insert(i);
-}
-
-/*!
- Applies a list of \a changes to a change set.
-*/
-
-void QQmlChangeSet::change(const QVector<Change> &changes)
-{
- QVector<Change> c = changes;
- change(&c);
-}
-
-void QQmlChangeSet::change(QVector<Change> *changes)
-{
- QVector<Change>::iterator insert = m_inserts.begin();
- QVector<Change>::iterator change = m_changes.begin();
- for (QVector<Change>::iterator cit = changes->begin(); cit != changes->end(); ++cit) {
- for (; insert != m_inserts.end() && insert->end() < cit->index; ++insert) {}
- for (; insert != m_inserts.end() && insert->index < cit->end(); ++insert) {
- const int offset = insert->index - cit->index;
- const int count = cit->count + cit->index - insert->index - insert->count;
- if (offset == 0) {
- cit->index = insert->index + insert->count;
- cit->count = count;
- } else {
- cit = changes->insert(++cit, Change(insert->index + insert->count, count));
- --cit;
- cit->count = offset;
- }
- }
-
- for (; change != m_changes.end() && change->index + change->count < cit->index; ++change) {}
- if (change == m_changes.end() || change->index > cit->index + cit->count) {
- if (cit->count > 0) {
- change = m_changes.insert(change, *cit);
- ++change;
- }
- } else {
- if (cit->index < change->index) {
- change->count += change->index - cit->index;
- change->index = cit->index;
- }
-
- if (cit->index + cit->count > change->index + change->count) {
- change->count = cit->index + cit->count - change->index;
- QVector<Change>::iterator cbegin = change;
- QVector<Change>::iterator cend = ++cbegin;
- for (; cend != m_changes.end() && cend->index <= change->index + change->count; ++cend) {
- if (cend->index + cend->count > change->index + change->count)
- change->count = cend->index + cend->count - change->index;
- }
- if (cbegin != cend) {
- change = m_changes.erase(cbegin, cend);
- --change;
- }
- }
- }
- }
-}
-
-/*!
- Prints the contents of a change \a set to the \a debug stream.
-*/
-
-QDebug operator <<(QDebug debug, const QQmlChangeSet &set)
-{
- debug.nospace() << "QQmlChangeSet(";
- const QVector<QQmlChangeSet::Change> &removes = set.removes();
- for (const QQmlChangeSet::Change &remove : removes)
- debug << remove;
- const QVector<QQmlChangeSet::Change> &inserts = set.inserts();
- for (const QQmlChangeSet::Change &insert : inserts)
- debug << insert;
- const QVector<QQmlChangeSet::Change> &changes = set.changes();
- for (const QQmlChangeSet::Change &change : changes)
- debug << change;
- return debug.nospace() << ')';
-}
-
-/*!
- Prints a \a change to the \a debug stream.
-*/
-
-QDebug operator <<(QDebug debug, const QQmlChangeSet::Change &change)
-{
- return (debug.nospace() << "Change(" << change.index << ',' << change.count << ')').space();
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/qml/util/qqmlchangeset_p.h b/src/qml/util/qqmlchangeset_p.h
deleted file mode 100644
index 8347a3ff19..0000000000
--- a/src/qml/util/qqmlchangeset_p.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLCHANGESET_P_H
-#define QQMLCHANGESET_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qvector.h>
-#include <QtQml/private/qtqmlglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_QML_PRIVATE_EXPORT QQmlChangeSet
-{
-public:
- struct MoveKey
- {
- MoveKey() {}
- MoveKey(int moveId, int offset) : moveId(moveId), offset(offset) {}
- int moveId = -1;
- int offset = 0;
- };
-
- // The storrage for Change (below). This struct is trivial, which it has to be in order to store
- // it in a QV4::Heap::Base object. The Change struct doesn't add any storage fields, so it is
- // safe to cast ChangeData to/from Change.
- struct ChangeData
- {
- int index;
- int count;
- int moveId;
- int offset;
- };
-
- struct Change: ChangeData
- {
- Change() {
- index = 0;
- count = 0;
- moveId = -1;
- offset = 0;
- }
- Change(int index, int count, int moveId = -1, int offset = 0) {
- this->index = index;
- this->count = count;
- this->moveId = moveId;
- this->offset = offset;
- }
-
- bool isMove() const { return moveId >= 0; }
-
- MoveKey moveKey(int index) const {
- return MoveKey(moveId, index - Change::index + offset); }
-
- int start() const { return index; }
- int end() const { return index + count; }
- };
-
- QQmlChangeSet();
- QQmlChangeSet(const QQmlChangeSet &changeSet);
- ~QQmlChangeSet();
-
- QQmlChangeSet &operator =(const QQmlChangeSet &changeSet);
-
- const QVector<Change> &removes() const { return m_removes; }
- const QVector<Change> &inserts() const { return m_inserts; }
- const QVector<Change> &changes() const { return m_changes; }
-
- void insert(int index, int count);
- void remove(int index, int count);
- void move(int from, int to, int count, int moveId);
- void change(int index, int count);
-
- void insert(const QVector<Change> &inserts);
- void remove(const QVector<Change> &removes, QVector<Change> *inserts = nullptr);
- void move(const QVector<Change> &removes, const QVector<Change> &inserts);
- void change(const QVector<Change> &changes);
- void apply(const QQmlChangeSet &changeSet);
-
- bool isEmpty() const { return m_removes.empty() && m_inserts.empty() && m_changes.isEmpty(); }
-
- void clear()
- {
- m_removes.clear();
- m_inserts.clear();
- m_changes.clear();
- m_difference = 0;
- }
-
- int difference() const { return m_difference; }
-
-private:
- void remove(QVector<Change> *removes, QVector<Change> *inserts);
- void change(QVector<Change> *changes);
-
- QVector<Change> m_removes;
- QVector<Change> m_inserts;
- QVector<Change> m_changes;
- int m_difference;
-};
-
-Q_DECLARE_TYPEINFO(QQmlChangeSet::Change, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(QQmlChangeSet::MoveKey, Q_PRIMITIVE_TYPE);
-
-inline uint qHash(const QQmlChangeSet::MoveKey &key) { return qHash(qMakePair(key.moveId, key.offset)); }
-inline bool operator ==(const QQmlChangeSet::MoveKey &l, const QQmlChangeSet::MoveKey &r) {
- return l.moveId == r.moveId && l.offset == r.offset; }
-
-Q_QML_PRIVATE_EXPORT QDebug operator <<(QDebug debug, const QQmlChangeSet::Change &change);
-Q_QML_PRIVATE_EXPORT QDebug operator <<(QDebug debug, const QQmlChangeSet &change);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/util/qqmllistaccessor.cpp b/src/qml/util/qqmllistaccessor.cpp
deleted file mode 100644
index 46a11e2bc2..0000000000
--- a/src/qml/util/qqmllistaccessor.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmllistaccessor_p.h"
-
-#include <private/qqmlmetatype_p.h>
-
-#include <QtCore/qstringlist.h>
-#include <QtCore/qdebug.h>
-
-// ### Remove me
-#include <private/qqmlengine_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QQmlListAccessor::QQmlListAccessor()
-: m_type(Invalid)
-{
-}
-
-QQmlListAccessor::~QQmlListAccessor()
-{
-}
-
-QVariant QQmlListAccessor::list() const
-{
- return d;
-}
-
-void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine)
-{
- d = v;
-
- // An incoming JS array as model is treated as a variant list, so we need to
- // convert it first with toVariant().
- if (d.userType() == qMetaTypeId<QJSValue>())
- d = d.value<QJSValue>().toVariant();
-
- QQmlEnginePrivate *enginePrivate = engine?QQmlEnginePrivate::get(engine):nullptr;
-
- if (!d.isValid()) {
- m_type = Invalid;
- } else if (d.userType() == QVariant::StringList) {
- m_type = StringList;
- } else if (d.userType() == QMetaType::QVariantList) {
- m_type = VariantList;
- } else if (d.canConvert(QVariant::Int)) {
- // Here we have to check for an upper limit, because down the line code might (well, will)
- // allocate memory depending on the number of elements. The upper limit cannot be INT_MAX:
- // QVector<QPointer<QQuickItem>> something;
- // something.resize(count());
- // (See e.g. QQuickRepeater::regenerate())
- // This will allocate data along the lines of:
- // sizeof(QPointer<QQuickItem>) * count() + QVector::headerSize
- // So, doing an approximate round-down-to-nice-number, we get:
- const int upperLimit = 100 * 1000 * 1000;
-
- int i = v.toInt();
- if (i < 0) {
- qWarning("Model size of %d is less than 0", i);
- m_type = Invalid;
- } else if (i > upperLimit) {
- qWarning("Model size of %d is bigger than the upper limit %d", i, upperLimit);
- m_type = Invalid;
- } else {
- m_type = Integer;
- }
- } else if ((!enginePrivate && QQmlMetaType::isQObject(d.userType())) ||
- (enginePrivate && enginePrivate->isQObject(d.userType()))) {
- QObject *data = enginePrivate?enginePrivate->toQObject(d):QQmlMetaType::toQObject(d);
- d = QVariant::fromValue(data);
- m_type = Instance;
- } else if (d.userType() == qMetaTypeId<QQmlListReference>()) {
- m_type = ListProperty;
- } else {
- m_type = Instance;
- }
-}
-
-int QQmlListAccessor::count() const
-{
- switch(m_type) {
- case StringList:
- return qvariant_cast<QStringList>(d).count();
- case VariantList:
- return qvariant_cast<QVariantList>(d).count();
- case ListProperty:
- return ((const QQmlListReference *)d.constData())->count();
- case Instance:
- return 1;
- case Integer:
- return d.toInt();
- default:
- case Invalid:
- return 0;
- }
-}
-
-QVariant QQmlListAccessor::at(int idx) const
-{
- Q_ASSERT(idx >= 0 && idx < count());
- switch(m_type) {
- case StringList:
- return QVariant::fromValue(qvariant_cast<QStringList>(d).at(idx));
- case VariantList:
- return qvariant_cast<QVariantList>(d).at(idx);
- case ListProperty:
- return QVariant::fromValue(((const QQmlListReference *)d.constData())->at(idx));
- case Instance:
- return d;
- case Integer:
- return QVariant(idx);
- default:
- case Invalid:
- return QVariant();
- }
-}
-
-bool QQmlListAccessor::isValid() const
-{
- return m_type != Invalid;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/util/qqmllistaccessor_p.h b/src/qml/util/qqmllistaccessor_p.h
deleted file mode 100644
index bcd079adef..0000000000
--- a/src/qml/util/qqmllistaccessor_p.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLLISTACCESSOR_H
-#define QQMLLISTACCESSOR_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/QVariant>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlEngine;
-class Q_AUTOTEST_EXPORT QQmlListAccessor
-{
-public:
- QQmlListAccessor();
- ~QQmlListAccessor();
-
- QVariant list() const;
- void setList(const QVariant &, QQmlEngine * = nullptr);
-
- bool isValid() const;
-
- int count() const;
- QVariant at(int) const;
-
- enum Type { Invalid, StringList, VariantList, ListProperty, Instance, Integer };
- Type type() const { return m_type; }
-
-private:
- Type m_type;
- QVariant d;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLLISTACCESSOR_H
diff --git a/src/qml/util/qqmllistcompositor.cpp b/src/qml/util/qqmllistcompositor.cpp
deleted file mode 100644
index 921e86f355..0000000000
--- a/src/qml/util/qqmllistcompositor.cpp
+++ /dev/null
@@ -1,1482 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmllistcompositor_p.h"
-
-#include <QtCore/qvarlengtharray.h>
-
-//#define QT_QML_VERIFY_MINIMAL
-//#define QT_QML_VERIFY_INTEGRITY
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QQmlListCompositor
- \brief The QQmlListCompositor class provides a lookup table for filtered, or re-ordered list
- indexes.
- \internal
-
- QQmlListCompositor is intended as an aid for developing proxy models. It doesn't however
- directly proxy a list or model, instead a range of indexes from one or many lists can be
- inserted into the compositor and then categorized and shuffled around and it will manage the
- task of translating from an index in the combined space into an index in a particular list.
-
- Within a compositor indexes are categorized into groups where a group is a sub-set of the
- total indexes referenced by the compositor, each with an address space ranging from 0 to
- the number of indexes in the group - 1. Group memberships are independent of each other with
- the one exception that items always retain the same order so if an index is moved within a
- group, its position in other groups will change as well.
-
- The iterator classes encapsulate information about a specific position in a compositor group.
- This includes a source list, the index of an item within that list and the groups that item
- is a member of. The iterator for a specific position in a group can be retrieved with the
- find() function and the addition and subtraction operators of the iterators can be used to
- navigate to adjacent items in the same group.
-
- Items can be added to the compositor with the append() and insert() functions, group
- membership can be changed with the setFlags() and clearFlags() functions, and the position
- of items in the compositor can be changed with the move() function. Each of these functions
- optionally returns a list of the changes made to indexes within each group which can then
- be propagated to view so that it can correctly refresh its contents; e.g. 3 items
- removed at index 6, and 5 items inserted at index 1. The notification changes are always
- ordered from the start of the list to the end and accumulate, so if 5 items are removed at
- index 4, one is skipped and then 3 move are removed, the changes returned are 5 items removed
- at index 4, followed by 3 items removed at index 4.
-
- When the contents of a source list change, the mappings within the compositor can be updated
- with the listItemsInserted(), listItemsRemoved(), listItemsMoved(), and listItemsChanged()
- functions. Like the direct manipulation functions these too return a list of group indexes
- affected by the change. If items are removed from a source list they are also removed from
- any groups they belong to with the one exception being items belonging to the \l Cache group.
- When items belonging to this group are removed the list, index, and other group membership
- information are discarded but Cache membership is retained until explicitly removed. This
- allows the cache index to be retained until cached resources for that item are actually
- released.
-
- Internally the index mapping is stored as a list of Range objects, each has a list identifier,
- a start index, a count, and a set of flags which represent group membership and some other
- properties. The group index of a range is the sum of all preceding ranges that are members of
- that group. To avoid the inefficiency of iterating over potentially all ranges when looking
- for a specific index, each time a lookup is done the range and its indexes are cached and the
- next lookup is done relative to this. This works out to near constant time in most relevant
- use cases because successive index lookups are most frequently adjacent. The total number of
- ranges is often quite small, which helps as well. If there is a need for faster random access
- then a skip list like index may be an appropriate addition.
-
- \sa DelegateModel
-*/
-
-#ifdef QT_QML_VERIFY_MINIMAL
-#define QT_QML_VERIFY_INTEGRITY
-/*
- Diagnostic to verify there are no consecutive ranges, or that the compositor contains the
- most compact representation possible.
-
- Returns false and prints a warning if any range has a starting index equal to the end
- (index + count) index of the previous range, and both ranges also have the same flags and list
- property.
-
- If there are no consecutive ranges this will return true.
-*/
-
-static bool qt_verifyMinimal(
- const QQmlListCompositor::iterator &begin,
- const QQmlListCompositor::iterator &end)
-{
- bool minimal = true;
- int index = 0;
-
- for (const QQmlListCompositor::Range *range = begin->next; range != *end; range = range->next, ++index) {
- if (range->previous->list == range->list
- && range->previous->flags == (range->flags & ~QQmlListCompositor::AppendFlag)
- && range->previous->end() == range->index) {
- qWarning() << index << "Consecutive ranges";
- qWarning() << *range->previous;
- qWarning() << *range;
- minimal = false;
- }
- }
-
- return minimal;
-}
-
-#endif
-
-#ifdef QT_QML_VERIFY_INTEGRITY
-static bool qt_printInfo(const QQmlListCompositor &compositor)
-{
- qWarning() << compositor;
- return true;
-}
-
-/*
- Diagnostic to verify the integrity of a compositor.
-
- Per range this verifies there are no invalid range combinations, that non-append ranges have
- positive non-zero counts, and that list ranges have non-negative indexes.
-
- Accumulatively this verifies that the cached total group counts match the sum of counts
- of member ranges.
-*/
-
-static bool qt_verifyIntegrity(
- const QQmlListCompositor::iterator &begin,
- const QQmlListCompositor::iterator &end,
- const QQmlListCompositor::iterator &cachedIt)
-{
- bool valid = true;
-
- int index = 0;
- QQmlListCompositor::iterator it;
- for (it = begin; *it != *end; *it = it->next) {
- if (it->count == 0 && !it->append()) {
- qWarning() << index << "Empty non-append range";
- valid = false;
- }
- if (it->count < 0) {
- qWarning() << index << "Negative count";
- valid = false;
- }
- if (it->list && it->flags != QQmlListCompositor::CacheFlag && it->index < 0) {
- qWarning() << index <<"Negative index";
- valid = false;
- }
- if (it->previous->next != it.range) {
- qWarning() << index << "broken list: it->previous->next != it.range";
- valid = false;
- }
- if (it->next->previous != it.range) {
- qWarning() << index << "broken list: it->next->previous != it.range";
- valid = false;
- }
- if (*it == *cachedIt) {
- for (int i = 0; i < end.groupCount; ++i) {
- int groupIndex = it.index[i];
- if (cachedIt->flags & (1 << i))
- groupIndex += cachedIt.offset;
- if (groupIndex != cachedIt.index[i]) {
- qWarning() << index
- << "invalid cached index"
- << QQmlListCompositor::Group(i)
- << "Expected:"
- << groupIndex
- << "Actual"
- << cachedIt.index[i]
- << cachedIt;
- valid = false;
- }
- }
- }
- it.incrementIndexes(it->count);
- ++index;
- }
-
- for (int i = 0; i < end.groupCount; ++i) {
- if (end.index[i] != it.index[i]) {
- qWarning() << "Group" << i << "count invalid. Expected:" << end.index[i] << "Actual:" << it.index[i];
- valid = false;
- }
- }
- return valid;
-}
-#endif
-
-#if defined(QT_QML_VERIFY_MINIMAL)
-# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!(qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
- && qt_verifyMinimal(iterator(m_ranges.next, 0, Default, m_groupCount), m_end)) \
- && qt_printInfo(*this)));
-#elif defined(QT_QML_VERIFY_INTEGRITY)
-# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
- && qt_printInfo(*this)));
-#else
-# define QT_QML_VERIFY_LISTCOMPOSITOR
-#endif
-
-//#define QT_QML_TRACE_LISTCOMPOSITOR(args) qDebug() << m_end.index[1] << m_end.index[0] << Q_FUNC_INFO args;
-#define QT_QML_TRACE_LISTCOMPOSITOR(args)
-
-QQmlListCompositor::iterator &QQmlListCompositor::iterator::operator +=(int difference)
-{
- // Update all indexes to the start of the range.
- decrementIndexes(offset);
-
- // If the iterator group isn't a member of the current range ignore the current offset.
- if (!(range->flags & groupFlag))
- offset = 0;
-
- offset += difference;
-
- // Iterate backwards looking for a range with a positive offset.
- while (offset <= 0 && range->previous->flags) {
- range = range->previous;
- if (range->flags & groupFlag)
- offset += range->count;
- decrementIndexes(range->count);
- }
-
- // Iterate forwards looking for the first range which contains both the offset and the
- // iterator group.
- while (range->flags && (offset >= range->count || !(range->flags & groupFlag))) {
- if (range->flags & groupFlag)
- offset -= range->count;
- incrementIndexes(range->count);
- range = range->next;
- }
-
- // Update all the indexes to inclue the remaining offset.
- incrementIndexes(offset);
-
- return *this;
-}
-
-QQmlListCompositor::insert_iterator &QQmlListCompositor::insert_iterator::operator +=(int difference)
-{
- iterator::operator +=(difference);
-
- // If the previous range contains the append flag move the iterator to the tail of the previous
- // range so that appended appear after the insert position.
- if (offset == 0 && range->previous->append()) {
- range = range->previous;
- offset = range->inGroup() ? range->count : 0;
- }
-
- return *this;
-}
-
-
-/*!
- Constructs an empty list compositor.
-*/
-
-QQmlListCompositor::QQmlListCompositor()
- : m_end(m_ranges.next, 0, Default, 2)
- , m_cacheIt(m_end)
- , m_groupCount(2)
- , m_defaultFlags(PrependFlag | DefaultFlag)
- , m_removeFlags(AppendFlag | PrependFlag | GroupMask)
- , m_moveId(0)
-{
-}
-
-/*!
- Destroys a list compositor.
-*/
-
-QQmlListCompositor::~QQmlListCompositor()
-{
- for (Range *next, *range = m_ranges.next; range != &m_ranges; range = next) {
- next = range->next;
- delete range;
- }
-}
-
-/*!
- Inserts a range with the given source \a list, start \a index, \a count and \a flags, in front
- of the existing range \a before.
-*/
-
-inline QQmlListCompositor::Range *QQmlListCompositor::insert(
- Range *before, void *list, int index, int count, uint flags)
-{
- return new Range(before, list, index, count, flags);
-}
-
-/*!
- Erases a \a range from the compositor.
-
- Returns a pointer to the next range in the compositor.
-*/
-
-inline QQmlListCompositor::Range *QQmlListCompositor::erase(
- Range *range)
-{
- Range *next = range->next;
- next->previous = range->previous;
- next->previous->next = range->next;
- delete range;
- return next;
-}
-
-/*!
- Sets the number (\a count) of possible groups that items may belong to in a compositor.
-*/
-
-void QQmlListCompositor::setGroupCount(int count)
-{
- m_groupCount = count;
- m_end = iterator(&m_ranges, 0, Default, m_groupCount);
- m_cacheIt = m_end;
-}
-
-/*!
- Returns the number of items that belong to a \a group.
-*/
-
-int QQmlListCompositor::count(Group group) const
-{
- return m_end.index[group];
-}
-
-/*!
- Returns an iterator representing the item at \a index in a \a group.
-
- The index must be between 0 and count(group) - 1.
-*/
-
-QQmlListCompositor::iterator QQmlListCompositor::find(Group group, int index)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< group << index)
- Q_ASSERT(index >=0 && index < count(group));
- if (m_cacheIt == m_end) {
- m_cacheIt = iterator(m_ranges.next, 0, group, m_groupCount);
- m_cacheIt += index;
- } else {
- const int offset = index - m_cacheIt.index[group];
- m_cacheIt.setGroup(group);
- m_cacheIt += offset;
- }
- Q_ASSERT(m_cacheIt.index[group] == index);
- Q_ASSERT(m_cacheIt->inGroup(group));
- QT_QML_VERIFY_LISTCOMPOSITOR
- return m_cacheIt;
-}
-
-/*!
- Returns an iterator representing the item at \a index in a \a group.
-
- The index must be between 0 and count(group) - 1.
-*/
-
-QQmlListCompositor::iterator QQmlListCompositor::find(Group group, int index) const
-{
- return const_cast<QQmlListCompositor *>(this)->find(group, index);
-}
-
-/*!
- Returns an iterator representing an insert position in front of the item at \a index in a
- \a group.
-
- The iterator for an insert position can sometimes resolve to a different Range than a regular
- iterator. This is because when items are inserted on a boundary between Ranges, if the first
- range has the Append flag set then the items should be inserted into that range to ensure
- that the append position for the existing range remains after the insert position.
-
- The index must be between 0 and count(group) - 1.
-*/
-
-QQmlListCompositor::insert_iterator QQmlListCompositor::findInsertPosition(Group group, int index)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< group << index)
- Q_ASSERT(index >=0 && index <= count(group));
- insert_iterator it;
- if (m_cacheIt == m_end) {
- it = iterator(m_ranges.next, 0, group, m_groupCount);
- it += index;
- } else {
- const int offset = index - m_cacheIt.index[group];
- it = m_cacheIt;
- it.setGroup(group);
- it += offset;
- }
- Q_ASSERT(it.index[group] == index);
- return it;
-}
-
-/*!
- Appends a range of \a count indexes starting at \a index from a \a list into a compositor
- with the given \a flags.
-
- If supplied the \a inserts list will be populated with the positions of the inserted items
- in each group.
-*/
-
-void QQmlListCompositor::append(
- void *list, int index, int count, uint flags, QVector<Insert> *inserts)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count << flags)
- insert(m_end, list, index, count, flags, inserts);
-}
-
-/*!
- Inserts a range of \a count indexes starting at \a index from a \a list with the given \a flags
- into a \a group at index \a before.
-
- If supplied the \a inserts list will be populated with the positions of items inserted into
- each group.
-*/
-
-void QQmlListCompositor::insert(
- Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< group << before << list << index << count << flags)
- insert(findInsertPosition(group, before), list, index, count, flags, inserts);
-}
-
-/*!
- Inserts a range of \a count indexes starting at \a index from a \a list with the given \a flags
- into a compositor at position \a before.
-
- If supplied the \a inserts list will be populated with the positions of items inserted into
- each group.
-*/
-
-QQmlListCompositor::iterator QQmlListCompositor::insert(
- iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< before << list << index << count << flags)
- if (inserts) {
- inserts->append(Insert(before, count, flags & GroupMask));
- }
- if (before.offset > 0) {
- // Inserting into the middle of a range. Split it two and update the iterator so it's
- // positioned at the start of the second half.
- *before = insert(
- *before, before->list, before->index, before.offset, before->flags & ~AppendFlag)->next;
- before->index += before.offset;
- before->count -= before.offset;
- before.offset = 0;
- }
-
-
- if (!(flags & AppendFlag) && *before != m_ranges.next
- && before->previous->list == list
- && before->previous->flags == flags
- && (!list || before->previous->end() == index)) {
- // The insert arguments represent a continuation of the previous range so increment
- // its count instead of inserting a new range.
- before->previous->count += count;
- before.incrementIndexes(count, flags);
- } else {
- *before = insert(*before, list, index, count, flags);
- before.offset = 0;
- }
-
- if (!(flags & AppendFlag) && before->next != &m_ranges
- && before->list == before->next->list
- && before->flags == before->next->flags
- && (!list || before->end() == before->next->index)) {
- // The current range and the next are continuous so add their counts and delete one.
- before->next->index = before->index;
- before->next->count += before->count;
- *before = erase(*before);
- }
-
- m_end.incrementIndexes(count, flags);
- m_cacheIt = before;
- QT_QML_VERIFY_LISTCOMPOSITOR
- return before;
-}
-
-/*!
- Sets the given flags \a flags on \a count items belonging to \a group starting at the position
- identified by \a fromGroup and the index \a from.
-
- If supplied the \a inserts list will be populated with insert notifications for affected groups.
-*/
-
-void QQmlListCompositor::setFlags(
- Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << count << group << flags)
- setFlags(find(fromGroup, from), count, group, flags, inserts);
-}
-
-/*!
- Sets the given flags \a flags on \a count items belonging to \a group starting at the position
- \a from.
-
- If supplied the \a inserts list will be populated with insert notifications for affected groups.
-*/
-
-void QQmlListCompositor::setFlags(
- iterator from, int count, Group group, uint flags, QVector<Insert> *inserts)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< from << count << flags)
- if (!flags || !count)
- return;
-
- if (from != group) {
- // Skip to the next full range if the start one is not a member of the target group.
- from.incrementIndexes(from->count - from.offset);
- from.offset = 0;
- *from = from->next;
- } else if (from.offset > 0) {
- // If the start position is mid range split off the portion unaffected.
- *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
- from->index += from.offset;
- from->count -= from.offset;
- from.offset = 0;
- }
-
- for (; count > 0; *from = from->next) {
- if (from != from.group) {
- // Skip ranges that are not members of the target group.
- from.incrementIndexes(from->count);
- continue;
- }
- // Find the number of items affected in the current range.
- const int difference = qMin(count, from->count);
- count -= difference;
-
- // Determine the actual changes made to the range and increment counts accordingly.
- const uint insertFlags = ~from->flags & flags;
- const uint setFlags = (from->flags | flags) & ~AppendFlag;
- if (insertFlags && inserts)
- inserts->append(Insert(from, difference, insertFlags | (from->flags & CacheFlag)));
- m_end.incrementIndexes(difference, insertFlags);
- from.incrementIndexes(difference, setFlags);
-
- if (from->previous != &m_ranges
- && from->previous->list == from->list
- && (!from->list || from->previous->end() == from->index)
- && from->previous->flags == setFlags) {
- // If the additional flags make the current range a continuation of the previous
- // then move the affected items over to the previous range.
- from->previous->count += difference;
- from->index += difference;
- from->count -= difference;
- if (from->count == 0) {
- // Delete the current range if it is now empty, preserving the append flag
- // in the previous range.
- if (from->append())
- from->previous->flags |= AppendFlag;
- *from = erase(*from)->previous;
- continue;
- } else {
- break;
- }
- } else if (!insertFlags) {
- // No new flags, so roll onto the next range.
- from.incrementIndexes(from->count - difference);
- continue;
- } else if (difference < from->count) {
- // Create a new range with the updated flags, and remove the affected items
- // from the current range.
- *from = insert(*from, from->list, from->index, difference, setFlags)->next;
- from->index += difference;
- from->count -= difference;
- } else {
- // The whole range is affected so simply update the flags.
- from->flags |= flags;
- continue;
- }
- from.incrementIndexes(from->count);
- }
-
- if (from->previous != &m_ranges
- && from->previous->list == from->list
- && (!from->list || from->previous->end() == from->index)
- && from->previous->flags == (from->flags & ~AppendFlag)) {
- // If the following range is now a continuation, merge it with its previous range.
- from.offset = from->previous->count;
- from->previous->count += from->count;
- from->previous->flags = from->flags;
- *from = erase(*from)->previous;
- }
- m_cacheIt = from;
- QT_QML_VERIFY_LISTCOMPOSITOR
-}
-
-/*!
- Clears the given flags \a flags on \a count items belonging to \a group starting at the position
- \a from.
-
- If supplied the \a removes list will be populated with remove notifications for affected groups.
-*/
-
-void QQmlListCompositor::clearFlags(
- Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removes)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << count << group << flags)
- clearFlags(find(fromGroup, from), count, group, flags, removes);
-}
-
-/*!
- Clears the given flags \a flags on \a count items belonging to \a group starting at the position
- identified by \a fromGroup and the index \a from.
-
- If supplied the \a removes list will be populated with remove notifications for affected groups.
-*/
-
-void QQmlListCompositor::clearFlags(
- iterator from, int count, Group group, uint flags, QVector<Remove> *removes)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< from << count << flags)
- if (!flags || !count)
- return;
-
- const bool clearCache = flags & CacheFlag;
-
- if (from != group) {
- // Skip to the next full range if the start one is not a member of the target group.
- from.incrementIndexes(from->count - from.offset);
- from.offset = 0;
- *from = from->next;
- } else if (from.offset > 0) {
- // If the start position is mid range split off the portion unaffected.
- *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
- from->index += from.offset;
- from->count -= from.offset;
- from.offset = 0;
- }
-
- for (; count > 0; *from = from->next) {
- if (from != group) {
- // Skip ranges that are not members of the target group.
- from.incrementIndexes(from->count);
- continue;
- }
- // Find the number of items affected in the current range.
- const int difference = qMin(count, from->count);
- count -= difference;
-
-
- // Determine the actual changes made to the range and decrement counts accordingly.
- const uint removeFlags = from->flags & flags & ~(AppendFlag | PrependFlag);
- const uint clearedFlags = from->flags & ~(flags | AppendFlag | UnresolvedFlag);
- if (removeFlags && removes) {
- const int maskedFlags = clearCache
- ? (removeFlags & ~CacheFlag)
- : (removeFlags | (from->flags & CacheFlag));
- if (maskedFlags)
- removes->append(Remove(from, difference, maskedFlags));
- }
- m_end.decrementIndexes(difference, removeFlags);
- from.incrementIndexes(difference, clearedFlags);
-
- if (from->previous != &m_ranges
- && from->previous->list == from->list
- && (!from->list || clearedFlags == CacheFlag || from->previous->end() == from->index)
- && from->previous->flags == clearedFlags) {
- // If the removed flags make the current range a continuation of the previous
- // then move the affected items over to the previous range.
- from->previous->count += difference;
- from->index += difference;
- from->count -= difference;
- if (from->count == 0) {
- // Delete the current range if it is now empty, preserving the append flag
- if (from->append())
- from->previous->flags |= AppendFlag;
- *from = erase(*from)->previous;
- } else {
- from.incrementIndexes(from->count);
- }
- } else if (difference < from->count) {
- // Create a new range with the reduced flags, and remove the affected items from
- // the current range.
- if (clearedFlags)
- *from = insert(*from, from->list, from->index, difference, clearedFlags)->next;
- from->index += difference;
- from->count -= difference;
- from.incrementIndexes(from->count);
- } else if (clearedFlags) {
- // The whole range is affected so simply update the flags.
- from->flags &= ~flags;
- } else {
- // All flags have been removed from the range so remove it.
- *from = erase(*from)->previous;
- }
- }
-
- if (*from != &m_ranges && from->previous != &m_ranges
- && from->previous->list == from->list
- && (!from->list || from->previous->end() == from->index)
- && from->previous->flags == (from->flags & ~AppendFlag)) {
- // If the following range is now a continuation, merge it with its previous range.
- from.offset = from->previous->count;
- from->previous->count += from->count;
- from->previous->flags = from->flags;
- *from = erase(*from)->previous;
- }
- m_cacheIt = from;
- QT_QML_VERIFY_LISTCOMPOSITOR
-}
-
-bool QQmlListCompositor::verifyMoveTo(
- Group fromGroup, int from, Group toGroup, int to, int count, Group group) const
-{
- if (group != toGroup) {
- // determine how many items from the destination group intersect with the source group.
- iterator fromIt = find(fromGroup, from);
-
- int intersectingCount = 0;
-
- for (; count > 0; *fromIt = fromIt->next) {
- if (*fromIt == &m_ranges)
- return false;
- if (!fromIt->inGroup(group))
- continue;
- if (fromIt->inGroup(toGroup))
- intersectingCount += qMin(count, fromIt->count - fromIt.offset);
- count -= fromIt->count - fromIt.offset;
- fromIt.offset = 0;
- }
- count = intersectingCount;
- }
-
- return to >= 0 && to + count <= m_end.index[toGroup];
-}
-
-/*!
- \internal
-
- Moves \a count items belonging to \a moveGroup from the index \a from in \a fromGroup
- to the index \a to in \a toGroup.
-
- If \a removes and \a inserts are not null they will be populated with per group notifications
- of the items moved.
- */
-
-void QQmlListCompositor::move(
- Group fromGroup,
- int from,
- Group toGroup,
- int to,
- int count,
- Group moveGroup,
- QVector<Remove> *removes,
- QVector<Insert> *inserts)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << toGroup << to << count)
- Q_ASSERT(count > 0);
- Q_ASSERT(from >=0);
- Q_ASSERT(verifyMoveTo(fromGroup, from, toGroup, to, count, moveGroup));
-
- // Find the position of the first item to move.
- iterator fromIt = find(fromGroup, from);
-
- if (fromIt != moveGroup) {
- // If the range at the from index doesn't contain items from the move group; skip
- // to the next range.
- fromIt.incrementIndexes(fromIt->count - fromIt.offset);
- fromIt.offset = 0;
- *fromIt = fromIt->next;
- } else if (fromIt.offset > 0) {
- // If the range at the from index contains items from the move group and the index isn't
- // at the start of the range; split the range at the index and move the iterator to start
- // of the second range.
- *fromIt = insert(
- *fromIt, fromIt->list, fromIt->index, fromIt.offset, fromIt->flags & ~AppendFlag)->next;
- fromIt->index += fromIt.offset;
- fromIt->count -= fromIt.offset;
- fromIt.offset = 0;
- }
-
- // Remove count items belonging to the move group from the list.
- Range movedFlags;
- for (int moveId = m_moveId; count > 0;) {
- if (fromIt != moveGroup) {
- // Skip ranges not containing items from the move group.
- fromIt.incrementIndexes(fromIt->count);
- *fromIt = fromIt->next;
- continue;
- }
- int difference = qMin(count, fromIt->count);
-
- // Create a new static range containing the moved items from an existing range.
- new Range(
- &movedFlags,
- fromIt->list,
- fromIt->index,
- difference,
- fromIt->flags & ~(PrependFlag | AppendFlag));
- // Remove moved items from the count, the existing range, and a remove notification.
- if (removes)
- removes->append(Remove(fromIt, difference, fromIt->flags, ++moveId));
- count -= difference;
- fromIt->count -= difference;
-
- // If the existing range contains the prepend flag replace the removed items with
- // a placeholder range for new items inserted into the source model.
- int removeIndex = fromIt->index;
- if (fromIt->prepend()
- && fromIt->previous != &m_ranges
- && fromIt->previous->flags == PrependFlag
- && fromIt->previous->list == fromIt->list
- && fromIt->previous->end() == fromIt->index) {
- // Grow the previous range instead of creating a new one if possible.
- fromIt->previous->count += difference;
- } else if (fromIt->prepend()) {
- *fromIt = insert(*fromIt, fromIt->list, removeIndex, difference, PrependFlag)->next;
- }
- fromIt->index += difference;
-
- if (fromIt->count == 0) {
- // If the existing range has no items remaining; remove it from the list.
- if (fromIt->append())
- fromIt->previous->flags |= AppendFlag;
- *fromIt = erase(*fromIt);
-
- // If the ranges before and after the removed range can be joined, do so.
- if (*fromIt != m_ranges.next && fromIt->flags == PrependFlag
- && fromIt->previous != &m_ranges
- && fromIt->previous->flags == PrependFlag
- && fromIt->previous->list == fromIt->list
- && fromIt->previous->end() == fromIt->index) {
- fromIt.incrementIndexes(fromIt->count);
- fromIt->previous->count += fromIt->count;
- *fromIt = erase(*fromIt);
- }
- } else if (count > 0) {
- *fromIt = fromIt->next;
- }
- }
-
- // Try and join the range following the removed items to the range preceding it.
- if (*fromIt != m_ranges.next
- && *fromIt != &m_ranges
- && fromIt->previous->list == fromIt->list
- && (!fromIt->list || fromIt->previous->end() == fromIt->index)
- && fromIt->previous->flags == (fromIt->flags & ~AppendFlag)) {
- if (fromIt == fromIt.group)
- fromIt.offset = fromIt->previous->count;
- fromIt.offset = fromIt->previous->count;
- fromIt->previous->count += fromIt->count;
- fromIt->previous->flags = fromIt->flags;
- *fromIt = erase(*fromIt)->previous;
- }
-
- // Find the destination position of the move.
- insert_iterator toIt = fromIt;
- toIt.setGroup(toGroup);
-
- const int difference = to - toIt.index[toGroup];
- toIt += difference;
-
- // If the insert position is part way through a range; split it and move the iterator to the
- // start of the second range.
- if (toIt.offset > 0) {
- *toIt = insert(*toIt, toIt->list, toIt->index, toIt.offset, toIt->flags & ~AppendFlag)->next;
- toIt->index += toIt.offset;
- toIt->count -= toIt.offset;
- toIt.offset = 0;
- }
-
- // Insert the moved ranges before the insert iterator, growing the previous range if that
- // is an option.
- for (Range *range = movedFlags.previous; range != &movedFlags; range = range->previous) {
- if (*toIt != &m_ranges
- && range->list == toIt->list
- && (!range->list || range->end() == toIt->index)
- && range->flags == (toIt->flags & ~AppendFlag)) {
- toIt->index -= range->count;
- toIt->count += range->count;
- } else {
- *toIt = insert(*toIt, range->list, range->index, range->count, range->flags);
- }
- }
-
- // Try and join the range after the inserted ranges to the last range inserted.
- if (*toIt != m_ranges.next
- && toIt->previous->list == toIt->list
- && (!toIt->list || (toIt->previous->end() == toIt->index && toIt->previous->flags == (toIt->flags & ~AppendFlag)))) {
- toIt.offset = toIt->previous->count;
- toIt->previous->count += toIt->count;
- toIt->previous->flags = toIt->flags;
- *toIt = erase(*toIt)->previous;
- }
- // Create insert notification for the ranges moved.
- Insert insert(toIt, 0, 0, 0);
- for (Range *next, *range = movedFlags.next; range != &movedFlags; range = next) {
- insert.count = range->count;
- insert.flags = range->flags;
- if (inserts) {
- insert.moveId = ++m_moveId;
- inserts->append(insert);
- }
- for (int i = 0; i < m_groupCount; ++i) {
- if (insert.inGroup(i))
- insert.index[i] += range->count;
- }
-
- next = range->next;
- delete range;
- }
-
- m_cacheIt = toIt;
-
- QT_QML_VERIFY_LISTCOMPOSITOR
-}
-
-/*!
- Clears the contents of a compositor.
-*/
-
-void QQmlListCompositor::clear()
-{
- QT_QML_TRACE_LISTCOMPOSITOR("")
- for (Range *range = m_ranges.next; range != &m_ranges; range = erase(range)) {}
- m_end = iterator(m_ranges.next, 0, Default, m_groupCount);
- m_cacheIt = m_end;
-}
-
-void QQmlListCompositor::listItemsInserted(
- QVector<Insert> *translatedInsertions,
- void *list,
- const QVector<QQmlChangeSet::Change> &insertions,
- const QVector<MovedFlags> *movedFlags)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< list << insertions)
- for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
- if (it->list != list || it->flags == CacheFlag) {
- // Skip ranges that don't reference list.
- it.incrementIndexes(it->count);
- continue;
- } else if (it->flags & MovedFlag) {
- // Skip ranges that were already moved in listItemsRemoved.
- it->flags &= ~MovedFlag;
- it.incrementIndexes(it->count);
- continue;
- }
- for (const QQmlChangeSet::Change &insertion : insertions) {
- int offset = insertion.index - it->index;
- if ((offset > 0 && offset < it->count)
- || (offset == 0 && it->prepend())
- || (offset == it->count && it->append())) {
- // The insert index is within the current range.
- if (it->prepend()) {
- // The range has the prepend flag set so we insert new items into the range.
- uint flags = m_defaultFlags;
- if (insertion.isMove()) {
- // If the insert was part of a move replace the default flags with
- // the flags from the source range.
- for (QVector<MovedFlags>::const_iterator move = movedFlags->begin();
- move != movedFlags->end();
- ++move) {
- if (move->moveId == insertion.moveId) {
- flags = move->flags;
- break;
- }
- }
- }
- if (flags & ~(AppendFlag | PrependFlag)) {
- // If any items are added to groups append an insert notification.
- Insert translatedInsert(it, insertion.count, flags, insertion.moveId);
- for (int i = 0; i < m_groupCount; ++i) {
- if (it->inGroup(i))
- translatedInsert.index[i] += offset;
- }
- translatedInsertions->append(translatedInsert);
- }
- if ((it->flags & ~AppendFlag) == flags) {
- // Accumulate items on the current range it its flags are the same as
- // the insert flags.
- it->count += insertion.count;
- } else if (offset == 0
- && it->previous != &m_ranges
- && it->previous->list == list
- && it->previous->end() == insertion.index
- && it->previous->flags == flags) {
- // Attempt to append to the previous range if the insert position is at
- // the start of the current range.
- it->previous->count += insertion.count;
- it->index += insertion.count;
- it.incrementIndexes(insertion.count);
- } else {
- if (offset > 0) {
- // Divide the current range at the insert position.
- it.incrementIndexes(offset);
- *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
- }
- // Insert a new range, and increment the start index of the current range.
- *it = insert(*it, it->list, insertion.index, insertion.count, flags)->next;
- it.incrementIndexes(insertion.count, flags);
- it->index += offset + insertion.count;
- it->count -= offset;
- }
- m_end.incrementIndexes(insertion.count, flags);
- } else {
- // The range doesn't have the prepend flag set so split the range into parts;
- // one before the insert position and one after the last inserted item.
- if (offset > 0) {
- *it = insert(*it, it->list, it->index, offset, it->flags)->next;
- it->index += offset;
- it->count -= offset;
- }
- it->index += insertion.count;
- }
- } else if (offset <= 0) {
- // The insert position was before the current range so increment the start index.
- it->index += insertion.count;
- }
- }
- it.incrementIndexes(it->count);
- }
- m_cacheIt = m_end;
- QT_QML_VERIFY_LISTCOMPOSITOR
-}
-
-/*!
- Updates the contents of a compositor when \a count items are inserted into a \a list at
- \a index.
-
- This corrects the indexes of each range for that list in the compositor, splitting the range
- in two if the insert index is in the middle of that range. If a range at the insert position
- has the Prepend flag set then a new range will be inserted at that position with the groups
- specified in defaultGroups(). If the insert index corresponds to the end of a range with
- the Append flag set a new range will be inserted before the end of the append range.
-
- The \a translatedInsertions list is populated with insert notifications for affected
- groups.
-*/
-
-void QQmlListCompositor::listItemsInserted(
- void *list, int index, int count, QVector<Insert> *translatedInsertions)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count)
- Q_ASSERT(count > 0);
-
- QVector<QQmlChangeSet::Change> insertions;
- insertions.append(QQmlChangeSet::Change(index, count));
-
- listItemsInserted(translatedInsertions, list, insertions);
-}
-
-void QQmlListCompositor::listItemsRemoved(
- QVector<Remove> *translatedRemovals,
- void *list,
- QVector<QQmlChangeSet::Change> *removals,
- QVector<QQmlChangeSet::Change> *insertions,
- QVector<MovedFlags> *movedFlags)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< list << *removals)
-
- for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
- if (it->list != list || it->flags == CacheFlag) {
- // Skip ranges that don't reference list.
- it.incrementIndexes(it->count);
- continue;
- }
- bool removed = false;
- for (QVector<QQmlChangeSet::Change>::iterator removal = removals->begin();
- !removed && removal != removals->end();
- ++removal) {
- int relativeIndex = removal->index - it->index;
- int itemsRemoved = removal->count;
- if (relativeIndex + removal->count > 0 && relativeIndex < it->count) {
- // If the current range intersects the remove; remove the intersecting items.
- const int offset = qMax(0, relativeIndex);
- int removeCount = qMin(it->count, relativeIndex + removal->count) - offset;
- it->count -= removeCount;
- int removeFlags = it->flags & m_removeFlags;
- Remove translatedRemoval(it, removeCount, it->flags);
- for (int i = 0; i < m_groupCount; ++i) {
- if (it->inGroup(i))
- translatedRemoval.index[i] += offset;
- }
- if (removal->isMove()) {
- // If the removal was part of a move find the corresponding insert.
- QVector<QQmlChangeSet::Change>::iterator insertion = insertions->begin();
- for (; insertion != insertions->end() && insertion->moveId != removal->moveId;
- ++insertion) {}
- Q_ASSERT(insertion != insertions->end());
- Q_ASSERT(insertion->count == removal->count);
-
- if (relativeIndex < 0) {
- // If the remove started before the current range, split it and the
- // corresponding insert so we're only working with intersecting part.
- int splitMoveId = ++m_moveId;
- removal = removals->insert(removal, QQmlChangeSet::Change(
- removal->index, -relativeIndex, splitMoveId));
- ++removal;
- removal->count -= -relativeIndex;
- insertion = insertions->insert(insertion, QQmlChangeSet::Change(
- insertion->index, -relativeIndex, splitMoveId));
- ++insertion;
- insertion->index += -relativeIndex;
- insertion->count -= -relativeIndex;
- }
-
- if (it->prepend()) {
- // If the current range has the prepend flag preserve its flags to transfer
- // to its new location.
- removeFlags |= it->flags & CacheFlag;
- translatedRemoval.moveId = ++m_moveId;
- movedFlags->append(MovedFlags(m_moveId, it->flags & ~AppendFlag));
-
- if (removeCount < removal->count) {
- // If the remove doesn't encompass all of the current range,
- // split it and the corresponding insert.
- removal = removals->insert(removal, QQmlChangeSet::Change(
- removal->index, removeCount, translatedRemoval.moveId));
- ++removal;
- insertion = insertions->insert(insertion, QQmlChangeSet::Change(
- insertion->index, removeCount, translatedRemoval.moveId));
- ++insertion;
-
- removal->count -= removeCount;
- insertion->index += removeCount;
- insertion->count -= removeCount;
- } else {
- // If there's no need to split the move simply replace its moveId
- // with that of the translated move.
- removal->moveId = translatedRemoval.moveId;
- insertion->moveId = translatedRemoval.moveId;
- }
- } else {
- // If the current range doesn't have prepend flags then insert a new range
- // with list indexes from the corresponding insert location. The MoveFlag
- // is to notify listItemsInserted that it can skip evaluation of that range.
- if (offset > 0) {
- *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
- it->index += offset;
- it->count -= offset;
- it.incrementIndexes(offset);
- }
- if (it->previous != &m_ranges
- && it->previous->list == it->list
- && it->end() == insertion->index
- && it->previous->flags == (it->flags | MovedFlag)) {
- it->previous->count += removeCount;
- } else {
- *it = insert(*it, it->list, insertion->index, removeCount, it->flags | MovedFlag)->next;
- }
- // Clear the changed flags as the item hasn't been removed.
- translatedRemoval.flags = 0;
- removeFlags = 0;
- }
- } else if (it->inCache()) {
- // If not moving and the current range has the cache flag, insert a new range
- // with just the cache flag set to retain caching information for the removed
- // range.
- if (offset > 0) {
- *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
- it->index += offset;
- it->count -= offset;
- it.incrementIndexes(offset);
- }
- if (it->previous != &m_ranges
- && it->previous->list == it->list
- && it->previous->flags == CacheFlag) {
- it->previous->count += removeCount;
- } else {
- *it = insert(*it, it->list, -1, removeCount, CacheFlag)->next;
- }
- it.index[Cache] += removeCount;
- }
- if (removeFlags & GroupMask)
- translatedRemovals->append(translatedRemoval);
- m_end.decrementIndexes(removeCount, removeFlags);
- if (it->count == 0 && !it->append()) {
- // Erase empty non-append ranges.
- *it = erase(*it)->previous;
- removed = true;
- } else if (relativeIndex <= 0) {
- // If the remove started before the current range move the start index of
- // the range to the remove index.
- it->index = removal->index;
- }
- } else if (relativeIndex < 0) {
- // If the remove was before the current range decrement the start index by the
- // number of items removed.
- it->index -= itemsRemoved;
-
- if (it->previous != &m_ranges
- && it->previous->list == it->list
- && it->previous->end() == it->index
- && it->previous->flags == (it->flags & ~AppendFlag)) {
- // Compress ranges made continuous by the removal of separating ranges.
- it.decrementIndexes(it->previous->count);
- it->previous->count += it->count;
- it->previous->flags = it->flags;
- *it = erase(*it)->previous;
- }
- }
- }
- if (it->flags == CacheFlag && it->next->flags == CacheFlag && it->next->list == it->list) {
- // Compress consecutive cache only ranges.
- it.index[Cache] += it->next->count;
- it->count += it->next->count;
- erase(it->next);
- } else if (!removed) {
- it.incrementIndexes(it->count);
- }
- }
- m_cacheIt = m_end;
- QT_QML_VERIFY_LISTCOMPOSITOR
-}
-
-
-/*!
- Updates the contents of a compositor when \a count items are removed from a \a list at
- \a index.
-
- Ranges that intersect the specified range are removed from the compositor and the indexes of
- ranges after index + count are updated.
-
- The \a translatedRemovals list is populated with remove notifications for the affected
- groups.
-*/
-
-
-void QQmlListCompositor::listItemsRemoved(
- void *list, int index, int count, QVector<Remove> *translatedRemovals)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count)
- Q_ASSERT(count >= 0);
-
- QVector<QQmlChangeSet::Change> removals;
- removals.append(QQmlChangeSet::Change(index, count));
- listItemsRemoved(translatedRemovals, list, &removals, nullptr, nullptr);
-}
-
-/*!
- Updates the contents of a compositor when \a count items are removed from a \a list at
- \a index.
-
- Ranges that intersect the specified range are removed from the compositor and the indexes of
- ranges after index + count are updated.
-
- The \a translatedRemovals and translatedInserts lists are populated with move
- notifications for the affected groups.
-*/
-
-void QQmlListCompositor::listItemsMoved(
- void *list,
- int from,
- int to,
- int count,
- QVector<Remove> *translatedRemovals,
- QVector<Insert> *translatedInsertions)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< list << from << to << count)
- Q_ASSERT(count >= 0);
-
- QVector<QQmlChangeSet::Change> removals;
- QVector<QQmlChangeSet::Change> insertions;
- QVector<MovedFlags> movedFlags;
- removals.append(QQmlChangeSet::Change(from, count, 0));
- insertions.append(QQmlChangeSet::Change(to, count, 0));
-
- listItemsRemoved(translatedRemovals, list, &removals, &insertions, &movedFlags);
- listItemsInserted(translatedInsertions, list, insertions, &movedFlags);
-}
-
-void QQmlListCompositor::listItemsChanged(
- QVector<Change> *translatedChanges,
- void *list,
- const QVector<QQmlChangeSet::Change> &changes)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< list << changes)
- for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
- if (it->list != list || it->flags == CacheFlag) {
- it.incrementIndexes(it->count);
- continue;
- } else if (!it->inGroup()) {
- continue;
- }
- for (const QQmlChangeSet::Change &change : changes) {
- const int offset = change.index - it->index;
- if (offset + change.count > 0 && offset < it->count) {
- const int changeOffset = qMax(0, offset);
- const int changeCount = qMin(it->count, offset + change.count) - changeOffset;
-
- Change translatedChange(it, changeCount, it->flags);
- for (int i = 0; i < m_groupCount; ++i) {
- if (it->inGroup(i))
- translatedChange.index[i] += changeOffset;
- }
- translatedChanges->append(translatedChange);
- }
- }
- it.incrementIndexes(it->count);
- }
-}
-
-
-/*!
- Translates the positions of \a count changed items at \a index in a \a list.
-
- The \a translatedChanges list is populated with change notifications for the
- affected groups.
-*/
-
-void QQmlListCompositor::listItemsChanged(
- void *list, int index, int count, QVector<Change> *translatedChanges)
-{
- QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count)
- Q_ASSERT(count >= 0);
- QVector<QQmlChangeSet::Change> changes;
- changes.append(QQmlChangeSet::Change(index, count));
- listItemsChanged(translatedChanges, list, changes);
-}
-
-void QQmlListCompositor::transition(
- Group from,
- Group to,
- QVector<QQmlChangeSet::Change> *removes,
- QVector<QQmlChangeSet::Change> *inserts)
-{
- int removeCount = 0;
- for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
- if (it == from && it != to) {
- removes->append(QQmlChangeSet::Change(it.index[from]- removeCount, it->count));
- removeCount += it->count;
- } else if (it != from && it == to) {
- inserts->append(QQmlChangeSet::Change(it.index[to], it->count));
- }
- it.incrementIndexes(it->count);
- }
-}
-
-/*!
- \internal
- Writes the name of \a group to \a debug.
-*/
-
-QDebug operator <<(QDebug debug, const QQmlListCompositor::Group &group)
-{
- switch (group) {
- case QQmlListCompositor::Cache: return debug << "Cache";
- case QQmlListCompositor::Default: return debug << "Default";
- default: return (debug.nospace() << "Group" << int(group)).space();
- }
-
-}
-
-/*!
- \internal
- Writes the contents of \a range to \a debug.
-*/
-
-QDebug operator <<(QDebug debug, const QQmlListCompositor::Range &range)
-{
- (debug.nospace()
- << "Range("
- << range.list) << ' '
- << range.index << ' '
- << range.count << ' '
- << (range.isUnresolved() ? 'U' : '0')
- << (range.append() ? 'A' : '0')
- << (range.prepend() ? 'P' : '0');
- for (int i = QQmlListCompositor::MaximumGroupCount - 1; i >= 2; --i)
- debug << (range.inGroup(i) ? '1' : '0');
- return (debug
- << (range.inGroup(QQmlListCompositor::Default) ? 'D' : '0')
- << (range.inGroup(QQmlListCompositor::Cache) ? 'C' : '0'));
-}
-
-static void qt_print_indexes(QDebug &debug, int count, const int *indexes)
-{
- for (int i = count - 1; i >= 0; --i)
- debug << indexes[i];
-}
-
-/*!
- \internal
- Writes the contents of \a it to \a debug.
-*/
-
-QDebug operator <<(QDebug debug, const QQmlListCompositor::iterator &it)
-{
- (debug.nospace() << "iterator(" << it.group).space() << "offset:" << it.offset;
- qt_print_indexes(debug, it.groupCount, it.index);
- return ((debug << **it).nospace() << ')').space();
-}
-
-static QDebug qt_print_change(QDebug debug, const char *name, const QQmlListCompositor::Change &change)
-{
- debug.nospace() << name << '(' << change.moveId << ' ' << change.count << ' ';
- for (int i = QQmlListCompositor::MaximumGroupCount - 1; i >= 2; --i)
- debug << (change.inGroup(i) ? '1' : '0');
- debug << (change.inGroup(QQmlListCompositor::Default) ? 'D' : '0')
- << (change.inGroup(QQmlListCompositor::Cache) ? 'C' : '0');
- int i = QQmlListCompositor::MaximumGroupCount - 1;
- for (; i >= 0 && !change.inGroup(i); --i) {}
- for (; i >= 0; --i)
- debug << ' ' << change.index[i];
- return (debug << ')').maybeSpace();
-}
-
-/*!
- \internal
- Writes the contents of \a change to \a debug.
-*/
-
-QDebug operator <<(QDebug debug, const QQmlListCompositor::Change &change)
-{
- return qt_print_change(debug, "Change", change);
-}
-
-/*!
- \internal
- Writes the contents of \a remove to \a debug.
-*/
-
-QDebug operator <<(QDebug debug, const QQmlListCompositor::Remove &remove)
-{
- return qt_print_change(debug, "Remove", remove);
-}
-
-/*!
- \internal
- Writes the contents of \a insert to \a debug.
-*/
-
-QDebug operator <<(QDebug debug, const QQmlListCompositor::Insert &insert)
-{
- return qt_print_change(debug, "Insert", insert);
-}
-
-/*!
- \internal
- Writes the contents of \a list to \a debug.
-*/
-
-QDebug operator <<(QDebug debug, const QQmlListCompositor &list)
-{
- int indexes[QQmlListCompositor::MaximumGroupCount];
- for (int i = 0; i < QQmlListCompositor::MaximumGroupCount; ++i)
- indexes[i] = 0;
- debug.nospace() << "QQmlListCompositor(";
- qt_print_indexes(debug, list.m_groupCount, list.m_end.index);
- for (QQmlListCompositor::Range *range = list.m_ranges.next; range != &list.m_ranges; range = range->next) {
- (debug << '\n').space();
- qt_print_indexes(debug, list.m_groupCount, indexes);
- debug << ' ' << *range;
-
- for (int i = 0; i < list.m_groupCount; ++i) {
- if (range->inGroup(i))
- indexes[i] += range->count;
- }
- }
- return (debug << ')').maybeSpace();
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/util/qqmllistcompositor_p.h b/src/qml/util/qqmllistcompositor_p.h
deleted file mode 100644
index 172040559c..0000000000
--- a/src/qml/util/qqmllistcompositor_p.h
+++ /dev/null
@@ -1,372 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLLISTCOMPOSITOR_P_H
-#define QQMLLISTCOMPOSITOR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qvector.h>
-
-#include <private/qqmlchangeset_p.h>
-
-#include <QtCore/qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_AUTOTEST_EXPORT QQmlListCompositor
-{
-public:
- enum { MinimumGroupCount = 3, MaximumGroupCount = 11 };
-
- enum Group
- {
- Cache = 0,
- Default = 1,
- Persisted = 2
- };
-
- enum Flag
- {
- CacheFlag = 1 << Cache,
- DefaultFlag = 1 << Default,
- PersistedFlag = 1 << Persisted,
- PrependFlag = 0x10000000,
- AppendFlag = 0x20000000,
- UnresolvedFlag = 0x40000000,
- MovedFlag = 0x80000000,
- GroupMask = ~(PrependFlag | AppendFlag | UnresolvedFlag | MovedFlag | CacheFlag)
- };
-
- class Range
- {
- public:
- Range() : next(this), previous(this) {}
- Range(Range *next, void *list, int index, int count, uint flags)
- : next(next), previous(next->previous), list(list), index(index), count(count), flags(flags) {
- next->previous = this; previous->next = this; }
-
- Range *next;
- Range *previous;
- void *list = nullptr;
- int index = 0;
- int count = 0;
- uint flags = 0;
-
- inline int start() const { return index; }
- inline int end() const { return index + count; }
-
- inline int groups() const { return flags & GroupMask; }
-
- inline bool inGroup() const { return flags & GroupMask; }
- inline bool inCache() const { return flags & CacheFlag; }
- inline bool inGroup(int group) const { return flags & (1 << group); }
- inline bool isUnresolved() const { return flags & UnresolvedFlag; }
-
- inline bool prepend() const { return flags & PrependFlag; }
- inline bool append() const { return flags & AppendFlag; }
- };
-
- class Q_AUTOTEST_EXPORT iterator
- {
- public:
- inline iterator();
- inline iterator(const iterator &it);
- inline iterator(Range *range, int offset, Group group, int groupCount);
- inline ~iterator() {}
-
- bool operator ==(const iterator &it) const { return range == it.range && offset == it.offset; }
- bool operator !=(const iterator &it) const { return range != it.range || offset != it.offset; }
-
- bool operator ==(Group group) const { return range->flags & (1 << group); }
- bool operator !=(Group group) const { return !(range->flags & (1 << group)); }
-
- Range *&operator *() { return range; }
- Range * const &operator *() const { return range; }
- Range *operator ->() { return range; }
- const Range *operator ->() const { return range; }
-
- iterator &operator +=(int difference);
-
- template<typename T> T *list() const { return static_cast<T *>(range->list); }
- int modelIndex() const { return range->index + offset; }
-
- void incrementIndexes(int difference) { incrementIndexes(difference, range->flags); }
- void decrementIndexes(int difference) { decrementIndexes(difference, range->flags); }
-
- inline void incrementIndexes(int difference, uint flags);
- inline void decrementIndexes(int difference, uint flags);
-
- void setGroup(Group g) { group = g; groupFlag = 1 << g; }
-
- Range *range = nullptr;
- int offset = 0;
- Group group = Default;
- int groupFlag;
- int groupCount = 0;
- union {
- struct {
- int cacheIndex;
- };
- int index[MaximumGroupCount];
- };
- };
-
- class Q_AUTOTEST_EXPORT insert_iterator : public iterator
- {
- public:
- inline insert_iterator() {}
- inline insert_iterator(const iterator &it) : iterator(it) {}
- inline insert_iterator(Range *, int, Group, int);
- inline ~insert_iterator() {}
-
- insert_iterator &operator +=(int difference);
- };
-
- struct Change
- {
- inline Change() {}
- inline Change(const iterator &it, int count, uint flags, int moveId = -1);
- int count;
- uint flags;
- int moveId;
- union {
- struct {
- int cacheIndex;
- };
- int index[MaximumGroupCount];
- };
-
- inline bool isMove() const { return moveId >= 0; }
- inline bool inCache() const { return flags & CacheFlag; }
- inline bool inGroup() const { return flags & GroupMask; }
- inline bool inGroup(int group) const { return flags & (CacheFlag << group); }
-
- inline int groups() const { return flags & GroupMask; }
- };
-
- struct Insert : public Change
- {
- Insert() {}
- Insert(const iterator &it, int count, uint flags, int moveId = -1)
- : Change(it, count, flags, moveId) {}
- };
-
- struct Remove : public Change
- {
- Remove() {}
- Remove(const iterator &it, int count, uint flags, int moveId = -1)
- : Change(it, count, flags, moveId) {}
- };
-
- QQmlListCompositor();
- ~QQmlListCompositor();
-
- int defaultGroups() const { return m_defaultFlags & ~PrependFlag; }
- void setDefaultGroups(int groups) { m_defaultFlags = groups | PrependFlag; }
- void setDefaultGroup(Group group) { m_defaultFlags |= (1 << group); }
- void clearDefaultGroup(Group group) { m_defaultFlags &= ~(1 << group); }
- void setRemoveGroups(int groups) { m_removeFlags = PrependFlag | AppendFlag | groups; }
- void setGroupCount(int count);
-
- int count(Group group) const;
- iterator find(Group group, int index);
- iterator find(Group group, int index) const;
- insert_iterator findInsertPosition(Group group, int index);
-
- const iterator &end() { return m_end; }
-
- void append(void *list, int index, int count, uint flags, QVector<Insert> *inserts = nullptr);
- void insert(Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = nullptr);
- iterator insert(iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = nullptr);
-
- void setFlags(Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts = nullptr);
- void setFlags(iterator from, int count, Group group, uint flags, QVector<Insert> *inserts = nullptr);
- void setFlags(Group fromGroup, int from, int count, uint flags, QVector<Insert> *inserts = nullptr) {
- setFlags(fromGroup, from, count, fromGroup, flags, inserts); }
- void setFlags(const iterator from, int count, uint flags, QVector<Insert> *inserts = nullptr) {
- setFlags(from, count, from.group, flags, inserts); }
-
- void clearFlags(Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removals = nullptr);
- void clearFlags(iterator from, int count, Group group, uint flags, QVector<Remove> *removals = nullptr);
- void clearFlags(Group fromGroup, int from, int count, uint flags, QVector<Remove> *removals = nullptr) {
- clearFlags(fromGroup, from, count, fromGroup, flags, removals); }
- void clearFlags(const iterator &from, int count, uint flags, QVector<Remove> *removals = nullptr) {
- clearFlags(from, count, from.group, flags, removals); }
-
- bool verifyMoveTo(Group fromGroup, int from, Group toGroup, int to, int count, Group group) const;
-
- void move(
- Group fromGroup,
- int from,
- Group toGroup,
- int to,
- int count,
- Group group,
- QVector<Remove> *removals = nullptr,
- QVector<Insert> *inserts = nullptr);
- void clear();
-
- void listItemsInserted(void *list, int index, int count, QVector<Insert> *inserts);
- void listItemsRemoved(void *list, int index, int count, QVector<Remove> *removals);
- void listItemsMoved(void *list, int from, int to, int count, QVector<Remove> *removals, QVector<Insert> *inserts);
- void listItemsChanged(void *list, int index, int count, QVector<Change> *changes);
-
- void transition(
- Group from,
- Group to,
- QVector<QQmlChangeSet::Change> *removes,
- QVector<QQmlChangeSet::Change> *inserts);
-
-private:
- Range m_ranges;
- iterator m_end;
- iterator m_cacheIt;
- int m_groupCount;
- int m_defaultFlags;
- int m_removeFlags;
- int m_moveId;
-
- inline Range *insert(Range *before, void *list, int index, int count, uint flags);
- inline Range *erase(Range *range);
-
- struct MovedFlags
- {
- MovedFlags() {}
- MovedFlags(int moveId, uint flags) : moveId(moveId), flags(flags) {}
-
- int moveId;
- uint flags;
- };
-
- void listItemsRemoved(
- QVector<Remove> *translatedRemovals,
- void *list,
- QVector<QQmlChangeSet::Change> *removals,
- QVector<QQmlChangeSet::Change> *insertions = nullptr,
- QVector<MovedFlags> *movedFlags = nullptr);
- void listItemsInserted(
- QVector<Insert> *translatedInsertions,
- void *list,
- const QVector<QQmlChangeSet::Change> &insertions,
- const QVector<MovedFlags> *movedFlags = nullptr);
- void listItemsChanged(
- QVector<Change> *translatedChanges,
- void *list,
- const QVector<QQmlChangeSet::Change> &changes);
-
- friend Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor &list);
-};
-
-Q_DECLARE_TYPEINFO(QQmlListCompositor::Change, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(QQmlListCompositor::Remove, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(QQmlListCompositor::Insert, Q_PRIMITIVE_TYPE);
-
-inline QQmlListCompositor::iterator::iterator() {}
-inline QQmlListCompositor::iterator::iterator(const iterator &it)
- : range(it.range)
- , offset(it.offset)
- , group(it.group)
- , groupFlag(it.groupFlag)
- , groupCount(it.groupCount)
-{
- for (int i = 0; i < groupCount; ++i)
- index[i] = it.index[i];
-}
-
-inline QQmlListCompositor::iterator::iterator(
- Range *range, int offset, Group group, int groupCount)
- : range(range)
- , offset(offset)
- , group(group)
- , groupFlag(1 << group)
- , groupCount(groupCount)
-{
- for (int i = 0; i < groupCount; ++i)
- index[i] = 0;
-}
-
-inline void QQmlListCompositor::iterator::incrementIndexes(int difference, uint flags)
-{
- for (int i = 0; i < groupCount; ++i) {
- if (flags & (1 << i))
- index[i] += difference;
- }
-}
-
-inline void QQmlListCompositor::iterator::decrementIndexes(int difference, uint flags)
-{
- for (int i = 0; i < groupCount; ++i) {
- if (flags & (1 << i))
- index[i] -= difference;
- }
-}
-
-inline QQmlListCompositor::insert_iterator::insert_iterator(
- Range *range, int offset, Group group, int groupCount)
- : iterator(range, offset, group, groupCount) {}
-
-inline QQmlListCompositor::Change::Change(const iterator &it, int count, uint flags, int moveId)
- : count(count), flags(flags), moveId(moveId)
-{
- for (int i = 0; i < MaximumGroupCount; ++i)
- index[i] = it.index[i];
-}
-
-Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Group &group);
-Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Range &range);
-Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::iterator &it);
-Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Change &change);
-Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Remove &remove);
-Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Insert &insert);
-Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor &list);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/util/util.pri b/src/qml/util/util.pri
index bebb271f1b..3b121ba3cb 100644
--- a/src/qml/util/util.pri
+++ b/src/qml/util/util.pri
@@ -1,19 +1,5 @@
SOURCES += \
- $$PWD/qqmlchangeset.cpp \
- $$PWD/qqmllistaccessor.cpp \
- $$PWD/qqmllistcompositor.cpp \
$$PWD/qqmlpropertymap.cpp
HEADERS += \
- $$PWD/qqmlchangeset_p.h \
- $$PWD/qqmllistaccessor_p.h \
- $$PWD/qqmllistcompositor_p.h \
$$PWD/qqmlpropertymap.h
-
-qtConfig(qml-delegate-model) {
- SOURCES += \
- $$PWD/qqmladaptormodel.cpp
-
- HEADERS += \
- $$PWD/qqmladaptormodel_p.h
-}