aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qtquick1/qdeclarativefocusscope
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qtquick1/qdeclarativefocusscope')
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/chain.qml28
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/forceActiveFocus.qml26
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/forcefocus.qml81
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/qtBug13380.qml24
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/signalEmission.qml33
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/test.qml77
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/test2.qml39
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/test3.qml52
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/test4.qml76
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/data/test5.qml84
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp546
12 files changed, 1080 insertions, 0 deletions
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/chain.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/chain.qml
new file mode 100644
index 0000000000..a40bc2cdd6
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/chain.qml
@@ -0,0 +1,28 @@
+import QtQuick 1.0
+
+Rectangle {
+ id: root
+ width:300; height:400
+
+ property bool focus1: root.activeFocus
+ property bool focus2: item1.activeFocus
+ property bool focus3: fs1.activeFocus
+ property bool focus4: fs2.activeFocus
+ property bool focus5: theItem.activeFocus
+
+ Item {
+ id: item1
+ FocusScope {
+ id: fs1
+ focus: true
+ FocusScope {
+ id: fs2
+ focus: true
+ Item {
+ id: theItem
+ focus: true
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/forceActiveFocus.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/forceActiveFocus.qml
new file mode 100644
index 0000000000..6c39d4a432
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/forceActiveFocus.qml
@@ -0,0 +1,26 @@
+import QtQuick 1.0
+
+Rectangle {
+ objectName: "root"
+ FocusScope {
+ objectName: "scope"
+ Item {
+ objectName: "item-a1"
+ FocusScope {
+ objectName: "scope-a"
+ Item {
+ objectName: "item-a2"
+ }
+ }
+ }
+ Item {
+ objectName: "item-b1"
+ FocusScope {
+ objectName: "scope-b"
+ Item {
+ objectName: "item-b2"
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/forcefocus.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/forcefocus.qml
new file mode 100644
index 0000000000..708e899146
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/forcefocus.qml
@@ -0,0 +1,81 @@
+import QtQuick 1.0
+
+Rectangle {
+ width: 800; height: 600
+
+ FocusScope {
+ focus: true
+
+ FocusScope {
+ id: firstScope
+ objectName: "item0"
+ focus: true
+
+ Rectangle {
+ height: 120; width: 420
+
+ color: "transparent"
+ border.width: 5; border.color: firstScope.activeFocus?"blue":"black"
+
+ Rectangle {
+ id: item1; objectName: "item1"
+ x: 10; y: 10; width: 100; height: 100; color: "green"
+ border.width: 5; border.color: activeFocus?"blue":"black"
+ focus: true
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+
+ Rectangle {
+ id: item2; objectName: "item2"
+ x: 310; y: 10; width: 100; height: 100; color: "green"
+ border.width: 5; border.color: activeFocus?"blue":"black"
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+ }
+ }
+
+ FocusScope {
+ id: secondScope
+ objectName: "item3"
+
+ Rectangle {
+ y: 160; height: 120; width: 420
+
+ color: "transparent"
+ border.width: 5; border.color: secondScope.activeFocus?"blue":"black"
+
+ Rectangle {
+ id: item4; objectName: "item4"
+ x: 10; y: 10; width: 100; height: 100; color: "green"
+ border.width: 5; border.color: activeFocus?"blue":"black"
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+
+ Rectangle {
+ id: item5; objectName: "item5"
+ x: 310; y: 10; width: 100; height: 100; color: "green"
+ border.width: 5; border.color: activeFocus?"blue":"black"
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+ }
+ }
+ }
+ Keys.onDigit4Pressed: item4.focus = true
+ Keys.onDigit5Pressed: item5.forceActiveFocus()
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/qtBug13380.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/qtBug13380.qml
new file mode 100644
index 0000000000..1784202e77
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/qtBug13380.qml
@@ -0,0 +1,24 @@
+import QtQuick 1.0
+
+Rectangle {
+ width: 400; height: 400
+
+ property bool showRect: false
+ onShowRectChanged: if (showRect) rect.visible = true
+ property bool noFocus: !fs2.activeFocus
+
+ FocusScope {
+ id: fs1
+ focus: true
+ }
+ Rectangle {
+ id: rect
+ visible: false
+ FocusScope {
+ id: fs2
+ Rectangle {
+ focus: true
+ }
+ }
+ }
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/signalEmission.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/signalEmission.qml
new file mode 100644
index 0000000000..5850791704
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/signalEmission.qml
@@ -0,0 +1,33 @@
+import QtQuick 1.0
+
+Rectangle {
+ width: 200
+ height: 200
+
+ FocusScope {
+ focus: true
+ Rectangle {
+ objectName: "item1"
+ color: "blue"
+ onFocusChanged: focus ? color = "red" : color = "blue"
+ }
+ Rectangle {
+ objectName: "item2"
+ color: "blue"
+ onFocusChanged: focus ? color = "red" : color = "blue"
+ }
+ }
+
+ FocusScope {
+ Rectangle {
+ objectName: "item3"
+ color: "blue"
+ onFocusChanged: focus ? color = "red" : color = "blue"
+ }
+ Rectangle {
+ objectName: "item4"
+ color: "blue"
+ onFocusChanged: focus ? color = "red" : color = "blue"
+ }
+ }
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/test.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/test.qml
new file mode 100644
index 0000000000..5983c19015
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/test.qml
@@ -0,0 +1,77 @@
+import QtQuick 1.0
+
+Rectangle {
+ color: "white"
+ width: 800
+ height: 600
+
+ Keys.onDigit9Pressed: console.log("Error - Root")
+
+ FocusScope {
+ id: myScope
+ objectName: "item0"
+ focus: true
+
+ Keys.onDigit9Pressed: console.log("Error - FocusScope")
+
+ Rectangle {
+ height: 120
+ width: 420
+
+ color: "transparent"
+ border.width: 5
+ border.color: myScope.activeFocus?"blue":"black"
+
+ Rectangle {
+ id: item1; objectName: "item1"
+ x: 10; y: 10
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: activeFocus?"blue":"black"
+ Keys.onDigit9Pressed: console.debug("Top Left");
+ KeyNavigation.right: item2
+ focus: true
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+
+ Rectangle {
+ id: item2; objectName: "item2"
+ x: 310; y: 10
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: activeFocus?"blue":"black"
+ KeyNavigation.left: item1
+ Keys.onDigit9Pressed: console.log("Top Right");
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+ }
+ KeyNavigation.down: item3
+ }
+
+ Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box indicates active focus\nUse arrow keys to navigate\nPress \"9\" to print currently focused item" }
+
+ Rectangle {
+ id: item3; objectName: "item3"
+ x: 10; y: 300
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: activeFocus?"blue":"black"
+
+ Keys.onDigit9Pressed: console.log("Bottom Left");
+ KeyNavigation.up: myScope
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/test2.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/test2.qml
new file mode 100644
index 0000000000..8c0b3b4267
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/test2.qml
@@ -0,0 +1,39 @@
+import QtQuick 1.0
+
+Rectangle {
+ color: "white"
+ width: 800
+ height: 600
+
+ Text { text: "All five rectangles should be red" }
+
+ FocusScope {
+ y: 100
+ focus: true; objectName: "item1"
+ Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" }
+
+ FocusScope {
+ y: 100
+ focus: true; objectName: "item2"
+ Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" }
+
+ FocusScope {
+ y: 100
+ focus: true; objectName: "item3"
+ Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" }
+
+ FocusScope {
+ y: 100
+ focus: true; objectName: "item4"
+ Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" }
+
+ FocusScope {
+ y: 100
+ focus: true; objectName: "item5"
+ Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/test3.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/test3.qml
new file mode 100644
index 0000000000..2e025cb6cc
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/test3.qml
@@ -0,0 +1,52 @@
+import QtQuick 1.0
+
+Rectangle {
+ color: "white"
+ width: 800
+ height: 600
+
+ ListModel {
+ id: model
+ ListElement { name: "1" }
+ ListElement { name: "2" }
+ ListElement { name: "3" }
+ ListElement { name: "4" }
+ ListElement { name: "5" }
+ ListElement { name: "6" }
+ ListElement { name: "7" }
+ ListElement { name: "8" }
+ ListElement { name: "9" }
+ }
+
+ Component {
+ id: verticalDelegate
+ FocusScope {
+ id: root
+ width: 50; height: 50;
+ Keys.onDigit9Pressed: console.log("Error - " + name)
+ Rectangle {
+ focus: true
+ Keys.onDigit9Pressed: console.log(name)
+ width: 50; height: 50;
+ color: root.ListView.isCurrentItem?"red":"green"
+ Text { text: name; anchors.centerIn: parent }
+ }
+ }
+ }
+
+ ListView {
+ width: 800; height: 50; orientation: "Horizontal"
+ focus: true
+ model: model
+ delegate: verticalDelegate
+ preferredHighlightBegin: 100
+ preferredHighlightEnd: 100
+ highlightRangeMode: "StrictlyEnforceRange"
+ }
+
+
+ Text {
+ y: 100; x: 50
+ text: "Currently selected element should be red\nPressing \"9\" should print the number of the currently selected item\nBe sure to scroll all the way to the right, pause, and then all the way to the left."
+ }
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/test4.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/test4.qml
new file mode 100644
index 0000000000..7192dee6db
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/test4.qml
@@ -0,0 +1,76 @@
+import QtQuick 1.0
+
+Rectangle {
+ color: "white"
+ width: 800
+ height: 600
+
+ Keys.onDigit9Pressed: console.log("Error - Root")
+
+ FocusScope {
+ id: myScope
+
+ Keys.onDigit9Pressed: console.log("Error - FocusScope")
+
+ Rectangle {
+ objectName: "item0"
+ height: 120
+ width: 420
+
+ color: "transparent"
+ border.width: 5
+ border.color: myScope.activeFocus?"blue":"black"
+
+ Rectangle {
+ id: item1; objectName: "item1"
+ x: 10; y: 10
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: activeFocus?"blue":"black"
+ Keys.onDigit9Pressed: console.log("Error - Top Left");
+ KeyNavigation.right: item2
+ focus: true
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+
+ Rectangle {
+ id: item2; objectName: "item2"
+ x: 310; y: 10
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: activeFocus?"blue":"black"
+ KeyNavigation.left: item1
+ Keys.onDigit9Pressed: console.log("Error - Top Right");
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+ }
+ KeyNavigation.down: item3
+ }
+
+ Text { x:100; y:170; text: "There should be no blue borders, or red squares.\nPressing \"9\" should do nothing.\nArrow keys should have no effect." }
+
+ Rectangle {
+ id: item3; objectName: "item3"
+ x: 10; y: 300
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: activeFocus?"blue":"black"
+
+ Keys.onDigit9Pressed: console.log("Error - Bottom Left");
+ KeyNavigation.up: myScope
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/data/test5.qml b/tests/auto/qtquick1/qdeclarativefocusscope/data/test5.qml
new file mode 100644
index 0000000000..01dada5d37
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/data/test5.qml
@@ -0,0 +1,84 @@
+import QtQuick 1.0
+
+Rectangle {
+ color: "white"
+ width: 800
+ height: 600
+
+ Keys.onReturnPressed: console.log("Error - Root")
+
+ FocusScope {
+ id: myScope
+ objectName: "item0"
+ focus: true
+
+ Keys.onReturnPressed: console.log("Error - FocusScope")
+
+ Rectangle {
+ height: 120
+ width: 420
+
+ color: "transparent"
+ border.width: 5
+ border.color: myScope.activeFocus?"blue":"black"
+
+ Rectangle {
+ x: 10; y: 10
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: item1.activeFocus?"blue":"black"
+ }
+
+ TextEdit {
+ id: item1; objectName: "item1"
+ x: 20; y: 20
+ width: 90; height: 90
+ color: "white"
+ font.pixelSize: 20
+ Keys.onReturnPressed: console.log("Top Left");
+ KeyNavigation.right: item2
+ focus: true
+ wrapMode: TextEdit.WordWrap
+ text: "Box 1"
+ }
+
+ Rectangle {
+ id: item2; objectName: "item2"
+ x: 310; y: 10
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: activeFocus?"blue":"black"
+ KeyNavigation.left: item1
+ Keys.onReturnPressed: console.log("Top Right");
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+ }
+ KeyNavigation.down: item3
+ }
+
+ Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box or flashing cursor indicates active focus\nUse arrow keys to navigate\nPress Ctrl-Return to print currently focused item" }
+
+ Rectangle {
+ x: 10; y: 300
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: item3.activeFocus?"blue":"black"
+ }
+
+ TextEdit {
+ id: item3; objectName: "item3"
+ x: 20; y: 310
+ width: 90; height: 90
+ color: "white"
+ font.pixelSize: 20
+ text: "Box 3"
+
+ Keys.onReturnPressed: console.log("Bottom Left");
+ KeyNavigation.up: myScope
+ wrapMode: TextEdit.WordWrap
+ }
+}
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro b/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro
new file mode 100644
index 0000000000..f532585b89
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro
@@ -0,0 +1,14 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative qtquick1
+SOURCES += tst_qdeclarativefocusscope.cpp
+macx:CONFIG -= app_bundle
+
+symbian: {
+ importFiles.files = data
+ importFiles.path = .
+ DEPLOYMENT += importFiles
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+}
+
+QT += core-private gui-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp b/tests/auto/qtquick1/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp
new file mode 100644
index 0000000000..50cca1d53d
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp
@@ -0,0 +1,546 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QSignalSpy>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtQuick1/qdeclarativeview.h>
+#include <QtQuick1/private/qdeclarativerectangle_p.h>
+#include <QtQuick1/private/qdeclarativetextedit_p.h>
+#include <QtQuick1/private/qdeclarativetext_p.h>
+#include <QtQuick1/private/qdeclarativefocusscope_p.h>
+
+#ifdef Q_OS_SYMBIAN
+// In Symbian OS test data is located in applications private dir
+#define SRCDIR "."
+#endif
+
+class tst_qdeclarativefocusscope : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qdeclarativefocusscope() {}
+
+ template<typename T>
+ T *findItem(QGraphicsObject *parent, const QString &id);
+
+private slots:
+ void basic();
+ void nested();
+ void noFocus();
+ void textEdit();
+ void forceFocus();
+ void noParentFocus();
+ void signalEmission();
+ void qtBug13380();
+ void forceActiveFocus();
+};
+
+/*
+ Find an item with the specified id.
+*/
+template<typename T>
+T *tst_qdeclarativefocusscope::findItem(QGraphicsObject *parent, const QString &objectName)
+{
+ const QMetaObject &mo = T::staticMetaObject;
+ QList<QGraphicsItem *> children = parent->childItems();
+ for (int i = 0; i < children.count(); ++i) {
+ QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(children.at(i)->toGraphicsObject());
+ if (item) {
+ if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+ return static_cast<T*>(item);
+ }
+ item = findItem<T>(item, objectName);
+ if (item)
+ return static_cast<T*>(item);
+ }
+ }
+ return 0;
+}
+
+void tst_qdeclarativefocusscope::basic()
+{
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test.qml"));
+
+ QDeclarative1FocusScope *item0 = findItem<QDeclarative1FocusScope>(view->rootObject(), QLatin1String("item0"));
+ QDeclarative1Rectangle *item1 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item1"));
+ QDeclarative1Rectangle *item2 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarative1Rectangle *item3 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item3"));
+ QVERIFY(item0 != 0);
+ QVERIFY(item1 != 0);
+ QVERIFY(item2 != 0);
+ QVERIFY(item3 != 0);
+
+ view->show();
+ qApp->setActiveWindow(view);
+ qApp->processEvents();
+
+#ifdef Q_WS_X11
+ // to be safe and avoid failing setFocus with window managers
+ qt_x11_wait_for_window_manager(view);
+#endif
+
+ QVERIFY(view->hasFocus());
+ QVERIFY(view->scene()->hasFocus());
+ QVERIFY(item0->hasActiveFocus() == true);
+ QVERIFY(item1->hasActiveFocus() == true);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == false);
+
+ QTest::keyClick(view, Qt::Key_Right);
+ QVERIFY(item0->hasActiveFocus() == true);
+ QVERIFY(item1->hasActiveFocus() == false);
+ QVERIFY(item2->hasActiveFocus() == true);
+ QVERIFY(item3->hasActiveFocus() == false);
+
+ QTest::keyClick(view, Qt::Key_Down);
+ QVERIFY(item0->hasActiveFocus() == false);
+ QVERIFY(item1->hasActiveFocus() == false);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == true);
+
+ delete view;
+}
+
+void tst_qdeclarativefocusscope::nested()
+{
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test2.qml"));
+
+ QDeclarative1FocusScope *item1 = findItem<QDeclarative1FocusScope>(view->rootObject(), QLatin1String("item1"));
+ QDeclarative1FocusScope *item2 = findItem<QDeclarative1FocusScope>(view->rootObject(), QLatin1String("item2"));
+ QDeclarative1FocusScope *item3 = findItem<QDeclarative1FocusScope>(view->rootObject(), QLatin1String("item3"));
+ QDeclarative1FocusScope *item4 = findItem<QDeclarative1FocusScope>(view->rootObject(), QLatin1String("item4"));
+ QDeclarative1FocusScope *item5 = findItem<QDeclarative1FocusScope>(view->rootObject(), QLatin1String("item5"));
+ QVERIFY(item1 != 0);
+ QVERIFY(item2 != 0);
+ QVERIFY(item3 != 0);
+ QVERIFY(item4 != 0);
+ QVERIFY(item5 != 0);
+
+ view->show();
+ qApp->setActiveWindow(view);
+ qApp->processEvents();
+
+#ifdef Q_WS_X11
+ // to be safe and avoid failing setFocus with window managers
+ qt_x11_wait_for_window_manager(view);
+#endif
+
+ QVERIFY(view->hasFocus());
+ QVERIFY(view->scene()->hasFocus());
+
+ QVERIFY(item1->hasActiveFocus() == true);
+ QVERIFY(item2->hasActiveFocus() == true);
+ QVERIFY(item3->hasActiveFocus() == true);
+ QVERIFY(item4->hasActiveFocus() == true);
+ QVERIFY(item5->hasActiveFocus() == true);
+ delete view;
+}
+
+void tst_qdeclarativefocusscope::noFocus()
+{
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test4.qml"));
+
+ QDeclarative1Rectangle *item0 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item0"));
+ QDeclarative1Rectangle *item1 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item1"));
+ QDeclarative1Rectangle *item2 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarative1Rectangle *item3 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item3"));
+ QVERIFY(item0 != 0);
+ QVERIFY(item1 != 0);
+ QVERIFY(item2 != 0);
+ QVERIFY(item3 != 0);
+
+ view->show();
+ qApp->setActiveWindow(view);
+ qApp->processEvents();
+
+#ifdef Q_WS_X11
+ // to be safe and avoid failing setFocus with window managers
+ qt_x11_wait_for_window_manager(view);
+#endif
+
+ QVERIFY(view->hasFocus());
+ QVERIFY(view->scene()->hasFocus());
+ QVERIFY(item0->hasActiveFocus() == false);
+ QVERIFY(item1->hasActiveFocus() == false);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == false);
+
+ QTest::keyClick(view, Qt::Key_Right);
+ QVERIFY(item0->hasActiveFocus() == false);
+ QVERIFY(item1->hasActiveFocus() == false);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == false);
+
+ QTest::keyClick(view, Qt::Key_Down);
+ QVERIFY(item0->hasActiveFocus() == false);
+ QVERIFY(item1->hasActiveFocus() == false);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == false);
+
+ delete view;
+}
+
+void tst_qdeclarativefocusscope::textEdit()
+{
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test5.qml"));
+
+ QDeclarative1FocusScope *item0 = findItem<QDeclarative1FocusScope>(view->rootObject(), QLatin1String("item0"));
+ QDeclarative1TextEdit *item1 = findItem<QDeclarative1TextEdit>(view->rootObject(), QLatin1String("item1"));
+ QDeclarative1Rectangle *item2 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarative1TextEdit *item3 = findItem<QDeclarative1TextEdit>(view->rootObject(), QLatin1String("item3"));
+ QVERIFY(item0 != 0);
+ QVERIFY(item1 != 0);
+ QVERIFY(item2 != 0);
+ QVERIFY(item3 != 0);
+
+ view->show();
+ qApp->setActiveWindow(view);
+ qApp->processEvents();
+
+#ifdef Q_WS_X11
+ // to be safe and avoid failing setFocus with window managers
+ qt_x11_wait_for_window_manager(view);
+#endif
+
+ QVERIFY(view->hasFocus());
+ QVERIFY(view->scene()->hasFocus());
+ QVERIFY(item0->hasActiveFocus() == true);
+ QVERIFY(item1->hasActiveFocus() == true);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == false);
+
+ QTest::keyClick(view, Qt::Key_Right);
+ QVERIFY(item0->hasActiveFocus() == true);
+ QVERIFY(item1->hasActiveFocus() == true);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == false);
+
+ QTest::keyClick(view, Qt::Key_Right);
+ QTest::keyClick(view, Qt::Key_Right);
+ QTest::keyClick(view, Qt::Key_Right);
+ QTest::keyClick(view, Qt::Key_Right);
+ QTest::keyClick(view, Qt::Key_Right);
+ QVERIFY(item0->hasActiveFocus() == true);
+ QVERIFY(item1->hasActiveFocus() == false);
+ QVERIFY(item2->hasActiveFocus() == true);
+ QVERIFY(item3->hasActiveFocus() == false);
+
+ QTest::keyClick(view, Qt::Key_Down);
+ QVERIFY(item0->hasActiveFocus() == false);
+ QVERIFY(item1->hasActiveFocus() == false);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == true);
+
+ delete view;
+}
+
+void tst_qdeclarativefocusscope::forceFocus()
+{
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/forcefocus.qml"));
+
+ QDeclarative1FocusScope *item0 = findItem<QDeclarative1FocusScope>(view->rootObject(), QLatin1String("item0"));
+ QDeclarative1Rectangle *item1 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item1"));
+ QDeclarative1Rectangle *item2 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarative1FocusScope *item3 = findItem<QDeclarative1FocusScope>(view->rootObject(), QLatin1String("item3"));
+ QDeclarative1Rectangle *item4 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item4"));
+ QDeclarative1Rectangle *item5 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item5"));
+ QVERIFY(item0 != 0);
+ QVERIFY(item1 != 0);
+ QVERIFY(item2 != 0);
+ QVERIFY(item3 != 0);
+ QVERIFY(item4 != 0);
+ QVERIFY(item5 != 0);
+
+ view->show();
+ qApp->setActiveWindow(view);
+ qApp->processEvents();
+
+#ifdef Q_WS_X11
+ // to be safe and avoid failing setFocus with window managers
+ qt_x11_wait_for_window_manager(view);
+#endif
+
+ QVERIFY(view->hasFocus());
+ QVERIFY(view->scene()->hasFocus());
+ QVERIFY(item0->hasActiveFocus() == true);
+ QVERIFY(item1->hasActiveFocus() == true);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == false);
+ QVERIFY(item4->hasActiveFocus() == false);
+ QVERIFY(item5->hasActiveFocus() == false);
+
+ QTest::keyClick(view, Qt::Key_4);
+ QVERIFY(item0->hasActiveFocus() == true);
+ QVERIFY(item1->hasActiveFocus() == true);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == false);
+ QVERIFY(item4->hasActiveFocus() == false);
+ QVERIFY(item5->hasActiveFocus() == false);
+
+ QTest::keyClick(view, Qt::Key_5);
+ QVERIFY(item0->hasActiveFocus() == false);
+ QVERIFY(item1->hasActiveFocus() == false);
+ QVERIFY(item2->hasActiveFocus() == false);
+ QVERIFY(item3->hasActiveFocus() == true);
+ QVERIFY(item4->hasActiveFocus() == false);
+ QVERIFY(item5->hasActiveFocus() == true);
+
+ delete view;
+}
+
+void tst_qdeclarativefocusscope::noParentFocus()
+{
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/chain.qml"));
+ QVERIFY(view->rootObject());
+
+ QVERIFY(view->rootObject()->property("focus1") == false);
+ QVERIFY(view->rootObject()->property("focus2") == false);
+ QVERIFY(view->rootObject()->property("focus3") == true);
+ QVERIFY(view->rootObject()->property("focus4") == true);
+ QVERIFY(view->rootObject()->property("focus5") == true);
+
+ delete view;
+}
+
+void tst_qdeclarativefocusscope::signalEmission()
+{
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/signalEmission.qml"));
+
+ QDeclarative1Rectangle *item1 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item1"));
+ QDeclarative1Rectangle *item2 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarative1Rectangle *item3 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item3"));
+ QDeclarative1Rectangle *item4 = findItem<QDeclarative1Rectangle>(view->rootObject(), QLatin1String("item4"));
+ QVERIFY(item1 != 0);
+ QVERIFY(item2 != 0);
+ QVERIFY(item3 != 0);
+ QVERIFY(item4 != 0);
+
+ view->show();
+ qApp->setActiveWindow(view);
+ qApp->processEvents();
+
+#ifdef Q_WS_X11
+ // to be safe and avoid failing setFocus with window managers
+ qt_x11_wait_for_window_manager(view);
+#endif
+
+ QVariant blue(QColor("blue"));
+ QVariant red(QColor("red"));
+
+ QVERIFY(view->hasFocus());
+ QVERIFY(view->scene()->hasFocus());
+ item1->setFocus(true);
+ QCOMPARE(item1->property("color"), red);
+ QCOMPARE(item2->property("color"), blue);
+ QCOMPARE(item3->property("color"), blue);
+ QCOMPARE(item4->property("color"), blue);
+
+ item2->setFocus(true);
+ QCOMPARE(item1->property("color"), blue);
+ QCOMPARE(item2->property("color"), red);
+ QCOMPARE(item3->property("color"), blue);
+ QCOMPARE(item4->property("color"), blue);
+
+ item3->setFocus(true);
+ QCOMPARE(item1->property("color"), blue);
+ QCOMPARE(item2->property("color"), red);
+ QCOMPARE(item3->property("color"), red);
+ QCOMPARE(item4->property("color"), blue);
+
+ item4->setFocus(true);
+ QCOMPARE(item1->property("color"), blue);
+ QCOMPARE(item2->property("color"), red);
+ QCOMPARE(item3->property("color"), blue);
+ QCOMPARE(item4->property("color"), red);
+
+ item4->setFocus(false);
+ QCOMPARE(item1->property("color"), blue);
+ QCOMPARE(item2->property("color"), red);
+ QCOMPARE(item3->property("color"), blue);
+ QCOMPARE(item4->property("color"), blue);
+
+ delete view;
+}
+
+void tst_qdeclarativefocusscope::qtBug13380()
+{
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtBug13380.qml"));
+
+ view->show();
+ QVERIFY(view->rootObject());
+ qApp->setActiveWindow(view);
+ qApp->processEvents();
+
+#ifdef Q_WS_X11
+ // to be safe and avoid failing setFocus with window managers
+ qt_x11_wait_for_window_manager(view);
+#endif
+
+ QVERIFY(view->hasFocus());
+ QVERIFY(view->scene()->hasFocus());
+ QVERIFY(view->rootObject()->property("noFocus").toBool());
+
+ view->rootObject()->setProperty("showRect", true);
+ QVERIFY(view->rootObject()->property("noFocus").toBool());
+
+ delete view;
+}
+
+void tst_qdeclarativefocusscope::forceActiveFocus()
+{
+ QDeclarativeView *view = new QDeclarativeView;
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/forceActiveFocus.qml"));
+
+ QGraphicsObject *rootObject = view->rootObject();
+ QVERIFY(rootObject);
+
+ QDeclarativeItem *scope = findItem<QDeclarativeItem>(rootObject, QLatin1String("scope"));
+ QDeclarativeItem *itemA1 = findItem<QDeclarativeItem>(rootObject, QLatin1String("item-a1"));
+ QDeclarativeItem *scopeA = findItem<QDeclarativeItem>(rootObject, QLatin1String("scope-a"));
+ QDeclarativeItem *itemA2 = findItem<QDeclarativeItem>(rootObject, QLatin1String("item-a2"));
+ QDeclarativeItem *itemB1 = findItem<QDeclarativeItem>(rootObject, QLatin1String("item-b1"));
+ QDeclarativeItem *scopeB = findItem<QDeclarativeItem>(rootObject, QLatin1String("scope-b"));
+ QDeclarativeItem *itemB2 = findItem<QDeclarativeItem>(rootObject, QLatin1String("item-b2"));
+
+ QVERIFY(scope);
+ QVERIFY(itemA1);
+ QVERIFY(scopeA);
+ QVERIFY(itemA2);
+ QVERIFY(itemB1);
+ QVERIFY(scopeB);
+ QVERIFY(itemB2);
+
+ QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool)));
+ QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool)));
+ QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool)));
+ QSignalSpy scopeBSpy(scopeB, SIGNAL(activeFocusChanged(bool)));
+
+ // First, walk the focus from item-a1 down to item-a2 and back again
+ itemA1->forceActiveFocus();
+ QVERIFY(itemA1->hasActiveFocus());
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ scopeA->forceActiveFocus();
+ QVERIFY(!itemA1->hasActiveFocus());
+ QVERIFY(scopeA->hasActiveFocus());
+ QCOMPARE(scopeASpy.count(), 1);
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ itemA2->forceActiveFocus();
+ QVERIFY(!itemA1->hasActiveFocus());
+ QVERIFY(itemA2->hasActiveFocus());
+ QVERIFY(scopeA->hasActiveFocus());
+ QCOMPARE(scopeASpy.count(), 1);
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ scopeA->forceActiveFocus();
+ QVERIFY(!itemA1->hasActiveFocus());
+ QVERIFY(itemA2->hasActiveFocus());
+ QVERIFY(scopeA->hasActiveFocus());
+ QCOMPARE(scopeASpy.count(), 1);
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ itemA1->forceActiveFocus();
+ QVERIFY(itemA1->hasActiveFocus());
+ QVERIFY(!scopeA->hasActiveFocus());
+ QVERIFY(!itemA2->hasActiveFocus());
+ QCOMPARE(scopeASpy.count(), 2);
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ // Then jump back and forth between branch 'a' and 'b'
+ itemB1->forceActiveFocus();
+ QVERIFY(itemB1->hasActiveFocus());
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ scopeA->forceActiveFocus();
+ QVERIFY(!itemA1->hasActiveFocus());
+ QVERIFY(!itemB1->hasActiveFocus());
+ QVERIFY(scopeA->hasActiveFocus());
+ QCOMPARE(scopeASpy.count(), 3);
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ scopeB->forceActiveFocus();
+ QVERIFY(!scopeA->hasActiveFocus());
+ QVERIFY(!itemB1->hasActiveFocus());
+ QVERIFY(scopeB->hasActiveFocus());
+ QCOMPARE(scopeASpy.count(), 4);
+ QCOMPARE(scopeBSpy.count(), 1);
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ itemA2->forceActiveFocus();
+ QVERIFY(!scopeB->hasActiveFocus());
+ QVERIFY(itemA2->hasActiveFocus());
+ QCOMPARE(scopeASpy.count(), 5);
+ QCOMPARE(scopeBSpy.count(), 2);
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ itemB2->forceActiveFocus();
+ QVERIFY(!itemA2->hasActiveFocus());
+ QVERIFY(itemB2->hasActiveFocus());
+ QCOMPARE(scopeASpy.count(), 6);
+ QCOMPARE(scopeBSpy.count(), 3);
+ QCOMPARE(rootSpy.count(), 1);
+ QCOMPARE(scopeSpy.count(), 1);
+
+ delete view;
+}
+
+QTEST_MAIN(tst_qdeclarativefocusscope)
+
+#include "tst_qdeclarativefocusscope.moc"