diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2023-02-07 16:01:41 +0200 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2023-02-07 14:55:18 +0000 |
commit | a5949543b6c1aecd638982274682942605e4c202 (patch) | |
tree | 96fcccb55ecbd66889cf9c18d40f55a057d455ea /src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp | |
parent | 980a9044f9477df0c4feac2367c236119bcad17c (diff) |
QmlDesigner: Fix condition chains in 3D import options
When an import option conditionally depends on another option that
depends on a third option, toggling the third option needs to change
the enabled state of the first option controls as well as the second
option controls.
For example, consider this set of options (actual case with options
for generating mesh levels of detail in Qt 6.5):
optA
optB, enabled when optA is true
optC, enabled when optB is true
optD, enabled when optB is true
If optA is false, optC and optD controls need to be disabled even if
optB is true, because of the chained conditions.
Fixes: QDS-9055
Change-Id: I10aeb7596cf9c8a9053c7d08ec9ebb7a46db2cd2
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Diffstat (limited to 'src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp')
-rw-r--r-- | src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp index dab4fb9e1f..ab829f1e6f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp @@ -587,11 +587,34 @@ QGridLayout *ItemLibraryAssetImportDialog::createOptionsGrid( m_labelToControlWidgetMaps[optionsIndex].insert(optKey, optControl); } - // Handle conditions + // Find condition chains (up to two levels supported) + // key: Option that has condition and is also specified in another condition as property + // value: List of extra widgets that are affected by key property via condition + QHash<QString, QList<QWidget *>> conditionChains; auto it = conditionMap.constBegin(); while (it != conditionMap.constEnd()) { const QString &option = it.key(); const QJsonArray &conditions = it.value(); + if (!conditions.isEmpty()) { + const QString optItem = conditions[0].toObject().value("property").toString(); + if (conditionMap.contains(optItem)) { + if (!conditionChains.contains(optItem)) + conditionChains.insert(optItem, {}); + QPair<QWidget *, QWidget *> widgetPair = optionToWidgetsMap.value(option); + if (widgetPair.first) + conditionChains[optItem].append(widgetPair.first); + if (widgetPair.second) + conditionChains[optItem].append(widgetPair.second); + } + } + ++it; + } + + // Handle conditions + it = conditionMap.constBegin(); + while (it != conditionMap.constEnd()) { + const QString &option = it.key(); + const QJsonArray &conditions = it.value(); const auto &conWidgets = optionToWidgetsMap.value(option); QWidget *conLabel = conWidgets.first; QWidget *conControl = conWidgets.second; @@ -620,21 +643,33 @@ QGridLayout *ItemLibraryAssetImportDialog::createOptionsGrid( auto optSpin = qobject_cast<QDoubleSpinBox *>(optWidgets.second); if (optCb) { auto enableConditionally = [optValue](QCheckBox *cb, QWidget *w1, - QWidget *w2, Mode mode) { + QWidget *w2, const QList<QWidget *> &extraWidgets, Mode mode) { bool equals = (mode == Mode::equals) == optValue.toBool(); bool enable = cb->isChecked() == equals; w1->setEnabled(enable); w2->setEnabled(enable); + if (extraWidgets.isEmpty()) + return; + + if (auto conditionCb = qobject_cast<QCheckBox *>(w2)) { + for (const auto w : extraWidgets) + w->setEnabled(conditionCb->isChecked() && enable); + } }; - enableConditionally(optCb, conLabel, conControl, mode); + // Only initialize conditional state if conditional control is enabled. + // If it is disabled, it is assumed that previous chained condition handling + // already handled this case. + if (optCb->isEnabled()) + enableConditionally(optCb, conLabel, conControl, conditionChains[option], mode); if (conditionalWidgetMap.contains(optCb)) conditionalWidgetMap.insert(optCb, nullptr); else conditionalWidgetMap.insert(optCb, conControl); QObject::connect( optCb, &QCheckBox::toggled, optCb, - [optCb, conLabel, conControl, mode, enableConditionally]() { - enableConditionally(optCb, conLabel, conControl, mode); + [optCb, conLabel, conControl, extraWidgets = conditionChains[option], + mode, enableConditionally]() { + enableConditionally(optCb, conLabel, conControl, extraWidgets, mode); }); } if (optSpin) { |