diff options
author | Andrew den Exter <andrew.den-exter@nokia.com> | 2011-12-22 13:49:03 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-23 07:23:48 +0100 |
commit | fb00bd445b1d77ffd7be8c60fce30f58e53eb6de (patch) | |
tree | e2000fd51e5c64a05fb45963e756aca29bca31d5 /src | |
parent | 347f84e5aca9423536cb0cd7a2eafaf836a72212 (diff) |
Insert items into VisualDataModel.
Add API for inserting data directly into a VisualDataModel which
can be used among other things to create temporary items that are
later resolved to an actual item in the source model.
Task-number: QTBUG-21516
Change-Id: I835f0e8d6c5edfb3a21029687de5b700f7400317
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickvisualadaptormodel.cpp | 363 | ||||
-rw-r--r-- | src/quick/items/qquickvisualdatamodel.cpp | 243 | ||||
-rw-r--r-- | src/quick/items/qquickvisualdatamodel_p.h | 8 | ||||
-rw-r--r-- | src/quick/items/qquickvisualdatamodel_p_p.h | 17 | ||||
-rw-r--r-- | src/quick/util/qdeclarativelistcompositor.cpp | 26 | ||||
-rw-r--r-- | src/quick/util/qdeclarativelistcompositor_p.h | 64 |
6 files changed, 556 insertions, 165 deletions
diff --git a/src/quick/items/qquickvisualadaptormodel.cpp b/src/quick/items/qquickvisualadaptormodel.cpp index c1402ae242..f5a5c8e325 100644 --- a/src/quick/items/qquickvisualadaptormodel.cpp +++ b/src/quick/items/qquickvisualadaptormodel.cpp @@ -108,6 +108,7 @@ public: , stringValue(&initializeStringValue) , m_ref(0) , m_count(0) + , m_roleCount(0) , m_objectList(false) { } @@ -142,14 +143,13 @@ public: return d->createItem(metaType, model, index); } - static QString initializeStringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) { - QQuickVisualAdaptorModelPrivate *d = get(model); - d->createMetaObject(); - return d->stringValue(model, index, name); + static QString initializeStringValue(QQuickVisualAdaptorModelPrivate *model, int index, const QString &name) { + model->createMetaObject(); + return model->stringValue(model, index, name); } typedef QQuickVisualDataModelItem *(*CreateModelData)(QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index); - typedef QString (*StringValue)(QQuickVisualAdaptorModel *model, int index, const QString &name); + typedef QString (*StringValue)(QQuickVisualAdaptorModelPrivate *model, int index, const QString &name); struct PropertyData { int role; @@ -177,6 +177,7 @@ public: int m_ref; int m_count; + int m_roleCount; QQuickVisualAdaptorModel::Flags m_flags; bool m_objectList : 1; @@ -191,6 +192,109 @@ public: QQuickVisualDataModelItemCache m_cache; }; +class QQuickVDMCachedModelData : public QQuickVisualDataModelItem +{ +public: + virtual QVariant value(QQuickVisualAdaptorModelPrivate *model, int role) const = 0; + virtual void setValue(QQuickVisualAdaptorModelPrivate *model, int role, const QVariant &value) = 0; + + void setValue(const QString &role, const QVariant &value) + { + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); + QHash<QByteArray, int>::iterator it = d->m_roleNames.find(role.toUtf8()); + if (it != d->m_roleNames.end()) { + for (int i = 0; i < d->m_propertyData.count(); ++i) { + if (d->m_propertyData.at(i).role == *it) { + cachedData[i] = value; + return; + } + } + } + } + + bool resolveIndex(int idx) + { + if (index[0] == -1) { + Q_ASSERT(idx >= 0); + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); + index[0] = idx; + cachedData.clear(); + emit modelIndexChanged(); + const QMetaObject *meta = metaObject(); + const int propertyCount = d->m_propertyData.count(); + for (int i = 0; i < propertyCount; ++i) + QMetaObject::activate(this, meta, i, 0); + return true; + } else { + return false; + } + } + + static v8::Handle<v8::Value> get_property(v8::Local<v8::String>, const v8::AccessorInfo &info) + { + QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); + if (!data) + V8THROW_ERROR("Not a valid VisualData object"); + + QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(data->model); + QQuickVDMCachedModelData *modelData = static_cast<QQuickVDMCachedModelData *>(data); + const int propertyId = info.Data()->Int32Value(); + if (data->index[0] == -1) { + if (!modelData->cachedData.isEmpty()) { + return data->engine->fromVariant( + modelData->cachedData.at(modelData->cachedData.count() > 1 ? propertyId : 0)); + } + } else { + return data->engine->fromVariant( + modelData->value(model, model->m_propertyData.at(propertyId).role)); + } + return v8::Undefined(); + } + + static void set_property( + v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info) + { + QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); + if (!data) + V8THROW_ERROR_SETTER("Not a valid VisualData object"); + + const int propertyId = info.Data()->Int32Value(); + if (data->index[0] == -1) { + QQuickVDMCachedModelData *modelData = static_cast<QQuickVDMCachedModelData *>(data); + if (!modelData->cachedData.isEmpty()) { + if (modelData->cachedData.count() > 1) { + modelData->cachedData[propertyId] = data->engine->toVariant(value, QVariant::Invalid); + QMetaObject::activate(data, data->metaObject(), propertyId, 0); + } else if (modelData->cachedData.count() == 1) { + modelData->cachedData[0] = data->engine->toVariant(value, QVariant::Invalid); + QMetaObject::activate(data, data->metaObject(), 0, 0); + QMetaObject::activate(data, data->metaObject(), 1, 0); + } + } + } + } + + v8::Handle<v8::Value> get() + { + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); + + v8::Local<v8::Object> data = d->m_constructor->NewInstance(); + data->SetExternalResource(this); + return data; + } + + + QQuickVDMCachedModelData( + QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) + : QQuickVisualDataModelItem(metaType, model, index) + { + if (index == -1) + cachedData.resize(QQuickVisualAdaptorModelPrivate::get(model)->m_roleCount); + } + + QVector<QVariant> cachedData; +}; + class QQuickVisualDataModelItemMetaObject : public QAbstractDynamicMetaObject { public: @@ -219,20 +323,48 @@ public: VDMDelegateDataType *m_type; }; -class QQuickVDMAbstractItemModelDataMetaObject : public QQuickVisualDataModelItemMetaObject +class QQuickVDMCachedModelDataMetaObject : public QQuickVisualDataModelItemMetaObject { public: - QQuickVDMAbstractItemModelDataMetaObject(QQuickVisualDataModelItem *object, VDMDelegateDataType *type) + QQuickVDMCachedModelDataMetaObject(QQuickVisualDataModelItem *object, VDMDelegateDataType *type) : QQuickVisualDataModelItemMetaObject(object, type) {} int metaCall(QMetaObject::Call call, int id, void **arguments) { if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) { QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_data->model); - if (m_data->index[0] == -1 || !model->m_abstractItemModel) - return -1; - *static_cast<QVariant *>(arguments[0]) = model->m_abstractItemModel->index( - m_data->index[0], 0, model->m_root).data(model->m_propertyData.at(id - m_type->propertyOffset).role); + const int propertyIndex = id - m_type->propertyOffset; + if (m_data->index[0] == -1) { + QQuickVDMCachedModelData *data = static_cast<QQuickVDMCachedModelData *>(m_data); + if (!data->cachedData.isEmpty()) { + *static_cast<QVariant *>(arguments[0]) = data->cachedData.count() > 1 + ? data->cachedData.at(propertyIndex) + : data->cachedData.at(0); + } + } else { + *static_cast<QVariant *>(arguments[0]) = static_cast<QQuickVDMCachedModelData *>( + m_data)->value(model, model->m_propertyData.at(propertyIndex).role); + } + return -1; + } else if (call == QMetaObject::WriteProperty && id >= m_type->propertyOffset) { + QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_data->model); + const int propertyIndex = id - m_type->propertyOffset; + if (m_data->index[0] == -1) { + QQuickVDMCachedModelData *data = static_cast<QQuickVDMCachedModelData *>(m_data); + if (data->cachedData.count() > 1) { + data->cachedData[propertyIndex] = *static_cast<QVariant *>(arguments[0]); + activate(data, this, propertyIndex, 0); + } else if (data->cachedData.count() == 1) { + data->cachedData[0] = *static_cast<QVariant *>(arguments[0]); + activate(data, this, 0, 0); + activate(data, this, 1, 0); + } + } else { + static_cast<QQuickVDMCachedModelData *>(m_data)->setValue( + model, + model->m_propertyData.at(propertyIndex).role, + *static_cast<QVariant *>(arguments[0])); + } return -1; } else { return m_data->qt_metacall(call, id, arguments); @@ -240,7 +372,7 @@ public: } }; -class QQuickVDMAbstractItemModelData : public QQuickVisualDataModelItem +class QQuickVDMAbstractItemModelData : public QQuickVDMCachedModelData { Q_OBJECT Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT) @@ -255,32 +387,30 @@ public: QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) { return new QQuickVDMAbstractItemModelData(metaType, model, index); } - static QString stringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) + static QString stringValue(QQuickVisualAdaptorModelPrivate *model, int index, const QString &role) { - QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); - const int role = d->m_roleNames.value(name.toUtf8(), -1); - - if (role != -1) - return d->m_abstractItemModel->index(index, 0, d->m_root).data(role).toString(); - else if (name == QLatin1String("hasModelChildren")) - return QVariant(d->m_abstractItemModel->hasChildren(d->m_abstractItemModel->index(index, 0, d->m_root))).toString(); - else + QHash<QByteArray, int>::const_iterator it = model->m_roleNames.find(role.toUtf8()); + if (it != model->m_roleNames.end()) { + return model->m_abstractItemModel->index(index, 0, model->m_root).data(*it).toString(); + } else if (role == QLatin1String("hasModelChildren")) { + return QVariant(model->m_abstractItemModel->hasChildren( + model->m_abstractItemModel->index(index, 0, model->m_root))).toString(); + } else { return QString(); + } } - static v8::Handle<v8::Value> get_property(v8::Local<v8::String>, const v8::AccessorInfo &info) + QVariant value(QQuickVisualAdaptorModelPrivate *model, int role) const { - QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - if (!data) - V8THROW_ERROR("Not a valid VisualData object"); - - QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(data->model); - if (data->index[0] == -1 || !model->m_abstractItemModel) - return v8::Undefined(); + return model->m_abstractItemModel + ? model->m_abstractItemModel->index(index[0], 0, model->m_root).data(role) + : 0; + } - const int role = info.Data()->Int32Value(); - const QVariant value = model->m_abstractItemModel->index(data->index[0], 0, model->m_root).data(role); - return data->engine->fromVariant(value); + void setValue(QQuickVisualAdaptorModelPrivate *model, int role, const QVariant &value) + { + model->m_abstractItemModel->setData( + model->m_abstractItemModel->index(index[0], 0, model->m_root), value, role); } static v8::Handle<v8::Value> get_hasModelChildren(v8::Local<v8::String>, const v8::AccessorInfo &info) @@ -295,21 +425,12 @@ public: model->m_abstractItemModel->index(data->index[0], 0, model->m_root))); } - v8::Handle<v8::Value> get() - { - QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); - - v8::Local<v8::Object> data = d->m_constructor->NewInstance(); - data->SetExternalResource(this); - return data; - } - private: QQuickVDMAbstractItemModelData( QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) - : QQuickVisualDataModelItem(metaType, model, index) + : QQuickVDMCachedModelData(metaType, model, index) { - new QQuickVDMAbstractItemModelDataMetaObject( + new QQuickVDMCachedModelDataMetaObject( this, QQuickVisualAdaptorModelPrivate::get(model)->m_delegateDataType); } }; @@ -336,51 +457,35 @@ public: }; -class QQuickVDMListModelInterfaceData : public QQuickVisualDataModelItem +class QQuickVDMListModelInterfaceData : public QQuickVDMCachedModelData { public: static QQuickVisualDataModelItem *create( QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) { return new QQuickVDMListModelInterfaceData(metaType, model, index); } - static QString stringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) + static QString stringValue(QQuickVisualAdaptorModelPrivate *model, int index, const QString &role) { - QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); - const int role = d->m_roleNames.value(name.toUtf8(), -1); - return role != -1 - ? d->m_listModelInterface->data(index, role).toString() + QHash<QByteArray, int>::const_iterator it = model->m_roleNames.find(role.toUtf8()); + return it != model->m_roleNames.end() + ? model->m_listModelInterface->data(index, *it).toString() : QString(); } - static v8::Handle<v8::Value> get_property(v8::Local<v8::String>, const v8::AccessorInfo &info) + QVariant value(QQuickVisualAdaptorModelPrivate *model, int role) const { - QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - if (!data) - V8THROW_ERROR("Not a valid VisualData object"); - - QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(data->model); - if (data->index[0] == -1 || !model->m_listModelInterface) - return v8::Undefined(); - - const int role = info.Data()->Int32Value(); - const QVariant value = model->m_listModelInterface->data(data->index[0], role); - return data->engine->fromVariant(value); + return model->m_listModelInterface + ? model->m_listModelInterface->data(index[0], role) + : 0; } - v8::Handle<v8::Value> get() - { - QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); - - v8::Local<v8::Object> data = d->m_constructor->NewInstance(); - data->SetExternalResource(this); - return data; - } + void setValue(QQuickVisualAdaptorModelPrivate *, int, const QVariant &) {} private: QQuickVDMListModelInterfaceData(QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) - : QQuickVisualDataModelItem(metaType, model, index) + : QQuickVDMCachedModelData(metaType, model, index) { - new QQuickVDMListModelInterfaceDataMetaObject( + new QQuickVDMCachedModelDataMetaObject( this, QQuickVisualAdaptorModelPrivate::get(model)->m_delegateDataType); } }; @@ -388,19 +493,32 @@ private: class QQuickVDMListAccessorData : public QQuickVisualDataModelItem { Q_OBJECT - Q_PROPERTY(QVariant modelData READ modelData CONSTANT) + Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged) public: - QVariant modelData() const { - return QQuickVisualAdaptorModelPrivate::get(model)->m_listAccessor->at(index[0]); } + QVariant modelData() const + { + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); + return index[0] != -1 && d->m_listAccessor + ? d->m_listAccessor->at(index[0]) + : cachedData; + } + + void setModelData(const QVariant &data) + { + if (index[0] == -1 && data != cachedData) { + cachedData = data; + emit modelDataChanged(); + } + } static QQuickVisualDataModelItem *create( QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) { return new QQuickVDMListAccessorData(metaType, model, index); } - static QString stringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) + static QString stringValue(QQuickVisualAdaptorModelPrivate *model, int index, const QString &role) { - return name == QLatin1String("modelData") - ? QQuickVisualAdaptorModelPrivate::get(model)->m_listAccessor->at(index).toString() + return role == QLatin1String("modelData") + ? model->m_listAccessor->at(index).toString() : QString(); } @@ -412,15 +530,52 @@ public: QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(data->model); if (data->index[0] == -1 || !d->m_listAccessor) - return v8::Undefined(); + return data->engine->fromVariant(static_cast<QQuickVDMListAccessorData *>(data)->cachedData); return data->engine->fromVariant(d->m_listAccessor->at(data->index[0])); } + + static void set_modelData(v8::Local<v8::String>, const v8::Handle<v8::Value> &value, const v8::AccessorInfo &info) + { + QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); + if (!data) + V8THROW_ERROR_SETTER("Not a valid VisualData object"); + + if (data->index[0] == -1) { + static_cast<QQuickVDMListAccessorData *>(data)->setModelData( + data->engine->toVariant(value, QVariant::Invalid)); + } + } + + void setValue(const QString &role, const QVariant &value) + { + if (role == QLatin1String("modelData")) + cachedData = value; + } + + bool resolveIndex(int idx) + { + if (index[0] == -1) { + index[0] = idx; + cachedData.clear(); + emit modelIndexChanged(); + emit modelDataChanged(); + return true; + } else { + return false; + } + } + +Q_SIGNALS: + void modelDataChanged(); + private: QQuickVDMListAccessorData(QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) : QQuickVisualDataModelItem(metaType, model, index) { } + + QVariant cachedData; }; class QQuickVDMObjectDataMetaObject : public QQuickVisualDataModelItemMetaObject @@ -517,11 +672,11 @@ public: static QQuickVisualDataModelItem *create( QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) { - return new QQuickVDMObjectData(metaType, model, index); } + return index >= 0 ? new QQuickVDMObjectData(metaType, model, index) : 0; } - static QString stringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) + static QString stringValue(QQuickVisualAdaptorModelPrivate *model, int index, const QString &name) { - if (QObject *object = QQuickVisualAdaptorModelPrivate::get(model)->m_listAccessor->at(index).value<QObject *>()) + if (QObject *object = model->m_listAccessor->at(index).value<QObject *>()) return object->property(name.toUtf8()).toString(); return QString(); } @@ -545,7 +700,7 @@ void QQuickVisualAdaptorModelPrivate::addProperty( m_delegateDataType->builder.addSignal("__" + QByteArray::number(propertyId) + "()"); QMetaPropertyBuilder property = m_delegateDataType->builder.addProperty( propertyName, propertyType, propertyId); - property.setWritable(false); + property.setWritable(true); // No, yes, yes no? m_propertyData.append(propertyData); } @@ -589,37 +744,42 @@ void QQuickVisualAdaptorModelPrivate::createMetaObject() ft->PrototypeTemplate()->SetAccessor( v8Engine->toString(roleName), QQuickVDMListModelInterfaceData::get_property, - 0, - v8::Int32::New(role)); + QQuickVDMListModelInterfaceData::set_property, + v8::Int32::New(propertyId)); m_roleNames.insert(propertyName, role); } + m_roleCount = m_propertyData.count(); if (m_propertyData.count() == 1) { addProperty(roles.first(), 1, "modelData", "QVariant", true); ft->PrototypeTemplate()->SetAccessor( v8::String::New("modelData"), QQuickVDMListModelInterfaceData::get_property, - 0, - v8::Int32::New(roles.first())); + QQuickVDMListModelInterfaceData::set_property, + v8::Int32::New(0)); + m_roleNames.insert("modelData", roles.first()); } } else if (m_abstractItemModel) { setModelDataType<QQuickVDMAbstractItemModelData>(); QHash<int, QByteArray> roleNames = m_abstractItemModel->roleNames(); for (QHash<int, QByteArray>::const_iterator it = roleNames.begin(); it != roleNames.end(); ++it) { - addProperty(it.key(), m_propertyData.count(), it.value(), "QVariant"); + const int propertyId = m_propertyData.count(); + addProperty(it.key(), propertyId, it.value(), "QVariant"); ft->PrototypeTemplate()->SetAccessor( v8::String::New(it.value().constData(), it.value().length()), QQuickVDMAbstractItemModelData::get_property, - 0, - v8::Int32::New(it.key())); + QQuickVDMAbstractItemModelData::set_property, + v8::Int32::New(propertyId)); m_roleNames.insert(it.value(), it.key()); } + m_roleCount = m_propertyData.count(); if (m_propertyData.count() == 1) { addProperty(roleNames.begin().key(), 1, "modelData", "QVariant", true); ft->PrototypeTemplate()->SetAccessor( v8::String::New("modelData"), QQuickVDMAbstractItemModelData::get_property, - 0, - v8::Int32::New(roleNames.begin().key())); + QQuickVDMAbstractItemModelData::set_property, + v8::Int32::New(0)); + m_roleNames.insert("modelData", roleNames.begin().key()); } ft->PrototypeTemplate()->SetAccessor( v8::String::New("hasModelChildren"), @@ -702,6 +862,7 @@ void QQuickVisualAdaptorModel::setModel(const QVariant &model, QDeclarativeEngin d->m_roles.clear(); d->m_roleNames.clear(); + d->m_roleCount = 0; d->m_flags = QQuickVisualAdaptorModel::Flags(); if (d->m_delegateDataType) d->m_delegateDataType->release(); @@ -798,22 +959,24 @@ int QQuickVisualAdaptorModel::count() const QQuickVisualDataModelItem *QQuickVisualAdaptorModel::createItem(QQuickVisualDataModelItemMetaType *metaType, int index) { Q_D(QQuickVisualAdaptorModel); - QQuickVisualDataModelItem *data = d->createItem(metaType, this, index); - d->m_cache.insert(data); - if (d->m_delegateDataType && d->m_delegateDataType->propertyCache) { - QDeclarativeData *qmldata = QDeclarativeData::get(data, true); - qmldata->propertyCache = d->m_delegateDataType->propertyCache; - qmldata->propertyCache->addref(); - } + if (QQuickVisualDataModelItem *item = d->createItem(metaType, this, index)) { + d->m_cache.insert(item); - return data; + if (d->m_delegateDataType && d->m_delegateDataType->propertyCache) { + QDeclarativeData *qmldata = QDeclarativeData::get(item, true); + qmldata->propertyCache = d->m_delegateDataType->propertyCache; + qmldata->propertyCache->addref(); + } + return item; + } + return 0; } QString QQuickVisualAdaptorModel::stringValue(int index, const QString &name) { Q_D(QQuickVisualAdaptorModel); - return d->stringValue(this, index, name); + return d->stringValue(d, index, name); } bool QQuickVisualAdaptorModel::canFetchMore() const diff --git a/src/quick/items/qquickvisualdatamodel.cpp b/src/quick/items/qquickvisualdatamodel.cpp index caad582cdd..b0294435b5 100644 --- a/src/quick/items/qquickvisualdatamodel.cpp +++ b/src/quick/items/qquickvisualdatamodel.cpp @@ -111,7 +111,8 @@ QQuickVisualDataModelPrivate::QQuickVisualDataModelPrivate(QDeclarativeContext * , m_filterGroup(QStringLiteral("items")) , m_cacheItems(0) , m_items(0) - , m_groupCount(3) + , m_persistedItems(0) + , m_groupCount(Compositor::MinimumGroupCount) { } @@ -169,8 +170,8 @@ QQuickVisualDataModel::~QQuickVisualDataModel() cacheItem->scriptRef += 1; delete cacheItem->object; cacheItem->scriptRef -= 1; - cacheItem->object = 0; cacheItem->objectRef = 0; + cacheItem->object = 0; if (!cacheItem->isReferenced()) delete cacheItem; } @@ -198,7 +199,7 @@ void QQuickVisualDataModel::componentComplete() defaultGroups |= Compositor::DefaultFlag; if (QQuickVisualDataGroupPrivate::get(d->m_persistedItems)->defaultInclude) defaultGroups |= Compositor::PersistedFlag; - for (int i = 3; i < d->m_groupCount; ++i) { + 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]; @@ -753,7 +754,8 @@ QObject *QQuickVisualDataModelPrivate::object(Compositor::Group group, int index cacheItem = m_adaptorModel->createItem(m_cacheMetaType, it.modelIndex()); for (int i = 1; i < m_groupCount; ++i) cacheItem->index[i] = it.index[i]; - cacheItem->groups = it->flags & Compositor::GroupMask; + + cacheItem->groups = it->flags; m_cache.insert(it.cacheIndex, cacheItem); m_compositor.setFlags(it, 1, Compositor::CacheFlag); @@ -893,13 +895,11 @@ void QQuickVisualDataModelPrivate::setGroups( 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(); } @@ -1070,7 +1070,14 @@ void QQuickVisualDataModelPrivate::itemsRemoved( emitDestroyingItem(item); cacheItem->object = 0; } - if (remove.groups() == cacheItem->groups) { + 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; for (int i = 1; i < m_groupCount; ++i) cacheItem->index[i] = -1; @@ -1079,7 +1086,7 @@ void QQuickVisualDataModelPrivate::itemsRemoved( if (remove.inGroup(i)) cacheItem->index[i] = remove.index[i]; } - cacheItem->groups &= ~remove.flags & Compositor::GroupMask; + cacheItem->groups &= ~remove.flags; } } } @@ -1113,6 +1120,7 @@ void QQuickVisualDataModel::_q_itemsRemoved(int index, int count) QVector<Compositor::Remove> removes; d->m_compositor.listItemsRemoved(d->m_adaptorModel, index, count, &removes); d->itemsRemoved(removes); + d->emitChanges(); } @@ -1221,6 +1229,35 @@ QQuickVisualDataModelAttached *QQuickVisualDataModel::qmlAttachedProperties(QObj return QQuickVisualDataModelAttached::properties(obj); } +bool QQuickVisualDataModelPrivate::insert( + Compositor::insert_iterator &before, const v8::Local<v8::Object> &object, int groups) +{ + QQuickVisualDataModelItem *cacheItem = m_adaptorModel->createItem(m_cacheMetaType, -1); + if (!cacheItem) + return false; + + for (int i = 1; i < m_groupCount; ++i) + cacheItem->index[i] = before.index[i]; + + v8::Local<v8::Array> propertyNames = object->GetPropertyNames(); + for (uint i = 0; i < propertyNames->Length(); ++i) { + v8::Local<v8::String> propertyName = propertyNames->Get(i)->ToString(); + cacheItem->setValue( + m_cacheMetaType->v8Engine->toString(propertyName), + m_cacheMetaType->v8Engine->toVariant(object->Get(propertyName), 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>() << Compositor::Insert(before, 1, cacheItem->groups & ~Compositor::CacheFlag)); + + before = m_compositor.insert(before, 0, 0, 1, cacheItem->groups); + m_cache.insert(before.cacheIndex, cacheItem); + + return true; +} + //============================================================================ QQuickVisualDataModelItemMetaType::QQuickVisualDataModelItemMetaType( @@ -1244,6 +1281,7 @@ QQuickVisualDataModelItemMetaType::QQuickVisualDataModelItemMetaType( ft->InstanceTemplate()->SetHasExternalResource(true); ft->PrototypeTemplate()->SetAccessor(v8::String::New("model"), get_model); ft->PrototypeTemplate()->SetAccessor(v8::String::New("groups"), get_groups, set_groups); + ft->PrototypeTemplate()->SetAccessor(v8::String::New("isUnresolved"), get_member, 0, v8::Int32::New(30)); int notifierId = 0; for (int i = 0; i < groupNames.count(); ++i, ++notifierId) { @@ -1593,6 +1631,14 @@ void QQuickVisualDataModelAttached::setGroups(const QStringList &groups) } } +bool QQuickVisualDataModelAttached::isUnresolved() const +{ + if (!m_cacheItem) + return false; + + return m_cacheItem->groups & Compositor::UnresolvedFlag; +} + /*! \qmlattachedproperty int QtQuick2::VisualDataModel::inItems @@ -1850,7 +1896,7 @@ QDeclarativeV8Handle QQuickVisualDataGroup::get(int index) cacheItem = model->m_adaptorModel->createItem(model->m_cacheMetaType, it.modelIndex()); for (int i = 1; i < model->m_groupCount; ++i) cacheItem->index[i] = it.index[i]; - cacheItem->groups = it->flags & Compositor::GroupMask; + cacheItem->groups = it->flags; model->m_cache.insert(it.cacheIndex, cacheItem); model->m_compositor.setFlags(it, 1, Compositor::CacheFlag); @@ -1863,6 +1909,7 @@ QDeclarativeV8Handle QQuickVisualDataGroup::get(int index) ++cacheItem->scriptRef; } + return QDeclarativeV8Handle::fromHandle(cacheItem->indexHandle); } @@ -1886,8 +1933,49 @@ bool QQuickVisualDataGroupPrivate::parseIndex( return false; } +void QQuickVisualDataGroup::insert(QDeclarativeV8Function *args) +{ + Q_D(QQuickVisualDataGroup); + QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); + + int index = model->m_compositor.count(d->group); + Compositor::Group group = d->group; + + if (args->Length() == 0) + return; + + int i = 0; + v8::Local<v8::Value> v = (*args)[i]; + if (d->parseIndex(v, &index, &group)) { + if (index < 0 || index > model->m_compositor.count(group)) { + qmlInfo(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()) + groups |= model->m_cacheMetaType->parseGroups((*args)[i]); + + if (v->IsArray()) { + return; + } else if (v->IsObject()) { + model->insert(before, v->ToObject(), groups); + model->emitChanges(); + } +} + /*! \qmlmethod QtQuick2::VisualDataGroup::create(var index) + \qmlmethod QtQuick2::VisualDataGroup::create(var index, jsdict data) + \qmlmethod QtQuick2::VisualDataGroup::create(jsdict data) Returns a reference to the instantiated item at \a index in the group. @@ -1904,14 +1992,35 @@ void QQuickVisualDataGroup::create(QDeclarativeV8Function *args) if (args->Length() == 0) return; + QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); + + int index = model->m_compositor.count(d->group); Compositor::Group group = d->group; - int index = -1; - if (!d->parseIndex((*args)[0], &index, &group)) { - qmlInfo(this) << tr("create: invalid index"); - return; - } - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); + int i = 0; + v8::Local<v8::Value> v = (*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->IsObject()) { + int groups = 1 << d->group; + if (++i < args->Length()) + groups |= model->m_cacheMetaType->parseGroups((*args)[i]); + + 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->ToObject(), groups)) { + return; + } + } + } if (index < 0 || index >= model->m_compositor.count(group)) { qmlInfo(this) << tr("create: index out of range"); return; @@ -1919,10 +2028,108 @@ void QQuickVisualDataGroup::create(QDeclarativeV8Function *args) QObject *object = model->object(group, index, false, false); if (object) { + QVector<Compositor::Insert> inserts; Compositor::iterator it = model->m_compositor.find(group, index); - model->addGroups(it, 1, group, Compositor::PersistedFlag); + model->m_compositor.setFlags(it, 1, d->group, Compositor::PersistedFlag, &inserts); + model->itemsInserted(inserts); } + args->returnValue(args->engine()->newQObject(object)); + model->emitChanges(); +} + +void QQuickVisualDataGroup::resolve(QDeclarativeV8Function *args) +{ + Q_D(QQuickVisualDataGroup); + if (!d->model) + return; + + QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); + + if (args->Length() < 2) + return; + + int from = -1; + int to = -1; + Compositor::Group fromGroup = d->group; + Compositor::Group toGroup = d->group; + + v8::Local<v8::Value> v = (*args)[0]; + if (d->parseIndex(v, &from, &fromGroup)) { + if (from < 0 || from >= model->m_compositor.count(fromGroup)) { + qmlInfo(this) << tr("resolve: from index out of range"); + return; + } + } else { + qmlInfo(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)) { + qmlInfo(this) << tr("resolve: to index out of range"); + return; + } + } else { + qmlInfo(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()) { + qmlInfo(this) << tr("resolve: from is not an unresolved item"); + return; + } + if (!toIt->list) { + qmlInfo(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; + + QQuickVisualDataModelItem *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>() << Compositor::Remove(fromIt, 1, unresolvedFlags, 0), + QVector<Compositor::Insert>() << Compositor::Insert(toIt, 1, unresolvedFlags, 0)); + model->itemsInserted( + QVector<Compositor::Insert>() << Compositor::Insert(toIt, 1, (resolvedFlags & ~unresolvedFlags) | Compositor::CacheFlag)); + toIt.incrementIndexes(1, resolvedFlags | unresolvedFlags); + model->itemsRemoved(QVector<Compositor::Remove>() << 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(resolvedIndex); + if (cacheItem->object) + cacheItem->attached->emitUnresolvedChanged(); + } + + model->emitChanges(); } /*! @@ -1946,7 +2153,7 @@ void QQuickVisualDataGroup::remove(QDeclarativeV8Function *args) int i = 0; v8::Local<v8::Value> v = (*args)[i]; if (!d->parseIndex(v, &index, &group)) { - qmlInfo(this) << tr("create: invalid index"); + qmlInfo(this) << tr("remove: invalid index"); return; } @@ -2118,7 +2325,7 @@ void QQuickVisualDataGroup::move(QDeclarativeV8Function *args) } if (!d->parseIndex((*args)[1], &to, &toGroup)) { - qmlInfo(this) << tr("move: invalid from index"); + qmlInfo(this) << tr("move: invalid to index"); return; } diff --git a/src/quick/items/qquickvisualdatamodel_p.h b/src/quick/items/qquickvisualdatamodel_p.h index ba9130abaa..aecf5e3034 100644 --- a/src/quick/items/qquickvisualdatamodel_p.h +++ b/src/quick/items/qquickvisualdatamodel_p.h @@ -162,7 +162,9 @@ public: Q_INVOKABLE QDeclarativeV8Handle get(int index); public Q_SLOTS: + void insert(QDeclarativeV8Function *); void create(QDeclarativeV8Function *); + void resolve(QDeclarativeV8Function *); void remove(QDeclarativeV8Function *); void addGroups(QDeclarativeV8Function *); void removeGroups(QDeclarativeV8Function *); @@ -185,6 +187,7 @@ class QQuickVisualDataModelAttached : public QObject Q_OBJECT Q_PROPERTY(QQuickVisualDataModel *model READ model NOTIFY modelChanged) Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged) + Q_PROPERTY(bool isUnresolved READ isUnresolved NOTIFY unresolvedChanged) public: QQuickVisualDataModelAttached(QObject *parent) : QObject(parent) @@ -201,8 +204,12 @@ public: QStringList groups() const; void setGroups(const QStringList &groups); + bool isUnresolved() const; + void emitChanges(); + void emitUnresolvedChanged() { emit unresolvedChanged(); } + static QQuickVisualDataModelAttached *properties(QObject *obj) { QQuickVisualDataModelAttached *rv = attachedProperties.value(obj); @@ -216,6 +223,7 @@ public: Q_SIGNALS: void modelChanged(); void groupsChanged(); + void unresolvedChanged(); public: QQuickVisualDataModelItem *m_cacheItem; diff --git a/src/quick/items/qquickvisualdatamodel_p_p.h b/src/quick/items/qquickvisualdatamodel_p_p.h index b843e6ac1a..03d9767661 100644 --- a/src/quick/items/qquickvisualdatamodel_p_p.h +++ b/src/quick/items/qquickvisualdatamodel_p_p.h @@ -62,6 +62,8 @@ QT_BEGIN_NAMESPACE +typedef QDeclarativeListCompositor Compositor; + class QQuickVisualDataModelItemMetaType : public QDeclarativeRefCount { public: @@ -107,10 +109,14 @@ public: ~QQuickVisualDataModelItem(); void referenceObject() { ++objectRef; } - bool releaseObject() { return --objectRef == 0 && !(groups & QDeclarativeListCompositor::PersistedFlag); } - bool isObjectReferenced() const { return objectRef == 0 && !(groups & QDeclarativeListCompositor::PersistedFlag); } + bool releaseObject() { return --objectRef == 0 && !(groups & Compositor::PersistedFlag); } + bool isObjectReferenced() const { return objectRef != 0 || (groups & Compositor::PersistedFlag); } - bool isReferenced() const { return scriptRef || incubationTask || (groups & QDeclarativeListCompositor::PersistedFlag); } + bool isReferenced() const { + return scriptRef + || incubationTask + || ((groups & Compositor::UnresolvedFlag) && (groups & Compositor::GroupMask)); + } void Dispose(); @@ -119,6 +125,9 @@ public: virtual v8::Handle<v8::Value> get() { return engine->newQObject(this); } + virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); } + virtual bool resolveIndex(int) { return false; } + Q_SIGNALS: void modelIndexChanged(); @@ -137,7 +146,6 @@ public: QVDMIncubationTask *incubationTask; }; -typedef QDeclarativeListCompositor Compositor; class QQuickVisualDataModelPrivate; class QVDMIncubationTask : public QDeclarativeIncubator @@ -256,6 +264,7 @@ public: void emitChanges(); void emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset); + bool insert(Compositor::insert_iterator &before, const v8::Local<v8::Object> &object, int groups); static void group_append(QDeclarativeListProperty<QQuickVisualDataGroup> *property, QQuickVisualDataGroup *group); static int group_count(QDeclarativeListProperty<QQuickVisualDataGroup> *property); diff --git a/src/quick/util/qdeclarativelistcompositor.cpp b/src/quick/util/qdeclarativelistcompositor.cpp index 1d8c781e7f..8dca91506a 100644 --- a/src/quick/util/qdeclarativelistcompositor.cpp +++ b/src/quick/util/qdeclarativelistcompositor.cpp @@ -209,6 +209,7 @@ QDeclarativeListCompositor::insert_iterator &QDeclarativeListCompositor::insert_ while (offset > range->count || (offset == range->count && !range->append() && offset > 0) || (!(range->flags & groupFlag) && offset > 0)) { + Q_ASSERT(range->flags); if (range->flags & groupFlag) offset -= range->count; incrementIndexes(range->count); @@ -265,7 +266,7 @@ QDeclarativeListCompositor::~QDeclarativeListCompositor() } inline QDeclarativeListCompositor::Range *QDeclarativeListCompositor::insert( - Range *before, void *list, int index, int count, int flags) + Range *before, void *list, int index, int count, uint flags) { return new Range(before, list, index, count, flags); } @@ -356,21 +357,21 @@ QDeclarativeListCompositor::iterator QDeclarativeListCompositor::begin(Group gro } void QDeclarativeListCompositor::append( - void *list, int index, int count, int flags, QVector<Insert> *inserts) + void *list, int index, int count, uint flags, QVector<Insert> *inserts) { QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << index << count << flags) insert(m_end, list, index, count, flags, inserts); } void QDeclarativeListCompositor::insert( - Group group, int before, void *list, int index, int count, int flags, QVector<Insert> *inserts) + Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts) { QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< group << before << list << index << count << flags) insert(findInsertPosition(group, before), list, index, count, flags, inserts); } QDeclarativeListCompositor::iterator QDeclarativeListCompositor::insert( - iterator before, void *list, int index, int count, int flags, QVector<Insert> *inserts) + iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts) { QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< before << list << index << count << flags) if (inserts) { @@ -418,7 +419,7 @@ void QDeclarativeListCompositor::setFlags( } void QDeclarativeListCompositor::setFlags( - iterator from, int count, Group group, int flags, QVector<Insert> *inserts) + iterator from, int count, Group group, uint flags, QVector<Insert> *inserts) { QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< from << count << flags) if (!flags || !count) @@ -443,8 +444,8 @@ void QDeclarativeListCompositor::setFlags( const int difference = qMin(count, from->count); count -= difference; - const int insertFlags = ~from->flags & flags; - const int setFlags = (from->flags | flags) & ~AppendFlag; + 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); @@ -493,14 +494,14 @@ void QDeclarativeListCompositor::setFlags( } void QDeclarativeListCompositor::clearFlags( - Group fromGroup, int from, int count, Group group, int flags, QVector<Remove> *removes) + Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removes) { QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< group << index << count << flags) clearFlags(find(fromGroup, from), count, group, flags, removes); } void QDeclarativeListCompositor::clearFlags( - iterator from, int count, Group group, int flags, QVector<Remove> *removes) + iterator from, int count, Group group, uint flags, QVector<Remove> *removes) { QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< from << count << flags) if (!flags || !count) @@ -527,8 +528,8 @@ void QDeclarativeListCompositor::clearFlags( const int difference = qMin(count, from->count); count -= difference; - const int removeFlags = from->flags & flags & ~(AppendFlag | PrependFlag); - const int clearedFlags = from->flags & ~(flags | AppendFlag); + 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) @@ -806,7 +807,7 @@ void QDeclarativeListCompositor::listItemsInserted( || (offset == 0 && it->prepend()) || (offset == it->count && it->append())) { if (it->prepend()) { - int flags = m_defaultFlags; + uint flags = m_defaultFlags; if (insertion.isMove()) { for (QVector<MovedFlags>::const_iterator move = movedFlags->begin(); move != movedFlags->end(); @@ -1139,6 +1140,7 @@ QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Range &range) << range.list) << " " << range.index << " " << range.count << " " + << (range.isUnresolved() ? "U" : "0") << (range.append() ? "A" : "0") << (range.prepend() ? "P" : "0"); for (int i = QDeclarativeListCompositor::MaximumGroupCount - 1; i >= 2; --i) diff --git a/src/quick/util/qdeclarativelistcompositor_p.h b/src/quick/util/qdeclarativelistcompositor_p.h index 8881d5749a..380de0189e 100644 --- a/src/quick/util/qdeclarativelistcompositor_p.h +++ b/src/quick/util/qdeclarativelistcompositor_p.h @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE class Q_AUTOTEST_EXPORT QDeclarativeListCompositor { public: - enum { MaximumGroupCount = 11 }; + enum { MinimumGroupCount = 3, MaximumGroupCount = 11 }; enum Group { @@ -76,13 +76,14 @@ public: enum Flag { - CacheFlag = 0x000001, - DefaultFlag = 0x000002, - PersistedFlag = 0x000004, - GroupMask = 0x00FFFE, - PrependFlag = 0x100000, - AppendFlag = 0x200000, - MovedFlag = 0x400000 + 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 @@ -98,7 +99,7 @@ public: void *list; int index; int count; - int flags; + uint flags; inline int start() const { return index; } inline int end() const { return index + count; } @@ -108,6 +109,7 @@ public: 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; } @@ -141,8 +143,8 @@ public: void incrementIndexes(int difference) { incrementIndexes(difference, range->flags); } void decrementIndexes(int difference) { decrementIndexes(difference, range->flags); } - inline void incrementIndexes(int difference, int flags); - inline void decrementIndexes(int difference, int flags); + inline void incrementIndexes(int difference, uint flags); + inline void decrementIndexes(int difference, uint flags); void setGroup(Group g) { group = g; groupFlag = 1 << g; } @@ -174,9 +176,9 @@ public: struct Change { inline Change() {} - inline Change(iterator it, int count, int flags, int moveId = -1); + inline Change(iterator it, int count, uint flags, int moveId = -1); int count; - int flags; + uint flags; int moveId; union { struct { @@ -196,14 +198,14 @@ public: struct Insert : public Change { Insert() {} - Insert(iterator it, int count, int flags, int moveId = -1) + Insert(iterator it, int count, uint flags, int moveId = -1) : Change(it, count, flags, moveId) {} }; struct Remove : public Change { Remove() {} - Remove(iterator it, int count, int flags, int moveId = -1) + Remove(iterator it, int count, uint flags, int moveId = -1) : Change(it, count, flags, moveId) {} }; @@ -225,22 +227,22 @@ public: iterator begin(Group group); const iterator &end() { return m_end; } - void append(void *list, int index, int count, int flags, QVector<Insert> *inserts = 0); - void insert(Group group, int before, void *list, int index, int count, int flags, QVector<Insert> *inserts = 0); - iterator insert(iterator before, void *list, int index, int count, int flags, QVector<Insert> *inserts = 0); + void append(void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0); + void insert(Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0); + iterator insert(iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0); void setFlags(Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts = 0); - void setFlags(iterator from, int count, Group group, int flags, QVector<Insert> *inserts = 0); - void setFlags(Group fromGroup, int from, int count, int flags, QVector<Insert> *inserts = 0) { + void setFlags(iterator from, int count, Group group, uint flags, QVector<Insert> *inserts = 0); + void setFlags(Group fromGroup, int from, int count, uint flags, QVector<Insert> *inserts = 0) { setFlags(fromGroup, from, count, fromGroup, flags, inserts); } - void setFlags(iterator from, int count, int flags, QVector<Insert> *inserts = 0) { + void setFlags(iterator from, int count, uint flags, QVector<Insert> *inserts = 0) { setFlags(from, count, from.group, flags, inserts); } - void clearFlags(Group fromGroup, int from, int count, Group group, int flags, QVector<Remove> *removals = 0); - void clearFlags(iterator from, int count, Group group, int flags, QVector<Remove> *removals = 0); - void clearFlags(Group fromGroup, int from, int count, int flags, QVector<Remove> *removals = 0) { + void clearFlags(Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removals = 0); + void clearFlags(iterator from, int count, Group group, uint flags, QVector<Remove> *removals = 0); + void clearFlags(Group fromGroup, int from, int count, uint flags, QVector<Remove> *removals = 0) { clearFlags(fromGroup, from, count, fromGroup, flags, removals); } - void clearFlags(iterator from, int count, int flags, QVector<Remove> *removals = 0) { + void clearFlags(iterator from, int count, uint flags, QVector<Remove> *removals = 0) { clearFlags(from, count, from.group, flags, removals); } void removeList(void *list, QVector<Remove> *removals, bool destroyed); @@ -283,16 +285,16 @@ private: int m_defaultFlags; int m_removeFlags; - inline Range *insert(Range *before, void *list, int index, int count, int flags); + inline Range *insert(Range *before, void *list, int index, int count, uint flags); inline Range *erase(Range *range); struct MovedFlags { MovedFlags() {} - MovedFlags(int moveId, int flags) : moveId(moveId), flags(flags) {} + MovedFlags(int moveId, uint flags) : moveId(moveId), flags(flags) {} int moveId; - int flags; + uint flags; }; void listItemsRemoved( @@ -340,7 +342,7 @@ inline QDeclarativeListCompositor::iterator::iterator( index[i] = 0; } -inline void QDeclarativeListCompositor::iterator::incrementIndexes(int difference, int flags) +inline void QDeclarativeListCompositor::iterator::incrementIndexes(int difference, uint flags) { for (int i = 0; i < groupCount; ++i) { if (flags & (1 << i)) @@ -348,7 +350,7 @@ inline void QDeclarativeListCompositor::iterator::incrementIndexes(int differenc } } -inline void QDeclarativeListCompositor::iterator::decrementIndexes(int difference, int flags) +inline void QDeclarativeListCompositor::iterator::decrementIndexes(int difference, uint flags) { for (int i = 0; i < groupCount; ++i) { if (flags & (1 << i)) @@ -360,7 +362,7 @@ inline QDeclarativeListCompositor::insert_iterator::insert_iterator( Range *range, int offset, Group group, int groupCount) : iterator(range, offset, group, groupCount) {} -inline QDeclarativeListCompositor::Change::Change(iterator it, int count, int flags, int moveId) +inline QDeclarativeListCompositor::Change::Change(iterator it, int count, uint flags, int moveId) : count(count), flags(flags), moveId(moveId) { for (int i = 0; i < MaximumGroupCount; ++i) |