diff --git a/src/plugins/mcusupport/CMakeLists.txt b/src/plugins/mcusupport/CMakeLists.txt index 81fadd4ddfb..b0ff6d8fc45 100644 --- a/src/plugins/mcusupport/CMakeLists.txt +++ b/src/plugins/mcusupport/CMakeLists.txt @@ -24,6 +24,7 @@ add_qtc_plugin(McuSupport settingshandler.cpp settingshandler.h mcuqmlprojectnode.cpp mcuqmlprojectnode.h mcubuildstep.cpp mcubuildstep.h + dialogs/mcukitcreationdialog.h dialogs/mcukitcreationdialog.cpp dialogs/mcukitcreationdialog.ui ) add_subdirectory(test) diff --git a/src/plugins/mcusupport/dialogs/mcukitcreationdialog.cpp b/src/plugins/mcusupport/dialogs/mcukitcreationdialog.cpp new file mode 100644 index 00000000000..e708d53039d --- /dev/null +++ b/src/plugins/mcusupport/dialogs/mcukitcreationdialog.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "mcukitcreationdialog.h" +#include "ui_mcukitcreationdialog.h" + +#include "mcuabstractpackage.h" +#include "mcusupportconstants.h" +#include "mcusupporttr.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace McuSupport::Internal { + +McuKitCreationDialog::McuKitCreationDialog(const MessagesList &messages, + const SettingsHandler::Ptr &settingsHandler, + McuPackagePtr qtMCUPackage, + QWidget *parent) + : QDialog(parent) + , ui(new Ui::McuKitCreationDialog) + , m_messages(messages) +{ + ui->setupUi(this); + ui->iconLabel->setPixmap(Utils::Icon(":/mcusupport/images/mcusupportdevice.png").pixmap()); + m_previousButton = ui->buttonBox->addButton("<", QDialogButtonBox::ActionRole); + m_nextButton = ui->buttonBox->addButton(">", QDialogButtonBox::ActionRole); + m_fixButton = ui->buttonBox->addButton(Tr::tr("Fix"), QDialogButtonBox::ActionRole); + m_helpButton = ui->buttonBox->addButton(Tr::tr("Help"), QDialogButtonBox::HelpRole); + // prevent clicking the buttons from closing the message box + m_nextButton->disconnect(); + m_previousButton->disconnect(); + + if (messages.size() == 1) { + m_nextButton->setVisible(false); + m_previousButton->setVisible(false); + } + //display first message + if (messages.size() > 1) + updateMessage(1); + + if (qtMCUPackage->isValidStatus()) + ui->qtMCUsPathLabel->setText( + Tr::tr("Qt for MCUs path %1").arg(qtMCUPackage->path().toUserOutput())); + connect(m_nextButton, &QPushButton::clicked, [=] { updateMessage(1); }); + connect(m_previousButton, &QPushButton::clicked, [=] { updateMessage(-1); }); + connect(m_fixButton, &QPushButton::clicked, [=] { + // Open the MCU Options widget on the current platform + settingsHandler->setInitialPlatformName(m_messages[m_currentIndex].platform); + Core::ICore::showOptionsDialog(Constants::SETTINGS_ID); + // reset the initial platform name + settingsHandler->setInitialPlatformName(""); + }); + connect(m_helpButton, &QPushButton::clicked, [] { + QDesktopServices::openUrl(QUrl("https://doc.qt.io/QtForMCUs/qtul-prerequisites.html")); + }); +} + +void McuKitCreationDialog::updateMessage(const int inc) +{ + m_currentIndex += inc; + m_nextButton->setEnabled(m_currentIndex < (m_messages.size() - 1)); + m_previousButton->setEnabled(m_currentIndex > 0); + ui->textLabel->setText(QString("%1 %2 : %3") + .arg(Tr::tr("Target"), + (m_messages[m_currentIndex].status == McuSupportMessage::Warning + ? Tr::tr("Warning") + : Tr::tr("Error")), + m_messages[m_currentIndex].platform)); + ui->iconLabel->setPixmap( + QApplication::style() + ->standardIcon(m_messages[m_currentIndex].status == McuSupportMessage::Warning + ? QStyle::SP_MessageBoxWarning + : QStyle::SP_MessageBoxCritical) + .pixmap(64, 64)); + ui->informationLabel->setText(QString("%1: %2

