McuSupport: fix optional packages

MCU plugin didn't have to handle "optional" property in MCU kit descriptions.
I believe this is mainly because "optional" was always "false" for all
the previous MCU targets. A newly introduced kit, with one package set
"optional" to "true", manifested the issue. The user couldn't create a
kit without providing a valid path to that optional package.

The user should be able to leave the optional package path empty or
provide a valid path.

This change introduces a new Groupbox widget to display the optional
packages. An optional package with empty path is considered valid.

Task-number: QTCREATORBUG-32777
Change-Id: I5f27952efc77bc5e4351ab4c013669eb6056810f
Reviewed-by: Sivert Krøvel <sivert.krovel@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Karim Abdelrahman
2025-04-16 16:26:11 +03:00
parent 664bfdea57
commit 667a8edc7a
9 changed files with 63 additions and 12 deletions

View File

@@ -34,6 +34,7 @@ public:
virtual QString label() const = 0; virtual QString label() const = 0;
virtual QString cmakeVariableName() const = 0; virtual QString cmakeVariableName() const = 0;
virtual QString environmentVariableName() const = 0; virtual QString environmentVariableName() const = 0;
virtual bool isOptional() const = 0;
virtual bool isAddToSystemPath() const = 0; virtual bool isAddToSystemPath() const = 0;
virtual QStringList versions() const = 0; virtual QStringList versions() const = 0;

View File

@@ -41,6 +41,7 @@ McuPackage::McuPackage(const SettingsHandler::Ptr &settingsHandler,
const QStringList &versions, const QStringList &versions,
const QString &downloadUrl, const QString &downloadUrl,
const McuPackageVersionDetector *versionDetector, const McuPackageVersionDetector *versionDetector,
const bool optional,
const bool addToSystemPath, const bool addToSystemPath,
const Utils::PathChooser::Kind &valueType, const Utils::PathChooser::Kind &valueType,
const bool allowNewerVersionKey) const bool allowNewerVersionKey)
@@ -53,6 +54,7 @@ McuPackage::McuPackage(const SettingsHandler::Ptr &settingsHandler,
, m_cmakeVariableName(cmakeVarName) , m_cmakeVariableName(cmakeVarName)
, m_environmentVariableName(envVarName) , m_environmentVariableName(envVarName)
, m_downloadUrl(downloadUrl) , m_downloadUrl(downloadUrl)
, m_optional(optional)
, m_addToSystemPath(addToSystemPath) , m_addToSystemPath(addToSystemPath)
, m_valueType(valueType) , m_valueType(valueType)
{ {
@@ -93,6 +95,11 @@ QString McuPackage::environmentVariableName() const
return m_environmentVariableName; return m_environmentVariableName;
} }
bool McuPackage::isOptional() const
{
return m_optional;
}
bool McuPackage::isAddToSystemPath() const bool McuPackage::isAddToSystemPath() const
{ {
return m_addToSystemPath; return m_addToSystemPath;
@@ -190,14 +197,22 @@ McuPackage::Status McuPackage::status() const
return m_status; return m_status;
} }
bool McuPackage::isOptionalAndEmpty() const
{
return m_status == Status::EmptyPath && isOptional();
}
bool McuPackage::isValidStatus() const bool McuPackage::isValidStatus() const
{ {
return m_status == Status::ValidPackage || m_status == Status::ValidPackageMismatchedVersion return m_status == Status::ValidPackage || m_status == Status::ValidPackageMismatchedVersion
|| m_status == Status::ValidPackageVersionNotDetected; || m_status == Status::ValidPackageVersionNotDetected || isOptionalAndEmpty();
} }
void McuPackage::updateStatusUi() void McuPackage::updateStatusUi()
{ {
if (isOptionalAndEmpty()) {
m_infoLabel->setType(InfoLabel::Ok);
} else {
switch (m_status) { switch (m_status) {
case Status::ValidPackage: case Status::ValidPackage:
m_infoLabel->setType(InfoLabel::Ok); m_infoLabel->setType(InfoLabel::Ok);
@@ -210,6 +225,7 @@ void McuPackage::updateStatusUi()
m_infoLabel->setType(InfoLabel::NotOk); m_infoLabel->setType(InfoLabel::NotOk);
break; break;
} }
}
m_infoLabel->setText(statusText()); m_infoLabel->setText(statusText());
} }

View File

@@ -39,6 +39,7 @@ public:
const QString &downloadUrl = {}, const QString &downloadUrl = {},
const McuPackageVersionDetector *versionDetector = nullptr, const McuPackageVersionDetector *versionDetector = nullptr,
const bool addToPath = false, const bool addToPath = false,
const bool optional = false,
const Utils::PathChooser::Kind &valueType const Utils::PathChooser::Kind &valueType
= Utils::PathChooser::Kind::ExistingDirectory, = Utils::PathChooser::Kind::ExistingDirectory,
const bool allowNewerVersionKey = false); const bool allowNewerVersionKey = false);
@@ -50,6 +51,7 @@ public:
QString label() const override; QString label() const override;
QString cmakeVariableName() const override; QString cmakeVariableName() const override;
QString environmentVariableName() const override; QString environmentVariableName() const override;
bool isOptional() const override;
bool isAddToSystemPath() const override; bool isAddToSystemPath() const override;
QStringList versions() const override; QStringList versions() const override;
@@ -77,6 +79,8 @@ private:
void updatePath(); void updatePath();
void updateStatusUi(); void updateStatusUi();
bool isOptionalAndEmpty() const;
SettingsHandler::Ptr settingsHandler; SettingsHandler::Ptr settingsHandler;
Utils::PathChooser *m_fileChooser = nullptr; Utils::PathChooser *m_fileChooser = nullptr;
@@ -95,6 +99,7 @@ private:
const QString m_cmakeVariableName; const QString m_cmakeVariableName;
const QString m_environmentVariableName; const QString m_environmentVariableName;
const QString m_downloadUrl; const QString m_downloadUrl;
const bool m_optional;
const bool m_addToSystemPath; const bool m_addToSystemPath;
const Utils::PathChooser::Kind m_valueType; const Utils::PathChooser::Kind m_valueType;

