diff options
-rw-r--r-- | src/quicktemplates2/qquickabstractbutton.cpp | 3 | ||||
-rw-r--r-- | tests/auto/qquickmenu/data/disableWhenTriggered.qml | 121 | ||||
-rw-r--r-- | tests/auto/qquickmenu/tst_qquickmenu.cpp | 70 |
3 files changed, 193 insertions, 1 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index 9157b4f9..3b41f34c 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -324,9 +324,10 @@ void QQuickAbstractButtonPrivate::click() void QQuickAbstractButtonPrivate::trigger() { Q_Q(QQuickAbstractButton); + const bool wasEnabled = effectiveEnable; if (action && action->isEnabled()) QQuickActionPrivate::get(action)->trigger(q, false); - else if (effectiveEnable) + if (wasEnabled && (!action || !action->isEnabled())) emit q->clicked(); } 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/tst_qquickmenu.cpp b/tests/auto/qquickmenu/tst_qquickmenu.cpp index b46b8781..a5780103 100644 --- a/tests/auto/qquickmenu/tst_qquickmenu.cpp +++ b/tests/auto/qquickmenu/tst_qquickmenu.cpp @@ -86,6 +86,8 @@ private slots: void addRemoveSubMenus(); void scrollable_data(); void scrollable(); + void disableWhenTriggered_data(); + void disableWhenTriggered(); }; void tst_QQuickMenu::defaults() @@ -1336,6 +1338,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" |