Fix bug in QGraphicsItem::isVisibleTo().
authorAndreas Aardal Hanssen <andrhans@cisco.com>
Thu, 29 Sep 2011 12:54:15 +0000 (14:54 +0200)
committerQt by Nokia <qt-info@nokia.com>
Mon, 3 Oct 2011 13:31:42 +0000 (15:31 +0200)
Task-number: QTBUG-21612
Reviewed-by: James Perrett
Reviewed-by: Magne Pettersen Zachrisen
Change-Id: I570c673a817c3c01593fcd7fa46d545f34e2c38d
Merge-request: 1396
Reviewed-by: Jan-Arve Saether <jan-arve.saether@nokia.com>
Reviewed-on: http://codereview.qt-project.org/5927
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
src/widgets/graphicsview/qgraphicsitem.cpp
tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp

index 07af928..756c2f2 100644 (file)
@@ -2238,7 +2238,8 @@ bool QGraphicsItem::isVisible() const
     returned. \a parent can be 0, in which case this function will return
     whether the item is visible to the scene or not.
 
-    An item may not be visible to its ancestors even if isVisible() is true. If
+    An item may not be visible to its ancestors even if isVisible() is true. It
+    may also be visible to its ancestors even if isVisible() is false. If
     any ancestor is hidden, the item itself will be implicitly hidden, in which
     case this function will return false.
 
