Clear focus of GraphicsItem focus scopes and their children.

A focus scope has effective focus if one of its children is the focus item,
clearFocus() should remove effective focus from an item and its children
not just from the focus item.

Task-number: QTBUG-28328
Change-Id: I62a292eff000151e50b2f5221e22f326a380fc3a
Reviewed-by: Martin Jones <martin.jones@jollamobile.com>
This commit is contained in:
Andrew den Exter 2012-12-03 17:03:02 +10:00 committed by The Qt Project
parent 5ede8ee80d
commit ab97a44b6a
2 changed files with 48 additions and 3 deletions

View File

@ -3313,6 +3313,12 @@ void QGraphicsItem::clearFocus()
*/
void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent, bool hiddenByParentPanel)
{
QGraphicsItem *subFocusItem = q_ptr;
if (flags & QGraphicsItem::ItemIsFocusScope) {
while (subFocusItem->d_ptr->focusScopeItem)
subFocusItem = subFocusItem->d_ptr->focusScopeItem;
}
if (giveFocusToParent) {
// Pass focus to the closest parent focus scope
if (!inDestructor) {
@ -3321,10 +3327,10 @@ void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent, bool hiddenB
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
if (p->d_ptr->focusScopeItem == q_ptr) {
p->d_ptr->focusScopeItem = 0;
if (!q_ptr->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere
if (!subFocusItem->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere
focusScopeItemChange(false);
}
if (q_ptr->hasFocus())
if (subFocusItem->hasFocus())
p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
/* focusFromHide = */ false);
return;
@ -3334,7 +3340,7 @@ void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent, bool hiddenB
}
}
if (q_ptr->hasFocus()) {
if (subFocusItem->hasFocus()) {
// Invisible items with focus must explicitly clear subfocus.
if (!hiddenByParentPanel)
clearSubFocus(q_ptr);

View File

@ -9228,6 +9228,45 @@ void tst_QGraphicsItem::focusScope()
scope3->setFocus();
QVERIFY(scope3->hasFocus());
// clearFocus() on a focus scope will remove focus from its children.
scope1->clearFocus();
QVERIFY(!scope1->hasFocus());
QVERIFY(!scope2->hasFocus());
QVERIFY(!scope3->hasFocus());
scope1->setFocus();
QVERIFY(!scope1->hasFocus());
QVERIFY(!scope2->hasFocus());
QVERIFY(scope3->hasFocus());
scope2->clearFocus();
QVERIFY(scope1->hasFocus());
QVERIFY(!scope2->hasFocus());
QVERIFY(!scope3->hasFocus());
scope2->setFocus();
QVERIFY(!scope1->hasFocus());
QVERIFY(!scope2->hasFocus());
QVERIFY(scope3->hasFocus());
// Focus cleared while a parent doesn't have focus remains cleared
// when the parent regains focus.
scope1->clearFocus();
scope3->clearFocus();
QVERIFY(!scope1->hasFocus());
QVERIFY(!scope2->hasFocus());
QVERIFY(!scope3->hasFocus());
scope1->setFocus();
QVERIFY(!scope1->hasFocus());
QVERIFY(scope2->hasFocus());
QVERIFY(!scope3->hasFocus());
scope3->setFocus();
QVERIFY(!scope1->hasFocus());
QVERIFY(!scope2->hasFocus());
QVERIFY(scope3->hasFocus());
QGraphicsRectItem *rect4 = new QGraphicsRectItem;
rect4->setData(0, "rect4");
rect4->setParentItem(scope3);