//---------------------------------------------------------------------------
-QHash<QObject*, QQuickVisualDataModelAttached*> QQuickVisualDataModelAttached::attachedProperties;
-
/*!
\qmlclass VisualDataModel QQuickVisualDataModel
\inqmlmodule QtQuick 2
return d->m_compositor.count(d->m_compositorGroup);
}
-void QQuickVisualDataModelPrivate::destroy(QObject *object)
-{
- QObjectPrivate *p = QObjectPrivate::get(object);
- Q_ASSERT(p->declarativeData);
- QQmlData *data = static_cast<QQmlData*>(p->declarativeData);
- if (data->ownContext && data->context)
- data->context->clearContext();
- object->deleteLater();
-}
-
QQuickVisualDataModel::ReleaseFlags QQuickVisualDataModelPrivate::release(QObject *object)
{
QQuickVisualDataModel::ReleaseFlags stat = 0;
if (!object)
return stat;
- if (QQuickVisualDataModelAttached *attached = QQuickVisualDataModelAttached::properties(object)) {
- QQuickVisualDataModelItem *cacheItem = attached->m_cacheItem;
+ if (QQuickVisualDataModelItem *cacheItem = QQuickVisualDataModelItem::dataForObject(object)) {
if (cacheItem->releaseObject()) {
- destroy(object);
+ cacheItem->destroyObject();
if (QQuickItem *item = qobject_cast<QQuickItem *>(object))
emitDestroyingItem(item);
- cacheItem->setObject(0);
if (cacheItem->incubationTask) {
releaseIncubator(cacheItem->incubationTask);
cacheItem->incubationTask = 0;
cacheItem->incubationTask = 0;
}
if (cacheItem->object() && !cacheItem->isObjectReferenced()) {
- d->destroy(cacheItem->object());
- if (QQuickPackage *package = qobject_cast<QQuickPackage *>(cacheItem->object()))
+ QObject *object = cacheItem->object();
+ cacheItem->destroyObject();
+ if (QQuickPackage *package = qobject_cast<QQuickPackage *>(object))
d->emitDestroyingPackage(package);
- else if (QQuickItem *item = qobject_cast<QQuickItem *>(cacheItem->object()))
+ else if (QQuickItem *item = qobject_cast<QQuickItem *>(object))
d->emitDestroyingItem(item);
- cacheItem->setObject(0);
- cacheItem->Dispose();
+ cacheItem->scriptRef -= 1;
}
if (!cacheItem->isReferenced()) {
d->m_compositor.clearFlags(Compositor::Cache, it.cacheIndex, 1, Compositor::CacheFlag);
QQml_setParent_noEvent(incubationTask->incubatingContext, cacheItem->object());
incubationTask->incubatingContext = 0;
- cacheItem->attached = QQuickVisualDataModelAttached::properties(cacheItem->object());
- cacheItem->attached->setCacheItem(cacheItem);
- new QQuickVisualDataModelAttachedMetaObject(cacheItem->attached, m_cacheMetaType);
- cacheItem->attached->emitChanges();
if (QQuickPackage *package = qobject_cast<QQuickPackage *>(cacheItem->object()))
emitInitPackage(cacheItem, package);
int QQuickVisualDataModel::indexOf(QQuickItem *item, QObject *) const
{
Q_D(const QQuickVisualDataModel);
- if (QQuickVisualDataModelAttached *attached = QQuickVisualDataModelAttached::properties(item))
- return attached->m_cacheItem->index[d->m_compositorGroup];
+ if (QQuickVisualDataModelItem *cacheItem = QQuickVisualDataModelItem::dataForObject(item))
+ return cacheItem->index[d->m_compositorGroup];
return -1;
}
for (; cacheIndex < remove.cacheIndex + remove.count - removedCache; ++cacheIndex) {
QQuickVisualDataModelItem *cacheItem = m_cache.at(cacheIndex);
if (remove.inGroup(Compositor::Persisted) && cacheItem->objectRef == 0 && cacheItem->object()) {
- destroy(cacheItem->object());
- if (QQuickPackage *package = qobject_cast<QQuickPackage *>(cacheItem->object()))
+ QObject *object = cacheItem->object();
+ cacheItem->destroyObject();
+ if (QQuickPackage *package = qobject_cast<QQuickPackage *>(object))
emitDestroyingPackage(package);
- else if (QQuickItem *item = qobject_cast<QQuickItem *>(cacheItem->object()))
+ else if (QQuickItem *item = qobject_cast<QQuickItem *>(object))
emitDestroyingItem(item);
cacheItem->setObject(0);
cacheItem->scriptRef -= 1;
QQuickVisualDataModelAttached *QQuickVisualDataModel::qmlAttachedProperties(QObject *obj)
{
- return QQuickVisualDataModelAttached::properties(obj);
+ if (QQuickVisualDataModelItem *cacheItem = QQuickVisualDataModelItem::dataForObject(obj)) {
+ if (cacheItem->object() == obj) { // Don't create attached item for child objects.
+ cacheItem->attached = new QQuickVisualDataModelAttached(cacheItem, obj);
+ return cacheItem->attached;
+ }
+ }
+ return new QQuickVisualDataModelAttached(obj);
}
bool QQuickVisualDataModelPrivate::insert(
//---------------------------------------------------------------------------
+QHash<QObject*, QQuickVisualDataModelItem *> QQuickVisualDataModelItem::contextData;
+
QQuickVisualDataModelItem::QQuickVisualDataModelItem(
QQuickVisualDataModelItemMetaType *metaType, int modelIndex)
: QV8ObjectResource(metaType->v8Engine)
delete this;
}
-void QQuickVisualDataModelItem::objectDestroyed(QObject *)
+void QQuickVisualDataModelItem::setObject(QObject *g)
+{
+ if (QObject *previous = object())
+ contextData.remove(previous);
+ if (g)
+ contextData.insert(g, this);
+
+ QQmlGuard<QObject>::setObject(g);
+}
+
+void QQuickVisualDataModelItem::destroyObject()
+{
+ QObject * const obj = object();
+ setObject(0);
+
+ Q_ASSERT(obj);
+
+ QObjectPrivate *p = QObjectPrivate::get(obj);
+ Q_ASSERT(p->declarativeData);
+ QQmlData *data = static_cast<QQmlData*>(p->declarativeData);
+ if (data->ownContext && data->context)
+ data->context->clearContext();
+ obj->deleteLater();
+
+ if (attached) {
+ attached->m_cacheItem = 0;
+ attached = 0;
+ }
+}
+
+void QQuickVisualDataModelItem::objectDestroyed(QObject *object)
{
+ contextData.remove(object);
+
attached = 0;
Dispose();
}
: attached(attached)
, metaType(metaType)
{
+ if (!metaType->metaObject)
+ metaType->initializeMetaObject();
+
metaType->addref();
*static_cast<QMetaObject *>(this) = *metaType->metaObject;
QObjectPrivate::get(attached)->metaObject = this;
return attached->qt_metacall(call, _id, arguments);
}
-void QQuickVisualDataModelAttached::setCacheItem(QQuickVisualDataModelItem *item)
+QQuickVisualDataModelAttached::QQuickVisualDataModelAttached(QObject *parent)
+ : m_cacheItem(0)
+ , m_previousGroups(0)
+ , m_modelChanged(false)
{
- m_cacheItem = item;
+ QQml_setParent_noEvent(this, parent);
+}
+
+QQuickVisualDataModelAttached::QQuickVisualDataModelAttached(
+ QQuickVisualDataModelItem *cacheItem, QObject *parent)
+ : m_cacheItem(cacheItem)
+ , m_previousGroups(cacheItem->groups)
+ , m_modelChanged(false)
+{
+ QQml_setParent_noEvent(this, parent);
for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i)
m_previousIndex[i] = m_cacheItem->index[i];
+
+ new QQuickVisualDataModelAttachedMetaObject(this, cacheItem->metaType);
}
/*!
Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache));
} else {
cacheItem->resolveIndex(model->m_adaptorModel, resolvedIndex);
- if (cacheItem->object())
+ if (cacheItem->attached)
cacheItem->attached->emitUnresolvedChanged();
}
{
QHash<QObject *, QQuickPackage *>::const_iterator it = m_packaged.find(item);
if (it != m_packaged.end()) {
- if (QQuickVisualDataModelAttached *attached = QQuickVisualDataModelAttached::properties(*it))
- return attached->m_cacheItem->index[m_compositorGroup];
+ if (QQuickVisualDataModelItem *cacheItem = QQuickVisualDataModelItem::dataForObject(*it))
+ return cacheItem->index[m_compositorGroup];
}
return -1;
}
class QQuickVisualAdaptorModel;
class QVDMIncubationTask;
-class QQuickVisualDataModelItem : public QObject, public QV8ObjectResource, public QQmlGuard<QObject>
+class QQuickVisualDataModelItem : public QObject, public QV8ObjectResource, private QQmlGuard<QObject>
{
Q_OBJECT
Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged)
QObject *modelObject() { return this; }
+ inline QObject *object() const { return QQmlGuard<QObject>::object(); }
+ void setObject(QObject *g);
+ void destroyObject();
+
+ static QQuickVisualDataModelItem *dataForObject(QObject *object) { return contextData.value(object, 0); }
+
int modelIndex() const { return index[0]; }
void setModelIndex(int idx) { index[0] = idx; emit modelIndexChanged(); }
protected:
void objectDestroyed(QObject *);
+
+private:
+ // A static hash of context data for all delegate object isn't ideal, but it provides a way
+ // to get the context data when constructing attached objects rather than constructing the
+ // attached objects on suspicion.
+ static QHash<QObject*, QQuickVisualDataModelItem *> contextData;
};
void connectModel(QQuickVisualAdaptorModel *model);
QObject *object(Compositor::Group group, int index, bool asynchronous, bool reference);
- void destroy(QObject *object);
QQuickVisualDataModel::ReleaseFlags release(QObject *object);
QString stringValue(Compositor::Group group, int index, const QString &name);
void emitCreatedPackage(QQuickVisualDataModelItem *cacheItem, QQuickPackage *package);
QString m_filterGroup;
-
int m_count;
int m_groupCount;