diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-02-09 03:02:20 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-02-09 03:02:21 +0100 |
commit | 7b48bda18f836671cda6d47d6570fc522a4361ec (patch) | |
tree | ba0093c597b5581aa6fc86964c3d95d7fe9bfe36 /tests | |
parent | 3afec43b69991753416380d88e22b5382b8b0832 (diff) | |
parent | 4e5601ac1c7aec6aba9ba09fe7adb7a0462da2f0 (diff) |
Merge remote-tracking branch 'origin/5.12' into 5.13
Change-Id: I8aded0949d38315d4d22fa511f83331d7caf3145
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/qquickmenu/data/disableWhenTriggered.qml | 121 | ||||
-rw-r--r-- | tests/auto/qquickmenu/data/disabledMenuItemKeyNavigation.qml | 74 | ||||
-rw-r--r-- | tests/auto/qquickmenu/data/subMenuDisabled.qml | 79 | ||||
-rw-r--r-- | tests/auto/qquickmenu/tst_qquickmenu.cpp | 257 | ||||
-rw-r--r-- | tests/auto/qquickpopup/data/disabledPalette.qml | 72 | ||||
-rw-r--r-- | tests/auto/qquickpopup/tst_qquickpopup.cpp | 88 | ||||
-rw-r--r-- | tests/auto/qquickstyle/data/custom.conf | 4 | ||||
-rw-r--r-- | tests/auto/qquickstyle/data/default.conf | 4 | ||||
-rw-r--r-- | tests/auto/qquickstyle/data/fusion.conf | 4 | ||||
-rw-r--r-- | tests/auto/qquickstyle/data/imagine.conf | 4 | ||||
-rw-r--r-- | tests/auto/qquickstyle/data/material.conf | 4 | ||||
-rw-r--r-- | tests/auto/qquickstyle/data/universal.conf | 4 | ||||
-rw-r--r-- | tests/auto/qquickstyle/tst_qquickstyle.cpp | 17 |
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() |