/** * is called after a reparent has taken place to fix up the focus chain(s) */ void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *newScene) { Q_Q(QGraphicsWidget); Q_ASSERT(focusNext && focusPrev); QGraphicsWidget *n = q; //last one in 'new' list QGraphicsWidget *o = 0; //last one in 'old' list QGraphicsWidget *w = focusNext; QGraphicsWidget *firstOld = 0; bool wasPreviousNew = true; if (focusChild) { // Ensure that the current focus child doesn't leave pointers around // before reparenting. focusChild->clearFocus(); } while (w != q) { bool isCurrentNew = q->isAncestorOf(w); if (isCurrentNew) { if (!wasPreviousNew) { n->d_func()->focusNext = w; w->d_func()->focusPrev = n; } n = w; } else { /*if (!isCurrentNew)*/ if (wasPreviousNew) { if (o) { o->d_func()->focusNext = w; w->d_func()->focusPrev = o; } else { firstOld = w; } } o = w; } w = w->d_func()->focusNext; wasPreviousNew = isCurrentNew; } // repair the 'old' chain if (firstOld) { o->d_func()->focusNext = firstOld; firstOld->d_func()->focusPrev = o; } // update tabFocusFirst for oldScene if the item is going to be removed from oldScene if (newParent) newScene = newParent->scene(); QGraphicsScene *oldScene = q->scene(); if (oldScene && newScene != oldScene) oldScene->d_func()->tabFocusFirst = firstOld; QGraphicsItem *topLevelItem = newParent ? newParent->topLevelItem() : 0; QGraphicsWidget *topLevel = 0; if (topLevelItem && topLevelItem->isWidget()) topLevel = static_cast<QGraphicsWidget *>(topLevelItem); if (topLevel && newParent) { QGraphicsWidget *last = topLevel->d_func()->focusPrev; // link last with new chain last->d_func()->focusNext = q; focusPrev = last; // link last in chain with topLevel->d_func()->focusPrev = n; n->d_func()->focusNext = topLevel; } else { // q is the start of the focus chain n->d_func()->focusNext = q; focusPrev = n; } }