From 6e1032f23567cae32be94039f46a9e7f7f69de88 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Fri, 14 Feb 2020 17:36:01 +0300 Subject: [PATCH] BareMetal: Allow to choose 'tools.ini' for UVSC provider configuration An each Keil installation contains an own 'tools.ini' file. The "tools.ini" file is used to determine the paths to the installed debugger drivers as well as to the device software packs. These drivers and packs are displayed on a UVSC provide configuration widget and are used for debugging. Previously, a path to 'tools.ini' file was detected automatically from the configured Kit of the opened project, using the SessionManager::startupTarget() method (a Kit contains the debugger path, which is the uVision executable). But, in that case the user can't configure the UVSC provider if a project is not opened yet. This issue is solved by adding a path chooser to the UVSC provider configuration widget. That allows to user to choose the desired 'tools.ini' file instance in any time. Change-Id: Ife44d69704c9dd2102baecb0ff1954fa4bc05f1e Reviewed-by: hjk --- .../baremetal/debugservers/uvsc/uvproject.cpp | 22 --------- .../baremetal/debugservers/uvsc/uvproject.h | 5 --- .../debugservers/uvsc/uvscserverprovider.cpp | 45 ++++++++++++++++++- .../debugservers/uvsc/uvscserverprovider.h | 9 ++++ .../debugservers/uvsc/uvtargetdevicemodel.cpp | 13 +++--- .../debugservers/uvsc/uvtargetdevicemodel.h | 5 ++- .../uvsc/uvtargetdeviceviewer.cpp | 38 ++++++++-------- .../debugservers/uvsc/uvtargetdeviceviewer.h | 7 ++- .../debugservers/uvsc/uvtargetdrivermodel.cpp | 5 +-- .../debugservers/uvsc/uvtargetdrivermodel.h | 3 +- .../uvsc/uvtargetdriverviewer.cpp | 38 ++++++++-------- .../debugservers/uvsc/uvtargetdriverviewer.h | 8 +++- 12 files changed, 119 insertions(+), 79 deletions(-) diff --git a/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp b/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp index 2a516281acf..c37090c1658 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp @@ -49,28 +49,6 @@ namespace Uv { const char kProjectSchema[] = "2.1"; -// Helpers - -QString toolsFilePath(const QString &uVisionFilePath) -{ - const QFileInfo fi(uVisionFilePath); - QDir dir = fi.dir(); - if (!dir.cdUp()) - return {}; - return dir.absoluteFilePath("tools.ini"); -} - -QString targetUVisionPath() -{ - if (const Target *target = SessionManager::startupTarget()) { - if (const Kit *kit = target->kit()) { - const Runnable runnable = DebuggerKitAspect::runnable(kit); - return runnable.executable.toString(); - } - } - return {}; -} - static QString buildToolsetNumber(int number) { return QStringLiteral("0x%1").arg(QString::number(number, 16)); diff --git a/src/plugins/baremetal/debugservers/uvsc/uvproject.h b/src/plugins/baremetal/debugservers/uvsc/uvproject.h index a1ac9fe634e..6642cf6cc3c 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvproject.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvproject.h @@ -39,11 +39,6 @@ class UvscServerProvider; namespace Uv { -// Helpers - -QString toolsFilePath(const QString &uVisionFilePath); -QString targetUVisionPath(); - // UvProject class Project final : public Gen::Xml::Project diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp index cedb22b82d0..bee1f72bad1 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -57,6 +58,7 @@ namespace Internal { using namespace Uv; // Whole software package selection keys. +constexpr char toolsIniKeyC[] = "BareMetal.UvscServerProvider.ToolsIni"; constexpr char deviceSelectionKeyC[] = "BareMetal.UvscServerProvider.DeviceSelection"; constexpr char driverSelectionKeyC[] = "BareMetal.UvscServerProvider.DriverSelection"; @@ -78,6 +80,16 @@ UvscServerProvider::UvscServerProvider(const UvscServerProvider &other) setEngineType(UvscEngineType); } +void UvscServerProvider::setToolsIniFile(const Utils::FilePath &toolsIniFile) +{ + m_toolsIniFile = toolsIniFile; +} + +Utils::FilePath UvscServerProvider::toolsIniFile() const +{ + return m_toolsIniFile; +} + void UvscServerProvider::setDeviceSelection(const DeviceSelection &deviceSelection) { m_deviceSelection = deviceSelection; @@ -123,7 +135,8 @@ bool UvscServerProvider::operator==(const IDebugServerProvider &other) const if (!IDebugServerProvider::operator==(other)) return false; const auto p = static_cast(&other); - return m_deviceSelection == p->m_deviceSelection + return m_toolsIniFile == p->m_toolsIniFile + && m_deviceSelection == p->m_deviceSelection && m_driverSelection == p->m_driverSelection && m_toolsetNumber == p->m_toolsetNumber; } @@ -147,6 +160,7 @@ FilePath UvscServerProvider::buildOptionsFilePath(DebuggerRunTool *runTool) cons QVariantMap UvscServerProvider::toMap() const { QVariantMap data = IDebugServerProvider::toMap(); + data.insert(toolsIniKeyC, m_toolsIniFile.toVariant()); data.insert(deviceSelectionKeyC, m_deviceSelection.toMap()); data.insert(driverSelectionKeyC, m_driverSelection.toMap()); return data; @@ -217,6 +231,7 @@ bool UvscServerProvider::fromMap(const QVariantMap &data) { if (!IDebugServerProvider::fromMap(data)) return false; + m_toolsIniFile = FilePath::fromVariant(data.value(toolsIniKeyC)); m_deviceSelection.fromMap(data.value(deviceSelectionKeyC).toMap()); m_driverSelection.fromMap(data.value(driverSelectionKeyC).toMap()); return true; @@ -257,6 +272,11 @@ UvscServerProviderConfigWidget::UvscServerProviderConfigWidget(UvscServerProvide { m_hostWidget = new HostWidget; m_mainLayout->addRow(tr("Host:"), m_hostWidget); + m_toolsIniChooser = new PathChooser; + m_toolsIniChooser->setExpectedKind(PathChooser::File); + m_toolsIniChooser->setPromptDialogFilter("tools.ini"); + m_toolsIniChooser->setPromptDialogTitle(tr("Choose a Keil toolset configuration file")); + m_mainLayout->addRow(tr("Tools file path:"), m_toolsIniChooser); m_deviceSelector = new DeviceSelector; m_mainLayout->addRow(tr("Target device:"), m_deviceSelector); m_driverSelector = new DriverSelector(provider->supportedDrivers()); @@ -266,15 +286,27 @@ UvscServerProviderConfigWidget::UvscServerProviderConfigWidget(UvscServerProvide connect(m_hostWidget, &HostWidget::dataChanged, this, &UvscServerProviderConfigWidget::dirty); + connect(m_toolsIniChooser, &PathChooser::pathChanged, + this, &UvscServerProviderConfigWidget::dirty); connect(m_deviceSelector, &DeviceSelector::selectionChanged, this, &UvscServerProviderConfigWidget::dirty); connect(m_driverSelector, &DriverSelector::selectionChanged, this, &UvscServerProviderConfigWidget::dirty); + + auto updateSelectors = [this]() { + const FilePath toolsIniFile = m_toolsIniChooser->fileName(); + m_deviceSelector->setToolsIniFile(toolsIniFile); + m_driverSelector->setToolsIniFile(toolsIniFile); + }; + + connect(m_toolsIniChooser, &PathChooser::pathChanged, updateSelectors); + updateSelectors(); } void UvscServerProviderConfigWidget::apply() { const auto p = static_cast(m_provider); + p->setToolsIniFile(toolsIniFile()); p->setDeviceSelection(deviceSelection()); p->setDriverSelection(driverSelection()); IDebugServerProviderConfigWidget::apply(); @@ -286,6 +318,16 @@ void UvscServerProviderConfigWidget::discard() IDebugServerProviderConfigWidget::discard(); } +void UvscServerProviderConfigWidget::setToolsIniFile(const Utils::FilePath &toolsIniFile) +{ + m_toolsIniChooser->setFileName(toolsIniFile); +} + +Utils::FilePath UvscServerProviderConfigWidget::toolsIniFile() const +{ + return m_toolsIniChooser->fileName(); +} + void UvscServerProviderConfigWidget::setDeviceSelection(const DeviceSelection &deviceSelection) { m_deviceSelector->setSelection(deviceSelection); @@ -310,6 +352,7 @@ void UvscServerProviderConfigWidget::setFromProvider() { const auto p = static_cast(m_provider); m_hostWidget->setChannel(p->channel()); + m_toolsIniChooser->setFileName(p->toolsIniFile()); m_deviceSelector->setSelection(p->deviceSelection()); m_driverSelector->setSelection(p->driverSelection()); } diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h index bab1a6c36d0..f4527f03a4e 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h @@ -32,6 +32,8 @@ #include // for RunWorker +namespace Utils { class PathChooser; } + namespace BareMetal { namespace Internal { @@ -54,6 +56,9 @@ public: ArmAdsToolsetNumber = 4 // ARM-ADS toolset }; + void setToolsIniFile(const Utils::FilePath &toolsIniFile); + Utils::FilePath toolsIniFile() const; + void setDeviceSelection(const Uv::DeviceSelection &deviceSelection); Uv::DeviceSelection deviceSelection() const; @@ -91,6 +96,7 @@ protected: virtual Utils::FilePath optionsFilePath(Debugger::DebuggerRunTool *runTool, QString &errorMessage) const = 0; + Utils::FilePath m_toolsIniFile; Uv::DeviceSelection m_deviceSelection; Uv::DriverSelection m_driverSelection; @@ -113,6 +119,8 @@ public: void discard() override; protected: + void setToolsIniFile(const Utils::FilePath &toolsIniFile); + Utils::FilePath toolsIniFile() const; void setDeviceSelection(const Uv::DeviceSelection &deviceSelection); Uv::DeviceSelection deviceSelection() const; void setDriverSelection(const Uv::DriverSelection &driverSelection); @@ -121,6 +129,7 @@ protected: void setFromProvider(); HostWidget *m_hostWidget = nullptr; + Utils::PathChooser *m_toolsIniChooser = nullptr; Uv::DeviceSelector *m_deviceSelector = nullptr; Uv::DriverSelector *m_driverSelector = nullptr; }; diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp index c6807b61095..391b0a4d158 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp @@ -23,7 +23,6 @@ ** ****************************************************************************/ -#include "uvproject.h" // for toolsFilePath() #include "uvtargetdevicemodel.h" #include @@ -37,9 +36,9 @@ namespace BareMetal { namespace Internal { namespace Uv { -static QString extractPacksPath(const QString &uVisionFilePath) +static QString extractPacksPath(const FilePath &toolsIniFile) { - QFile f(toolsFilePath(uVisionFilePath)); + QFile f(toolsIniFile.toString()); if (!f.open(QIODevice::ReadOnly)) return {}; QTextStream in(&f); @@ -258,15 +257,15 @@ DeviceSelectionModel::DeviceSelectionModel(QObject *parent) setHeader({tr("Name"), tr("Version"), tr("Vendor")}); } -void DeviceSelectionModel::fillAllPacks(const QString &uVisionFilePath) +void DeviceSelectionModel::fillAllPacks(const FilePath &toolsIniFile) { - if (m_uVisionFilePath == uVisionFilePath) + if (m_toolsIniFile == toolsIniFile) return; clear(); - m_uVisionFilePath = uVisionFilePath; - const QString packsPath = extractPacksPath(m_uVisionFilePath); + m_toolsIniFile = toolsIniFile; + const QString packsPath = extractPacksPath(m_toolsIniFile); if (packsPath.isEmpty()) return; diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h index 3bd8e857019..c3a510f36e9 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h @@ -28,6 +28,7 @@ #include "uvtargetdeviceselection.h" #include +#include #include QT_BEGIN_NAMESPACE @@ -47,7 +48,7 @@ class DeviceSelectionModel final : public Utils::TreeModel public: explicit DeviceSelectionModel(QObject *parent = nullptr); - void fillAllPacks(const QString &uVisionFilePath); + void fillAllPacks(const Utils::FilePath &toolsIniFile); private: void parsePackage(const QString &packageFile); @@ -59,7 +60,7 @@ private: DeviceSelection::Cpu &cpu, DeviceSelection::Memories &memories); void parseDeviceVariant(QXmlStreamReader &in, DeviceSelectionItem *parent); - QString m_uVisionFilePath; + Utils::FilePath m_toolsIniFile; }; // DeviceSelectionView diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp index 69cbd30129f..84436d3b651 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp @@ -124,28 +124,30 @@ DeviceSelector::DeviceSelector(QWidget *parent) setWidget(detailsPanel); connect(toolPanel, &DeviceSelectorToolPanel::clicked, this, [this]() { - const QString uVisionPath = targetUVisionPath(); - if (uVisionPath.isEmpty()) { - QMessageBox::warning(this, - tr("uVision path not found"), - tr("Please open a configured project before\n" - "the target device selection."), - QMessageBox::Ok); - } else { - DeviceSelectionDialog dialog(uVisionPath, this); - const int result = dialog.exec(); - if (result != QDialog::Accepted) - return; - DeviceSelection selection; - selection = dialog.selection(); - setSelection(selection); - } + DeviceSelectionDialog dialog(m_toolsIniFile, this); + const int result = dialog.exec(); + if (result != QDialog::Accepted) + return; + DeviceSelection selection; + selection = dialog.selection(); + setSelection(selection); }); connect(detailsPanel, &DeviceSelectorDetailsPanel::selectionChanged, this, &DeviceSelector::selectionChanged); } +void DeviceSelector::setToolsIniFile(const Utils::FilePath &toolsIniFile) +{ + m_toolsIniFile = toolsIniFile; + setEnabled(m_toolsIniFile.exists()); +} + +Utils::FilePath DeviceSelector::toolsIniFile() const +{ + return m_toolsIniFile; +} + void DeviceSelector::setSelection(const DeviceSelection &selection) { m_selection = selection; @@ -167,7 +169,7 @@ DeviceSelection DeviceSelector::selection() const // DeviceSelectionDialog -DeviceSelectionDialog::DeviceSelectionDialog(const QString &uVisionPath, QWidget *parent) +DeviceSelectionDialog::DeviceSelectionDialog(const Utils::FilePath &toolsIniFile, QWidget *parent) : QDialog(parent), m_model(new DeviceSelectionModel(this)), m_view(new DeviceSelectionView(this)) { setWindowTitle(tr("Available target devices")); @@ -187,7 +189,7 @@ DeviceSelectionDialog::DeviceSelectionDialog(const QString &uVisionPath, QWidget m_selection = selection; }); - m_model->fillAllPacks(uVisionPath); + m_model->fillAllPacks(toolsIniFile); m_view->setModel(m_model); } diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h index eaeb089e790..abc00e9c1c7 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h @@ -29,6 +29,7 @@ #include #include +#include #include @@ -55,6 +56,9 @@ class DeviceSelector final : public Utils::DetailsWidget public: explicit DeviceSelector(QWidget *parent = nullptr); + void setToolsIniFile(const Utils::FilePath &toolsIniFile); + Utils::FilePath toolsIniFile() const; + void setSelection(const DeviceSelection &selection); DeviceSelection selection() const; @@ -62,6 +66,7 @@ signals: void selectionChanged(); private: + Utils::FilePath m_toolsIniFile; DeviceSelection m_selection; }; @@ -111,7 +116,7 @@ class DeviceSelectionDialog final : public QDialog Q_OBJECT public: - explicit DeviceSelectionDialog(const QString &uVisionPath, QWidget *parent = nullptr); + explicit DeviceSelectionDialog(const Utils::FilePath &toolsIniFile, QWidget *parent = nullptr); DeviceSelection selection() const; private: diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp index c3a737cbc8a..11199aca526 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp @@ -23,7 +23,6 @@ ** ****************************************************************************/ -#include "uvproject.h" // for toolsFilePath() #include "uvtargetdrivermodel.h" #include @@ -132,12 +131,12 @@ DriverSelectionModel::DriverSelectionModel(QObject *parent) setHeader({tr("Path")}); } -void DriverSelectionModel::fillDrivers(const QString &uVisionFilePath, +void DriverSelectionModel::fillDrivers(const FilePath &toolsIniFile, const QStringList &supportedDrivers) { clear(); - QFile f(toolsFilePath(uVisionFilePath)); + QFile f(toolsIniFile.toString()); if (!f.open(QIODevice::ReadOnly)) return; diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h index 845681d0c1a..9d9dda37890 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h @@ -28,6 +28,7 @@ #include "uvtargetdriverselection.h" #include +#include #include namespace BareMetal { @@ -43,7 +44,7 @@ class DriverSelectionModel final : public Utils::TreeModel public: explicit DriverSelectionModel(QObject *parent = nullptr); - void fillDrivers(const QString &uVisionFilePath, const QStringList &supportedDrivers); + void fillDrivers(const Utils::FilePath &toolsIniFile, const QStringList &supportedDrivers); }; // DriverSelectionView diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp index 04e6721e566..10baa3b2741 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp @@ -105,28 +105,30 @@ DriverSelector::DriverSelector(const QStringList &supportedDrivers, QWidget *par setWidget(detailsPanel); connect(toolPanel, &DriverSelectorToolPanel::clicked, this, [=]() { - const QString uVisionPath = targetUVisionPath(); - if (uVisionPath.isEmpty()) { - QMessageBox::warning(this, - tr("uVision path not found"), - tr("Please open a configured project before\n" - "the target driver selection."), - QMessageBox::Ok); - } else { - DriverSelectionDialog dialog(uVisionPath, supportedDrivers, this); - const int result = dialog.exec(); - if (result != QDialog::Accepted) - return; - DriverSelection selection; - selection = dialog.selection(); - setSelection(selection); - } + DriverSelectionDialog dialog(m_toolsIniFile, supportedDrivers, this); + const int result = dialog.exec(); + if (result != QDialog::Accepted) + return; + DriverSelection selection; + selection = dialog.selection(); + setSelection(selection); }); connect(detailsPanel, &DriverSelectorDetailsPanel::selectionChanged, this, &DriverSelector::selectionChanged); } +void DriverSelector::setToolsIniFile(const Utils::FilePath &toolsIniFile) +{ + m_toolsIniFile = toolsIniFile; + setEnabled(m_toolsIniFile.exists()); +} + +Utils::FilePath DriverSelector::toolsIniFile() const +{ + return m_toolsIniFile; +} + void DriverSelector::setSelection(const DriverSelection &selection) { m_selection = selection; @@ -148,7 +150,7 @@ DriverSelection DriverSelector::selection() const // DriverSelectionDialog -DriverSelectionDialog::DriverSelectionDialog(const QString &uVisionPath, +DriverSelectionDialog::DriverSelectionDialog(const Utils::FilePath &toolsIniFile, const QStringList &supportedDrivers, QWidget *parent) : QDialog(parent), m_model(new DriverSelectionModel(this)), @@ -171,7 +173,7 @@ DriverSelectionDialog::DriverSelectionDialog(const QString &uVisionPath, m_selection = selection; }); - m_model->fillDrivers(uVisionPath, supportedDrivers); + m_model->fillDrivers(toolsIniFile, supportedDrivers); m_view->setModel(m_model); } diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h index a72d3baf69f..c8c390318ce 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h @@ -29,6 +29,7 @@ #include #include +#include #include @@ -52,6 +53,10 @@ class DriverSelector final : public Utils::DetailsWidget public: explicit DriverSelector(const QStringList &supportedDrivers, QWidget *parent = nullptr); + + void setToolsIniFile(const Utils::FilePath &toolsIniFile); + Utils::FilePath toolsIniFile() const; + void setSelection(const DriverSelection &selection); DriverSelection selection() const; @@ -59,6 +64,7 @@ signals: void selectionChanged(); private: + Utils::FilePath m_toolsIniFile; DriverSelection m_selection; }; @@ -105,7 +111,7 @@ class DriverSelectionDialog final : public QDialog Q_OBJECT public: - explicit DriverSelectionDialog(const QString &uVisionPath, + explicit DriverSelectionDialog(const Utils::FilePath &toolsIniFile, const QStringList &supportedDrivers, QWidget *parent = nullptr); DriverSelection selection() const;