From a45c4ce878e49c3d2b0e5525fe6b6cbf8cceef99 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Wed, 16 Nov 2011 13:08:16 +1000 Subject: [PATCH] Don't leak objects when a VisualDataModel is destroyed before a view. If an item is still referenced by a view when the VisualDataModel is destroyed delete it, otherwise it will leak as the view have no interface to release it and deleting the item won't delete the package. Task-number: QTBUG-22672 Change-Id: I7b89962d724d7a391c97722638e03b7a186b8a8f Reviewed-by: Chris Adams --- src/declarative/items/qquickvisualdatamodel.cpp | 2 + .../data/itemsDestroyed_listView.qml | 13 ++++++ .../data/itemsDestroyed_package.qml | 42 ++++++++++++++++++++ .../data/itemsDestroyed_pathView.qml | 18 ++++++++ .../data/itemsDestroyed_repeater.qml | 15 +++++++ .../tst_qquickvisualdatamodel.cpp | 33 +++++++++++++++ 6 files changed, 123 insertions(+), 0 deletions(-) create mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_listView.qml create mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_package.qml create mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml create mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml diff --git a/src/declarative/items/qquickvisualdatamodel.cpp b/src/declarative/items/qquickvisualdatamodel.cpp index 5cf2d6c..7d0abfc 100644 --- a/src/declarative/items/qquickvisualdatamodel.cpp +++ b/src/declarative/items/qquickvisualdatamodel.cpp @@ -457,7 +457,9 @@ QQuickVisualDataModel::QQuickVisualDataModel(QDeclarativeContext *ctxt, QObject QQuickVisualDataModel::~QQuickVisualDataModel() { Q_D(QQuickVisualDataModel); + foreach (QQuickVisualDataModelCacheItem *cacheItem, d->m_cache) { + delete cacheItem->object; cacheItem->object = 0; cacheItem->objectRef = 0; if (!cacheItem->isReferenced()) diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_listView.qml b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_listView.qml new file mode 100644 index 0000000..103c4d2 --- /dev/null +++ b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_listView.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + + model: myModel + delegate: Item { + objectName: "delegate" + width: 100 + height: 20 + } +} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_package.qml b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_package.qml new file mode 100644 index 0000000..b47f22d --- /dev/null +++ b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_package.qml @@ -0,0 +1,42 @@ +import QtQuick 2.0 + +Item { + width: 100 + height: 100 + + ListView { + anchors.fill: parent + + model: visualModel.parts.list + } + VisualDataModel { + id: visualModel + + model: myModel + delegate: Package { + Item { + Package.name: "list" + width: 100 + height: 20 + } + + Item { + id: gridItem + Package.name: "grid" + width: 50 + height: 50 + } + Rectangle { + objectName: "delegate" + parent: gridItem + width: 20 + height: 20 + } + } + } + GridView { + anchors.fill: parent + + model: visualModel.parts.grid + } +} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml new file mode 100644 index 0000000..bc61912 --- /dev/null +++ b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +PathView { + width: 100 + height: 100 + + model: myModel + delegate: Item { + objectName: "delegate" + width: 100 + height: 20 + } + + path: Path { + startX: 50; startY: 0 + PathLine { x: 50; y: 100 } + } +} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml new file mode 100644 index 0000000..e97e0da --- /dev/null +++ b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +Grid { + Repeater { + width: 100 + height: 100 + + model: myModel + delegate: Item { + objectName: "delegate" + width: 50 + height: 50 + } + } +} diff --git a/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp index 706c20f..44759d4 100644 --- a/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp +++ b/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp @@ -131,6 +131,8 @@ private slots: void modelProperties(); void noDelegate_data(); void noDelegate(); + void itemsDestroyed_data(); + void itemsDestroyed(); void qaimRowsMoved(); void qaimRowsMoved_data(); void remove_data(); @@ -628,6 +630,37 @@ void tst_qquickvisualdatamodel::noDelegate() QCOMPARE(vdm->count(), 0); } +void tst_qquickvisualdatamodel::itemsDestroyed_data() +{ + QTest::addColumn("source"); + + QTest::newRow("listView") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_listView.qml")); + QTest::newRow("package") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_package.qml")); + QTest::newRow("pathView") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_pathView.qml")); + QTest::newRow("repeater") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_repeater.qml")); +} + +void tst_qquickvisualdatamodel::itemsDestroyed() +{ + QFETCH(QUrl, source); + + QDeclarativeGuard delegate; + + { + QQuickView view; + QStandardItemModel model; + initStandardTreeModel(&model); + view.rootContext()->setContextProperty("myModel", &model); + view.setSource(source); + + view.show(); + QTest::qWaitForWindowShown(&view); + + QVERIFY(delegate = findItem(view.rootItem(), "delegate", 1)); + } + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QVERIFY(!delegate); +} void tst_qquickvisualdatamodel::qaimRowsMoved() { -- 1.7.2.5