diff --git a/src/gui/kernel/qguiaction.cpp b/src/gui/kernel/qguiaction.cpp index f111d4fe91..dc5d3808b8 100644 --- a/src/gui/kernel/qguiaction.cpp +++ b/src/gui/kernel/qguiaction.cpp @@ -76,7 +76,7 @@ QGuiActionPrivate::QGuiActionPrivate() : #if QT_CONFIG(shortcut) autorepeat(1), #endif - enabled(1), forceDisabled(0), visible(1), forceInvisible(0), checkable(0), + enabled(1), explicitEnabled(0), explicitEnabledValue(1), visible(1), forceInvisible(0), checkable(0), checked(0), separator(0), fontSet(false), iconVisibleInMenu(-1), shortcutVisibleInContextMenu(-1) { @@ -887,17 +887,45 @@ bool QGuiAction::isChecked() const void QGuiAction::setEnabled(bool b) { Q_D(QGuiAction); - if (b == d->enabled && b != d->forceDisabled) - return; - d->forceDisabled = !b; - if (b && (!d->visible || (d->group && !d->group->isEnabled()))) + if (d->explicitEnabledValue == b && d->explicitEnabled) return; + d->explicitEnabledValue = b; + d->explicitEnabled = true; QAPP_CHECK("setEnabled"); - d->enabled = b; + d->setEnabled(b, false); +} + +bool QGuiActionPrivate::setEnabled(bool b, bool byGroup) +{ + Q_Q(QGuiAction); + if (b && !visible) + b = false; + if (b && !byGroup && (group && !group->isEnabled())) + b = false; + if (b && byGroup && explicitEnabled) + b = explicitEnabledValue; + + if (b == enabled) + return false; + + enabled = b; #if QT_CONFIG(shortcut) - d->setShortcutEnabled(b, QGuiApplicationPrivate::instance()->shortcutMap); + setShortcutEnabled(b, QGuiApplicationPrivate::instance()->shortcutMap); #endif - d->sendDataChanged(); + QPointer guard(q); + sendDataChanged(); + if (guard) + emit q->enabledChanged(b); + return true; +} + +void QGuiAction::resetEnabled() +{ + Q_D(QGuiAction); + if (!d->explicitEnabled) + return; + d->explicitEnabled = false; + d->setEnabled(true, false); } bool QGuiAction::isEnabled() const @@ -927,11 +955,11 @@ void QGuiAction::setVisible(bool b) QAPP_CHECK("setVisible"); d->forceInvisible = !b; d->visible = b; - d->enabled = b && !d->forceDisabled && (!d->group || d->group->isEnabled()) ; -#if QT_CONFIG(shortcut) - d->setShortcutEnabled(d->enabled, QGuiApplicationPrivate::instance()->shortcutMap); -#endif - d->sendDataChanged(); + bool enabled = d->visible; + if (enabled && d->explicitEnabled) + enabled = d->explicitEnabledValue; + if (!d->setEnabled(enabled, false)) + d->sendDataChanged(); } diff --git a/src/gui/kernel/qguiaction.h b/src/gui/kernel/qguiaction.h index 454f66893f..f717821120 100644 --- a/src/gui/kernel/qguiaction.h +++ b/src/gui/kernel/qguiaction.h @@ -63,7 +63,7 @@ class Q_GUI_EXPORT QGuiAction : public QObject Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY changed) Q_PROPERTY(bool checked READ isChecked WRITE setChecked NOTIFY toggled) - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY changed) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged RESET resetEnabled FINAL) Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY changed) Q_PROPERTY(QString text READ text WRITE setText NOTIFY changed) Q_PROPERTY(QString iconText READ iconText WRITE setIconText NOTIFY changed) @@ -175,11 +175,13 @@ public Q_SLOTS: void setChecked(bool); void toggle(); void setEnabled(bool); + void resetEnabled(); inline void setDisabled(bool b) { setEnabled(!b); } void setVisible(bool); Q_SIGNALS: void changed(); + void enabledChanged(bool changed); void triggered(bool checked = false); void hovered(); void toggled(bool); diff --git a/src/gui/kernel/qguiaction_p.h b/src/gui/kernel/qguiaction_p.h index 3358ed1070..08d9708a7e 100644 --- a/src/gui/kernel/qguiaction_p.h +++ b/src/gui/kernel/qguiaction_p.h @@ -81,6 +81,7 @@ public: return q->d_func(); } + bool setEnabled(bool enable, bool byGroup); QPointer group; QString text; @@ -101,7 +102,7 @@ public: uint autorepeat : 1; #endif QFont font; - uint enabled : 1, forceDisabled : 1; + uint enabled : 1, explicitEnabled : 1, explicitEnabledValue : 1; uint visible : 1, forceInvisible : 1; uint checkable : 1; uint checked : 1; diff --git a/src/gui/kernel/qguiactiongroup.cpp b/src/gui/kernel/qguiactiongroup.cpp index 7360214aad..defa5f15aa 100644 --- a/src/gui/kernel/qguiactiongroup.cpp +++ b/src/gui/kernel/qguiactiongroup.cpp @@ -170,10 +170,7 @@ QGuiAction *QGuiActionGroup::addAction(QGuiAction* a) QObject::connect(a, &QGuiAction::changed, this, &QGuiActionGroup::_q_actionChanged); QObject::connect(a, &QGuiAction::hovered, this, &QGuiActionGroup::_q_actionHovered); } - if (!a->d_func()->forceDisabled) { - a->setEnabled(d->enabled); - a->d_func()->forceDisabled = false; - } + a->d_func()->setEnabled(d->enabled, true); if (!a->d_func()->forceInvisible) { a->setVisible(d->visible); a->d_func()->forceInvisible = false; @@ -293,10 +290,7 @@ void QGuiActionGroup::setEnabled(bool b) Q_D(QGuiActionGroup); d->enabled = b; for (auto action : qAsConst(d->actions)) { - if (!action->d_func()->forceDisabled) { - action->setEnabled(b); - action->d_func()->forceDisabled = false; - } + action->d_func()->setEnabled(b, true); } } diff --git a/tests/auto/gui/kernel/qguiaction/tst_qguiaction.cpp b/tests/auto/gui/kernel/qguiaction/tst_qguiaction.cpp index 9d45d4ae14..3f314a74ae 100644 --- a/tests/auto/gui/kernel/qguiaction/tst_qguiaction.cpp +++ b/tests/auto/gui/kernel/qguiaction/tst_qguiaction.cpp @@ -56,6 +56,7 @@ private slots: #endif void task229128TriggeredSignalWithoutActiongroup(); void setData(); + void setEnabledSetVisible(); private: const int m_keyboardScheme; @@ -206,5 +207,29 @@ void tst_QGuiAction::setData() // QTBUG-62006 QCOMPARE(spy.count(), 1); } +void tst_QGuiAction::setEnabledSetVisible() +{ + QGuiAction action(nullptr); + QSignalSpy spy(&action, &QGuiAction::enabledChanged); + QVERIFY(action.isEnabled()); + QVERIFY(action.isVisible()); + QCOMPARE(spy.count(), 0); + action.setVisible(false); + QVERIFY(!action.isEnabled()); + QVERIFY(!action.isVisible()); + QCOMPARE(spy.count(), 1); + action.setEnabled(false); + QVERIFY(!action.isEnabled()); + QVERIFY(!action.isVisible()); + QCOMPARE(spy.count(), 1); + action.setVisible(true); + QVERIFY(!action.isEnabled()); + QVERIFY(action.isVisible()); + QCOMPARE(spy.count(), 1); + action.resetEnabled(); + QVERIFY(action.isEnabled()); + QCOMPARE(spy.count(), 2); +} + QTEST_MAIN(tst_QGuiAction) #include "tst_qguiaction.moc"