Clean up transition objects for positioners
authorBea Lam <bea.lam@nokia.com>
Wed, 7 Mar 2012 08:20:06 +0000 (18:20 +1000)
committerQt by Nokia <qt-info@nokia.com>
Sat, 10 Mar 2012 02:49:01 +0000 (03:49 +0100)
These must be cleaned up whenever items are removed from the internal
PositionedItem lists.

Change-Id: I56f64a29bd98c603b00faaead514fd43780c18de
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
src/quick/items/qquickpositioners.cpp
src/quick/items/qquickpositioners_p.h
src/quick/items/qquickpositioners_p_p.h

index 4a4e6fc..7c4cd18 100644 (file)
@@ -168,7 +168,8 @@ QQuickBasePositioner::~QQuickBasePositioner()
         d->unwatchChanges(positionedItems.at(i).item);
     for (int i = 0; i < unpositionedItems.count(); ++i)
         d->unwatchChanges(unpositionedItems.at(i).item);
-    positionedItems.clear();
+    clearPositionedItems(&positionedItems);
+    clearPositionedItems(&unpositionedItems);
 }
 
 void QQuickBasePositioner::updatePolish()
@@ -248,10 +249,10 @@ void QQuickBasePositioner::itemChange(ItemChange change, const ItemChangeData &v
         int idx = positionedItems.find(posItem);
         if (idx >= 0) {
             d->unwatchChanges(child);
-            positionedItems.remove(idx);
+            removePositionedItem(&positionedItems, idx);
         } else if ((idx = unpositionedItems.find(posItem)) >= 0) {
             d->unwatchChanges(child);
-            unpositionedItems.remove(idx);
+            removePositionedItem(&unpositionedItems, idx);
         }
         d->setPositioningDirty();
     }
@@ -394,6 +395,24 @@ void QQuickBasePositioner::positionItemY(qreal y, PositionedItem *target)
     }
 }
 
+/*
+  Since PositionedItem values are stored by value, their internal transitionableItem pointers
+  must be cleaned up when a PositionedItem is removed from a QPODVector, otherwise the pointer
+  is never deleted since QPODVector doesn't invoke the destructor.
+  */
+void QQuickBasePositioner::removePositionedItem(QPODVector<PositionedItem,8> *items, int index)
+{
+    Q_ASSERT(index >= 0 && index < items->count());
+    delete items->at(index).transitionableItem;
+    items->remove(index);
+}
+void QQuickBasePositioner::clearPositionedItems(QPODVector<PositionedItem,8> *items)
+{
+    for (int i=0; i<items->count(); i++)
+        delete items->at(i).transitionableItem;
+    items->clear();
+}
+
 QQuickPositionerAttached *QQuickBasePositioner::qmlAttachedProperties(QObject *obj)
 {
     return new QQuickPositionerAttached(obj);
index 1e456a9..c13d997 100644 (file)
@@ -158,10 +158,14 @@ protected:
 
     QPODVector<PositionedItem,8> positionedItems;
     QPODVector<PositionedItem,8> unpositionedItems;//Still 'in' the positioner, just not positioned
+
     void positionItem(qreal x, qreal y, PositionedItem *target);
     void positionItemX(qreal, PositionedItem *target);
     void positionItemY(qreal, PositionedItem *target);
 
+    void removePositionedItem(QPODVector<PositionedItem,8> *items, int index);
+    void clearPositionedItems(QPODVector<PositionedItem,8> *items);
+
 private:
     Q_DISABLE_COPY(QQuickBasePositioner)
     Q_DECLARE_PRIVATE(QQuickBasePositioner)
index 21fa675..8c6bf7f 100644 (file)
@@ -139,7 +139,9 @@ public:
     void itemDestroyed(QQuickItem *item)
     {
         Q_Q(QQuickBasePositioner);
-        q->positionedItems.removeOne(QQuickBasePositioner::PositionedItem(item));
+        int index = q->positionedItems.find(QQuickBasePositioner::PositionedItem(item));
+        if (index >= 0)
+            q->removePositionedItem(&q->positionedItems, index);
     }
 
     static Qt::LayoutDirection getLayoutDirection(const QQuickBasePositioner *positioner)