View File

@@ -55,8 +55,10 @@ private:
QMap<McuPackagePtr, QWidget *> m_packageWidgets; QMap<McuPackagePtr, QWidget *> m_packageWidgets;
QMap<McuTargetPtr, QWidget *> m_mcuTargetPacketWidgets; QMap<McuTargetPtr, QWidget *> m_mcuTargetPacketWidgets;
QFormLayout *m_packagesLayout = nullptr; QFormLayout *m_packagesLayout = nullptr;
QFormLayout *m_optionalPackagesLayout = nullptr;
QGroupBox *m_qtForMCUsSdkGroupBox = nullptr; QGroupBox *m_qtForMCUsSdkGroupBox = nullptr;
QGroupBox *m_packagesGroupBox = nullptr; QGroupBox *m_packagesGroupBox = nullptr;
QGroupBox *m_optionalPackagesGroupBox = nullptr;
QGroupBox *m_mcuTargetsGroupBox = nullptr; QGroupBox *m_mcuTargetsGroupBox = nullptr;
QComboBox *m_mcuTargetsComboBox = nullptr; QComboBox *m_mcuTargetsComboBox = nullptr;
QGroupBox *m_kitCreationGroupBox = nullptr; QGroupBox *m_kitCreationGroupBox = nullptr;
@@ -122,6 +124,14 @@ McuSupportOptionsWidget::McuSupportOptionsWidget(McuSupportOptions &options,
m_packagesGroupBox->setLayout(m_packagesLayout); m_packagesGroupBox->setLayout(m_packagesLayout);
} }
{
m_optionalPackagesGroupBox = new QGroupBox(Tr::tr("Optional"));
m_optionalPackagesGroupBox->setFlat(true);
mainLayout->addWidget(m_optionalPackagesGroupBox);
m_optionalPackagesLayout = new QFormLayout;
m_optionalPackagesGroupBox->setLayout(m_optionalPackagesLayout);
}
{ {
m_mcuTargetsInfoLabel = new Utils::InfoLabel; m_mcuTargetsInfoLabel = new Utils::InfoLabel;
mainLayout->addWidget(m_mcuTargetsInfoLabel); mainLayout->addWidget(m_mcuTargetsInfoLabel);
@@ -187,6 +197,10 @@ void McuSupportOptionsWidget::updateStatus()
const bool ready = valid && mcuTarget; const bool ready = valid && mcuTarget;
m_mcuTargetsGroupBox->setVisible(ready); m_mcuTargetsGroupBox->setVisible(ready);
m_packagesGroupBox->setVisible(ready && !mcuTarget->packages().isEmpty()); m_packagesGroupBox->setVisible(ready && !mcuTarget->packages().isEmpty());
m_optionalPackagesGroupBox->setVisible(
ready && std::ranges::any_of(mcuTarget->packages(), [](McuPackagePtr p) {
return p->isOptional();
}));
m_kitCreationGroupBox->setVisible(ready); m_kitCreationGroupBox->setVisible(ready);
m_mcuTargetsInfoLabel->setVisible(valid && m_options.sdkRepository.mcuTargets.isEmpty()); m_mcuTargetsInfoLabel->setVisible(valid && m_options.sdkRepository.mcuTargets.isEmpty());
if (m_mcuTargetsInfoLabel->isVisible()) { if (m_mcuTargetsInfoLabel->isVisible()) {
@@ -266,6 +280,10 @@ void McuSupportOptionsWidget::showMcuTargetPackages()
m_packagesLayout->removeRow(0); m_packagesLayout->removeRow(0);
} }
while (m_optionalPackagesLayout->rowCount() > 0) {
m_optionalPackagesLayout->removeRow(0);
}
std::set<McuPackagePtr, McuPackageSort> packages; std::set<McuPackagePtr, McuPackageSort> packages;
for (const auto &package : mcuTarget->packages()) { for (const auto &package : mcuTarget->packages()) {
@@ -285,6 +303,9 @@ void McuSupportOptionsWidget::showMcuTargetPackages()
package->setPath(macroExpander->expand(package->defaultPath())); package->setPath(macroExpander->expand(package->defaultPath()));
} }
}); });
if (package->isOptional())
m_optionalPackagesLayout->addRow(package->label(), packageWidget);
else
m_packagesLayout->addRow(package->label(), packageWidget); m_packagesLayout->addRow(package->label(), packageWidget);
packageWidget->show(); packageWidget->show();
} }