@@ -2246,15 +2247,16 @@ bool QGraphicsItem::isVisible() const
 */
 bool QGraphicsItem::isVisibleTo(const QGraphicsItem *parent) const
 {
-    if (!d_ptr->visible)
+    const QGraphicsItem *p = this;
+    if (d_ptr->explicitlyHidden)
         return false;
-    if (parent == this)
-        return true;
-    if (parentItem() && parentItem()->isVisibleTo(parent))
-        return true;
-    if (!parent && !parentItem())
-        return true;
-    return false;
+    do {
+        if (p == parent)
+            return true;
+        if (p->d_ptr->explicitlyHidden)
+            return false;
+    } while ((p = p->d_ptr->parent));
+    return parent == 0;
 }
 
 /*!
index ce099e0..c6babb8 100644 (file)
@@ -305,6 +305,7 @@ private slots:
     void inputMethodHints();
     void toolTip();
     void visible();
+    void isVisibleTo();
     void explicitlyVisible();
     void enabled();
     void explicitlyEnabled();
@@ -1138,6 +1139,113 @@ void tst_QGraphicsItem::visible()
     QVERIFY(!item->hasFocus());
 }
 
+void tst_QGraphicsItem::isVisibleTo()
+{
+    QGraphicsScene scene;
+    QGraphicsItem *parent = scene.addRect(QRectF(0, 0, 100, 100));
+    QGraphicsItem *child = scene.addRect(QRectF(25, 25, 50, 50));
+    QGraphicsItem *grandChild = scene.addRect(QRectF(50, 50, 50, 50));
+    QGraphicsItem *stranger = scene.addRect(100, 100, 100, 100);
+
+    child->setParentItem(parent);
+    grandChild->setParentItem(child);
+
+    QVERIFY(grandChild->isVisible());
+    QVERIFY(grandChild->isVisibleTo(grandChild));
+    QVERIFY(grandChild->isVisibleTo(child));
+    QVERIFY(grandChild->isVisibleTo(parent));
+    QVERIFY(grandChild->isVisibleTo(0));
+    QVERIFY(child->isVisible());
+    QVERIFY(child->isVisibleTo(child));
+    QVERIFY(child->isVisibleTo(parent));
+    QVERIFY(child->isVisibleTo(0));
+    QVERIFY(parent->isVisible());
+    QVERIFY(parent->isVisibleTo(parent));
+    QVERIFY(parent->isVisibleTo(0));
+    QVERIFY(!parent->isVisibleTo(child));
+    QVERIFY(!child->isVisibleTo(grandChild));
+    QVERIFY(!grandChild->isVisibleTo(stranger));
+    QVERIFY(!child->isVisibleTo(stranger));
+    QVERIFY(!parent->isVisibleTo(stranger));
+    QVERIFY(!stranger->isVisibleTo(grandChild));
+    QVERIFY(!stranger->isVisibleTo(child));
+    QVERIFY(!stranger->isVisibleTo(parent));
+
+    // Case 1: only parent is explicitly hidden
+    parent->hide();
+
+    QVERIFY(!grandChild->isVisible());
+    QVERIFY(grandChild->isVisibleTo(grandChild));
+    QVERIFY(grandChild->isVisibleTo(child));
+    QVERIFY(grandChild->isVisibleTo(parent));
+    QVERIFY(!grandChild->isVisibleTo(0));
+    QVERIFY(!child->isVisible());
+    QVERIFY(child->isVisibleTo(child));
+    QVERIFY(child->isVisibleTo(parent));
+    QVERIFY(!child->isVisibleTo(0));
+    QVERIFY(!parent->isVisible());
+    QVERIFY(!parent->isVisibleTo(parent));
+    QVERIFY(!parent->isVisibleTo(0));
+    QVERIFY(!parent->isVisibleTo(child));
+    QVERIFY(!child->isVisibleTo(grandChild));
+    QVERIFY(!grandChild->isVisibleTo(stranger));
+    QVERIFY(!child->isVisibleTo(stranger));
+    QVERIFY(!parent->isVisibleTo(stranger));
+    QVERIFY(!stranger->isVisibleTo(grandChild));
+    QVERIFY(!stranger->isVisibleTo(child));
+    QVERIFY(!stranger->isVisibleTo(parent));
+
+    // Case 2: only child is hidden
+    parent->show();
+    child->hide();
+
+    QVERIFY(!grandChild->isVisible());
+    QVERIFY(grandChild->isVisibleTo(grandChild));
+    QVERIFY(grandChild->isVisibleTo(child));
+    QVERIFY(!grandChild->isVisibleTo(parent));
+    QVERIFY(!grandChild->isVisibleTo(0));
+    QVERIFY(!child->isVisible());
+    QVERIFY(!child->isVisibleTo(child));
+    QVERIFY(!child->isVisibleTo(parent));
+    QVERIFY(!child->isVisibleTo(0));
+    QVERIFY(parent->isVisible());
+    QVERIFY(parent->isVisibleTo(parent));
+    QVERIFY(parent->isVisibleTo(0));
+    QVERIFY(!parent->isVisibleTo(child));
+    QVERIFY(!child->isVisibleTo(grandChild));
+    QVERIFY(!grandChild->isVisibleTo(stranger));
+    QVERIFY(!child->isVisibleTo(stranger));
+    QVERIFY(!parent->isVisibleTo(stranger));
+    QVERIFY(!stranger->isVisibleTo(grandChild));
+    QVERIFY(!stranger->isVisibleTo(child));
+    QVERIFY(!stranger->isVisibleTo(parent));
+
+    // Case 3: only grand child is hidden
+    child->show();
+    grandChild->hide();
+
+    QVERIFY(!grandChild->isVisible());
+    QVERIFY(!grandChild->isVisibleTo(grandChild));
+    QVERIFY(!grandChild->isVisibleTo(child));
+    QVERIFY(!grandChild->isVisibleTo(parent));
+    QVERIFY(!grandChild->isVisibleTo(0));
+    QVERIFY(child->isVisible());
+    QVERIFY(child->isVisibleTo(child));
+    QVERIFY(child->isVisibleTo(parent));
+    QVERIFY(child->isVisibleTo(0));
+    QVERIFY(parent->isVisible());
+    QVERIFY(parent->isVisibleTo(parent));
+    QVERIFY(parent->isVisibleTo(0));
+    QVERIFY(!parent->isVisibleTo(child));
+    QVERIFY(!child->isVisibleTo(grandChild));
+    QVERIFY(!grandChild->isVisibleTo(stranger));
+    QVERIFY(!child->isVisibleTo(stranger));
+    QVERIFY(!parent->isVisibleTo(stranger));
+    QVERIFY(!stranger->isVisibleTo(grandChild));
+    QVERIFY(!stranger->isVisibleTo(child));
+    QVERIFY(!stranger->isVisibleTo(parent));
+}
+
 void tst_QGraphicsItem::explicitlyVisible()
 {
     QGraphicsScene scene;