aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quickcontrols2/qquicktumblerview.cpp2
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp4
-rw-r--r--src/quicktemplates2/qquickcontainer.cpp6
-rw-r--r--src/quicktemplates2/qquickmenu.cpp42
-rw-r--r--src/quicktemplates2/qquickmenu_p_p.h3
-rw-r--r--tests/auto/controls/data/tst_combobox.qml25
-rw-r--r--tests/auto/controls/data/tst_container.qml27
-rw-r--r--tests/auto/menu/tst_menu.cpp113
8 files changed, 192 insertions, 30 deletions
diff --git a/src/quickcontrols2/qquicktumblerview.cpp b/src/quickcontrols2/qquicktumblerview.cpp
index 59f443d5..817ec370 100644
--- a/src/quickcontrols2/qquicktumblerview.cpp
+++ b/src/quickcontrols2/qquicktumblerview.cpp
@@ -170,7 +170,7 @@ void QQuickTumblerView::createView()
}
}
-// Called whever the size or visibleItemCount changes.
+// Called whenever the size or visibleItemCount changes.
void QQuickTumblerView::updateView()
{
QQuickItem *theView = view();
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index a6f9f6ca..dceda7d7 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -204,6 +204,10 @@ QString QQuickComboBoxDelegateModel::stringValue(int index, const QString &role)
if (data.count() == 1 && role == QLatin1String("modelData"))
return data.first().toString();
return data.value(role).toString();
+ } else if (object.userType() == QMetaType::QObjectStar) {
+ const QObject *data = object.value<QObject *>();
+ if (data && role != QLatin1String("modelData"))
+ return data->property(role.toUtf8()).toString();
}
}
return QQmlDelegateModel::stringValue(index, role);
diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp
index 9b8298c2..eaf18714 100644
--- a/src/quicktemplates2/qquickcontainer.cpp
+++ b/src/quicktemplates2/qquickcontainer.cpp
@@ -350,10 +350,14 @@ void QQuickContainerPrivate::itemSiblingOrderChanged(QQuickItem *)
// reorder the restacked items (eg. by a Repeater)
Q_Q(QQuickContainer);
QList<QQuickItem *> siblings = effectiveContentItem(contentItem)->childItems();
+
+ int to = 0;
for (int i = 0; i < siblings.count(); ++i) {
QQuickItem* sibling = siblings.at(i);
+ if (QQuickItemPrivate::get(sibling)->isTransparentForPositioner())
+ continue;
int index = contentModel->indexOf(sibling, nullptr);
- q->moveItem(index, i);
+ q->moveItem(index, to++);
}
}
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp
index 5a2ad066..8639e504 100644
--- a/src/quicktemplates2/qquickmenu.cpp
+++ b/src/quicktemplates2/qquickmenu.cpp
@@ -330,10 +330,14 @@ void QQuickMenuPrivate::itemSiblingOrderChanged(QQuickItem *)
// reorder the restacked items (eg. by a Repeater)
Q_Q(QQuickMenu);
QList<QQuickItem *> siblings = contentItem->childItems();
+
+ int to = 0;
for (int i = 0; i < siblings.count(); ++i) {
QQuickItem* sibling = siblings.at(i);
+ if (QQuickItemPrivate::get(sibling)->isTransparentForPositioner())
+ continue;
int index = contentModel->indexOf(sibling, nullptr);
- q->moveItem(index, i);
+ q->moveItem(index, to++);
}
}
@@ -513,6 +517,31 @@ void QQuickMenuPrivate::setCurrentIndex(int index)
}
}
+void QQuickMenuPrivate::activateNextItem()
+{
+ int index = currentIndex();
+ int count = contentModel->count();
+ while (++index < count) {
+ QQuickItem *item = itemAt(index);
+ if (!item || !item->activeFocusOnTab())
+ continue;
+ item->forceActiveFocus(Qt::TabFocusReason);
+ break;
+ }
+}
+
+void QQuickMenuPrivate::activatePreviousItem()
+{
+ int index = currentIndex();
+ while (--index >= 0) {
+ QQuickItem *item = itemAt(index);
+ if (!item || !item->activeFocusOnTab())
+ continue;
+ item->forceActiveFocus(Qt::BacktabFocusReason);
+ break;
+ }
+}
+
void QQuickMenuPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj)
{
QQuickMenu *q = qobject_cast<QQuickMenu *>(prop->object);
@@ -1158,13 +1187,11 @@ void QQuickMenu::keyReleaseEvent(QKeyEvent *event)
// shown at once.
switch (event->key()) {
case Qt::Key_Up:
- if (d->contentItem->metaObject()->indexOfMethod("decrementCurrentIndex()") != -1)
- QMetaObject::invokeMethod(d->contentItem, "decrementCurrentIndex");
+ d->activatePreviousItem();
break;
case Qt::Key_Down:
- if (d->contentItem->metaObject()->indexOfMethod("incrementCurrentIndex()") != -1)
- QMetaObject::invokeMethod(d->contentItem, "incrementCurrentIndex");
+ d->activateNextItem();
break;
case Qt::Key_Left:
@@ -1180,11 +1207,6 @@ void QQuickMenu::keyReleaseEvent(QKeyEvent *event)
default:
break;
}
-
- int index = d->currentIndex();
- QQuickItem *item = itemAt(index);
- if (item)
- item->forceActiveFocus();
}
void QQuickMenu::timerEvent(QTimerEvent *event)
diff --git a/src/quicktemplates2/qquickmenu_p_p.h b/src/quicktemplates2/qquickmenu_p_p.h
index 5887d4e5..a81c87c2 100644
--- a/src/quicktemplates2/qquickmenu_p_p.h
+++ b/src/quicktemplates2/qquickmenu_p_p.h
@@ -108,6 +108,9 @@ public:
int currentIndex() const;
void setCurrentIndex(int index);
+ void activateNextItem();
+ void activatePreviousItem();
+
static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj);
static int contentData_count(QQmlListProperty<QObject> *prop);
static QObject *contentData_at(QQmlListProperty<QObject> *prop, int index);
diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml
index 4f969106..136c0830 100644
--- a/tests/auto/controls/data/tst_combobox.qml
+++ b/tests/auto/controls/data/tst_combobox.qml
@@ -156,6 +156,31 @@ TestCase {
compare(control.currentText, "")
}
+ function test_qobjects() {
+ var control = createTemporaryObject(emptyBox, testCase, {textRole: "text"})
+ verify(control)
+
+ var obj1 = Qt.createQmlObject("import QtQml 2.0; QtObject { property string text: 'one' }", control)
+ var obj2 = Qt.createQmlObject("import QtQml 2.0; QtObject { property string text: 'two' }", control)
+ var obj3 = Qt.createQmlObject("import QtQml 2.0; QtObject { property string text: 'three' }", control)
+
+ control.model = [obj1, obj2, obj3]
+
+ compare(control.count, 3)
+ compare(control.currentIndex, 0)
+ compare(control.currentText, "one")
+
+ control.currentIndex = 2
+ compare(control.currentIndex, 2)
+ compare(control.currentText, "three")
+
+ control.model = null
+ compare(control.model, null)
+ compare(control.count, 0)
+ compare(control.currentIndex, -1)
+ compare(control.currentText, "")
+ }
+
function test_number() {
var control = createTemporaryObject(comboBox, testCase)
verify(control)
diff --git a/tests/auto/controls/data/tst_container.qml b/tests/auto/controls/data/tst_container.qml
index 44d8e67a..94f22ad2 100644
--- a/tests/auto/controls/data/tst_container.qml
+++ b/tests/auto/controls/data/tst_container.qml
@@ -127,6 +127,33 @@ TestCase {
compare(control2.currentIndex, 1)
}
+ Component {
+ id: repeaterContainer
+ Container {
+ id: container
+ Item { objectName: "0" }
+ Item { objectName: "1" }
+ Item { objectName: "2" }
+ Item { objectName: "3" }
+ contentItem: Row {
+ Repeater {
+ model: container.contentModel
+ }
+ }
+ }
+ }
+
+ // don't crash (QTBUG-61310)
+ function test_repeater() {
+ var control = createTemporaryObject(repeaterContainer)
+ verify(control)
+
+ compare(control.itemAt(0).objectName, "0")
+ compare(control.itemAt(1).objectName, "1")
+ compare(control.itemAt(2).objectName, "2")
+ compare(control.itemAt(3).objectName, "3")
+ }
+
function test_removeTakeItem() {
var control = createTemporaryObject(container, testCase)
verify(control)
diff --git a/tests/auto/menu/tst_menu.cpp b/tests/auto/menu/tst_menu.cpp
index 5cf25168..79a459b8 100644
--- a/tests/auto/menu/tst_menu.cpp
+++ b/tests/auto/menu/tst_menu.cpp
@@ -194,7 +194,8 @@ void tst_menu::contextMenuKeyboard()
QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1));
- QQuickItem *firstItem = menu->itemAt(0);
+ QQuickMenuItem *firstItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(0));
+ QVERIFY(firstItem);
QSignalSpy visibleSpy(menu, SIGNAL(visibleChanged()));
menu->setFocus(true);
@@ -208,15 +209,21 @@ void tst_menu::contextMenuKeyboard()
QTest::keyClick(window, Qt::Key_Tab);
QVERIFY(firstItem->hasActiveFocus());
- QVERIFY(firstItem->property("highlighted").toBool());
+ QVERIFY(firstItem->hasVisualFocus());
+ QVERIFY(firstItem->isHighlighted());
+ QCOMPARE(firstItem->focusReason(), Qt::TabFocusReason);
QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(0));
- QQuickItem *secondItem = menu->itemAt(1);
+ QQuickMenuItem *secondItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(1));
+ QVERIFY(secondItem);
QTest::keyClick(window, Qt::Key_Tab);
QVERIFY(!firstItem->hasActiveFocus());
- QVERIFY(!firstItem->property("highlighted").toBool());
+ QVERIFY(!firstItem->hasVisualFocus());
+ QVERIFY(!firstItem->isHighlighted());
QVERIFY(secondItem->hasActiveFocus());
- QVERIFY(secondItem->property("highlighted").toBool());
+ QVERIFY(secondItem->hasVisualFocus());
+ QVERIFY(secondItem->isHighlighted());
+ QCOMPARE(secondItem->focusReason(), Qt::TabFocusReason);
QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(1));
QSignalSpy secondTriggeredSpy(secondItem, SIGNAL(triggered()));
@@ -226,9 +233,11 @@ void tst_menu::contextMenuKeyboard()
QVERIFY(!menu->isVisible());
QVERIFY(!window->overlay()->childItems().contains(menu->contentItem()));
QVERIFY(!firstItem->hasActiveFocus());
- QVERIFY(!firstItem->property("highlighted").toBool());
+ QVERIFY(!firstItem->hasVisualFocus());
+ QVERIFY(!firstItem->isHighlighted());
QVERIFY(!secondItem->hasActiveFocus());
- QVERIFY(!secondItem->property("highlighted").toBool());
+ QVERIFY(!secondItem->hasVisualFocus());
+ QVERIFY(!secondItem->isHighlighted());
QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1));
menu->open();
@@ -236,36 +245,75 @@ void tst_menu::contextMenuKeyboard()
QVERIFY(menu->isVisible());
QVERIFY(window->overlay()->childItems().contains(menu->contentItem()->parentItem()));
QVERIFY(!firstItem->hasActiveFocus());
- QVERIFY(!firstItem->property("highlighted").toBool());
+ QVERIFY(!firstItem->hasVisualFocus());
+ QVERIFY(!firstItem->isHighlighted());
QVERIFY(!secondItem->hasActiveFocus());
- QVERIFY(!secondItem->property("highlighted").toBool());
+ QVERIFY(!secondItem->hasVisualFocus());
+ QVERIFY(!secondItem->isHighlighted());
QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1));
QTest::keyClick(window, Qt::Key_Down);
QVERIFY(firstItem->hasActiveFocus());
- QVERIFY(firstItem->property("highlighted").toBool());
+ QVERIFY(firstItem->hasVisualFocus());
+ QVERIFY(firstItem->isHighlighted());
+ QCOMPARE(firstItem->focusReason(), Qt::TabFocusReason);
QTest::keyClick(window, Qt::Key_Down);
QVERIFY(secondItem->hasActiveFocus());
- QVERIFY(secondItem->property("highlighted").toBool());
+ QVERIFY(secondItem->hasVisualFocus());
+ QVERIFY(secondItem->isHighlighted());
+ QCOMPARE(secondItem->focusReason(), Qt::TabFocusReason);
QTest::keyClick(window, Qt::Key_Down);
- QQuickItem *thirdItem = menu->itemAt(2);
+ QQuickMenuItem *thirdItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(2));
+ QVERIFY(thirdItem);
QVERIFY(!firstItem->hasActiveFocus());
- QVERIFY(!firstItem->property("highlighted").toBool());
+ QVERIFY(!firstItem->hasVisualFocus());
+ QVERIFY(!firstItem->isHighlighted());
QVERIFY(!secondItem->hasActiveFocus());
- QVERIFY(!secondItem->property("highlighted").toBool());
+ QVERIFY(!secondItem->hasVisualFocus());
+ QVERIFY(!secondItem->isHighlighted());
QVERIFY(thirdItem->hasActiveFocus());
- QVERIFY(thirdItem->property("highlighted").toBool());
+ QVERIFY(thirdItem->hasVisualFocus());
+ QVERIFY(thirdItem->isHighlighted());
+ QCOMPARE(thirdItem->focusReason(), Qt::TabFocusReason);
// Key navigation shouldn't wrap by default.
QTest::keyClick(window, Qt::Key_Down);
QVERIFY(!firstItem->hasActiveFocus());
- QVERIFY(!firstItem->property("highlighted").toBool());
+ QVERIFY(!firstItem->hasVisualFocus());
+ QVERIFY(!firstItem->isHighlighted());
QVERIFY(!secondItem->hasActiveFocus());
- QVERIFY(!secondItem->property("highlighted").toBool());
+ QVERIFY(!secondItem->hasVisualFocus());
+ QVERIFY(!secondItem->isHighlighted());
QVERIFY(thirdItem->hasActiveFocus());
- QVERIFY(thirdItem->property("highlighted").toBool());
+ QVERIFY(thirdItem->hasVisualFocus());
+ QVERIFY(thirdItem->isHighlighted());
+ QCOMPARE(thirdItem->focusReason(), Qt::TabFocusReason);
+
+ QTest::keyClick(window, Qt::Key_Up);
+ QVERIFY(!firstItem->hasActiveFocus());
+ QVERIFY(!firstItem->hasVisualFocus());
+ QVERIFY(!firstItem->isHighlighted());
+ QVERIFY(secondItem->hasActiveFocus());
+ QVERIFY(secondItem->hasVisualFocus());
+ QVERIFY(secondItem->isHighlighted());
+ QCOMPARE(secondItem->focusReason(), Qt::BacktabFocusReason);
+ QVERIFY(!thirdItem->hasActiveFocus());
+ QVERIFY(!thirdItem->hasVisualFocus());
+ QVERIFY(!thirdItem->isHighlighted());
+
+ QTest::keyClick(window, Qt::Key_Backtab);
+ QVERIFY(firstItem->hasActiveFocus());
+ QVERIFY(firstItem->hasVisualFocus());
+ QVERIFY(firstItem->isHighlighted());
+ QCOMPARE(firstItem->focusReason(), Qt::BacktabFocusReason);
+ QVERIFY(!secondItem->hasActiveFocus());
+ QVERIFY(!secondItem->hasVisualFocus());
+ QVERIFY(!secondItem->isHighlighted());
+ QVERIFY(!thirdItem->hasActiveFocus());
+ QVERIFY(!thirdItem->hasVisualFocus());
+ QVERIFY(!thirdItem->isHighlighted());
QTest::keyClick(window, Qt::Key_Escape);
QCOMPARE(visibleSpy.count(), 4);
@@ -362,6 +410,35 @@ void tst_menu::menuSeparator()
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier,
saveMenuItem->mapToScene(QPointF(saveMenuItem->width() / 2, saveMenuItem->height() / 2)).toPoint());
QTRY_VERIFY(!menu->isVisible());
+
+ menu->open();
+ QVERIFY(menu->isVisible());
+
+ // Key navigation skips separators
+ QTest::keyClick(window, Qt::Key_Down);
+ QVERIFY(newMenuItem->hasActiveFocus());
+ QVERIFY(newMenuItem->hasVisualFocus());
+ QCOMPARE(newMenuItem->focusReason(), Qt::TabFocusReason);
+
+ QTest::keyClick(window, Qt::Key_Down);
+ QVERIFY(saveMenuItem->hasActiveFocus());
+ QVERIFY(saveMenuItem->hasVisualFocus());
+ QCOMPARE(saveMenuItem->focusReason(), Qt::TabFocusReason);
+
+ QTest::keyClick(window, Qt::Key_Down);
+ QVERIFY(saveMenuItem->hasActiveFocus());
+ QVERIFY(saveMenuItem->hasVisualFocus());
+ QCOMPARE(saveMenuItem->focusReason(), Qt::TabFocusReason);
+
+ QTest::keyClick(window, Qt::Key_Up);
+ QVERIFY(newMenuItem->hasActiveFocus());
+ QVERIFY(newMenuItem->hasVisualFocus());
+ QCOMPARE(newMenuItem->focusReason(), Qt::BacktabFocusReason);
+
+ QTest::keyClick(window, Qt::Key_Up);
+ QVERIFY(newMenuItem->hasActiveFocus());
+ QVERIFY(newMenuItem->hasVisualFocus());
+ QCOMPARE(newMenuItem->focusReason(), Qt::BacktabFocusReason);
}
void tst_menu::repeater()