aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quickcontrols/nativemenus/data/dynamicSubmenus.qml51
-rw-r--r--tests/auto/quickcontrols/nativemenus/tst_nativemenus.cpp56
-rw-r--r--tests/manual/quickcontrols/menus/main.qml80
3 files changed, 166 insertions, 21 deletions
diff --git a/tests/auto/quickcontrols/nativemenus/data/dynamicSubmenus.qml b/tests/auto/quickcontrols/nativemenus/data/dynamicSubmenus.qml
new file mode 100644
index 0000000000..c0326fb511
--- /dev/null
+++ b/tests/auto/quickcontrols/nativemenus/data/dynamicSubmenus.qml
@@ -0,0 +1,51 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Templates as T
+import QtQuick.Controls
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias contextMenu: contextMenu
+
+ function addSubMenu(title: string) {
+ contextMenu.addMenu(subMenuComponent.createObject(null, { title: title }))
+ }
+
+ function addAction(menu: T.Menu, text: string) {
+ menu.addAction(actionComponent.createObject(null, { text: text }))
+ }
+
+ function insertAction(menu: T.Menu, index: int, text: string) {
+ menu.insertAction(index, actionComponent.createObject(null, { text: text }))
+ }
+
+ Component {
+ id: actionComponent
+
+ Action {
+ objectName: text
+ }
+ }
+
+ Component {
+ id: subMenuComponent
+
+ Menu {
+ id: subMenu
+ objectName: title
+
+ Action {
+ text: subMenu.objectName + "Action1"
+ }
+ }
+ }
+
+ Menu {
+ id: contextMenu
+ objectName: "menu"
+ }
+}
diff --git a/tests/auto/quickcontrols/nativemenus/tst_nativemenus.cpp b/tests/auto/quickcontrols/nativemenus/tst_nativemenus.cpp
index 4e1fe9dd70..1de581eb7a 100644
--- a/tests/auto/quickcontrols/nativemenus/tst_nativemenus.cpp
+++ b/tests/auto/quickcontrols/nativemenus/tst_nativemenus.cpp
@@ -148,7 +148,7 @@ void tst_NativeMenus::dynamicActions()
void tst_NativeMenus::dynamicSubmenus()
{
- QQuickControlsApplicationHelper helper(this, QLatin1String("emptyMenu.qml"));
+ QQuickControlsApplicationHelper helper(this, QLatin1String("dynamicSubmenus.qml"));
QVERIFY2(helper.ready, helper.failureMessage());
QQuickApplicationWindow *window = helper.appWindow;
window->show();
@@ -158,19 +158,61 @@ void tst_NativeMenus::dynamicSubmenus()
QVERIFY(contextMenu);
auto *contextMenuPrivate = QQuickMenuPrivate::get(contextMenu);
- // Check that sub-menus (with no menu items, yet) can be appended to an empty parent menu.
- QVERIFY(QMetaObject::invokeMethod(window, "addMenu",
- Q_ARG(QQuickMenu *, contextMenu), Q_ARG(QString, "subMenu1")));
+ // We construct the sub-menu first in QML. At least on Windows, menu items
+ // added to an empty sub-menu won't show up (tested with Widgets): QTBUG-120494.
+ // So, this adds an already-populated menu as a sub-menu.
+ QVERIFY(QMetaObject::invokeMethod(window, "addSubMenu", Q_ARG(QString, "subMenu1")));
auto subMenu1 = contextMenu->menuAt(0);
+ auto *subMenu1Private = QQuickMenuPrivate::get(subMenu1);
QVERIFY(subMenu1);
QCOMPARE(subMenu1->title(), "subMenu1");
QCOMPARE(contextMenuPrivate->contentData.at(0), subMenu1);
+ QCOMPARE(contextMenuPrivate->contentData.size(), 1);
+ {
+ auto subMenuAction1 = subMenu1->actionAt(0);
+ QVERIFY(subMenuAction1);
+ QCOMPARE(subMenuAction1->text(), "subMenu1Action1");
+ QCOMPARE(subMenu1Private->contentData.at(0), subMenuAction1);
+ }
- //
+ // Check that actions can be appended after existing items in the sub-menu.
+ QCOMPARE(subMenu1->actionAt(1), nullptr);
QVERIFY(QMetaObject::invokeMethod(window, "addAction",
- Q_ARG(QQuickMenu *, subMenu1), Q_ARG(QString, "subMenuAction1")));
+ Q_ARG(QQuickMenu *, subMenu1), Q_ARG(QString, "subMenu1Action2")));
+ {
+ auto subMenu1Action2 = subMenu1->actionAt(1);
+ QVERIFY(subMenu1Action2);
+ QCOMPARE(subMenu1Action2->text(), "subMenu1Action2");
+ QCOMPARE(subMenu1Private->contentData.at(1), subMenu1Action2);
+ QCOMPARE(subMenu1Private->contentData.size(), 2);
+ }
+
+ // Check that actions can be inserted before existing items in the sub-menu.
+ QVERIFY(QMetaObject::invokeMethod(window, "insertAction",
+ Q_ARG(QQuickMenu *, subMenu1), Q_ARG(int, 0), Q_ARG(QString, "subMenu1Action0")));
+ {
+ auto subMenu1Action0 = subMenu1->actionAt(0);
+ QVERIFY(subMenu1Action0);
+ QCOMPARE(subMenu1Action0->text(), "subMenu1Action0");
+ QCOMPARE(subMenu1Private->contentData.at(0), subMenu1Action0);
+ QCOMPARE(subMenu1Private->contentData.size(), 3);
+ }
+
+ {
+ // Check that takeMenu works.
+ auto *takenSubMenu = contextMenu->takeMenu(0);
+ QCOMPARE(takenSubMenu, subMenu1);
+ QCOMPARE(contextMenuPrivate->contentData.size(), 0);
+
+ // Check that the sub-menu can be added back in to the menu.
+ contextMenu->addMenu(takenSubMenu);
+ QCOMPARE(contextMenuPrivate->contentData.size(), 1);
+ }
- // TODO: insert another sub-menu action before the first one
+ // Check that removeMenu works.
+ QVERIFY(contextMenu->menuAt(0));
+ contextMenu->removeMenu(contextMenu->menuAt(0));
+ QCOMPARE(contextMenuPrivate->contentData.size(), 0);
}
// TODO: add a test that mixes items with native items
diff --git a/tests/manual/quickcontrols/menus/main.qml b/tests/manual/quickcontrols/menus/main.qml
index 804b5637bb..59dfbac3fc 100644
--- a/tests/manual/quickcontrols/menus/main.qml
+++ b/tests/manual/quickcontrols/menus/main.qml
@@ -64,6 +64,7 @@ ApplicationWindow {
text: qsTr("Right click on the window background to open a context menu. "
+ "Right click on the TextArea to access its edit context menu.\n\n"
+ "Things to check:\n\n"
+ + "- Do the menu items trigger their actions (check console for output)?\n"
+ "- Do the Edit menu items (in the MenuBar menu and edit context menu)"
+ " work as expected with the TextArea?\n"
+ " - Are they enabled/disabled as expected?\n"
@@ -77,14 +78,35 @@ ApplicationWindow {
Layout.fillHeight: true
}
- RowLayout {
- Button {
- text: qsTr("Add context menu item")
- onClicked: backgroundContextMenu.appendAction()
- }
- Button {
- text: qsTr("Remove context menu item")
- onClicked: backgroundContextMenu.removeLastAction()
+ GroupBox {
+ title: qsTr("Context menu")
+
+ Layout.fillWidth: true
+
+ RowLayout {
+ anchors.fill: parent
+
+ Button {
+ text: qsTr("Add action")
+ onClicked: backgroundContextMenu.appendAction()
+ }
+ Button {
+ text: qsTr("Remove action")
+ onClicked: backgroundContextMenu.removeLastAction()
+ }
+
+ Button {
+ text: qsTr("Add sub-menu action")
+ onClicked: subMenu.appendAction()
+ }
+ Button {
+ text: qsTr("Remove sub-menu action")
+ onClicked: subMenu.removeLastAction()
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
}
}
@@ -115,6 +137,10 @@ ApplicationWindow {
Action {}
}
+ component ContextAction: Action {
+ onTriggered: print("triggered", text)
+ }
+
Menu {
id: backgroundContextMenu
@@ -132,29 +158,55 @@ ApplicationWindow {
backgroundContextMenu.removeAction(backgroundContextMenu.actionAt(backgroundContextMenu.contentData.length - 1))
}
- Action {
+ ContextAction {
text: qsTr("Context menu item 1")
}
- Action {
+ ContextAction {
text: qsTr("Context menu item 2")
}
- Action {
+ ContextAction {
text: qsTr("Context menu item 3")
}
+
+ // TODO: separator
+
+ Menu {
+ id: subMenu
+ title: qsTr("Sub-menu")
+
+ function appendAction() {
+ let action = actionComponent.createObject(null, { text: qsTr("Extra sub-menu item") })
+ subMenu.addAction(action)
+ }
+
+ function removeLastAction() {
+ subMenu.removeAction(subMenu.actionAt(subMenu.contentData.length - 1))
+ }
+
+ ContextAction {
+ text: qsTr("Sub-menu item 1")
+ }
+ ContextAction {
+ text: qsTr("Sub-menu item 2")
+ }
+ ContextAction {
+ text: qsTr("Sub-menu item 3")
+ }
+ }
}
Menu {
id: editContextMenu
- Action {
+ ContextAction {
text: qsTr("Cut")
enabled: textArea.selectedText.length > 0
}
- Action {
+ ContextAction {
text: qsTr("Copy")
enabled: textArea.selectedText.length > 0
}
- Action {
+ ContextAction {
text: qsTr("Paste")
enabled: textArea.activeFocus
}