aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-12-22 13:49:03 +1000
committerQt by Nokia <qt-info@nokia.com>2011-12-23 07:23:48 +0100
commitfb00bd445b1d77ffd7be8c60fce30f58e53eb6de (patch)
treee2000fd51e5c64a05fb45963e756aca29bca31d5 /src
parent347f84e5aca9423536cb0cd7a2eafaf836a72212 (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.cpp363
-rw-r--r--src/quick/items/qquickvisualdatamodel.cpp243
-rw-r--r--src/quick/items/qquickvisualdatamodel_p.h8
-rw-r--r--src/quick/items/qquickvisualdatamodel_p_p.h17
-rw-r--r--src/quick/util/qdeclarativelistcompositor.cpp26
-rw-r--r--src/quick/util/qdeclarativelistcompositor_p.h64
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)