From 62b264e90a48997e1736d7a335bad99e2c52a50d Mon Sep 17 00:00:00 2001
From: Aaron Kennedy <aaron.kennedy@nokia.com>
Date: Wed, 14 Apr 2010 17:27:45 +1000
Subject: Reduce warnings at shutdown

QTBUG-9799

Reviewed-by: Alexis Menard
---
 .../graphicsitems/qdeclarativevisualitemmodel.cpp   |  2 +-
 src/declarative/qml/qdeclarativecomponent.cpp       |  5 +++++
 src/declarative/qml/qdeclarativecontext.cpp         | 21 +++++++++++++++++++++
 src/declarative/qml/qdeclarativecontext.h           |  2 ++
 src/declarative/qml/qdeclarativecontext_p.h         |  2 +-
 src/gui/graphicsview/qgraphicsitem.cpp              | 12 ++++++++++--
 .../qdeclarativeecmascript/data/SpuriousWarning.qml |  5 +++++
 .../data/noSpuriousWarningsAtShutdown.2.qml         | 10 ++++++++++
 .../tst_qdeclarativeecmascript.cpp                  | 18 ++++++++++++++++++
 9 files changed, 73 insertions(+), 4 deletions(-)
 create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/SpuriousWarning.qml
 create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.2.qml

diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
index dc325ce..03e4703 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -243,7 +243,7 @@ public:
     QString m_part;
 
     QDeclarativeComponent *m_delegate;
-    QDeclarativeContext *m_context;
+    QDeclarativeGuard<QDeclarativeContext> m_context;
     QList<int> m_roles;
     QHash<QByteArray,int> m_roleNames;
     void ensureRoles() {
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index d319e8f..5f26ad5 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -597,6 +597,11 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons
         return 0;
     }
 
+    if (!context->isValid()) {
+        qWarning("QDeclarativeComponent::beginCreate(): Cannot create a component in an invalid context");
+        return 0;
+    }
+
     if (context->engine != engine) {
         qWarning("QDeclarativeComponent::beginCreate(): Must create component in context from the same QDeclarativeEngine");
         return 0;
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index 9307bcc..ba4da95 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -202,6 +202,12 @@ QDeclarativeContext::~QDeclarativeContext()
         d->data->destroy();
 }
 
+bool QDeclarativeContext::isValid() const
+{
+    Q_D(const QDeclarativeContext);
+    return d->data && d->data->isValid();
+}
+
 /*!
     Return the context's QDeclarativeEngine, or 0 if the context has no QDeclarativeEngine or the
     QDeclarativeEngine was destroyed.
@@ -245,6 +251,11 @@ void QDeclarativeContext::setContextObject(QObject *object)
         return;
     }
 
+    if (!isValid()) {
+        qWarning("QDeclarativeContext: Cannot set context object on invalid context.");
+        return;
+    }
+
     data->contextObject = object;
 }
 
@@ -264,6 +275,11 @@ void QDeclarativeContext::setContextProperty(const QString &name, const QVariant
         return;
     }
 
+    if (!isValid()) {
+        qWarning("QDeclarativeContext: Cannot set property on invalid context.");
+        return;
+    }
+
     if (data->engine) {
         bool ok;
         QObject *o = QDeclarativeEnginePrivate::get(data->engine)->toQObject(value, &ok);
@@ -305,6 +321,11 @@ void QDeclarativeContext::setContextProperty(const QString &name, QObject *value
         return;
     }
 
+    if (!isValid()) {
+        qWarning("QDeclarativeContext: Cannot set property on invalid context.");
+        return;
+    }
+
     if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine);
     int idx = data->propertyNames->value(name);
 
diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h
index 11b4771..94c9f4a 100644
--- a/src/declarative/qml/qdeclarativecontext.h
+++ b/src/declarative/qml/qdeclarativecontext.h
@@ -71,6 +71,8 @@ public:
     QDeclarativeContext(QDeclarativeContext *parent, QObject *objParent=0);
     virtual ~QDeclarativeContext();
 
+    bool isValid() const;
+
     QDeclarativeEngine *engine() const;
     QDeclarativeContext *parentContext() const;
 
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 6059f72..7a16179 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -115,7 +115,7 @@ public:
     void destroy();
 
     inline bool isValid() const {
-        return engine && (!isInternal || contextObject && !QObjectPrivate::get(contextObject)->wasDeleted);
+        return engine && (!isInternal || !contextObject || !QObjectPrivate::get(contextObject)->wasDeleted);
     }
 
     // My parent context and engine
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 150343e..9e0ec2e 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1408,8 +1408,16 @@ QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent,
 */
 QGraphicsItem::~QGraphicsItem()
 {
-    if (d_ptr->isObject)
-        QObjectPrivate::get(static_cast<QGraphicsObject *>(this))->wasDeleted = true;
+    if (d_ptr->isObject) {
+        QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
+        QObjectPrivate *p = QObjectPrivate::get(o);
+        p->wasDeleted = true;
+        if (p->declarativeData) {
+            QDeclarativeData::destroyed(p->declarativeData, o);
+            p->declarativeData = 0;
+        }
+    }
+
     d_ptr->inDestructor = 1;
     d_ptr->removeExtraItemCache();
 
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/SpuriousWarning.qml b/tests/auto/declarative/qdeclarativeecmascript/data/SpuriousWarning.qml
new file mode 100644
index 0000000..86c312c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/SpuriousWarning.qml
@@ -0,0 +1,5 @@
+import Qt 4.6
+
+Item {
+    property int children: root.children.length
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.2.qml
new file mode 100644
index 0000000..a762d6d
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.2.qml
@@ -0,0 +1,10 @@
+import Qt 4.6
+
+Item {
+    id: root
+
+    Item {}
+
+    SpuriousWarning {}
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 12a065e..35b4d99 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -2242,6 +2242,7 @@ void tst_qdeclarativeecmascript::qtbug_9792()
 // Test that we shut down without stupid warnings
 void tst_qdeclarativeecmascript::noSpuriousWarningsAtShutdown()
 {
+    {
     QDeclarativeComponent component(&engine, TEST_FILE("noSpuriousWarningsAtShutdown.qml"));
 
     QObject *o = component.create();
@@ -2254,6 +2255,23 @@ void tst_qdeclarativeecmascript::noSpuriousWarningsAtShutdown()
     qInstallMsgHandler(old);
 
     QCOMPARE(transientErrorsMsgCount, 0);
+    }
+
+
+    {
+    QDeclarativeComponent component(&engine, TEST_FILE("noSpuriousWarningsAtShutdown.2.qml"));
+
+    QObject *o = component.create();
+
+    transientErrorsMsgCount = 0;
+    QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler);
+
+    delete o;
+
+    qInstallMsgHandler(old);
+
+    QCOMPARE(transientErrorsMsgCount, 0);
+    }
 }
 
 QTEST_MAIN(tst_qdeclarativeecmascript)
-- 
cgit v0.12