aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlmodels/qqmldmlistaccessordata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmlmodels/qqmldmlistaccessordata.cpp')
-rw-r--r--src/qmlmodels/qqmldmlistaccessordata.cpp157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/qmlmodels/qqmldmlistaccessordata.cpp b/src/qmlmodels/qqmldmlistaccessordata.cpp
new file mode 100644
index 0000000000..bfd353771c
--- /dev/null
+++ b/src/qmlmodels/qqmldmlistaccessordata.cpp
@@ -0,0 +1,157 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <private/qqmldmlistaccessordata_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQmlDMListAccessorData::QQmlDMListAccessorData(
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
+ VDMListDelegateDataType *dataType,
+ int index, int row, int column, const QVariant &value)
+ : QQmlDelegateModelItem(metaType, dataType, index, row, column)
+ , cachedData(value)
+{
+ QObjectPrivate::get(this)->metaObject = dataType;
+ dataType->addref();
+}
+
+QQmlDMListAccessorData::~QQmlDMListAccessorData()
+{
+ QObjectPrivate *d = QObjectPrivate::get(this);
+ static_cast<VDMListDelegateDataType *>(d->metaObject)->release();
+ d->metaObject = nullptr;
+}
+
+void QQmlDMListAccessorData::setModelData(const QVariant &data) {
+ if (data == cachedData)
+ return;
+
+ cachedData = data;
+ cachedDataClean = false;
+ static_cast<const VDMListDelegateDataType *>(QObjectPrivate::get(this)->metaObject)
+ ->emitAllSignals(this);
+}
+
+void QQmlDMListAccessorData::setValue(const QString &role, const QVariant &value)
+{
+ // Used only for initialization of the cached data. Does not have to emit change signals.
+ Q_ASSERT(!cachedDataClean);
+
+ if (role == QLatin1String("modelData") || role.isEmpty())
+ cachedData = value;
+ else
+ VDMListDelegateDataType::setValue(&cachedData, role, value);
+}
+
+bool QQmlDMListAccessorData::resolveIndex(const QQmlAdaptorModel &model, int idx)
+{
+ if (index == -1) {
+ index = idx;
+ setModelData(model.list.at(idx));
+ emit modelIndexChanged();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void VDMListDelegateDataType::emitAllSignals(QQmlDMListAccessorData *accessor) const
+{
+ for (int i = propertyOffset, end = propertyCount(); i != end; ++i)
+ QMetaObject::activate(accessor, this, i - propertyOffset, nullptr);
+ emit accessor->modelDataChanged();
+}
+
+int VDMListDelegateDataType::metaCall(
+ QObject *object, QMetaObject::Call call, int id, void **arguments)
+{
+ Q_ASSERT(qobject_cast<QQmlDMListAccessorData *>(object));
+ QQmlDMListAccessorData *accessor = static_cast<QQmlDMListAccessorData *>(object);
+
+ switch (call) {
+ case QMetaObject::ReadProperty: {
+ if (id < propertyOffset)
+ break;
+
+ QVariant *result = static_cast<QVariant *>(arguments[0]);
+ const QByteArray name = property(id).name();
+ const QVariant data = accessor->index == -1
+ ? accessor->modelData()
+ : model->list.at(accessor->index);
+ *result = value(&data, name);
+ return -1;
+ }
+ case QMetaObject::WriteProperty: {
+ if (id < propertyOffset)
+ break;
+
+ const QVariant &argument = *static_cast<QVariant *>(arguments[0]);
+ const QByteArray name = property(id).name();
+ QVariant data = accessor->index == -1
+ ? accessor->modelData()
+ : model->list.at(accessor->index);
+ if (argument == value(&data, name))
+ return -1;
+ setValue(&data, name, argument);
+ if (accessor->index == -1) {
+ accessor->cachedData = data;
+ accessor->cachedDataClean = false;
+ } else {
+ model->list.set(accessor->index, data);
+ }
+ QMetaObject::activate(accessor, this, id - propertyOffset, nullptr);
+ emit accessor->modelDataChanged();
+ return -1;
+ }
+ default:
+ break;
+ }
+
+ return accessor->qt_metacall(call, id, arguments);
+}
+
+int VDMListDelegateDataType::createProperty(const char *name, const char *)
+{
+ const int propertyIndex = propertyCount() - propertyOffset;
+
+ // We use QVariant because the types may be different in the different objects.
+ QQmlAdaptorModelEngineData::addProperty(
+ &builder, propertyIndex, name, QByteArrayLiteral("QVariant"));
+
+ metaObject.reset(builder.toMetaObject());
+ *static_cast<QMetaObject *>(this) = *metaObject;
+ return propertyIndex + propertyOffset;
+}
+
+QMetaObject *VDMListDelegateDataType::toDynamicMetaObject(QObject *object)
+{
+ if (const QQmlRefPointer<QQmlContextData> &contextData
+ = static_cast<QQmlDMListAccessorData *>(object)->contextData) {
+ if (contextData->contextObject() == object) {
+ // We are using context properties. There should be a propertyCache so that row and
+ // column are hidden. We shall also return the static metaObject in that case.
+
+ if (!propertyCache) {
+ propertyCache = QQmlPropertyCache::createStandalone(
+ &QQmlDMListAccessorData::staticMetaObject, model->modelItemRevision);
+ if (QQmlData *ddata = QQmlData::get(object, true))
+ ddata->propertyCache = propertyCache;
+ }
+
+ // ### Qt 7: Return const from toDynamicMetaObject() and drop the const_cast.
+ return const_cast<QMetaObject *>(&QQmlDMListAccessorData::staticMetaObject);
+ }
+ }
+
+ // If the context object is not the model object, we are using required properties.
+ // In that case, create any extra properties.
+ QQmlDMListAccessorData *data = static_cast<QQmlDMListAccessorData *>(object);
+ if (!data->cachedDataClean) {
+ createMissingProperties(&data->cachedData);
+ data->cachedDataClean = true;
+ }
+ return this;
+}
+
+QT_END_NAMESPACE