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 <hjk@qt.io>
This commit is contained in:
Denis Shienkov
2020-02-14 17:36:01 +03:00
parent 46e5d52238
commit 6e1032f235
12 changed files with 119 additions and 79 deletions

View File

@@ -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));

View File

@@ -39,11 +39,6 @@ class UvscServerProvider;
namespace Uv {
// Helpers
QString toolsFilePath(const QString &uVisionFilePath);
QString targetUVisionPath();
// UvProject
class Project final : public Gen::Xml::Project

View File

@@ -39,6 +39,7 @@
#include <projectexplorer/project.h>
#include <projectexplorer/runconfigurationaspects.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <QComboBox>
@@ -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<const UvscServerProvider *>(&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<UvscServerProvider *>(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<UvscServerProvider *>(m_provider);
m_hostWidget->setChannel(p->channel());
m_toolsIniChooser->setFileName(p->toolsIniFile());
m_deviceSelector->setSelection(p->deviceSelection());
m_driverSelector->setSelection(p->driverSelection());
}

View File

@@ -32,6 +32,8 @@
#include <projectexplorer/runcontrol.h> // 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;
};

View File

@@ -23,7 +23,6 @@
**
****************************************************************************/
#include "uvproject.h" // for toolsFilePath()
#include "uvtargetdevicemodel.h"
#include <QDirIterator>
@@ -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;

View File

@@ -28,6 +28,7 @@
#include "uvtargetdeviceselection.h"
#include <utils/basetreeview.h>
#include <utils/fileutils.h>
#include <utils/treemodel.h>
QT_BEGIN_NAMESPACE
@@ -47,7 +48,7 @@ class DeviceSelectionModel final : public Utils::TreeModel<DeviceSelectionItem>
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

View File

@@ -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);
}

View File

@@ -29,6 +29,7 @@
#include <utils/detailsbutton.h>
#include <utils/detailswidget.h>
#include <utils/fileutils.h>
#include <QDialog>
@@ -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:

View File

@@ -23,7 +23,6 @@
**
****************************************************************************/
#include "uvproject.h" // for toolsFilePath()
#include "uvtargetdrivermodel.h"
#include <QFile>
@@ -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;

View File

@@ -28,6 +28,7 @@
#include "uvtargetdriverselection.h"
#include <utils/basetreeview.h>
#include <utils/fileutils.h>
#include <utils/treemodel.h>
namespace BareMetal {
@@ -43,7 +44,7 @@ class DriverSelectionModel final : public Utils::TreeModel<DriverSelectionItem>
public:
explicit DriverSelectionModel(QObject *parent = nullptr);
void fillDrivers(const QString &uVisionFilePath, const QStringList &supportedDrivers);
void fillDrivers(const Utils::FilePath &toolsIniFile, const QStringList &supportedDrivers);
};
// DriverSelectionView

View File

@@ -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);
}

View File

@@ -29,6 +29,7 @@
#include <utils/detailsbutton.h>
#include <utils/detailswidget.h>
#include <utils/fileutils.h>
#include <QDialog>
@@ -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;