From 262d0348f7a38a22809662e296545d07d686afde Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 11 Aug 2009 17:59:49 +0200 Subject: Fix autotest failure in qgraphicsitem. When autofocused child is deleted, remove from ancestors to avoid double deletion crash. Check for null receiver when auto SIP is enabled in mouseReleaseEvent --- src/gui/graphicsview/qgraphicsitem.cpp | 22 ++++++++++++++++++---- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 1e7708c..2ef78b2 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -938,6 +938,17 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant); } + // Auto-update focus proxy. Any ancestor that has this as focus proxy + //needs to be nulled. + QGraphicsItem *p = parent; + while (p) { + if ((p->d_ptr->flags & QGraphicsItem::ItemAutoDetectsFocusProxy) && + (p->focusProxy() == q)) { + p->setFocusProxy(0); + } + p = p->d_ptr->parent; + } + // Update toplevelitem list. If this item is being deleted, its parent // will be 0 but we don't want to register/unregister it in the TLI list. if (scene && !inDestructor) { @@ -1016,7 +1027,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) // Auto-update focus proxy. The closest parent that detects // focus proxies is updated as the proxy gains or loses focus. - QGraphicsItem *p = newParent; + p = newParent; while (p) { if (p->d_ptr->flags & QGraphicsItem::ItemAutoDetectsFocusProxy) { p->setFocusProxy(q); @@ -9092,10 +9103,13 @@ void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (event->button() == Qt::LeftButton && qApp->autoSipEnabled() && (!dd->clickCausedFocus || qApp->autoSipOnMouseFocus())) { QEvent _event(QEvent::RequestSoftwareInputPanel); - QApplication::sendEvent(event->widget(), &_event); - } else { - QGraphicsItem::mouseReleaseEvent(event); + QWidget *receiver = event->widget(); + if(receiver) { + QApplication::sendEvent(receiver, &_event); + } } + QGraphicsItem::mouseReleaseEvent(event); + dd->clickCausedFocus = 0; dd->sendControlEvent(event); } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 558688f..892e182 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -160,6 +160,7 @@ public slots: void init(); private slots: + void explicitDeleteAutoFocusProxy(); void construction(); void constructionWithParent(); void destruction(); @@ -7516,5 +7517,28 @@ void tst_QGraphicsItem::reverseCreateAutoFocusProxy() QVERIFY(text2->hasFocus()); } +void tst_QGraphicsItem::explicitDeleteAutoFocusProxy() +{ + QGraphicsTextItem *text = new QGraphicsTextItem; + text->setTextInteractionFlags(Qt::TextEditorInteraction); + text->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy); + + QGraphicsTextItem *text2 = new QGraphicsTextItem; + text2->setTextInteractionFlags(Qt::TextEditorInteraction); + text2->setFocus(); + QVERIFY(!text2->hasFocus()); + QCOMPARE(text->focusProxy(), (QGraphicsItem *)0); + text2->setParentItem(text); + QCOMPARE(text->focusProxy(), (QGraphicsItem *)text2); + QCOMPARE(text->focusItem(), (QGraphicsItem *)text2); + + QGraphicsScene scene; + scene.addItem(text); + QVERIFY(text2->hasFocus()); + + delete text2; + QCOMPARE(text->focusProxy(), (QGraphicsItem *)0); +} + QTEST_MAIN(tst_QGraphicsItem) #include "tst_qgraphicsitem.moc" -- cgit v0.12