View File

@@ -61,6 +61,7 @@ McuPackagePtr createQtForMCUsPackage(const SettingsHandler::Ptr &settingsHandler
{}, // versions {}, // versions
{}, // downloadUrl {}, // downloadUrl
nullptr, // versionDetector nullptr, // versionDetector
false, // optional
false, // addToPath false, // addToPath
Utils::PathChooser::Kind::ExistingDirectory, // valueType Utils::PathChooser::Kind::ExistingDirectory, // valueType
true)}; // useNewestVersionKey true)}; // useNewestVersionKey
@@ -706,6 +707,7 @@ static PackageDescription parsePackage(const QJsonObject &cmakeEntry)
detectionPaths, detectionPaths,
versions, versions,
parseVersionDetection(cmakeEntry), parseVersionDetection(cmakeEntry),
cmakeEntry["optional"].toBool(),
cmakeEntry["addToSystemPath"].toBool(), cmakeEntry["addToSystemPath"].toBool(),
parseLineEditType(cmakeEntry["type"])}; parseLineEditType(cmakeEntry["type"])};
} }

View File

@@ -33,6 +33,7 @@ struct PackageDescription
Utils::FilePaths detectionPaths; Utils::FilePaths detectionPaths;
QStringList versions; QStringList versions;
VersionDetection versionDetection; VersionDetection versionDetection;
bool optional;
bool shouldAddToSystemPath; bool shouldAddToSystemPath;
Utils::PathChooser::Kind type; Utils::PathChooser::Kind type;
}; //struct PackageDescription }; //struct PackageDescription

View File

@@ -137,6 +137,7 @@ McuPackagePtr McuTargetFactory::createPackage(const PackageDescription &pkgDesc)
pkgDesc.versions, pkgDesc.versions,
{}, {},
createVersionDetection(pkgDesc.versionDetection), createVersionDetection(pkgDesc.versionDetection),
pkgDesc.optional,
pkgDesc.shouldAddToSystemPath, pkgDesc.shouldAddToSystemPath,
pkgDesc.type}}; pkgDesc.type}};
} }

View File

@@ -29,6 +29,7 @@ public:
MOCK_METHOD(bool, isValidStatus, (), (const)); MOCK_METHOD(bool, isValidStatus, (), (const));
MOCK_METHOD(QString, cmakeVariableName, (), (const)); MOCK_METHOD(QString, cmakeVariableName, (), (const));
MOCK_METHOD(QString, environmentVariableName, (), (const)); MOCK_METHOD(QString, environmentVariableName, (), (const));
MOCK_METHOD(bool, isOptional, (), (const));
MOCK_METHOD(bool, isAddToSystemPath, (), (const)); MOCK_METHOD(bool, isAddToSystemPath, (), (const));
MOCK_METHOD(bool, writeToSettings, (), (const)); MOCK_METHOD(bool, writeToSettings, (), (const));
MOCK_METHOD(void, readFromSettings, ()); MOCK_METHOD(void, readFromSettings, ());

View File

@@ -196,6 +196,7 @@ const PackageDescription
{}, {},
VersionDetection{}, VersionDetection{},
false, false,
false,
Utils::PathChooser::Kind::ExistingDirectory}; Utils::PathChooser::Kind::ExistingDirectory};
const McuTargetDescription::Platform platformDescription{id, const McuTargetDescription::Platform platformDescription{id,
@@ -851,6 +852,7 @@ void McuSupportTest::test_useFallbackPathForToolchainWhenPathFromSettingsIsNotAv
{}, {},
VersionDetection{}, VersionDetection{},
false, false,
false,
Utils::PathChooser::Kind::ExistingDirectory}; Utils::PathChooser::Kind::ExistingDirectory};
McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}}; McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}};
@@ -875,6 +877,7 @@ void McuSupportTest::test_usePathFromSettingsForToolchainPath()
{}, {},
VersionDetection{}, VersionDetection{},
false, false,
false,
Utils::PathChooser::Kind::ExistingDirectory}; Utils::PathChooser::Kind::ExistingDirectory};
McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}}; McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}};