From d39d01497640c3a0818d25036894495f8b597bdb Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 2 Aug 2010 12:51:28 +1000 Subject: Reference count items in VisualItemModel. The views expect the models to reference count and not destroy (or hide in the case of VisualItemModel) until there are no references. Task-number: QTBUG-12450 Reviewed-by: Michael Brasser --- .../graphicsitems/qdeclarativevisualitemmodel.cpp | 48 +++++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 7952b97..79c1c43 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -78,7 +78,7 @@ public: static void children_append(QDeclarativeListProperty *prop, QDeclarativeItem *item) { QDeclarative_setParent_noEvent(item, prop->object); - static_cast(prop->data)->children.append(item); + static_cast(prop->data)->children.append(Item(item)); static_cast(prop->data)->itemAppended(); static_cast(prop->data)->emitChildrenChanged(); } @@ -88,12 +88,12 @@ public: } static QDeclarativeItem *children_at(QDeclarativeListProperty *prop, int index) { - return static_cast(prop->data)->children.at(index); + return static_cast(prop->data)->children.at(index).item; } void itemAppended() { Q_Q(QDeclarativeVisualItemModel); - QDeclarativeVisualItemModelAttached *attached = QDeclarativeVisualItemModelAttached::properties(children.last()); + QDeclarativeVisualItemModelAttached *attached = QDeclarativeVisualItemModelAttached::properties(children.last().item); attached->setIndex(children.count()-1); emit q->itemsInserted(children.count()-1, 1); emit q->countChanged(); @@ -104,7 +104,25 @@ public: emit q->childrenChanged(); } - QList children; + int indexOf(QDeclarativeItem *item) const { + for (int i = 0; i < children.count(); ++i) + if (children.at(i).item == item) + return i; + return -1; + } + + class Item { + public: + Item(QDeclarativeItem *i) : item(i), ref(0) {} + + void addRef() { ++ref; } + bool deref() { return --ref == 0; } + + QDeclarativeItem *item; + int ref; + }; + + QList children; }; @@ -182,14 +200,22 @@ bool QDeclarativeVisualItemModel::isValid() const QDeclarativeItem *QDeclarativeVisualItemModel::item(int index, bool) { Q_D(QDeclarativeVisualItemModel); - return d->children.at(index); + QDeclarativeVisualItemModelPrivate::Item &item = d->children[index]; + item.addRef(); + return item.item; } QDeclarativeVisualModel::ReleaseFlags QDeclarativeVisualItemModel::release(QDeclarativeItem *item) { - if (item->scene()) - item->scene()->removeItem(item); - QDeclarative_setParent_noEvent(item, this); + Q_D(QDeclarativeVisualItemModel); + int idx = d->indexOf(item); + if (idx >= 0) { + if (d->children[idx].deref()) { + if (item->scene()) + item->scene()->removeItem(item); + QDeclarative_setParent_noEvent(item, this); + } + } return 0; } @@ -208,7 +234,7 @@ QString QDeclarativeVisualItemModel::stringValue(int index, const QString &name) Q_D(QDeclarativeVisualItemModel); if (index < 0 || index >= d->children.count()) return QString(); - return QDeclarativeEngine::contextForObject(d->children.at(index))->contextProperty(name).toString(); + return QDeclarativeEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString(); } QVariant QDeclarativeVisualItemModel::evaluate(int index, const QString &expression, QObject *objectContext) @@ -218,7 +244,7 @@ QVariant QDeclarativeVisualItemModel::evaluate(int index, const QString &express return QVariant(); QDeclarativeContext *ccontext = qmlContext(this); QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext); - ctxt->setContextObject(d->children.at(index)); + ctxt->setContextObject(d->children.at(index).item); QDeclarativeExpression e(ctxt, objectContext, expression); QVariant value = e.evaluate(); delete ctxt; @@ -228,7 +254,7 @@ QVariant QDeclarativeVisualItemModel::evaluate(int index, const QString &express int QDeclarativeVisualItemModel::indexOf(QDeclarativeItem *item, QObject *) const { Q_D(const QDeclarativeVisualItemModel); - return d->children.indexOf(item); + return d->indexOf(item); } QDeclarativeVisualItemModelAttached *QDeclarativeVisualItemModel::qmlAttachedProperties(QObject *obj) -- cgit v0.12