%3: %4") + .arg(Tr::tr("Package"), + m_messages[m_currentIndex].packageName, + Tr::tr("Status"), + m_messages.at(m_currentIndex).message)); + ui->messageCountLabel->setText(QString("%1 / %2").arg(QString::number(m_currentIndex + 1), + QString::number(m_messages.size()))); +} + +McuKitCreationDialog::~McuKitCreationDialog() +{ + delete ui; +} + +} // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/dialogs/mcukitcreationdialog.h b/src/plugins/mcusupport/dialogs/mcukitcreationdialog.h new file mode 100644 index 00000000000..186eec7be41 --- /dev/null +++ b/src/plugins/mcusupport/dialogs/mcukitcreationdialog.h @@ -0,0 +1,40 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "mcusupport_global.h" +#include "settingshandler.h" +#include +#include + +namespace Ui { +class McuKitCreationDialog; +} + +namespace McuSupport::Internal { + +class McuKitCreationDialog : public QDialog +{ + Q_OBJECT + +public: + explicit McuKitCreationDialog(const MessagesList &messages, + const SettingsHandler::Ptr &settingsHandler, + McuPackagePtr qtMCUPackage, + QWidget *parent = nullptr); + ~McuKitCreationDialog(); + +private slots: + void updateMessage(const int inc); + +private: + Ui::McuKitCreationDialog *ui; + int m_currentIndex = -1; + QPushButton *m_previousButton; + QPushButton *m_nextButton; + QPushButton *m_helpButton; + QPushButton *m_fixButton; + const MessagesList &m_messages; +}; +} // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/dialogs/mcukitcreationdialog.ui b/src/plugins/mcusupport/dialogs/mcukitcreationdialog.ui new file mode 100644 index 00000000000..f6194bbe6e3 --- /dev/null +++ b/src/plugins/mcusupport/dialogs/mcukitcreationdialog.ui @@ -0,0 +1,154 @@ + + + McuKitCreationDialog + + + + 0 + 0 + 349 + 200 + + + + QtMCUs Kit Creation + + + true + + + + + + QtMCUs path: + + + + + + + Qt::Vertical + + + + + + + 1/3 + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + QDialogButtonBox::Ignore + + + + + + + Dialog text + + + Qt::RichText + + + true + + + + + + + + 64 + 64 + + + + + 70 + 1000 + + + + + + + false + + + Qt::AlignHCenter|Qt::AlignTop + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + TextLabel + + + Qt::RichText + + + + + + + + + + + buttonBox + accepted() + McuKitCreationDialog + accept() + + + 339 + 23 + + + 157 + 199 + + + + + buttonBox + rejected() + McuKitCreationDialog + reject() + + + 339 + 29 + + + 286 + 199 + + + + + diff --git a/src/plugins/mcusupport/mcukitmanager.cpp b/src/plugins/mcusupport/mcukitmanager.cpp index f68eca6973d..00709b126f5 100644 --- a/src/plugins/mcusupport/mcukitmanager.cpp +++ b/src/plugins/mcusupport/mcukitmanager.cpp @@ -3,6 +3,7 @@ #include "mcukitmanager.h" #include "mculegacyconstants.h" +#include "mcusupport_global.h" #include "mcusupportoptions.h" #include "mcukitinformation.h" @@ -486,31 +487,37 @@ void createAutomaticKits(const SettingsHandler::Ptr &settingsHandler) { McuPackagePtr qtForMCUsPackage{createQtForMCUsPackage(settingsHandler)}; - const auto createKits = [qtForMCUsPackage, settingsHandler]() { + // add a list of package, board, errormessage, + MessagesList autoGenerationMessages; + + const auto createKits = [&autoGenerationMessages, qtForMCUsPackage, settingsHandler] { if (settingsHandler->isAutomaticKitCreationEnabled()) { qtForMCUsPackage->updateStatus(); if (!qtForMCUsPackage->isValidStatus()) { switch (qtForMCUsPackage->status()) { case McuAbstractPackage::Status::ValidPathInvalidPackage: { - printMessage(Tr::tr("Path %1 exists, but does not contain %2.") - .arg(qtForMCUsPackage->path().toUserOutput(), - qtForMCUsPackage->detectionPath().toUserOutput()), - true); + const QString message + = Tr::tr("Path %1 exists, but does not contain %2.") + .arg(qtForMCUsPackage->path().toUserOutput(), + qtForMCUsPackage->detectionPath().toUserOutput()); + autoGenerationMessages.push_back({qtForMCUsPackage->label(), "", message}); + printMessage(message, true); break; } case McuAbstractPackage::Status::InvalidPath: { - printMessage(Tr::tr( - "Path %1 does not exist. Add the path in Edit > Preferences > " - "Devices > MCU.") - .arg(qtForMCUsPackage->path().toUserOutput()), - true); + const QString message + = Tr::tr("Path %1 does not exist. Add the path in Edit > Preferences > " + "Devices > MCU.") + .arg(qtForMCUsPackage->path().toUserOutput()); + autoGenerationMessages.push_back({qtForMCUsPackage->label(), "", message}); + printMessage(message, true); break; } case McuAbstractPackage::Status::EmptyPath: { - printMessage( - Tr::tr("Missing %1. Add the path in Edit > Preferences > Devices > MCU.") - .arg(qtForMCUsPackage->detectionPath().toUserOutput()), - true); + const QString message = Tr::tr("Missing %1. Add the path in Edit > Preferences > Devices > MCU.") + .arg(qtForMCUsPackage->detectionPath().toUserOutput()); + autoGenerationMessages.push_back({qtForMCUsPackage->label(), "", message}); + printMessage(message, true); return; } default: @@ -520,10 +527,10 @@ void createAutomaticKits(const SettingsHandler::Ptr &settingsHandler) } if (CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty()) { - printMessage( - Tr::tr("No CMake tool was detected. Add a CMake tool in Edit > Preferences > " - "Kits > CMake."), - true); + const QString message = Tr::tr("No CMake tool was detected. Add a CMake tool in Edit > Preferences > " + "Kits > CMake."); + autoGenerationMessages.push_back({qtForMCUsPackage->label(), "", message}); + printMessage(message, true); return; } @@ -543,7 +550,7 @@ void createAutomaticKits(const SettingsHandler::Ptr &settingsHandler) // if no kits for this target, create if (target->isValid()) newKit(target.get(), qtForMCUsPackage); - target->printPackageProblems(); + target->handlePackageProblems(autoGenerationMessages); } } if (needsUpgrade) @@ -552,6 +559,9 @@ void createAutomaticKits(const SettingsHandler::Ptr &settingsHandler) }; createKits(); + McuSupportOptions::displayKitCreationMessages(autoGenerationMessages, + settingsHandler, + qtForMCUsPackage); } // Maintenance @@ -569,6 +579,7 @@ void upgradeKitsByCreatingNewPackage(const SettingsHandler::Ptr &settingsHandler McuSdkRepository repo{targetsAndPackages(qtForMCUsPackage, settingsHandler)}; + MessagesList messages; for (const auto &target : std::as_const(repo.mcuTargets)) { if (!matchingKits(target.get(), qtForMCUsPackage).empty()) // already up-to-date @@ -583,9 +594,11 @@ void upgradeKitsByCreatingNewPackage(const SettingsHandler::Ptr &settingsHandler if (target->isValid()) newKit(target.get(), qtForMCUsPackage); - target->printPackageProblems(); + target->handlePackageProblems(messages); } } + // Open the dialog showing warnings and errors in packages + McuSupportOptions::displayKitCreationMessages(messages, settingsHandler, qtForMCUsPackage); } // Maintenance diff --git a/src/plugins/mcusupport/mcusupport.qbs b/src/plugins/mcusupport/mcusupport.qbs index 0587067cc64..7b686075cac 100644 --- a/src/plugins/mcusupport/mcusupport.qbs +++ b/src/plugins/mcusupport/mcusupport.qbs @@ -58,6 +58,9 @@ QtcPlugin { "mcuhelpers.h", "settingshandler.h", "settingshandler.cpp", + "dialogs/mcukitcreationdialog.ui", + "dialogs/mcukitcreationdialog.h", + "dialogs/mcukitcreationdialog.cpp", ] QtcTestFiles { diff --git a/src/plugins/mcusupport/mcusupport_global.h b/src/plugins/mcusupport/mcusupport_global.h index c1a20746a24..20de9a73298 100644 --- a/src/plugins/mcusupport/mcusupport_global.h +++ b/src/plugins/mcusupport/mcusupport_global.h @@ -30,4 +30,13 @@ static const QVersionNumber newVersion{2, 3}; using Targets = QList; using Packages = QSet; +struct McuSupportMessage +{ + QString packageName; + QString platform; + QString message; + enum Status { Warning, Error } status = Status::Error; +}; +using MessagesList = QList; + } // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcusupportconstants.h b/src/plugins/mcusupport/mcusupportconstants.h index 31e67c7b1ca..780880d9d11 100644 --- a/src/plugins/mcusupport/mcusupportconstants.h +++ b/src/plugins/mcusupport/mcusupportconstants.h @@ -22,5 +22,7 @@ const char SETTINGS_GROUP[]{"McuSupport"}; const char SETTINGS_KEY_PACKAGE_PREFIX[]{"Package_"}; const char SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK[]{"QtForMCUsSdk"}; // Key known by SDK installer const char SETTINGS_KEY_AUTOMATIC_KIT_CREATION[]{"AutomaticKitCreation"}; +// Used to decide which platform will be displayed first in the MCU Options page +const char SETTINGS_KEY_INITIAL_PLATFORM_KEY[]{"McuSupport.InitialPlatform"}; } // namespace McuSupport::Internal::Constants diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index 474314b6a6b..51cb1eacd81 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -3,9 +3,11 @@ #include "mcusupportoptions.h" +#include "dialogs/mcukitcreationdialog.h" #include "mcuhelpers.h" #include "mcukitmanager.h" #include "mcupackage.h" +#include "mcusupport_global.h" #include "mcusupportconstants.h" #include "mcusupportsdk.h" #include "mcusupporttr.h" @@ -19,6 +21,7 @@ #include #include #include +#include #include #include @@ -252,6 +255,30 @@ McuKitManager::UpgradeOption McuSupportOptions::askForKitUpgrades() return McuKitManager::UpgradeOption::Ignore; } +void McuSupportOptions::displayKitCreationMessages(const MessagesList &messages, + const SettingsHandler::Ptr &settingsHandler, + McuPackagePtr qtMCUsPackage) +{ + if (messages.isEmpty() || !qtMCUsPackage->isValidStatus()) + return; + static const char mcuKitCreationErrorInfoId[] = "ErrorWhileCreatingMCUKits"; + if (!Core::ICore::infoBar()->canInfoBeAdded(mcuKitCreationErrorInfoId)) + return; + + Utils::InfoBarEntry info(mcuKitCreationErrorInfoId, + Tr::tr("Errors while creating Qt for MCUs kits"), + Utils::InfoBarEntry::GlobalSuppression::Enabled); + + info.addCustomButton(Tr::tr("Details"), [=] { + auto popup = new McuKitCreationDialog(messages, settingsHandler, qtMCUsPackage); + popup->exec(); + delete popup; + Core::ICore::infoBar()->removeInfo(mcuKitCreationErrorInfoId); + }); + + Core::ICore::infoBar()->addInfo(info); +} + void McuSupportOptions::checkUpgradeableKits() { if (!qtForMCUsSdkPackage->isValidStatus() || sdkRepository.mcuTargets.isEmpty()) diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index a442c0864a7..1090f871004 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -61,6 +61,9 @@ public: [[nodiscard]] Utils::FilePath qulDirFromSettings() const; [[nodiscard]] Utils::FilePath qulDocsDir() const; static McuKitManager::UpgradeOption askForKitUpgrades(); + static void displayKitCreationMessages(const MessagesList &messages, + const SettingsHandler::Ptr &settingsHandler, + McuPackagePtr qtMCUsPackage); void registerQchFiles() const; void registerExamples() const; diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index d75568a8f66..a05a3771b07 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -350,10 +350,17 @@ void McuSupportOptionsWidget::populateMcuTargetsComboBox() { m_options.populatePackagesAndTargets(); m_mcuTargetsComboBox->clear(); + int initialPlatformIndex = 0; + int targetsCounter = -1; m_mcuTargetsComboBox->addItems( - Utils::transform(m_options.sdkRepository.mcuTargets, [](const McuTargetPtr &t) { + Utils::transform(m_options.sdkRepository.mcuTargets, [&](const McuTargetPtr &t) { + if (t->platform().name == m_settingsHandler->initialPlatformName()) + initialPlatformIndex = m_options.sdkRepository.mcuTargets.indexOf(t); + targetsCounter++; return McuKitManager::generateKitNameFromTarget(t.get()); })); + if (targetsCounter != -1) + m_mcuTargetsComboBox->setCurrentIndex(initialPlatformIndex); updateStatus(); } diff --git a/src/plugins/mcusupport/mcutarget.cpp b/src/plugins/mcusupport/mcutarget.cpp index 2040c260398..d7a3b0fe397 100644 --- a/src/plugins/mcusupport/mcutarget.cpp +++ b/src/plugins/mcusupport/mcutarget.cpp @@ -1,11 +1,12 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include "mcutarget.h" #include "mcukitmanager.h" #include "mcupackage.h" +#include "mcusupport_global.h" #include "mcusupportplugin.h" #include "mcusupporttr.h" -#include "mcutarget.h" #include @@ -82,22 +83,33 @@ QString McuTarget::desktopCompilerId() const return QLatin1String("invalid"); } -void McuTarget::printPackageProblems() const +void McuTarget::handlePackageProblems(MessagesList &messages) const { for (auto package : packages()) { package->updateStatus(); - if (!package->isValidStatus()) + if (!package->isValidStatus()) { printMessage(Tr::tr("Error creating kit for target %1, package %2: %3") .arg(McuKitManager::generateKitNameFromTarget(this), package->label(), package->statusText()), true); - if (package->status() == McuAbstractPackage::Status::ValidPackageMismatchedVersion) + messages.push_back({package->label(), + this->platform().name, + package->statusText(), + McuSupportMessage::Error}); + } + if (package->status() == McuAbstractPackage::Status::ValidPackageMismatchedVersion) { printMessage(Tr::tr("Warning creating kit for target %1, package %2: %3") .arg(McuKitManager::generateKitNameFromTarget(this), package->label(), package->statusText()), false); + + messages.push_back({package->label(), + this->platform().name, + package->statusText(), + McuSupportMessage::Warning}); + } } } diff --git a/src/plugins/mcusupport/mcutarget.h b/src/plugins/mcusupport/mcutarget.h index 57f28030be7..8ee19f54ab0 100644 --- a/src/plugins/mcusupport/mcutarget.h +++ b/src/plugins/mcusupport/mcutarget.h @@ -54,7 +54,7 @@ public: int colorDepth() const; bool isValid() const; QString desktopCompilerId() const; - void printPackageProblems() const; + void handlePackageProblems(MessagesList &messages) const; private: const QVersionNumber m_qulVersion; diff --git a/src/plugins/mcusupport/settingshandler.cpp b/src/plugins/mcusupport/settingshandler.cpp index d292ea6cd69..67fbd27f978 100644 --- a/src/plugins/mcusupport/settingshandler.cpp +++ b/src/plugins/mcusupport/settingshandler.cpp @@ -68,4 +68,17 @@ void SettingsHandler::setAutomaticKitCreation(bool isEnabled) settings->setValue(automaticKitCreationSettingsKey, isEnabled); } +void SettingsHandler::setInitialPlatformName(const QString &platform) +{ + QSettings *settings = Core::ICore::settings(QSettings::UserScope); + settings->setValue(Constants::SETTINGS_KEY_INITIAL_PLATFORM_KEY, platform); +} + +QString SettingsHandler::initialPlatformName() const +{ + QSettings *settings = Core::ICore::settings(QSettings::UserScope); + const QString name + = settings->value(Constants::SETTINGS_KEY_INITIAL_PLATFORM_KEY, "").toString(); + return name; +} } // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/settingshandler.h b/src/plugins/mcusupport/settingshandler.h index 02bbbcf26df..145049e31db 100644 --- a/src/plugins/mcusupport/settingshandler.h +++ b/src/plugins/mcusupport/settingshandler.h @@ -27,5 +27,8 @@ public: virtual bool isAutomaticKitCreationEnabled() const; void setAutomaticKitCreation(bool isEnabled); + void setInitialPlatformName(const QString &platform); + QString initialPlatformName() const; + }; //class SettingsHandler } // namespace McuSupport::Internal