From d59f868312238f16bd8534f61c01dd0695512d38 Mon Sep 17 00:00:00 2001
From: Bea Lam <bea.lam@nokia.com>
Date: Thu, 15 Mar 2012 10:15:49 +1000
Subject: [PATCH] Pull out some duplicate focus-related code

Change-Id: I920a9b75ccbdb3a9b169c7669121734c14d18ff9
Reviewed-by: Andrew den Exter <andrew.den-exter@nokia.com>
---
 src/quick/items/qquickcanvas.cpp | 32 ++++----------------------
 src/quick/items/qquickitem.cpp   | 39 ++++++++++++++++++++++++++++----
 src/quick/items/qquickitem_p.h   |  1 +
 3 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index d5c826b67a..a5d3250b41 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -548,27 +548,12 @@ void QQuickCanvasPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F
 
     if (item != rootItem && !(options & DontChangeSubFocusItem)) {
         QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
-        // Correct focus chain in scope
-        if (oldSubFocusItem) {
-            QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
-            while (sfi != scope) {
-                QQuickItemPrivate::get(sfi)->subFocusItem = 0;
-                sfi = sfi->parentItem();
-            }
-        }
-        {
-            scopePrivate->subFocusItem = item;
-            QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
-            while (sfi != scope) {
-                QQuickItemPrivate::get(sfi)->subFocusItem = item;
-                sfi = sfi->parentItem();
-            }
-        }
-
         if (oldSubFocusItem) {
             QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
             changed << oldSubFocusItem;
         }
+
+        QQuickItemPrivate::get(item)->updateSubFocusItem(scope, true);
     }
 
     if (!(options & DontChangeFocusProperty)) {
@@ -658,20 +643,13 @@ void QQuickCanvasPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
 
     if (item != rootItem && !(options & DontChangeSubFocusItem)) {
         QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
-        // Correct focus chain in scope
-        if (oldSubFocusItem) {
-            QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
-            while (sfi != scope) {
-                QQuickItemPrivate::get(sfi)->subFocusItem = 0;
-                sfi = sfi->parentItem();
-            }
-        }
-        scopePrivate->subFocusItem = 0;
-
         if (oldSubFocusItem && !(options & DontChangeFocusProperty)) {
             QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
             changed << oldSubFocusItem;
         }
+
+        QQuickItemPrivate::get(item)->updateSubFocusItem(scope, false);
+
     } else if (!(options & DontChangeFocusProperty)) {
         QQuickItemPrivate::get(item)->focus = false;
         changed << item;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 2d84b43008..cb41adde87 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1621,6 +1621,36 @@ void QQuickItemPrivate::setAccessibleFlagAndListener()
     }
 }
 
+void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
+{
+    Q_Q(QQuickItem);
+    Q_ASSERT(scope);
+
+    QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
+
+    QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
+    // Correct focus chain in scope
+    if (oldSubFocusItem) {
+        QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
+        while (sfi != scope) {
+            QQuickItemPrivate::get(sfi)->subFocusItem = 0;
+            sfi = sfi->parentItem();
+        }
+    }
+
+    if (focus) {
+        scopePrivate->subFocusItem = q;
+        QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
+        while (sfi != scope) {
+            QQuickItemPrivate::get(sfi)->subFocusItem = q;
+            sfi = sfi->parentItem();
+        }
+    } else {
+        scopePrivate->subFocusItem = 0;
+    }
+}
+
+
 /*!
     \class QQuickItem
     \brief The QQuickItem class provides the most basic of all visual items in QML.
@@ -1895,18 +1925,17 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
         QQuickItem *scopeItem = 0;
 
         if (d->canvas && hasFocus()) {
-            scopeItem = oldParentItem;
-            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
             scopeFocusedItem = this;
         } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
-            scopeItem = oldParentItem;
-            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
             scopeFocusedItem = d->subFocusItem;
         }
 
-        if (scopeFocusedItem)
+        if (scopeFocusedItem) {
+            scopeItem = oldParentItem;
+            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
             QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
                                                                 QQuickCanvasPrivate::DontChangeFocusProperty);
+        }
 
         const bool wasVisible = isVisible();
         op->removeChild(this);
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 03fc66eadb..3443a38e95 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -475,6 +475,7 @@ public:
     void initCanvas(InitializationState *, QQuickCanvas *);
 
     QQuickItem *subFocusItem;
+    void updateSubFocusItem(QQuickItem *scope, bool focus);
 
     QTransform canvasToItemTransform() const;
     QTransform itemToCanvasTransform() const;
-- 
GitLab