diff options
author | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-09-09 15:10:58 (GMT) |
---|---|---|
committer | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-09-09 15:18:07 (GMT) |
commit | ebb1162f54a29baeccb71d1e283146892629518f (patch) | |
tree | 509880629128bf0f1d62f75fb40d87dc1fbcee8a /src/gui/graphicsview | |
parent | 948038f077ea413ab7aa7634d1c9987ec7ab50f6 (diff) | |
download | Qt-ebb1162f54a29baeccb71d1e283146892629518f.zip Qt-ebb1162f54a29baeccb71d1e283146892629518f.tar.gz Qt-ebb1162f54a29baeccb71d1e283146892629518f.tar.bz2 |
Fix crash/bug in QGraphicsItem's subFocus handling.
Removes dangling subFocusItem pointers when changing focus after
reparenting. This change also includes a mini-optimization when adding
focusable items to an inactive scene.
Reviewed-by: brad
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 19 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 3 |
2 files changed, 14 insertions, 8 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index e553517..9c0c649 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1198,6 +1198,7 @@ QGraphicsItem::~QGraphicsItem() d_ptr->removeExtraItemCache(); clearFocus(); + if (!d_ptr->children.isEmpty()) { QList<QGraphicsItem *> oldChildren = d_ptr->children; qDeleteAll(oldChildren); @@ -2750,7 +2751,7 @@ void QGraphicsItem::setFocus(Qt::FocusReason focusReason) // Update the scene's focus item. if (d_ptr->scene) { QGraphicsItem *p = panel(); - if ((!p && d_ptr->scene->isActive()) || p->isActive()) { + if ((!p && d_ptr->scene->isActive()) || (p && p->isActive())) { // Visible items immediately gain focus from scene. d_ptr->scene->d_func()->setFocusItemHelper(f, focusReason); } @@ -2770,10 +2771,9 @@ void QGraphicsItem::setFocus(Qt::FocusReason focusReason) */ void QGraphicsItem::clearFocus() { - if (!d_ptr->scene) - return; // Invisible items with focus must explicitly clear subfocus. d_ptr->clearSubFocus(); + if (hasFocus()) { // If this item has the scene's input focus, clear it. d_ptr->scene->setFocusItem(0); @@ -4856,10 +4856,15 @@ void QGraphicsItemPrivate::setSubFocus() { // Update focus child chain. Stop at panels, or if this item // is hidden, stop at the first item with a visible parent. - QGraphicsItem *item = q_ptr; - QGraphicsItem *parent = item; + QGraphicsItem *parent = q_ptr; do { - parent->d_func()->subFocusItem = item; + // Clear any existing ancestor's subFocusItem. + if (parent != q_ptr && parent->d_ptr->subFocusItem) { + if (parent->d_ptr->subFocusItem == q_ptr) + break; + parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(); + } + parent->d_ptr->subFocusItem = q_ptr; } while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible)); if (!parent && scene && !scene->isActive()) @@ -4871,7 +4876,7 @@ void QGraphicsItemPrivate::setSubFocus() */ void QGraphicsItemPrivate::clearSubFocus() { - // Reset focus child chain. + // Reset sub focus chain. QGraphicsItem *parent = q_ptr; do { if (parent->d_ptr->subFocusItem != q_ptr) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 43f2932..0fd1647 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1390,6 +1390,7 @@ QGraphicsScene::QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObj QGraphicsScene::~QGraphicsScene() { Q_D(QGraphicsScene); + // Remove this scene from qApp's global scene list. qApp->d_func()->scene_list.removeAll(this); @@ -2430,7 +2431,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Ensure that newly added items that have subfocus set, gain // focus automatically if there isn't a focus item already. - if (!d->focusItem && item->focusItem()) + if (!d->focusItem && item->focusItem() && item->isActive()) item->focusItem()->setFocus(); d->updateInputMethodSensitivityInViews(); |