diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/declarative/fx/qfxcomponentinstance.cpp | 2 | ||||
-rw-r--r-- | src/declarative/fx/qfxfocusscope.cpp | 2 | ||||
-rw-r--r-- | src/declarative/fx/qfxgridview.cpp | 2 | ||||
-rw-r--r-- | src/declarative/fx/qfxitem.cpp | 56 | ||||
-rw-r--r-- | src/declarative/fx/qfxitem_p.h | 3 | ||||
-rw-r--r-- | src/declarative/fx/qfxlistview.cpp | 2 | ||||
-rw-r--r-- | src/declarative/fx/qfxpathview_p.h | 2 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 79 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.h | 4 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 40 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 129 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 2 |
12 files changed, 190 insertions, 133 deletions
diff --git a/src/declarative/fx/qfxcomponentinstance.cpp b/src/declarative/fx/qfxcomponentinstance.cpp index def7a9f..7a712aa 100644 --- a/src/declarative/fx/qfxcomponentinstance.cpp +++ b/src/declarative/fx/qfxcomponentinstance.cpp @@ -73,13 +73,11 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,ComponentInstance,QFxComponentIn QFxComponentInstance::QFxComponentInstance(QFxItem *parent) : QFxItem(*(new QFxComponentInstancePrivate), parent) { - setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy); } QFxComponentInstance::QFxComponentInstance(QFxComponentInstancePrivate &dd, QFxItem *parent) : QFxItem(dd, parent) { - setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy); } /*! diff --git a/src/declarative/fx/qfxfocusscope.cpp b/src/declarative/fx/qfxfocusscope.cpp index 8981256..9bcc17e 100644 --- a/src/declarative/fx/qfxfocusscope.cpp +++ b/src/declarative/fx/qfxfocusscope.cpp @@ -63,7 +63,7 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,FocusScope,QFxFocusScope) QFxFocusScope::QFxFocusScope(QFxItem *parent) : QFxItem(parent) { - setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy); + setFlag(QGraphicsItem::ItemIsFocusScope); } QFxFocusScope::~QFxFocusScope() diff --git a/src/declarative/fx/qfxgridview.cpp b/src/declarative/fx/qfxgridview.cpp index e2c7fa3..b429895 100644 --- a/src/declarative/fx/qfxgridview.cpp +++ b/src/declarative/fx/qfxgridview.cpp @@ -325,7 +325,7 @@ public: void QFxGridViewPrivate::init() { Q_Q(QFxGridView); - q->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy); + q->setFlag(QGraphicsItem::ItemIsFocusScope); QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(sizeChange())); QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(sizeChange())); } diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index a8be81f..9b9355e 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -2363,7 +2363,14 @@ QPointF QFxItemPrivate::computeTransformOrigin() const */ bool QFxItem::sceneEvent(QEvent *event) { - return QGraphicsItem::sceneEvent(event); + bool rv = QGraphicsItem::sceneEvent(event); + + if (event->type() == QEvent::FocusIn || + event->type() == QEvent::FocusOut) { + activeFocusChanged(hasActiveFocus()); + } + + return rv; } /*! @@ -2548,49 +2555,20 @@ bool QFxItem::heightValid() const bool QFxItem::hasFocus() const { - const QGraphicsItem *current = this->parentItem(); - while (current && !(current->flags() & ItemAutoDetectsFocusProxy)) - current = current->parentItem(); - - if (current) - return current->focusProxy() == this; - else - return QGraphicsItem::hasFocus(); + Q_D(const QFxItem); + return d->itemIsFocusedInScope; } void QFxItem::setFocus(bool focus) { - QGraphicsScene *s = scene(); - if (!s) { - if (focus) QGraphicsItem::setFocus(Qt::OtherFocusReason); - else QGraphicsItem::clearFocus(); - focusChanged(focus); - return; - } - - QGraphicsItem *current = this->parentItem(); - while (current && !(current->flags() & ItemAutoDetectsFocusProxy)) - current = current->parentItem(); - - if (!current) { - if (focus) QGraphicsItem::setFocus(Qt::OtherFocusReason); - else QGraphicsItem::clearFocus(); - focusChanged(focus); - return; - } - - if (current->focusProxy() && current->focusProxy() != this) { - QFxItem *currentItem = qobject_cast<QFxItem *>(current->focusProxy()); - if (currentItem) - currentItem->setFocus(false); - } - - if (current->focusProxy() == this && !focus) - current->setFocusProxy(0); - else if (focus) - current->setFocusProxy(this); + if (focus) QGraphicsItem::setFocus(Qt::OtherFocusReason); + else QGraphicsItem::clearFocus(); +} - focusChanged(focus); +void QFxItemPrivate::focusedInScopeChanged() +{ + Q_Q(QFxItem); + q->focusChanged(q->hasFocus()); } /*! diff --git a/src/declarative/fx/qfxitem_p.h b/src/declarative/fx/qfxitem_p.h index d30e324..054bdc7 100644 --- a/src/declarative/fx/qfxitem_p.h +++ b/src/declarative/fx/qfxitem_p.h @@ -223,6 +223,9 @@ public: QGraphicsItemPrivate::setPosHelper(pos); q->geometryChanged(QRectF(this->pos.x(), this->pos.y(), width, height), oldGeometry); } + + // Inherited from QGraphcisItemPrivate + virtual void focusedInScopeChanged(); }; QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index 048cb0f..9498854 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -396,7 +396,7 @@ public: void QFxListViewPrivate::init() { Q_Q(QFxListView); - q->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy); + q->setFlag(QGraphicsItem::ItemIsFocusScope); QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(refill())); QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(refill())); } diff --git a/src/declarative/fx/qfxpathview_p.h b/src/declarative/fx/qfxpathview_p.h index a69f75f..60bfdb3 100644 --- a/src/declarative/fx/qfxpathview_p.h +++ b/src/declarative/fx/qfxpathview_p.h @@ -87,7 +87,7 @@ public: Q_Q(QFxPathView); _offset = 0; q->setAcceptedMouseButtons(Qt::LeftButton); - q->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy); + q->setFlag(QGraphicsItem::ItemIsFocusScope); q->setFiltersChildEvents(true); q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked())); } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 620f6f4..ead5aee 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -331,10 +331,6 @@ \value ItemNegativeZStacksBehindParent The item automatically stacks behind it's parent if it's z-value is negative. This flag enables setZValue() to toggle ItemStacksBehindParent. - - \value ItemAutoDetectsFocusProxy The item will assign any child that - gains input focus as its focus proxy. See also focusProxy(). - This flag was introduced in Qt 4.6. */ /*! @@ -944,17 +940,6 @@ 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) { @@ -969,7 +954,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) bool implicitUpdate = false; if (parent->d_func()->scene && parent->d_func()->scene != scene) { // Move this item to its new parent's scene - parent->d_func()->scene->addItem(q); + + QGraphicsItem *focusScope = newParent; + while (focusScope && !(focusScope->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)) + focusScope = focusScope->d_ptr->parent; + parent->d_func()->scene->d_func()->addItem(q, focusScope); implicitUpdate = true; } else if (!parent->d_func()->scene && scene) { // Remove this item from its former scene @@ -1031,17 +1020,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) if (lastSubFocusItem) lastSubFocusItem->d_ptr->setSubFocus(); - // Auto-update focus proxy. The closest parent that detects - // focus proxies is updated as the proxy gains or loses focus. - p = newParent; - while (p) { - if (p->d_ptr->flags & QGraphicsItem::ItemAutoDetectsFocusProxy) { - p->setFocusProxy(q); - break; - } - p = p->d_ptr->parent; - } - // Deliver post-change notification q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); @@ -2663,11 +2641,27 @@ void QGraphicsItem::setFocus(Qt::FocusReason focusReason) // Update the scene's focus item. if (d_ptr->scene) { + QGraphicsItem *s = d_ptr->focusScope(); + if (s) { + bool scopeHasFocus = + s->d_ptr->hasActiveFocus(d_ptr->scene->focusItem()); + if (s->d_ptr->focusScopeItem) + s->d_ptr->focusScopeItem->d_ptr->setItemFocusedInScope(false); + s->d_ptr->focusScopeItem = this; + d_ptr->setItemFocusedInScope(true); + if (scopeHasFocus) + d_ptr->scene->d_func()->setFocusItemHelper(s, focusReason); + return; + } + d_ptr->setItemFocusedInScope(false); + QGraphicsWidget *w = window(); if (!w || w->isActiveWindow()) { // Visible items immediately gain focus from scene. d_ptr->scene->d_func()->setFocusItemHelper(f, focusReason); } + } else { + d_ptr->setItemFocusedInScope(true); } } @@ -2684,12 +2678,31 @@ void QGraphicsItem::setFocus(Qt::FocusReason focusReason) */ void QGraphicsItem::clearFocus() { - if (!d_ptr->scene) + if (!d_ptr->scene) { + d_ptr->setItemFocusedInScope(false); return; + } // Invisible items with focus must explicitly clear subfocus. d_ptr->clearSubFocus(); + + if (d_ptr->itemIsFocusedInScope) { + d_ptr->setItemFocusedInScope(false); + QGraphicsItem *s = d_ptr->focusScope(); + if (s) { + if (s->d_ptr->focusScopeItem == this) { + bool scopeHasFocus = + s->d_ptr->hasActiveFocus(d_ptr->scene->focusItem()); + s->d_ptr->focusScopeItem = 0; + if (scopeHasFocus) + d_ptr->scene->setFocusItem(s); + return; + } + } + } + if (hasFocus()) { // If this item has the scene's input focus, clear it. + d_ptr->setItemFocusedInScope(false); d_ptr->scene->setFocusItem(0); } } @@ -2700,7 +2713,7 @@ void QGraphicsItem::clearFocus() Returns this item's focus proxy, or 0 if this item has no focus proxy. - \sa setFocusProxy(), ItemAutoDetectsFocusProxy, setFocus(), hasFocus() + \sa setFocusProxy(), setFocus(), hasFocus() */ QGraphicsItem *QGraphicsItem::focusProxy() const { @@ -2724,7 +2737,7 @@ QGraphicsItem *QGraphicsItem::focusProxy() const The focus proxy \a item must belong to the same scene as this item. - \sa focusProxy(), ItemAutoDetectsFocusProxy, setFocus(), hasFocus() + \sa focusProxy(), setFocus(), hasFocus() */ void QGraphicsItem::setFocusProxy(QGraphicsItem *item) { @@ -4770,7 +4783,7 @@ void QGraphicsItemPrivate::setSubFocus() bool hidden = !visible; do { parent->d_func()->subFocusItem = item; - } while (!parent->isWindow() && (parent = parent->d_ptr->parent) && (!hidden || !parent->d_func()->visible)); + } while (!parent->isWindow() && (parent = parent->d_ptr->parent) && (!hidden || !parent->d_func()->visible) && !(parent->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)); } /*! @@ -10437,8 +10450,8 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag) case QGraphicsItem::ItemNegativeZStacksBehindParent: str = "ItemNegativeZStacksBehindParent"; break; - case QGraphicsItem::ItemAutoDetectsFocusProxy: - str = "ItemAutoDetectsFocusProxy"; + case QGraphicsItem::ItemIsFocusScope: + str = "ItemIsFocusScope"; break; } debug << str; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 7af7c2f..b76f5ac 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -103,8 +103,8 @@ public: ItemHasNoContents = 0x400, ItemSendsGeometryChanges = 0x800, ItemAcceptsInputMethod = 0x1000, - ItemAutoDetectsFocusProxy = 0x2000, - ItemNegativeZStacksBehindParent = 0x4000 + ItemNegativeZStacksBehindParent = 0x4000, + ItemIsFocusScope = 0x8000 // NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag. }; Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 11f6f53..7abd7f5 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -97,6 +97,8 @@ public: void purge(); }; +#include <QDebug> + class Q_GUI_EXPORT QGraphicsItemPrivate { Q_DECLARE_PUBLIC(QGraphicsItem) @@ -128,6 +130,7 @@ public: siblingIndex(-1), itemDepth(-1), focusProxy(0), + focusScopeItem(0), subFocusItem(0), imHints(Qt::ImhNone), acceptedMouseButtons(0x1f), @@ -171,6 +174,7 @@ public: notifyBoundingRectChanged(0), notifyInvalidated(0), mouseSetsFocus(1), + itemIsFocusedInScope(0), globalStackingOrder(-1), q_ptr(0) { @@ -410,6 +414,38 @@ public: void clearSubFocus(); void resetFocusProxy(); + inline QGraphicsItem *rootLevelFocusItem() const { + QGraphicsItem *fi = q_ptr; + while(QGraphicsItem *i = fi->d_ptr->focusScope()) + fi = i; + return fi; + } + + inline QGraphicsItem *focusScope() const { + QGraphicsItem *item = parent; + while (item) { + if (item->isWindow()) + return 0; + if (item->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) + return item; + item = item->d_ptr->parent; + } + return 0; + } + inline bool hasActiveFocus(QGraphicsItem *focusItem) const { + if (!(flags & QGraphicsItem::ItemIsFocusScope) || !focusScopeItem) + return focusItem == q_ptr; + else + return focusScopeItem->d_ptr->hasActiveFocus(focusItem); + } + inline void setItemFocusedInScope(bool f) { + if (itemIsFocusedInScope != f) { + itemIsFocusedInScope = f; + if (!inDestructor) focusedInScopeChanged(); + } + } + inline virtual void focusedInScopeChanged() {} + inline QTransform transformToParent() const; inline void ensureSortedChildren(); @@ -431,6 +467,7 @@ public: int siblingIndex; int itemDepth; // Lazily calculated when calling depth(). QGraphicsItem *focusProxy; + QGraphicsItem *focusScopeItem; // Only used if this is a focus scope QList<QGraphicsItem **> focusProxyRefs; QGraphicsItem *subFocusItem; Qt::InputMethodHints imHints; @@ -463,7 +500,7 @@ public: // New 32 bits quint32 fullUpdatePending : 1; - quint32 flags : 15; + quint32 flags : 16; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; quint32 dirtySceneTransform : 1; @@ -479,6 +516,7 @@ public: quint32 notifyBoundingRectChanged : 1; quint32 notifyInvalidated : 1; quint32 mouseSetsFocus : 1; + quint32 itemIsFocusedInScope : 1; quint32 unused : 1; // feel free to use // Optional stacking order diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a819822..73dba7b 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -572,6 +572,10 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, Qt::FocusReason focusReason) { Q_Q(QGraphicsScene); + + while (item && item->d_ptr->focusScopeItem) + item = item->d_ptr->focusScopeItem; + if (item == focusItem) return; @@ -589,22 +593,18 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, return; } - // Auto-update focus proxy. The closest parent that detects - // focus proxies is updated as the proxy gains or loses focus. - if (item) { - QGraphicsItem *p = item->d_ptr->parent; - while (p) { - if (p->d_ptr->flags & QGraphicsItem::ItemAutoDetectsFocusProxy) { - p->setFocusProxy(item); - break; - } - p = p->d_ptr->parent; - } - } + QGraphicsItem *itemRootLevelFocusItem = + item?item->d_ptr->rootLevelFocusItem():0; if (focusItem) { QFocusEvent event(QEvent::FocusOut, focusReason); lastFocusItem = focusItem; + + QGraphicsItem *oldRootLevelFocusItem = + focusItem->d_ptr->rootLevelFocusItem(); + if (oldRootLevelFocusItem != itemRootLevelFocusItem) + oldRootLevelFocusItem->d_ptr->setItemFocusedInScope(false); + focusItem = 0; sendEvent(lastFocusItem, &event); @@ -622,6 +622,8 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, if (item) { focusItem = item; + itemRootLevelFocusItem->d_ptr->setItemFocusedInScope(true); + item->d_ptr->setItemFocusedInScope(true); QFocusEvent event(QEvent::FocusIn, focusReason); sendEvent(item, &event); } @@ -2240,11 +2242,19 @@ void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group) void QGraphicsScene::addItem(QGraphicsItem *item) { Q_D(QGraphicsScene); + d->addItem(item); +} + +void QGraphicsScenePrivate::addItem(QGraphicsItem *item, + QGraphicsItem *focusScope) +{ + Q_Q(QGraphicsScene); + if (!item) { qWarning("QGraphicsScene::addItem: cannot add null item"); return; } - if (item->scene() == this) { + if (item->scene() == q) { qWarning("QGraphicsScene::addItem: item has already been added to this scene"); return; } @@ -2255,9 +2265,9 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Notify the item that its scene is changing, and allow the item to // react. const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange, - qVariantFromValue<QGraphicsScene *>(this))); + qVariantFromValue<QGraphicsScene *>(q))); QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant); - if (targetScene != this) { + if (targetScene != q) { if (targetScene && item->scene() != targetScene) targetScene->addItem(item); return; @@ -2266,7 +2276,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Detach this item from its parent if the parent's scene is different // from this scene. if (QGraphicsItem *itemParent = item->parentItem()) { - if (itemParent->scene() != this) + if (itemParent->scene() != q) item->setParentItem(0); } @@ -2274,98 +2284,113 @@ void QGraphicsScene::addItem(QGraphicsItem *item) item->d_func()->scene = targetScene; // Add the item in the index - d->index->addItem(item); + index->addItem(item); // Add to list of toplevels if this item is a toplevel. if (!item->d_ptr->parent) - d->registerTopLevelItem(item); + registerTopLevelItem(item); // Add to list of items that require an update. We cannot assume that the // item is fully constructed, so calling item->update() can lead to a pure // virtual function call to boundingRect(). - d->markDirty(item); - d->dirtyGrowingItemsBoundingRect = true; + markDirty(item); + dirtyGrowingItemsBoundingRect = true; // Disable selectionChanged() for individual items - ++d->selectionChanging; - int oldSelectedItemSize = d->selectedItems.size(); + ++selectionChanging; + int oldSelectedItemSize = selectedItems.size(); // Enable mouse tracking if the item accepts hover events or has a cursor set. - if (d->allItemsIgnoreHoverEvents && d->itemAcceptsHoverEvents_helper(item)) { - d->allItemsIgnoreHoverEvents = false; - d->enableMouseTrackingOnViews(); + if (allItemsIgnoreHoverEvents && itemAcceptsHoverEvents_helper(item)) { + allItemsIgnoreHoverEvents = false; + enableMouseTrackingOnViews(); } #ifndef QT_NO_CURSOR - if (d->allItemsUseDefaultCursor && item->hasCursor()) { - d->allItemsUseDefaultCursor = false; - if (d->allItemsIgnoreHoverEvents) // already enabled otherwise - d->enableMouseTrackingOnViews(); + if (allItemsUseDefaultCursor && item->hasCursor()) { + allItemsUseDefaultCursor = false; + if (allItemsIgnoreHoverEvents) // already enabled otherwise + enableMouseTrackingOnViews(); } #endif //QT_NO_CURSOR // Enable touch events if the item accepts touch events. - if (d->allItemsIgnoreTouchEvents && item->acceptTouchEvents()) { - d->allItemsIgnoreTouchEvents = false; - d->enableTouchEventsOnViews(); + if (allItemsIgnoreTouchEvents && item->acceptTouchEvents()) { + allItemsIgnoreTouchEvents = false; + enableTouchEventsOnViews(); } // Update selection lists if (item->isSelected()) - d->selectedItems << item; + selectedItems << item; if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup) - d->addPopup(static_cast<QGraphicsWidget *>(item)); + addPopup(static_cast<QGraphicsWidget *>(item)); // Update creation order focus chain. Make sure to leave the widget's // internal tab order intact. if (item->isWidget()) { QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item); - if (!d->tabFocusFirst) { + if (!tabFocusFirst) { // No first tab focus widget - make this the first tab focus // widget. - d->tabFocusFirst = widget; + tabFocusFirst = widget; } else if (!widget->parentWidget()) { // Adding a widget that is not part of a tab focus chain. - QGraphicsWidget *last = d->tabFocusFirst->d_func()->focusPrev; + QGraphicsWidget *last = tabFocusFirst->d_func()->focusPrev; QGraphicsWidget *lastNew = widget->d_func()->focusPrev; last->d_func()->focusNext = widget; widget->d_func()->focusPrev = last; - d->tabFocusFirst->d_func()->focusPrev = lastNew; - lastNew->d_func()->focusNext = d->tabFocusFirst; + tabFocusFirst->d_func()->focusPrev = lastNew; + lastNew->d_func()->focusNext = tabFocusFirst; } } // Add all children recursively + QGraphicsItem *subFocusScope = + (item->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)?item:focusScope; foreach (QGraphicsItem *child, item->children()) - addItem(child); + addItem(child, subFocusScope); // Resolve font and palette. - item->d_ptr->resolveFont(d->font.resolve()); - item->d_ptr->resolvePalette(d->palette.resolve()); + item->d_ptr->resolveFont(font.resolve()); + item->d_ptr->resolvePalette(palette.resolve()); if (!item->d_ptr->explicitlyHidden) { - if (d->unpolishedItems.isEmpty()) - QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); - d->unpolishedItems << item; + if (unpolishedItems.isEmpty()) + QMetaObject::invokeMethod(q, "_q_polishItems", Qt::QueuedConnection); + unpolishedItems << item; } // Reenable selectionChanged() for individual items - --d->selectionChanging; - if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize) - emit selectionChanged(); + --selectionChanging; + if (!selectionChanging && selectedItems.size() != oldSelectedItemSize) + emit q->selectionChanged(); // Deliver post-change notification item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant); // Auto-activate the first inactive window if the scene is active. - if (d->activationRefCount > 0 && !d->activeWindow && item->isWindow()) - setActiveWindow(static_cast<QGraphicsWidget *>(item)); + if (activationRefCount > 0 && !activeWindow && item->isWindow()) + q->setActiveWindow(static_cast<QGraphicsWidget *>(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 (!focusItem && item->focusItem()) item->focusItem()->setFocus(); - d->updateInputMethodSensitivityInViews(); + // Ensure that focus scopes set themselves up at add time + if (item->d_ptr->itemIsFocusedInScope) { + if (focusScope && !focusScope->d_ptr->focusScopeItem) { + item->setFocus(); + } else if (!(focusScope && focusScope->d_ptr->focusScopeItem == item) && + !(focusItem && focusItem->d_ptr->rootLevelFocusItem() == item)) { + // We unset the focused in scope variable in this item if: + // It's not scope focused in the closest focus scope, and + // It's not the root-level item for the globally focused item + item->d_ptr->setItemFocusedInScope(false); + } + } + + updateInputMethodSensitivityInViews(); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 4b8791e..9e62901 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -124,6 +124,8 @@ public: QBrush backgroundBrush; QBrush foregroundBrush; + void addItem(QGraphicsItem *, QGraphicsItem *focusScope = 0); + bool stickyFocus; bool hasFocus; QGraphicsItem *focusItem; |