aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/declarative/qdeclarativefocusscope
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/declarative/qdeclarativefocusscope')
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/chain.qml28
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/forceActiveFocus.qml26
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/forcefocus.qml81
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/qtBug13380.qml24
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/signalEmission.qml33
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/test.qml77
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/test2.qml39
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/test3.qml52
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/test4.qml76
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/test5.qml84
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro13
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp546
12 files changed, 1079 insertions, 0 deletions
diff --git a/tests/auto/declarative/qdeclarativefocusscope/data/chain.qml b/tests/auto/declarative/qdeclarativefocusscope/data/chain.qml
new file mode 100644
index 0000000000..a40bc2cdd6
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/data/forceActiveFocus.qml b/tests/auto/declarative/qdeclarativefocusscope/data/forceActiveFocus.qml
new file mode 100644
index 0000000000..6c39d4a432
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/data/forcefocus.qml b/tests/auto/declarative/qdeclarativefocusscope/data/forcefocus.qml
new file mode 100644
index 0000000000..708e899146
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/data/qtBug13380.qml b/tests/auto/declarative/qdeclarativefocusscope/data/qtBug13380.qml
new file mode 100644
index 0000000000..1784202e77
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/data/signalEmission.qml b/tests/auto/declarative/qdeclarativefocusscope/data/signalEmission.qml
new file mode 100644
index 0000000000..5850791704
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/data/test.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test.qml
new file mode 100644
index 0000000000..5983c19015
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/data/test2.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test2.qml
new file mode 100644
index 0000000000..8c0b3b4267
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/data/test3.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test3.qml
new file mode 100644
index 0000000000..2e025cb6cc
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/data/test4.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test4.qml
new file mode 100644
index 0000000000..7192dee6db
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/data/test5.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test5.qml
new file mode 100644
index 0000000000..01dada5d37
--- /dev/null
+++ b/tests/auto/declarative/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/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro b/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro
new file mode 100644
index 0000000000..eab983ffe4
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro
@@ -0,0 +1,13 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative
+SOURCES += tst_qdeclarativefocusscope.cpp
+macx:CONFIG -= app_bundle
+
+symbian: {
+ importFiles.files = data
+ importFiles.path = .
+ DEPLOYMENT += importFiles
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+}
+
diff --git a/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp b/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp
new file mode 100644
index 0000000000..9c6b888c91
--- /dev/null
+++ b/tests/auto/declarative/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QSignalSpy>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativeview.h>
+#include <private/qdeclarativerectangle_p.h>
+#include <private/qdeclarativetextedit_p.h>
+#include <private/qdeclarativetext_p.h>
+#include <QtDeclarative/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"));
+
+ QDeclarativeFocusScope *item0 = findItem<QDeclarativeFocusScope>(view->rootObject(), QLatin1String("item0"));
+ QDeclarativeRectangle *item1 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item1"));
+ QDeclarativeRectangle *item2 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarativeRectangle *item3 = findItem<QDeclarativeRectangle>(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"));
+
+ QDeclarativeFocusScope *item1 = findItem<QDeclarativeFocusScope>(view->rootObject(), QLatin1String("item1"));
+ QDeclarativeFocusScope *item2 = findItem<QDeclarativeFocusScope>(view->rootObject(), QLatin1String("item2"));
+ QDeclarativeFocusScope *item3 = findItem<QDeclarativeFocusScope>(view->rootObject(), QLatin1String("item3"));
+ QDeclarativeFocusScope *item4 = findItem<QDeclarativeFocusScope>(view->rootObject(), QLatin1String("item4"));
+ QDeclarativeFocusScope *item5 = findItem<QDeclarativeFocusScope>(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"));
+
+ QDeclarativeRectangle *item0 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item0"));
+ QDeclarativeRectangle *item1 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item1"));
+ QDeclarativeRectangle *item2 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarativeRectangle *item3 = findItem<QDeclarativeRectangle>(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"));
+
+ QDeclarativeFocusScope *item0 = findItem<QDeclarativeFocusScope>(view->rootObject(), QLatin1String("item0"));
+ QDeclarativeTextEdit *item1 = findItem<QDeclarativeTextEdit>(view->rootObject(), QLatin1String("item1"));
+ QDeclarativeRectangle *item2 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarativeTextEdit *item3 = findItem<QDeclarativeTextEdit>(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"));
+
+ QDeclarativeFocusScope *item0 = findItem<QDeclarativeFocusScope>(view->rootObject(), QLatin1String("item0"));
+ QDeclarativeRectangle *item1 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item1"));
+ QDeclarativeRectangle *item2 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarativeFocusScope *item3 = findItem<QDeclarativeFocusScope>(view->rootObject(), QLatin1String("item3"));
+ QDeclarativeRectangle *item4 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item4"));
+ QDeclarativeRectangle *item5 = findItem<QDeclarativeRectangle>(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"));
+
+ QDeclarativeRectangle *item1 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item1"));
+ QDeclarativeRectangle *item2 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item2"));
+ QDeclarativeRectangle *item3 = findItem<QDeclarativeRectangle>(view->rootObject(), QLatin1String("item3"));
+ QDeclarativeRectangle *item4 = findItem<QDeclarativeRectangle>(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"