aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickitem.cpp41
-rw-r--r--src/quick/items/qquickitem.h1
-rw-r--r--src/quick/items/qquickitem_p.h1
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp75
4 files changed, 112 insertions, 6 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 59ab56dc66..7e606eb282 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2044,6 +2044,18 @@ QQuickItem::~QQuickItem()
*/
bool QQuickItemPrivate::focusNextPrev(QQuickItem *item, bool forward)
{
+ QQuickItem *next = QQuickItemPrivate::nextPrevItemInTabFocusChain(item, forward);
+
+ if (next == item)
+ return false;
+
+ next->forceActiveFocus(forward ? Qt::TabFocusReason : Qt::BacktabFocusReason);
+
+ return true;
+}
+
+QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward)
+{
Q_ASSERT(item);
Q_ASSERT(item->activeFocusOnTab());
@@ -2111,12 +2123,7 @@ bool QQuickItemPrivate::focusNextPrev(QQuickItem *item, bool forward)
from = last;
} while (skip || !current->activeFocusOnTab() || !current->isEnabled() || !current->isVisible());
- if (current == item)
- return false;
-
- current->forceActiveFocus(forward ? Qt::TabFocusReason : Qt::BacktabFocusReason);
-
- return true;
+ return current;
}
/*!
@@ -3928,6 +3935,28 @@ void QQuickItem::forceActiveFocus(Qt::FocusReason reason)
}
/*!
+ \qmlmethod QtQuick2::Item::nextItemInFocusChain(bool forward)
+
+ \since QtQuick 2.1
+
+ Returns the item in the focus chain which is next to this item.
+ If \a forward is \c true, or not supplied, it is the next item in
+ the forwards direction. If \a forward is \c false, it is the next
+ item in the backwards direction.
+*/
+/*!
+ Returns the item in the focus chain which is next to this item.
+ If \a forward is \c true, or not supplied, it is the next item in
+ the forwards direction. If \a forward is \c false, it is the next
+ item in the backwards direction.
+*/
+
+QQuickItem *QQuickItem::nextItemInFocusChain(bool forward)
+{
+ return QQuickItemPrivate::nextPrevItemInTabFocusChain(this, forward);
+}
+
+/*!
\qmlmethod QtQuick2::Item::childAt(real x, real y)
Returns the first visible child item found at point (\a x, \a y) within
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 5dea86296f..078df2ea84 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -324,6 +324,7 @@ public:
Q_INVOKABLE void mapToItem(QQmlV8Function*) const;
Q_INVOKABLE void forceActiveFocus();
Q_INVOKABLE void forceActiveFocus(Qt::FocusReason reason);
+ Q_INVOKABLE QQuickItem *nextItemInFocusChain(bool forward = true);
Q_INVOKABLE QQuickItem *childAt(qreal x, qreal y) const;
#ifndef QT_NO_IM
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 4bd9d82c20..3602b578e2 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -485,6 +485,7 @@ public:
void itemToParentTransform(QTransform &) const;
static bool focusNextPrev(QQuickItem *item, bool forward);
+ static QQuickItem *nextPrevItemInTabFocusChain(QQuickItem *item, bool forward);
qreal x;
qreal y;
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index f2d25e81ed..3ec77ce950 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -70,6 +70,8 @@ private slots:
void activeFocusOnTab4();
void activeFocusOnTab5();
+ void nextItemInFocusChain();
+
void keys();
void keysProcessingOrder();
void keysim();
@@ -664,6 +666,79 @@ void tst_QQuickItem::activeFocusOnTab5()
delete window;
}
+void tst_QQuickItem::nextItemInFocusChain()
+{
+ QQuickView *window = new QQuickView(0);
+ window->setBaseSize(QSize(800,600));
+
+ window->setSource(testFileUrl("activeFocusOnTab.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+
+ QQuickItem *button11 = findItem<QQuickItem>(window->rootObject(), "button11");
+ QVERIFY(button11);
+ QQuickItem *button12 = findItem<QQuickItem>(window->rootObject(), "button12");
+ QVERIFY(button12);
+
+ QQuickItem *sub2 = findItem<QQuickItem>(window->rootObject(), "sub2");
+ QVERIFY(sub2);
+ QQuickItem *button21 = findItem<QQuickItem>(window->rootObject(), "button21");
+ QVERIFY(button21);
+ QQuickItem *button22 = findItem<QQuickItem>(window->rootObject(), "button22");
+ QVERIFY(button22);
+
+ QQuickItem *edit = findItem<QQuickItem>(window->rootObject(), "edit");
+ QVERIFY(edit);
+
+ QQuickItem *next, *prev;
+
+ next = button11->nextItemInFocusChain(true);
+ QVERIFY(next);
+ QCOMPARE(next, button12);
+ prev = button11->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, edit);
+
+ next = button12->nextItemInFocusChain();
+ QVERIFY(next);
+ QCOMPARE(next, sub2);
+ prev = button12->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button11);
+
+ next = sub2->nextItemInFocusChain(true);
+ QVERIFY(next);
+ QCOMPARE(next, button21);
+ prev = sub2->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button12);
+
+ next = button21->nextItemInFocusChain();
+ QVERIFY(next);
+ QCOMPARE(next, button22);
+ prev = button21->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, sub2);
+
+ next = button22->nextItemInFocusChain(true);
+ QVERIFY(next);
+ QCOMPARE(next, edit);
+ prev = button22->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button21);
+
+ next = edit->nextItemInFocusChain();
+ QVERIFY(next);
+ QCOMPARE(next, button11);
+ prev = edit->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button22);
+
+ delete window;
+}
+
void tst_QQuickItem::keys()
{
QQuickView *window = new QQuickView(0);