aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-09 03:02:20 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-09 03:02:21 +0100
commit7b48bda18f836671cda6d47d6570fc522a4361ec (patch)
treeba0093c597b5581aa6fc86964c3d95d7fe9bfe36 /tests
parent3afec43b69991753416380d88e22b5382b8b0832 (diff)
parent4e5601ac1c7aec6aba9ba09fe7adb7a0462da2f0 (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qquickmenu/data/disableWhenTriggered.qml121
-rw-r--r--tests/auto/qquickmenu/data/disabledMenuItemKeyNavigation.qml74
-rw-r--r--tests/auto/qquickmenu/data/subMenuDisabled.qml79
-rw-r--r--tests/auto/qquickmenu/tst_qquickmenu.cpp257
-rw-r--r--tests/auto/qquickpopup/data/disabledPalette.qml72
-rw-r--r--tests/auto/qquickpopup/tst_qquickpopup.cpp88
-rw-r--r--tests/auto/qquickstyle/data/custom.conf4
-rw-r--r--tests/auto/qquickstyle/data/default.conf4
-rw-r--r--tests/auto/qquickstyle/data/fusion.conf4
-rw-r--r--tests/auto/qquickstyle/data/imagine.conf4
-rw-r--r--tests/auto/qquickstyle/data/material.conf4
-rw-r--r--tests/auto/qquickstyle/data/universal.conf4
-rw-r--r--tests/auto/qquickstyle/tst_qquickstyle.cpp17
13 files changed, 731 insertions, 1 deletions
diff --git a/tests/auto/qquickmenu/data/disableWhenTriggered.qml b/tests/auto/qquickmenu/data/disableWhenTriggered.qml
new file mode 100644
index 00000000..c64916ae
--- /dev/null
+++ b/tests/auto/qquickmenu/data/disableWhenTriggered.qml
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ Action {
+ id: actionOutsideMenu
+ text: "Action declared outside menu"
+ onTriggered: enabled = false
+ }
+
+ menuBar: MenuBar {
+ Menu {
+ title: "Menu"
+ objectName: title
+
+ Action {
+ text: "Action"
+ objectName: text
+ onTriggered: enabled = false
+ }
+ MenuItem {
+ objectName: "MenuItem with Action"
+ action: Action {
+ text: "Action declared inside MenuItem"
+ objectName: text
+ onTriggered: enabled = false
+ }
+ }
+ MenuItem {
+ objectName: "MenuItem with Action declared outside menu"
+ action: actionOutsideMenu
+ }
+ MenuItem {
+ text: "MenuItem with no Action"
+ objectName: text
+ onTriggered: enabled = false
+ }
+
+ Menu {
+ title: "Submenu"
+ objectName: title
+
+ Action {
+ text: "Sub-Action"
+ objectName: text
+ onTriggered: enabled = false
+ }
+ MenuItem {
+ objectName: "Sub-MenuItem with Action declared inside"
+ action: Action {
+ text: "Action declared inside Sub-MenuItem"
+ objectName: text
+ onTriggered: enabled = false
+ }
+ }
+ MenuItem {
+ objectName: "Sub-MenuItem with Action declared outside menu"
+ action: actionOutsideMenu
+ }
+ MenuItem {
+ text: "Sub-MenuItem with no Action"
+ objectName: text
+ onTriggered: enabled = false
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/qquickmenu/data/disabledMenuItemKeyNavigation.qml b/tests/auto/qquickmenu/data/disabledMenuItemKeyNavigation.qml
new file mode 100644
index 00000000..a39c5f44
--- /dev/null
+++ b/tests/auto/qquickmenu/data/disabledMenuItemKeyNavigation.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+
+ApplicationWindow {
+ width: 200
+ height: 200
+
+ property alias menu: menu
+
+ Menu {
+ id: menu
+
+ MenuItem {
+ text: qsTr("Enabled 1")
+ }
+ MenuItem {
+ text: qsTr("Disabled 1")
+ enabled: false
+ }
+ MenuItem {
+ text: qsTr("Enabled 2")
+ }
+ }
+}
diff --git a/tests/auto/qquickmenu/data/subMenuDisabled.qml b/tests/auto/qquickmenu/data/subMenuDisabled.qml
new file mode 100644
index 00000000..36ca1103
--- /dev/null
+++ b/tests/auto/qquickmenu/data/subMenuDisabled.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+
+ApplicationWindow {
+ width: 600
+ height: 400
+
+ property alias mainMenu: mainMenu
+ property alias subMenu: subMenu
+
+ Menu {
+ id: mainMenu
+ title: "Menu"
+
+ Menu {
+ id: subMenu
+ title: "Sub Menu"
+ MenuItem {
+ id: subMenuItem1
+ text: "Sub Menu Item 1"
+ enabled: false
+ }
+ MenuItem {
+ id: subMenuItem2
+ text: "Sub Menu Item 2"
+ }
+ }
+ }
+}
diff --git a/tests/auto/qquickmenu/tst_qquickmenu.cpp b/tests/auto/qquickmenu/tst_qquickmenu.cpp
index b46b8781..a24305b7 100644
--- a/tests/auto/qquickmenu/tst_qquickmenu.cpp
+++ b/tests/auto/qquickmenu/tst_qquickmenu.cpp
@@ -68,6 +68,7 @@ private slots:
void mouse();
void pressAndHold();
void contextMenuKeyboard();
+ void disabledMenuItemKeyNavigation();
void mnemonics();
void menuButton();
void addItem();
@@ -79,13 +80,19 @@ private slots:
void removeTakeItem();
void subMenuMouse_data();
void subMenuMouse();
+ void subMenuDisabledMouse_data();
+ void subMenuDisabledMouse();
void subMenuKeyboard_data();
void subMenuKeyboard();
+ void subMenuDisabledKeyboard_data();
+ void subMenuDisabledKeyboard();
void subMenuPosition_data();
void subMenuPosition();
void addRemoveSubMenus();
void scrollable_data();
void scrollable();
+ void disableWhenTriggered_data();
+ void disableWhenTriggered();
};
void tst_QQuickMenu::defaults()
@@ -390,6 +397,69 @@ void tst_QQuickMenu::contextMenuKeyboard()
QVERIFY(!menu->isVisible());
}
+// QTBUG-70181
+void tst_QQuickMenu::disabledMenuItemKeyNavigation()
+{
+ if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls)
+ QSKIP("This platform only allows tab focus for text controls");
+
+ QQuickApplicationHelper helper(this, QLatin1String("disabledMenuItemKeyNavigation.qml"));
+
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+ centerOnScreen(window);
+ moveMouseAway(window);
+
+ QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
+ QCOMPARE(menu->currentIndex(), -1);
+ QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1));
+
+ QQuickMenuItem *firstItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(0));
+ QVERIFY(firstItem);
+
+ QQuickMenuItem *secondItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(1));
+ QVERIFY(secondItem);
+
+ QQuickMenuItem *thirdItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(2));
+ QVERIFY(thirdItem);
+
+ menu->setFocus(true);
+ menu->open();
+ QVERIFY(menu->isVisible());
+ QVERIFY(!firstItem->hasActiveFocus());
+ QVERIFY(!firstItem->property("highlighted").toBool());
+ QCOMPARE(menu->currentIndex(), -1);
+
+ QTest::keyClick(window, Qt::Key_Tab);
+ QVERIFY(firstItem->hasActiveFocus());
+ QVERIFY(firstItem->hasVisualFocus());
+ QVERIFY(firstItem->isHighlighted());
+ QCOMPARE(firstItem->focusReason(), Qt::TabFocusReason);
+ QCOMPARE(menu->currentIndex(), 0);
+
+ // Shouldn't be possible to give focus to a disabled menu item.
+ QTest::keyClick(window, Qt::Key_Down);
+ QVERIFY(!secondItem->hasActiveFocus());
+ QVERIFY(!secondItem->hasVisualFocus());
+ QVERIFY(!secondItem->isHighlighted());
+ QVERIFY(thirdItem->hasActiveFocus());
+ 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());
+ QCOMPARE(firstItem->focusReason(), Qt::BacktabFocusReason);
+
+ QTest::keyClick(window, Qt::Key_Escape);
+ QVERIFY(!menu->isVisible());
+}
+
void tst_QQuickMenu::mnemonics()
{
#ifdef Q_OS_MACOS
@@ -995,6 +1065,64 @@ void tst_QQuickMenu::subMenuMouse()
QVERIFY(!subSubMenu1->isVisible());
}
+void tst_QQuickMenu::subMenuDisabledMouse_data()
+{
+ subMenuMouse_data();
+}
+
+// QTBUG-69540
+void tst_QQuickMenu::subMenuDisabledMouse()
+{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Mouse hovering not functional on offscreen/minimal platforms");
+
+ QFETCH(bool, cascade);
+
+ QQuickApplicationHelper helper(this, QLatin1String("subMenuDisabled.qml"));
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ centerOnScreen(window);
+ moveMouseAway(window);
+
+ QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>();
+ QVERIFY(mainMenu);
+ mainMenu->setCascade(cascade);
+ QCOMPARE(mainMenu->cascade(), cascade);
+
+ QQuickMenuItem *menuItem1 = qobject_cast<QQuickMenuItem *>(mainMenu->itemAt(0));
+ QVERIFY(menuItem1);
+
+ QQuickMenu *subMenu = window->property("subMenu").value<QQuickMenu *>();
+ QVERIFY(subMenu);
+
+ mainMenu->open();
+ QVERIFY(mainMenu->isVisible());
+ QVERIFY(!menuItem1->isHighlighted());
+ QVERIFY(!subMenu->isVisible());
+
+ // Open the sub-menu with a mouse click.
+ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, menuItem1->mapToScene(QPoint(1, 1)).toPoint());
+ QCOMPARE(mainMenu->isVisible(), cascade);
+ QVERIFY(subMenu->isVisible());
+ QVERIFY(menuItem1->isHighlighted());
+ // Now the sub-menu is open. The current behavior is that the first menu item
+ // in the new menu is highlighted; make sure that we choose the next item if
+ // the first is disabled.
+ QQuickMenuItem *subMenuItem1 = qobject_cast<QQuickMenuItem *>(subMenu->itemAt(0));
+ QVERIFY(subMenuItem1);
+ QQuickMenuItem *subMenuItem2 = qobject_cast<QQuickMenuItem *>(subMenu->itemAt(1));
+ QVERIFY(subMenuItem2);
+ QVERIFY(!subMenuItem1->isHighlighted());
+ QVERIFY(subMenuItem2->isHighlighted());
+
+ // Close all menus by clicking on the item that isn't disabled.
+ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, subMenuItem2->mapToScene(QPoint(1, 1)).toPoint());
+ QVERIFY(!mainMenu->isVisible());
+ QVERIFY(!subMenu->isVisible());
+}
+
void tst_QQuickMenu::subMenuKeyboard_data()
{
QTest::addColumn<bool>("cascade");
@@ -1119,6 +1247,67 @@ void tst_QQuickMenu::subMenuKeyboard()
QVERIFY(!subSubMenu1->isVisible());
}
+void tst_QQuickMenu::subMenuDisabledKeyboard_data()
+{
+ subMenuKeyboard_data();
+}
+
+// QTBUG-69540
+void tst_QQuickMenu::subMenuDisabledKeyboard()
+{
+ QFETCH(bool, cascade);
+ QFETCH(bool, mirrored);
+
+ QQuickApplicationHelper helper(this, QLatin1String("subMenuDisabled.qml"));
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ centerOnScreen(window);
+ moveMouseAway(window);
+
+ if (mirrored)
+ window->setLocale(QLocale("ar_EG"));
+
+ QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>();
+ QVERIFY(mainMenu);
+ mainMenu->setCascade(cascade);
+ QCOMPARE(mainMenu->cascade(), cascade);
+
+ QQuickMenuItem *menuItem1 = qobject_cast<QQuickMenuItem *>(mainMenu->itemAt(0));
+ QVERIFY(menuItem1);
+
+ QQuickMenu *subMenu = window->property("subMenu").value<QQuickMenu *>();
+ QVERIFY(subMenu);
+
+ mainMenu->open();
+ QVERIFY(mainMenu->isVisible());
+ QVERIFY(!menuItem1->isHighlighted());
+ QVERIFY(!subMenu->isVisible());
+
+ // Highlight the top-level menu item.
+ QTest::keyClick(window, Qt::Key_Down);
+ QVERIFY(menuItem1->isHighlighted());
+
+ QQuickMenuItem *subMenuItem1 = qobject_cast<QQuickMenuItem *>(subMenu->itemAt(0));
+ QVERIFY(subMenuItem1);
+ QQuickMenuItem *subMenuItem2 = qobject_cast<QQuickMenuItem *>(subMenu->itemAt(1));
+ QVERIFY(subMenuItem2);
+
+ // Open the sub-menu.
+ QTest::keyClick(window, mirrored ? Qt::Key_Left : Qt::Key_Right);
+ // The first sub-menu item is disabled, so it should highlight the second one.
+ QVERIFY(!subMenuItem1->isHighlighted());
+ QVERIFY(subMenuItem2->isHighlighted());
+
+ // Close the menus with escape.
+ QTest::keyClick(window, Qt::Key_Escape);
+ QCOMPARE(mainMenu->isVisible(), cascade);
+ QVERIFY(!subMenu->isVisible());
+ QTest::keyClick(window, Qt::Key_Escape);
+ QVERIFY(!mainMenu->isVisible());
+ QVERIFY(!subMenu->isVisible());
+}
+
void tst_QQuickMenu::subMenuPosition_data()
{
QTest::addColumn<bool>("cascade");
@@ -1336,6 +1525,74 @@ void tst_QQuickMenu::scrollable()
QCOMPARE(contentItem->property("interactive").toBool(), true);
}
+void tst_QQuickMenu::disableWhenTriggered_data()
+{
+ QTest::addColumn<int>("menuItemIndex");
+ QTest::addColumn<int>("subMenuItemIndex");
+
+ QTest::addRow("Action") << 0 << -1;
+ QTest::addRow("MenuItem with Action") << 1 << -1;
+ QTest::addRow("MenuItem with Action declared outside menu") << 2 << -1;
+ QTest::addRow("MenuItem with no Action") << 3 << -1;
+
+ QTest::addRow("Sub-Action") << 4 << 0;
+ QTest::addRow("Sub-MenuItem with Action declared inside") << 4 << 1;
+ QTest::addRow("Sub-MenuItem with Action declared outside menu") << 4 << 2;
+ QTest::addRow("Sub-MenuItem with no Action") << 4 << 3;
+}
+
+// Tests that the menu is dismissed when a menu item sets "enabled = false" in onTriggered().
+void tst_QQuickMenu::disableWhenTriggered()
+{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Mouse hovering not functional on offscreen/minimal platforms");
+
+ QFETCH(int, menuItemIndex);
+ QFETCH(int, subMenuItemIndex);
+
+ QQuickApplicationHelper helper(this, QLatin1String("disableWhenTriggered.qml"));
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QQuickMenu *menu = window->findChild<QQuickMenu*>("Menu");
+ QVERIFY(menu);
+
+ menu->open();
+ QVERIFY(menu->isVisible());
+
+ QPointer<QQuickMenuItem> menuItem = qobject_cast<QQuickMenuItem*>(menu->itemAt(menuItemIndex));
+ QVERIFY(menuItem);
+
+ if (subMenuItemIndex == -1) {
+ // Click a top-level menu item.
+ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier,
+ menuItem->mapToScene(QPointF(menuItem->width() / 2, menuItem->height() / 2)).toPoint());
+ QCOMPARE(menuItem->isEnabled(), false);
+ QVERIFY(!menu->isVisible());
+ } else {
+ // Click a sub-menu item.
+ QPointer<QQuickMenu> subMenu = menuItem->subMenu();
+ QVERIFY(subMenu);
+
+ QPointer<QQuickMenuItem> subMenuItem = qobject_cast<QQuickMenuItem*>(subMenu->itemAt(subMenuItemIndex));
+ QVERIFY(subMenuItem);
+
+ // First, open the sub-menu.
+ QTest::mouseMove(window, menuItem->mapToScene(QPoint(1, 1)).toPoint());
+ QTRY_VERIFY(subMenu->isVisible());
+ QVERIFY(menuItem->isHovered());
+ QTRY_VERIFY(subMenu->contentItem()->property("contentHeight").toReal() > 0.0);
+
+ // Click the item.
+ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier,
+ subMenuItem->mapToScene(QPointF(subMenuItem->width() / 2, subMenuItem->height() / 2)).toPoint());
+ QCOMPARE(subMenuItem->isEnabled(), false);
+ QVERIFY(!menu->isVisible());
+ }
+}
+
QTEST_MAIN(tst_QQuickMenu)
#include "tst_qquickmenu.moc"
diff --git a/tests/auto/qquickpopup/data/disabledPalette.qml b/tests/auto/qquickpopup/data/disabledPalette.qml
new file mode 100644
index 00000000..f080f5e8
--- /dev/null
+++ b/tests/auto/qquickpopup/data/disabledPalette.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias popup: popup
+
+ function disableOverlay() {
+ popup.Overlay.overlay.enabled = false
+ }
+
+ Popup {
+ id: popup
+ width: 200
+ height: 200
+ background: Rectangle {
+ color: popup.palette.base
+ }
+ }
+}
diff --git a/tests/auto/qquickpopup/tst_qquickpopup.cpp b/tests/auto/qquickpopup/tst_qquickpopup.cpp
index 35d05244..81b2d583 100644
--- a/tests/auto/qquickpopup/tst_qquickpopup.cpp
+++ b/tests/auto/qquickpopup/tst_qquickpopup.cpp
@@ -86,6 +86,8 @@ private slots:
void orientation_data();
void orientation();
void qquickview();
+ void disabledPalette();
+ void disabledParentPalette();
};
void tst_QQuickPopup::initTestCase()
@@ -1083,6 +1085,92 @@ void tst_QQuickPopup::qquickview()
// QTBUG-72746: shouldn't crash on application exit after closing a Dialog when using QQuickView.
}
+// TODO: also test it out without setting enabled directly on menu, but on a parent
+
+// QTBUG-73447
+void tst_QQuickPopup::disabledPalette()
+{
+ QQuickApplicationHelper helper(this, "disabledPalette.qml");
+
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QQuickPopup *popup = window->property("popup").value<QQuickPopup*>();
+ QVERIFY(popup);
+
+ QSignalSpy popupEnabledSpy(popup, SIGNAL(enabledChanged()));
+ QVERIFY(popupEnabledSpy.isValid());
+ QSignalSpy popupPaletteSpy(popup, SIGNAL(paletteChanged()));
+ QVERIFY(popupPaletteSpy.isValid());
+
+ QSignalSpy popupItemEnabledSpy(popup->popupItem(), SIGNAL(enabledChanged()));
+ QVERIFY(popupItemEnabledSpy.isValid());
+ QSignalSpy popupItemPaletteSpy(popup->popupItem(), SIGNAL(paletteChanged()));
+ QVERIFY(popupItemPaletteSpy.isValid());
+
+ QPalette palette = popup->palette();
+ palette.setColor(QPalette::Active, QPalette::Base, Qt::green);
+ palette.setColor(QPalette::Disabled, QPalette::Base, Qt::red);
+ popup->setPalette(palette);
+ QCOMPARE(popupPaletteSpy.count(), 1);
+ QCOMPARE(popupItemPaletteSpy.count(), 1);
+ QCOMPARE(popup->background()->property("color").value<QColor>(), Qt::green);
+
+ popup->setEnabled(false);
+ QCOMPARE(popupEnabledSpy.count(), 1);
+ QCOMPARE(popupItemEnabledSpy.count(), 1);
+ QCOMPARE(popupPaletteSpy.count(), 2);
+ QCOMPARE(popupItemPaletteSpy.count(), 2);
+ QCOMPARE(popup->background()->property("color").value<QColor>(), Qt::red);
+}
+
+void tst_QQuickPopup::disabledParentPalette()
+{
+ QQuickApplicationHelper helper(this, "disabledPalette.qml");
+
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QQuickPopup *popup = window->property("popup").value<QQuickPopup*>();
+ QVERIFY(popup);
+
+ QSignalSpy popupEnabledSpy(popup, SIGNAL(enabledChanged()));
+ QVERIFY(popupEnabledSpy.isValid());
+ QSignalSpy popupPaletteSpy(popup, SIGNAL(paletteChanged()));
+ QVERIFY(popupPaletteSpy.isValid());
+
+ QSignalSpy popupItemEnabledSpy(popup->popupItem(), SIGNAL(enabledChanged()));
+ QVERIFY(popupItemEnabledSpy.isValid());
+ QSignalSpy popupItemPaletteSpy(popup->popupItem(), SIGNAL(paletteChanged()));
+ QVERIFY(popupItemPaletteSpy.isValid());
+
+ QPalette palette = popup->palette();
+ palette.setColor(QPalette::Active, QPalette::Base, Qt::green);
+ palette.setColor(QPalette::Disabled, QPalette::Base, Qt::red);
+ popup->setPalette(palette);
+ QCOMPARE(popupPaletteSpy.count(), 1);
+ QCOMPARE(popupItemPaletteSpy.count(), 1);
+ QCOMPARE(popup->background()->property("color").value<QColor>(), Qt::green);
+
+ // Disable the overlay (which is QQuickPopupItem's parent) to ensure that
+ // the palette is changed when the popup is indirectly disabled.
+ popup->open();
+ QTRY_VERIFY(popup->isOpened());
+ QVERIFY(QMetaObject::invokeMethod(window, "disableOverlay"));
+ QVERIFY(!popup->isEnabled());
+ QVERIFY(!popup->popupItem()->isEnabled());
+ QCOMPARE(popup->background()->property("color").value<QColor>(), Qt::red);
+ QCOMPARE(popupEnabledSpy.count(), 1);
+ QCOMPARE(popupItemEnabledSpy.count(), 1);
+ QCOMPARE(popupPaletteSpy.count(), 2);
+ QCOMPARE(popupItemPaletteSpy.count(), 2);
+
+ popup->close();
+ QTRY_VERIFY(!popup->isVisible());
+}
+
QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
#include "tst_qquickpopup.moc"
diff --git a/tests/auto/qquickstyle/data/custom.conf b/tests/auto/qquickstyle/data/custom.conf
index 4e17d1dc..2230b452 100644
--- a/tests/auto/qquickstyle/data/custom.conf
+++ b/tests/auto/qquickstyle/data/custom.conf
@@ -1,2 +1,6 @@
[Controls]
Style=:/Custom
+
+[Custom]
+Font\PixelSize=3
+Palette\WindowText=#ff0000
diff --git a/tests/auto/qquickstyle/data/default.conf b/tests/auto/qquickstyle/data/default.conf
index caace6db..12ca5d8f 100644
--- a/tests/auto/qquickstyle/data/default.conf
+++ b/tests/auto/qquickstyle/data/default.conf
@@ -1,2 +1,6 @@
[Controls]
Style=Default
+
+[Default]
+Font\PixelSize=3
+Palette\WindowText=#ff0000
diff --git a/tests/auto/qquickstyle/data/fusion.conf b/tests/auto/qquickstyle/data/fusion.conf
index 9cd14111..1f343e65 100644
--- a/tests/auto/qquickstyle/data/fusion.conf
+++ b/tests/auto/qquickstyle/data/fusion.conf
@@ -1,2 +1,6 @@
[Controls]
Style=Fusion
+
+[Fusion]
+Font\PixelSize=3
+Palette\WindowText=#ff0000
diff --git a/tests/auto/qquickstyle/data/imagine.conf b/tests/auto/qquickstyle/data/imagine.conf
index add378d4..919bbcf0 100644
--- a/tests/auto/qquickstyle/data/imagine.conf
+++ b/tests/auto/qquickstyle/data/imagine.conf
@@ -1,2 +1,6 @@
[Controls]
Style=Imagine
+
+[Imagine]
+Font\PixelSize=3
+Palette\WindowText=#ff0000
diff --git a/tests/auto/qquickstyle/data/material.conf b/tests/auto/qquickstyle/data/material.conf
index b6c7c87e..27c7931a 100644
--- a/tests/auto/qquickstyle/data/material.conf
+++ b/tests/auto/qquickstyle/data/material.conf
@@ -1,2 +1,6 @@
[Controls]
Style=Material
+
+[Material]
+Font\PixelSize=3
+Palette\WindowText=#ff0000
diff --git a/tests/auto/qquickstyle/data/universal.conf b/tests/auto/qquickstyle/data/universal.conf
index 8c6dd807..a5ac3ca3 100644
--- a/tests/auto/qquickstyle/data/universal.conf
+++ b/tests/auto/qquickstyle/data/universal.conf
@@ -1,2 +1,6 @@
[Controls]
Style=Universal
+
+[Universal]
+Font\PixelSize=3
+Palette\WindowText=#ff0000
diff --git a/tests/auto/qquickstyle/tst_qquickstyle.cpp b/tests/auto/qquickstyle/tst_qquickstyle.cpp
index 3f55bcfb..e99dad62 100644
--- a/tests/auto/qquickstyle/tst_qquickstyle.cpp
+++ b/tests/auto/qquickstyle/tst_qquickstyle.cpp
@@ -39,6 +39,7 @@
#include <QtQml/qqmlcomponent.h>
#include <QtQuickControls2/qquickstyle.h>
#include <QtQuickControls2/private/qquickstyle_p.h>
+#include <QtQuickTemplates2/private/qquicklabel_p.h>
#include <QtQuickTemplates2/private/qquicktheme_p.h>
#include <QtGui/private/qguiapplication_p.h>
@@ -133,11 +134,25 @@ void tst_QQuickStyle::configurationFile()
qputenv("QT_QUICK_CONTROLS_CONF", testFile(fileName).toLocal8Bit());
- loadControls();
+ // Load a control. The import causes the configuration file to be read.
+ QQmlEngine engine;
+ QQmlComponent labelComponent(&engine);
+ labelComponent.setData("import QtQuick 2.0; import QtQuick.Controls 2.12; Label {}", QUrl());
+
+ QScopedPointer<QObject> object(labelComponent.create());
+ QVERIFY2(!object.isNull(), qPrintable(labelComponent.errorString()));
QCOMPARE(QQuickStyle::name(), expectedStyle);
if (!expectedPath.isEmpty())
QCOMPARE(QQuickStyle::path(), expectedPath);
+
+ // Test that fonts and palettes specified in configuration files are respected.
+ QQuickLabel *label = qobject_cast<QQuickLabel *>(object.data());
+ QVERIFY(label);
+ // Make it small so that there's less possibility for the default/system
+ // pixel size to match it and give us false positives.
+ QCOMPARE(label->font().pixelSize(), 3);
+ QCOMPARE(label->palette().windowText(), Qt::red);
}
void tst_QQuickStyle::commandLineArgument()