ProjectExplorer: Move device-related kit aspects into dedicated files

Change-Id: I477c3aa13b7c9d71ed44129608239f9a5f0b11a8
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2024-10-10 15:51:44 +02:00
parent 5266da2785
commit 035d581807
8 changed files with 756 additions and 729 deletions

View File

@@ -8,6 +8,7 @@
#include "debuggertr.h"
#include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/kitaspect.h>
#include <projectexplorer/kitaspects.h>
#include <projectexplorer/projectexplorerconstants.h>

View File

@@ -52,6 +52,7 @@ add_qtc_plugin(ProjectExplorer
devicesupport/desktopprocesssignaloperation.cpp devicesupport/desktopprocesssignaloperation.h
devicesupport/devicecheckbuildstep.cpp devicesupport/devicecheckbuildstep.h
devicesupport/devicefactoryselectiondialog.cpp devicesupport/devicefactoryselectiondialog.h
devicesupport/devicekitaspects.cpp devicesupport/devicekitaspects.h
devicesupport/devicemanager.cpp devicesupport/devicemanager.h
devicesupport/devicemanagermodel.cpp devicesupport/devicemanagermodel.h
devicesupport/deviceprocessesdialog.cpp devicesupport/deviceprocessesdialog.h

View File

@@ -0,0 +1,697 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "devicekitaspects.h"
#include "devicemanager.h"
#include "devicemanagermodel.h"
#include "idevicefactory.h"
#include "sshparameters.h"
#include "../kit.h"
#include "../kitaspect.h"
#include "../kitmanager.h"
#include "../projectexplorerconstants.h"
#include "../projectexplorertr.h"
#include <utils/id.h>
#include <utils/layoutbuilder.h>
#include <utils/listmodel.h>
#include <utils/macroexpander.h>
#include <QComboBox>
#include <tuple>
using namespace Utils;
namespace ProjectExplorer {
// --------------------------------------------------------------------------
// DeviceTypeKitAspect:
// --------------------------------------------------------------------------
namespace Internal {
class DeviceTypeKitAspectImpl final : public KitAspect
{
public:
DeviceTypeKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
: KitAspect(workingCopy, factory)
{
using ItemData = std::tuple<QString, Id, QIcon>;
const auto model = new ListModel<ItemData>(this);
model->setDataAccessor([](const ItemData &d, int column, int role) -> QVariant {
if (column != 0)
return {};
if (role == Qt::DisplayRole)
return std::get<0>(d);
if (role == KitAspect::IdRole)
return std::get<1>(d).toSetting();
if (role == Qt::DecorationRole)
return std::get<2>(d);
return {};
});
auto getter = [](const Kit &k) { return DeviceTypeKitAspect::deviceTypeId(&k).toSetting(); };
auto setter = [](Kit &k, const QVariant &type) {
DeviceTypeKitAspect::setDeviceTypeId(&k, Id::fromSetting(type));
};
auto resetModel = [model] {
model->clear();
for (IDeviceFactory *factory : IDeviceFactory::allDeviceFactories()) {
model->appendItem(
std::make_tuple(factory->displayName(), factory->deviceType(), factory->icon()));
}
};
setListAspectSpec(
{model, std::move(getter), std::move(setter), std::move(resetModel)});
}
};
class DeviceTypeKitAspectFactory : public KitAspectFactory
{
public:
DeviceTypeKitAspectFactory();
void setup(Kit *k) override;
Tasks validate(const Kit *k) const override;
KitAspect *createKitAspect(Kit *k) const override;
ItemList toUserOutput(const Kit *k) const override;
QSet<Id> supportedPlatforms(const Kit *k) const override;
QSet<Id> availableFeatures(const Kit *k) const override;
};
DeviceTypeKitAspectFactory::DeviceTypeKitAspectFactory()
{
setId(DeviceTypeKitAspect::id());
setDisplayName(Tr::tr("Run device type"));
setDescription(Tr::tr("The type of device to run applications on."));
setPriority(33000);
makeEssential();
}
void DeviceTypeKitAspectFactory::setup(Kit *k)
{
if (k && !k->hasValue(id()))
k->setValue(id(), QByteArray(Constants::DESKTOP_DEVICE_TYPE));
}
Tasks DeviceTypeKitAspectFactory::validate(const Kit *k) const
{
Q_UNUSED(k)
return {};
}
KitAspect *DeviceTypeKitAspectFactory::createKitAspect(Kit *k) const
{
QTC_ASSERT(k, return nullptr);
return new Internal::DeviceTypeKitAspectImpl(k, this);
}
KitAspectFactory::ItemList DeviceTypeKitAspectFactory::toUserOutput(const Kit *k) const
{
QTC_ASSERT(k, return {});
Id type = DeviceTypeKitAspect::deviceTypeId(k);
QString typeDisplayName = Tr::tr("Unknown device type");
if (type.isValid()) {
if (IDeviceFactory *factory = IDeviceFactory::find(type))
typeDisplayName = factory->displayName();
}
return {{Tr::tr("Device type"), typeDisplayName}};
}
QSet<Id> DeviceTypeKitAspectFactory::supportedPlatforms(const Kit *k) const
{
return {DeviceTypeKitAspect::deviceTypeId(k)};
}
QSet<Id> DeviceTypeKitAspectFactory::availableFeatures(const Kit *k) const
{
Id id = DeviceTypeKitAspect::deviceTypeId(k);
if (id.isValid())
return {id.withPrefix("DeviceType.")};
return {};
}
const DeviceTypeKitAspectFactory theDeviceTypeKitAspectFactory;
} // namespace Internal
const Id DeviceTypeKitAspect::id()
{
return "PE.Profile.DeviceType";
}
const Id DeviceTypeKitAspect::deviceTypeId(const Kit *k)
{
return k ? Id::fromSetting(k->value(DeviceTypeKitAspect::id())) : Id();
}
void DeviceTypeKitAspect::setDeviceTypeId(Kit *k, Id type)
{
QTC_ASSERT(k, return);
k->setValue(DeviceTypeKitAspect::id(), type.toSetting());
}
// --------------------------------------------------------------------------
// DeviceKitAspect:
// --------------------------------------------------------------------------
namespace Internal {
class DeviceKitAspectImpl final : public KitAspect
{
public:
DeviceKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
: KitAspect(workingCopy, factory),
m_comboBox(createSubWidget<QComboBox>()),
m_model(new DeviceManagerModel(DeviceManager::instance()))
{
setManagingPage(Constants::DEVICE_SETTINGS_PAGE_ID);
m_comboBox->setSizePolicy(QSizePolicy::Preferred,
m_comboBox->sizePolicy().verticalPolicy());
m_comboBox->setModel(m_model);
m_comboBox->setMinimumContentsLength(16); // Don't stretch too much for Kit Page
refresh();
m_comboBox->setToolTip(factory->description());
connect(m_model, &QAbstractItemModel::modelAboutToBeReset,
this, &DeviceKitAspectImpl::modelAboutToReset);
connect(m_model, &QAbstractItemModel::modelReset,
this, &DeviceKitAspectImpl::modelReset);
connect(m_comboBox, &QComboBox::currentIndexChanged,
this, &DeviceKitAspectImpl::currentDeviceChanged);
}
~DeviceKitAspectImpl() override
{
delete m_comboBox;
delete m_model;
}
private:
void addToInnerLayout(Layouting::Layout &builder) override
{
addMutableAction(m_comboBox);
builder.addItem(m_comboBox);
}
void makeReadOnly() override { m_comboBox->setEnabled(false); }
Id settingsPageItemToPreselect() const override { return DeviceKitAspect::deviceId(kit()); }
void refresh() override
{
m_model->setTypeFilter(DeviceTypeKitAspect::deviceTypeId(kit()));
m_comboBox->setCurrentIndex(m_model->indexOf(DeviceKitAspect::device(kit())));
}
void modelAboutToReset()
{
m_selectedId = m_model->deviceId(m_comboBox->currentIndex());
m_ignoreChanges.lock();
}
void modelReset()
{
m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId));
m_ignoreChanges.unlock();
}
void currentDeviceChanged()
{
if (m_ignoreChanges.isLocked())
return;
DeviceKitAspect::setDeviceId(kit(), m_model->deviceId(m_comboBox->currentIndex()));
}
Guard m_ignoreChanges;
QComboBox *m_comboBox;
DeviceManagerModel *m_model;
Id m_selectedId;
};
class DeviceKitAspectFactory : public KitAspectFactory
{
public:
DeviceKitAspectFactory();
private:
Tasks validate(const Kit *k) const override;
void fix(Kit *k) override;
void setup(Kit *k) override;
KitAspect *createKitAspect(Kit *k) const override;
QString displayNamePostfix(const Kit *k) const override;
ItemList toUserOutput(const Kit *k) const override;
void addToMacroExpander(Kit *kit, MacroExpander *expander) const override;
QVariant defaultValue(const Kit *k) const;
void onKitsLoaded() override;
void deviceUpdated(Id dataId);
void devicesChanged();
void kitUpdated(Kit *k);
};
DeviceKitAspectFactory::DeviceKitAspectFactory()
{
setId(DeviceKitAspect::id());
setDisplayName(Tr::tr("Run device"));
setDescription(Tr::tr("The device to run the applications on."));
setPriority(32000);
}
QVariant DeviceKitAspectFactory::defaultValue(const Kit *k) const
{
Id type = DeviceTypeKitAspect::deviceTypeId(k);
// Use default device if that is compatible:
IDevice::ConstPtr dev = DeviceManager::instance()->defaultDevice(type);
if (dev && dev->isCompatibleWith(k))
return dev->id().toString();
// Use any other device that is compatible:
for (int i = 0; i < DeviceManager::instance()->deviceCount(); ++i) {
dev = DeviceManager::instance()->deviceAt(i);
if (dev && dev->isCompatibleWith(k))
return dev->id().toString();
}
// Fail: No device set up.
return {};
}
Tasks DeviceKitAspectFactory::validate(const Kit *k) const
{
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
Tasks result;
if (!dev)
result.append(BuildSystemTask(Task::Warning, Tr::tr("No device set.")));
else if (!dev->isCompatibleWith(k))
result.append(BuildSystemTask(Task::Error, Tr::tr("Device is incompatible with this kit.")));
if (dev)
result.append(dev->validate());
return result;
}
void DeviceKitAspectFactory::fix(Kit *k)
{
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
if (dev && !dev->isCompatibleWith(k)) {
qWarning("Device is no longer compatible with kit \"%s\", removing it.",
qPrintable(k->displayName()));
DeviceKitAspect::setDeviceId(k, Id());
}
}
void DeviceKitAspectFactory::setup(Kit *k)
{
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return);
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
if (dev && dev->isCompatibleWith(k))
return;
DeviceKitAspect::setDeviceId(k, Id::fromSetting(defaultValue(k)));
}
KitAspect *DeviceKitAspectFactory::createKitAspect(Kit *k) const
{
QTC_ASSERT(k, return nullptr);
return new Internal::DeviceKitAspectImpl(k, this);
}
QString DeviceKitAspectFactory::displayNamePostfix(const Kit *k) const
{
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
return dev ? dev->displayName() : QString();
}
KitAspectFactory::ItemList DeviceKitAspectFactory::toUserOutput(const Kit *k) const
{
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
return {{Tr::tr("Device"), dev ? dev->displayName() : Tr::tr("Unconfigured") }};
}
void DeviceKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const
{
QTC_ASSERT(kit, return);
expander->registerVariable("Device:HostAddress", Tr::tr("Host address"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->sshParameters().host() : QString();
});
expander->registerVariable("Device:SshPort", Tr::tr("SSH port"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? QString::number(device->sshParameters().port()) : QString();
});
expander->registerVariable("Device:UserName", Tr::tr("User name"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->sshParameters().userName() : QString();
});
expander->registerVariable("Device:KeyFile", Tr::tr("Private key file"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->sshParameters().privateKeyFile.toString() : QString();
});
expander->registerVariable("Device:Name", Tr::tr("Device name"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->displayName() : QString();
});
expander->registerFileVariables("Device::Root", Tr::tr("Device root directory"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->rootPath() : FilePath{};
});
}
void DeviceKitAspectFactory::onKitsLoaded()
{
for (Kit *k : KitManager::kits())
fix(k);
DeviceManager *dm = DeviceManager::instance();
connect(dm, &DeviceManager::deviceListReplaced, this, &DeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceAdded, this, &DeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceRemoved, this, &DeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceUpdated, this, &DeviceKitAspectFactory::deviceUpdated);
connect(KitManager::instance(), &KitManager::kitUpdated,
this, &DeviceKitAspectFactory::kitUpdated);
connect(KitManager::instance(), &KitManager::unmanagedKitUpdated,
this, &DeviceKitAspectFactory::kitUpdated);
}
void DeviceKitAspectFactory::deviceUpdated(Id id)
{
for (Kit *k : KitManager::kits()) {
if (DeviceKitAspect::deviceId(k) == id)
notifyAboutUpdate(k);
}
}
void DeviceKitAspectFactory::kitUpdated(Kit *k)
{
setup(k); // Set default device if necessary
}
void DeviceKitAspectFactory::devicesChanged()
{
for (Kit *k : KitManager::kits())
setup(k); // Set default device if necessary
}
const DeviceKitAspectFactory theDeviceKitAspectFactory;
} // namespace Internal
Id DeviceKitAspect::id()
{
return "PE.Profile.Device";
}
IDevice::ConstPtr DeviceKitAspect::device(const Kit *k)
{
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return IDevice::ConstPtr());
return DeviceManager::instance()->find(deviceId(k));
}
Id DeviceKitAspect::deviceId(const Kit *k)
{
return k ? Id::fromSetting(k->value(DeviceKitAspect::id())) : Id();
}
void DeviceKitAspect::setDevice(Kit *k, IDevice::ConstPtr dev)
{
setDeviceId(k, dev ? dev->id() : Id());
}
void DeviceKitAspect::setDeviceId(Kit *k, Id id)
{
QTC_ASSERT(k, return);
k->setValue(DeviceKitAspect::id(), id.toSetting());
}
FilePath DeviceKitAspect::deviceFilePath(const Kit *k, const QString &pathOnDevice)
{
if (IDevice::ConstPtr dev = device(k))
return dev->filePath(pathOnDevice);
return FilePath::fromString(pathOnDevice);
}
// --------------------------------------------------------------------------
// BuildDeviceKitAspect:
// --------------------------------------------------------------------------
namespace Internal {
class BuildDeviceKitAspectImpl final : public KitAspect
{
public:
BuildDeviceKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
: KitAspect(workingCopy, factory),
m_comboBox(createSubWidget<QComboBox>()),
m_model(new DeviceManagerModel(DeviceManager::instance()))
{
setManagingPage(Constants::DEVICE_SETTINGS_PAGE_ID);
m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy());
m_comboBox->setModel(m_model);
refresh();
m_comboBox->setToolTip(factory->description());
connect(m_model, &QAbstractItemModel::modelAboutToBeReset,
this, &BuildDeviceKitAspectImpl::modelAboutToReset);
connect(m_model, &QAbstractItemModel::modelReset,
this, &BuildDeviceKitAspectImpl::modelReset);
connect(m_comboBox, &QComboBox::currentIndexChanged,
this, &BuildDeviceKitAspectImpl::currentDeviceChanged);
}
~BuildDeviceKitAspectImpl() override
{
delete m_comboBox;
delete m_model;
}
private:
void addToInnerLayout(Layouting::Layout &builder) override
{
addMutableAction(m_comboBox);
builder.addItem(m_comboBox);
}
void makeReadOnly() override { m_comboBox->setEnabled(false); }
void refresh() override
{
QList<Id> blackList;
const DeviceManager *dm = DeviceManager::instance();
for (int i = 0; i < dm->deviceCount(); ++i) {
IDevice::ConstPtr device = dm->deviceAt(i);
if (!device->usableAsBuildDevice())
blackList.append(device->id());
}
m_model->setFilter(blackList);
m_comboBox->setCurrentIndex(m_model->indexOf(BuildDeviceKitAspect::device(kit())));
}
void modelAboutToReset()
{
m_selectedId = m_model->deviceId(m_comboBox->currentIndex());
m_ignoreChanges.lock();
}
void modelReset()
{
m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId));
m_ignoreChanges.unlock();
}
void currentDeviceChanged()
{
if (m_ignoreChanges.isLocked())
return;
BuildDeviceKitAspect::setDeviceId(kit(), m_model->deviceId(m_comboBox->currentIndex()));
}
Guard m_ignoreChanges;
QComboBox *m_comboBox;
DeviceManagerModel *m_model;
Id m_selectedId;
};
class BuildDeviceKitAspectFactory : public KitAspectFactory
{
public:
BuildDeviceKitAspectFactory();
private:
void setup(Kit *k) override;
Tasks validate(const Kit *k) const override;
KitAspect *createKitAspect(Kit *k) const override;
QString displayNamePostfix(const Kit *k) const override;
ItemList toUserOutput(const Kit *k) const override;
void addToMacroExpander(Kit *kit, MacroExpander *expander) const override;
void onKitsLoaded() override;
void deviceUpdated(Id dataId);
void devicesChanged();
void kitUpdated(Kit *k);
};
BuildDeviceKitAspectFactory::BuildDeviceKitAspectFactory()
{
setId(BuildDeviceKitAspect::id());
setDisplayName(Tr::tr("Build device"));
setDescription(Tr::tr("The device used to build applications on."));
setPriority(31900);
}
static IDeviceConstPtr defaultDevice()
{
return DeviceManager::defaultDesktopDevice();
}
void BuildDeviceKitAspectFactory::setup(Kit *k)
{
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return );
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
if (dev)
return;
dev = defaultDevice();
BuildDeviceKitAspect::setDeviceId(k, dev ? dev->id() : Id());
}
Tasks BuildDeviceKitAspectFactory::validate(const Kit *k) const
{
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
Tasks result;
if (!dev)
result.append(BuildSystemTask(Task::Warning, Tr::tr("No build device set.")));
return result;
}
KitAspect *BuildDeviceKitAspectFactory::createKitAspect(Kit *k) const
{
QTC_ASSERT(k, return nullptr);
return new Internal::BuildDeviceKitAspectImpl(k, this);
}
QString BuildDeviceKitAspectFactory::displayNamePostfix(const Kit *k) const
{
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
return dev ? dev->displayName() : QString();
}
KitAspectFactory::ItemList BuildDeviceKitAspectFactory::toUserOutput(const Kit *k) const
{
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
return {{Tr::tr("Build device"), dev ? dev->displayName() : Tr::tr("Unconfigured")}};
}
void BuildDeviceKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const
{
QTC_ASSERT(kit, return);
expander->registerVariable("BuildDevice:HostAddress", Tr::tr("Build host address"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->sshParameters().host() : QString();
});
expander->registerVariable("BuildDevice:SshPort", Tr::tr("Build SSH port"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? QString::number(device->sshParameters().port()) : QString();
});
expander->registerVariable("BuildDevice:UserName", Tr::tr("Build user name"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->sshParameters().userName() : QString();
});
expander->registerVariable("BuildDevice:KeyFile", Tr::tr("Build private key file"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->sshParameters().privateKeyFile.toString() : QString();
});
expander->registerVariable("BuildDevice:Name", Tr::tr("Build device name"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->displayName() : QString();
});
expander
->registerFileVariables("BuildDevice::Root", Tr::tr("Build device root directory"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->rootPath() : FilePath{};
});
}
void BuildDeviceKitAspectFactory::onKitsLoaded()
{
for (Kit *k : KitManager::kits())
fix(k);
DeviceManager *dm = DeviceManager::instance();
connect(dm, &DeviceManager::deviceListReplaced,
this, &BuildDeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceAdded,
this, &BuildDeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceRemoved,
this, &BuildDeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceUpdated,
this, &BuildDeviceKitAspectFactory::deviceUpdated);
connect(KitManager::instance(), &KitManager::kitUpdated,
this, &BuildDeviceKitAspectFactory::kitUpdated);
connect(KitManager::instance(), &KitManager::unmanagedKitUpdated,
this, &BuildDeviceKitAspectFactory::kitUpdated);
}
void BuildDeviceKitAspectFactory::deviceUpdated(Id id)
{
const QList<Kit *> kits = KitManager::kits();
for (Kit *k : kits) {
if (BuildDeviceKitAspect::deviceId(k) == id)
notifyAboutUpdate(k);
}
}
void BuildDeviceKitAspectFactory::kitUpdated(Kit *k)
{
setup(k); // Set default device if necessary
}
void BuildDeviceKitAspectFactory::devicesChanged()
{
const QList<Kit *> kits = KitManager::kits();
for (Kit *k : kits)
setup(k); // Set default device if necessary
}
const BuildDeviceKitAspectFactory theBuildDeviceKitAspectFactory;
} // namespace Internal
Id BuildDeviceKitAspect::id()
{
return "PE.Profile.BuildDevice";
}
IDevice::ConstPtr BuildDeviceKitAspect::device(const Kit *k)
{
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return IDevice::ConstPtr());
IDevice::ConstPtr dev = DeviceManager::instance()->find(deviceId(k));
if (!dev)
dev = Internal::defaultDevice();
return dev;
}
Id BuildDeviceKitAspect::deviceId(const Kit *k)
{
return k ? Id::fromSetting(k->value(BuildDeviceKitAspect::id())) : Id();
}
void BuildDeviceKitAspect::setDevice(Kit *k, IDevice::ConstPtr dev)
{
setDeviceId(k, dev ? dev->id() : Id());
}
void BuildDeviceKitAspect::setDeviceId(Kit *k, Id id)
{
QTC_ASSERT(k, return);
k->setValue(BuildDeviceKitAspect::id(), id.toSetting());
}
} // namespace ProjectExplorer

View File

@@ -0,0 +1,45 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "idevicefwd.h"
#include "../projectexplorer_export.h"
#include <utils/id.h>
namespace Utils { class FilePath; }
namespace ProjectExplorer {
class Kit;
class PROJECTEXPLORER_EXPORT DeviceTypeKitAspect
{
public:
static const Utils::Id id();
static const Utils::Id deviceTypeId(const Kit *k);
static void setDeviceTypeId(Kit *k, Utils::Id type);
};
class PROJECTEXPLORER_EXPORT DeviceKitAspect
{
public:
static Utils::Id id();
static IDeviceConstPtr device(const Kit *k);
static Utils::Id deviceId(const Kit *k);
static void setDevice(Kit *k, IDeviceConstPtr dev);
static void setDeviceId(Kit *k, Utils::Id dataId);
static Utils::FilePath deviceFilePath(const Kit *k, const QString &pathOnDevice);
};
class PROJECTEXPLORER_EXPORT BuildDeviceKitAspect
{
public:
static Utils::Id id();
static IDeviceConstPtr device(const Kit *k);
static Utils::Id deviceId(const Kit *k);
static void setDevice(Kit *k, IDeviceConstPtr dev);
static void setDeviceId(Kit *k, Utils::Id dataId);
};
} // namespace ProjectExplorer

View File

@@ -3,18 +3,11 @@
#include "kitaspects.h"
#include "abi.h"
#include "devicesupport/devicemanager.h"
#include "devicesupport/devicemanagermodel.h"
#include "devicesupport/idevicefactory.h"
#include "devicesupport/sshparameters.h"
#include "projectexplorerconstants.h"
#include "projectexplorertr.h"
#include "kit.h"
#include "kitaspect.h"
#include "kitmanager.h"
#include "toolchain.h"
#include "toolchainmanager.h"
#include <utils/algorithm.h>
#include <utils/elidinglabel.h>
@@ -30,16 +23,9 @@
#include <utils/variablechooser.h>
#include <QCheckBox>
#include <QComboBox>
#include <QFontMetrics>
#include <QGridLayout>
#include <QHash>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <tuple>
using namespace Utils;
namespace ProjectExplorer {
@@ -88,7 +74,6 @@ private:
PathChooser *m_chooser;
Guard m_ignoreChanges;
};
} // namespace Internal
class SysRootKitAspectFactory : public KitAspectFactory
{
@@ -154,6 +139,10 @@ void SysRootKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expand
});
}
const SysRootKitAspectFactory theSyRootKitAspectFactory;
} // namespace Internal
Id SysRootKitAspect::id()
{
return "PE.Profile.SysRoot";
@@ -192,674 +181,6 @@ void SysRootKitAspect::setSysRoot(Kit *k, const FilePath &v)
k->setValue(SysRootKitAspect::id(), v.toString());
}
const SysRootKitAspectFactory theSyRootKitAspectFactory;
// --------------------------------------------------------------------------
// DeviceTypeKitAspect:
// --------------------------------------------------------------------------
namespace Internal {
class DeviceTypeKitAspectImpl final : public KitAspect
{
public:
DeviceTypeKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
: KitAspect(workingCopy, factory)
{
using ItemData = std::tuple<QString, Id, QIcon>;
const auto model = new ListModel<ItemData>(this);
model->setDataAccessor([](const ItemData &d, int column, int role) -> QVariant {
if (column != 0)
return {};
if (role == Qt::DisplayRole)
return std::get<0>(d);
if (role == KitAspect::IdRole)
return std::get<1>(d).toSetting();
if (role == Qt::DecorationRole)
return std::get<2>(d);
return {};
});
auto getter = [](const Kit &k) { return DeviceTypeKitAspect::deviceTypeId(&k).toSetting(); };
auto setter = [](Kit &k, const QVariant &type) {
DeviceTypeKitAspect::setDeviceTypeId(&k, Id::fromSetting(type));
};
auto resetModel = [model] {
model->clear();
for (IDeviceFactory *factory : IDeviceFactory::allDeviceFactories()) {
model->appendItem(
std::make_tuple(factory->displayName(), factory->deviceType(), factory->icon()));
}
};
setListAspectSpec(
{model, std::move(getter), std::move(setter), std::move(resetModel)});
}
};
} // namespace Internal
class DeviceTypeKitAspectFactory : public KitAspectFactory
{
public:
DeviceTypeKitAspectFactory();
void setup(Kit *k) override;
Tasks validate(const Kit *k) const override;
KitAspect *createKitAspect(Kit *k) const override;
ItemList toUserOutput(const Kit *k) const override;
QSet<Id> supportedPlatforms(const Kit *k) const override;
QSet<Id> availableFeatures(const Kit *k) const override;
};
DeviceTypeKitAspectFactory::DeviceTypeKitAspectFactory()
{
setId(DeviceTypeKitAspect::id());
setDisplayName(Tr::tr("Run device type"));
setDescription(Tr::tr("The type of device to run applications on."));
setPriority(33000);
makeEssential();
}
void DeviceTypeKitAspectFactory::setup(Kit *k)
{
if (k && !k->hasValue(id()))
k->setValue(id(), QByteArray(Constants::DESKTOP_DEVICE_TYPE));
}
Tasks DeviceTypeKitAspectFactory::validate(const Kit *k) const
{
Q_UNUSED(k)
return {};
}
KitAspect *DeviceTypeKitAspectFactory::createKitAspect(Kit *k) const
{
QTC_ASSERT(k, return nullptr);
return new Internal::DeviceTypeKitAspectImpl(k, this);
}
KitAspectFactory::ItemList DeviceTypeKitAspectFactory::toUserOutput(const Kit *k) const
{
QTC_ASSERT(k, return {});
Id type = DeviceTypeKitAspect::deviceTypeId(k);
QString typeDisplayName = Tr::tr("Unknown device type");
if (type.isValid()) {
if (IDeviceFactory *factory = IDeviceFactory::find(type))
typeDisplayName = factory->displayName();
}
return {{Tr::tr("Device type"), typeDisplayName}};
}
const Id DeviceTypeKitAspect::id()
{
return "PE.Profile.DeviceType";
}
const Id DeviceTypeKitAspect::deviceTypeId(const Kit *k)
{
return k ? Id::fromSetting(k->value(DeviceTypeKitAspect::id())) : Id();
}
void DeviceTypeKitAspect::setDeviceTypeId(Kit *k, Id type)
{
QTC_ASSERT(k, return);
k->setValue(DeviceTypeKitAspect::id(), type.toSetting());
}
QSet<Id> DeviceTypeKitAspectFactory::supportedPlatforms(const Kit *k) const
{
return {DeviceTypeKitAspect::deviceTypeId(k)};
}
QSet<Id> DeviceTypeKitAspectFactory::availableFeatures(const Kit *k) const
{
Id id = DeviceTypeKitAspect::deviceTypeId(k);
if (id.isValid())
return {id.withPrefix("DeviceType.")};
return {};
}
const DeviceTypeKitAspectFactory theDeviceTypeKitAspectFactory;
// --------------------------------------------------------------------------
// DeviceKitAspect:
// --------------------------------------------------------------------------
namespace Internal {
class DeviceKitAspectImpl final : public KitAspect
{
public:
DeviceKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
: KitAspect(workingCopy, factory),
m_comboBox(createSubWidget<QComboBox>()),
m_model(new DeviceManagerModel(DeviceManager::instance()))
{
setManagingPage(Constants::DEVICE_SETTINGS_PAGE_ID);
m_comboBox->setSizePolicy(QSizePolicy::Preferred,
m_comboBox->sizePolicy().verticalPolicy());
m_comboBox->setModel(m_model);
m_comboBox->setMinimumContentsLength(16); // Don't stretch too much for Kit Page
refresh();
m_comboBox->setToolTip(factory->description());
connect(m_model, &QAbstractItemModel::modelAboutToBeReset,
this, &DeviceKitAspectImpl::modelAboutToReset);
connect(m_model, &QAbstractItemModel::modelReset,
this, &DeviceKitAspectImpl::modelReset);
connect(m_comboBox, &QComboBox::currentIndexChanged,
this, &DeviceKitAspectImpl::currentDeviceChanged);
}
~DeviceKitAspectImpl() override
{
delete m_comboBox;
delete m_model;
}
private:
void addToInnerLayout(Layouting::Layout &builder) override
{
addMutableAction(m_comboBox);
builder.addItem(m_comboBox);
}
void makeReadOnly() override { m_comboBox->setEnabled(false); }
Id settingsPageItemToPreselect() const override { return DeviceKitAspect::deviceId(kit()); }
void refresh() override
{
m_model->setTypeFilter(DeviceTypeKitAspect::deviceTypeId(kit()));
m_comboBox->setCurrentIndex(m_model->indexOf(DeviceKitAspect::device(kit())));
}
void modelAboutToReset()
{
m_selectedId = m_model->deviceId(m_comboBox->currentIndex());
m_ignoreChanges.lock();
}
void modelReset()
{
m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId));
m_ignoreChanges.unlock();
}
void currentDeviceChanged()
{
if (m_ignoreChanges.isLocked())
return;
DeviceKitAspect::setDeviceId(kit(), m_model->deviceId(m_comboBox->currentIndex()));
}
Guard m_ignoreChanges;
QComboBox *m_comboBox;
DeviceManagerModel *m_model;
Id m_selectedId;
};
} // namespace Internal
class DeviceKitAspectFactory : public KitAspectFactory
{
public:
DeviceKitAspectFactory();
private:
Tasks validate(const Kit *k) const override;
void fix(Kit *k) override;
void setup(Kit *k) override;
KitAspect *createKitAspect(Kit *k) const override;
QString displayNamePostfix(const Kit *k) const override;
ItemList toUserOutput(const Kit *k) const override;
void addToMacroExpander(Kit *kit, MacroExpander *expander) const override;
QVariant defaultValue(const Kit *k) const;
void onKitsLoaded() override;
void deviceUpdated(Id dataId);
void devicesChanged();
void kitUpdated(Kit *k);
};
DeviceKitAspectFactory::DeviceKitAspectFactory()
{
setId(DeviceKitAspect::id());
setDisplayName(Tr::tr("Run device"));
setDescription(Tr::tr("The device to run the applications on."));
setPriority(32000);
}
QVariant DeviceKitAspectFactory::defaultValue(const Kit *k) const
{
Id type = DeviceTypeKitAspect::deviceTypeId(k);
// Use default device if that is compatible:
IDevice::ConstPtr dev = DeviceManager::instance()->defaultDevice(type);
if (dev && dev->isCompatibleWith(k))
return dev->id().toString();
// Use any other device that is compatible:
for (int i = 0; i < DeviceManager::instance()->deviceCount(); ++i) {
dev = DeviceManager::instance()->deviceAt(i);
if (dev && dev->isCompatibleWith(k))
return dev->id().toString();
}
// Fail: No device set up.
return {};
}
Tasks DeviceKitAspectFactory::validate(const Kit *k) const
{
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
Tasks result;
if (!dev)
result.append(BuildSystemTask(Task::Warning, Tr::tr("No device set.")));
else if (!dev->isCompatibleWith(k))
result.append(BuildSystemTask(Task::Error, Tr::tr("Device is incompatible with this kit.")));
if (dev)
result.append(dev->validate());
return result;
}
void DeviceKitAspectFactory::fix(Kit *k)
{
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
if (dev && !dev->isCompatibleWith(k)) {
qWarning("Device is no longer compatible with kit \"%s\", removing it.",
qPrintable(k->displayName()));
DeviceKitAspect::setDeviceId(k, Id());
}
}
void DeviceKitAspectFactory::setup(Kit *k)
{
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return);
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
if (dev && dev->isCompatibleWith(k))
return;
DeviceKitAspect::setDeviceId(k, Id::fromSetting(defaultValue(k)));
}
KitAspect *DeviceKitAspectFactory::createKitAspect(Kit *k) const
{
QTC_ASSERT(k, return nullptr);
return new Internal::DeviceKitAspectImpl(k, this);
}
QString DeviceKitAspectFactory::displayNamePostfix(const Kit *k) const
{
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
return dev ? dev->displayName() : QString();
}
KitAspectFactory::ItemList DeviceKitAspectFactory::toUserOutput(const Kit *k) const
{
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
return {{Tr::tr("Device"), dev ? dev->displayName() : Tr::tr("Unconfigured") }};
}
void DeviceKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const
{
QTC_ASSERT(kit, return);
expander->registerVariable("Device:HostAddress", Tr::tr("Host address"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->sshParameters().host() : QString();
});
expander->registerVariable("Device:SshPort", Tr::tr("SSH port"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? QString::number(device->sshParameters().port()) : QString();
});
expander->registerVariable("Device:UserName", Tr::tr("User name"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->sshParameters().userName() : QString();
});
expander->registerVariable("Device:KeyFile", Tr::tr("Private key file"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->sshParameters().privateKeyFile.toString() : QString();
});
expander->registerVariable("Device:Name", Tr::tr("Device name"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->displayName() : QString();
});
expander->registerFileVariables("Device::Root", Tr::tr("Device root directory"), [kit] {
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
return device ? device->rootPath() : FilePath{};
});
}
Id DeviceKitAspect::id()
{
return "PE.Profile.Device";
}
IDevice::ConstPtr DeviceKitAspect::device(const Kit *k)
{
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return IDevice::ConstPtr());
return DeviceManager::instance()->find(deviceId(k));
}
Id DeviceKitAspect::deviceId(const Kit *k)
{
return k ? Id::fromSetting(k->value(DeviceKitAspect::id())) : Id();
}
void DeviceKitAspect::setDevice(Kit *k, IDevice::ConstPtr dev)
{
setDeviceId(k, dev ? dev->id() : Id());
}
void DeviceKitAspect::setDeviceId(Kit *k, Id id)
{
QTC_ASSERT(k, return);
k->setValue(DeviceKitAspect::id(), id.toSetting());
}
FilePath DeviceKitAspect::deviceFilePath(const Kit *k, const QString &pathOnDevice)
{
if (IDevice::ConstPtr dev = device(k))
return dev->filePath(pathOnDevice);
return FilePath::fromString(pathOnDevice);
}
void DeviceKitAspectFactory::onKitsLoaded()
{
for (Kit *k : KitManager::kits())
fix(k);
DeviceManager *dm = DeviceManager::instance();
connect(dm, &DeviceManager::deviceListReplaced, this, &DeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceAdded, this, &DeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceRemoved, this, &DeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceUpdated, this, &DeviceKitAspectFactory::deviceUpdated);
connect(KitManager::instance(), &KitManager::kitUpdated,
this, &DeviceKitAspectFactory::kitUpdated);
connect(KitManager::instance(), &KitManager::unmanagedKitUpdated,
this, &DeviceKitAspectFactory::kitUpdated);
}
void DeviceKitAspectFactory::deviceUpdated(Id id)
{
for (Kit *k : KitManager::kits()) {
if (DeviceKitAspect::deviceId(k) == id)
notifyAboutUpdate(k);
}
}
void DeviceKitAspectFactory::kitUpdated(Kit *k)
{
setup(k); // Set default device if necessary
}
void DeviceKitAspectFactory::devicesChanged()
{
for (Kit *k : KitManager::kits())
setup(k); // Set default device if necessary
}
const DeviceKitAspectFactory theDeviceKitAspectFactory;
// --------------------------------------------------------------------------
// BuildDeviceKitAspect:
// --------------------------------------------------------------------------
namespace Internal {
class BuildDeviceKitAspectImpl final : public KitAspect
{
public:
BuildDeviceKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
: KitAspect(workingCopy, factory),
m_comboBox(createSubWidget<QComboBox>()),
m_model(new DeviceManagerModel(DeviceManager::instance()))
{
setManagingPage(Constants::DEVICE_SETTINGS_PAGE_ID);
m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy());
m_comboBox->setModel(m_model);
refresh();
m_comboBox->setToolTip(factory->description());
connect(m_model, &QAbstractItemModel::modelAboutToBeReset,
this, &BuildDeviceKitAspectImpl::modelAboutToReset);
connect(m_model, &QAbstractItemModel::modelReset,
this, &BuildDeviceKitAspectImpl::modelReset);
connect(m_comboBox, &QComboBox::currentIndexChanged,
this, &BuildDeviceKitAspectImpl::currentDeviceChanged);
}
~BuildDeviceKitAspectImpl() override
{
delete m_comboBox;
delete m_model;
}
private:
void addToInnerLayout(Layouting::Layout &builder) override
{
addMutableAction(m_comboBox);
builder.addItem(m_comboBox);
}
void makeReadOnly() override { m_comboBox->setEnabled(false); }
void refresh() override
{
QList<Id> blackList;
const DeviceManager *dm = DeviceManager::instance();
for (int i = 0; i < dm->deviceCount(); ++i) {
IDevice::ConstPtr device = dm->deviceAt(i);
if (!device->usableAsBuildDevice())
blackList.append(device->id());
}
m_model->setFilter(blackList);
m_comboBox->setCurrentIndex(m_model->indexOf(BuildDeviceKitAspect::device(kit())));
}
void modelAboutToReset()
{
m_selectedId = m_model->deviceId(m_comboBox->currentIndex());
m_ignoreChanges.lock();
}
void modelReset()
{
m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId));
m_ignoreChanges.unlock();
}
void currentDeviceChanged()
{
if (m_ignoreChanges.isLocked())
return;
BuildDeviceKitAspect::setDeviceId(kit(), m_model->deviceId(m_comboBox->currentIndex()));
}
Guard m_ignoreChanges;
QComboBox *m_comboBox;
DeviceManagerModel *m_model;
Id m_selectedId;
};
} // namespace Internal
class BuildDeviceKitAspectFactory : public KitAspectFactory
{
public:
BuildDeviceKitAspectFactory();
private:
void setup(Kit *k) override;
Tasks validate(const Kit *k) const override;
KitAspect *createKitAspect(Kit *k) const override;
QString displayNamePostfix(const Kit *k) const override;
ItemList toUserOutput(const Kit *k) const override;
void addToMacroExpander(Kit *kit, MacroExpander *expander) const override;
void onKitsLoaded() override;
void deviceUpdated(Id dataId);
void devicesChanged();
void kitUpdated(Kit *k);
};
BuildDeviceKitAspectFactory::BuildDeviceKitAspectFactory()
{
setId(BuildDeviceKitAspect::id());
setDisplayName(Tr::tr("Build device"));
setDescription(Tr::tr("The device used to build applications on."));
setPriority(31900);
}
static IDeviceConstPtr defaultDevice()
{
return DeviceManager::defaultDesktopDevice();
}
void BuildDeviceKitAspectFactory::setup(Kit *k)
{
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return );
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
if (dev)
return;
dev = defaultDevice();
BuildDeviceKitAspect::setDeviceId(k, dev ? dev->id() : Id());
}
Tasks BuildDeviceKitAspectFactory::validate(const Kit *k) const
{
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
Tasks result;
if (!dev)
result.append(BuildSystemTask(Task::Warning, Tr::tr("No build device set.")));
return result;
}
KitAspect *BuildDeviceKitAspectFactory::createKitAspect(Kit *k) const
{
QTC_ASSERT(k, return nullptr);
return new Internal::BuildDeviceKitAspectImpl(k, this);
}
QString BuildDeviceKitAspectFactory::displayNamePostfix(const Kit *k) const
{
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
return dev ? dev->displayName() : QString();
}
KitAspectFactory::ItemList BuildDeviceKitAspectFactory::toUserOutput(const Kit *k) const
{
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
return {{Tr::tr("Build device"), dev ? dev->displayName() : Tr::tr("Unconfigured")}};
}
void BuildDeviceKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const
{
QTC_ASSERT(kit, return);
expander->registerVariable("BuildDevice:HostAddress", Tr::tr("Build host address"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->sshParameters().host() : QString();
});
expander->registerVariable("BuildDevice:SshPort", Tr::tr("Build SSH port"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? QString::number(device->sshParameters().port()) : QString();
});
expander->registerVariable("BuildDevice:UserName", Tr::tr("Build user name"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->sshParameters().userName() : QString();
});
expander->registerVariable("BuildDevice:KeyFile", Tr::tr("Build private key file"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->sshParameters().privateKeyFile.toString() : QString();
});
expander->registerVariable("BuildDevice:Name", Tr::tr("Build device name"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->displayName() : QString();
});
expander
->registerFileVariables("BuildDevice::Root", Tr::tr("Build device root directory"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->rootPath() : FilePath{};
});
}
Id BuildDeviceKitAspect::id()
{
return "PE.Profile.BuildDevice";
}
IDevice::ConstPtr BuildDeviceKitAspect::device(const Kit *k)
{
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return IDevice::ConstPtr());
IDevice::ConstPtr dev = DeviceManager::instance()->find(deviceId(k));
if (!dev)
dev = defaultDevice();
return dev;
}
Id BuildDeviceKitAspect::deviceId(const Kit *k)
{
return k ? Id::fromSetting(k->value(BuildDeviceKitAspect::id())) : Id();
}
void BuildDeviceKitAspect::setDevice(Kit *k, IDevice::ConstPtr dev)
{
setDeviceId(k, dev ? dev->id() : Id());
}
void BuildDeviceKitAspect::setDeviceId(Kit *k, Id id)
{
QTC_ASSERT(k, return);
k->setValue(BuildDeviceKitAspect::id(), id.toSetting());
}
void BuildDeviceKitAspectFactory::onKitsLoaded()
{
for (Kit *k : KitManager::kits())
fix(k);
DeviceManager *dm = DeviceManager::instance();
connect(dm, &DeviceManager::deviceListReplaced,
this, &BuildDeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceAdded,
this, &BuildDeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceRemoved,
this, &BuildDeviceKitAspectFactory::devicesChanged);
connect(dm, &DeviceManager::deviceUpdated,
this, &BuildDeviceKitAspectFactory::deviceUpdated);
connect(KitManager::instance(), &KitManager::kitUpdated,
this, &BuildDeviceKitAspectFactory::kitUpdated);
connect(KitManager::instance(), &KitManager::unmanagedKitUpdated,
this, &BuildDeviceKitAspectFactory::kitUpdated);
}
void BuildDeviceKitAspectFactory::deviceUpdated(Id id)
{
const QList<Kit *> kits = KitManager::kits();
for (Kit *k : kits) {
if (BuildDeviceKitAspect::deviceId(k) == id)
notifyAboutUpdate(k);
}
}
void BuildDeviceKitAspectFactory::kitUpdated(Kit *k)
{
setup(k); // Set default device if necessary
}
void BuildDeviceKitAspectFactory::devicesChanged()
{
const QList<Kit *> kits = KitManager::kits();
for (Kit *k : kits)
setup(k); // Set default device if necessary
}
const BuildDeviceKitAspectFactory theBuildDeviceKitAspectFactory;
// --------------------------------------------------------------------------
// EnvironmentKitAspect:
// --------------------------------------------------------------------------

View File

@@ -4,18 +4,16 @@
#pragma once
#include "abi.h"
#include "devicesupport/idevicefwd.h"
#include "kit.h"
#include "devicesupport/devicekitaspects.h"
#include "toolchainkitaspect.h"
#include <utils/environment.h>
namespace ProjectExplorer {
class Kit;
class Toolchain;
class ToolchainBundle;
// SysRootKitAspect
class PROJECTEXPLORER_EXPORT SysRootKitAspect
{
public:
@@ -24,44 +22,6 @@ public:
static void setSysRoot(Kit *k, const Utils::FilePath &v);
};
// DeviceTypeKitAspect
class PROJECTEXPLORER_EXPORT DeviceTypeKitAspect
{
public:
static const Utils::Id id();
static const Utils::Id deviceTypeId(const Kit *k);
static void setDeviceTypeId(Kit *k, Utils::Id type);
};
// DeviceKitAspect
class PROJECTEXPLORER_EXPORT DeviceKitAspect
{
public:
static Utils::Id id();
static IDeviceConstPtr device(const Kit *k);
static Utils::Id deviceId(const Kit *k);
static void setDevice(Kit *k, IDeviceConstPtr dev);
static void setDeviceId(Kit *k, Utils::Id dataId);
static Utils::FilePath deviceFilePath(const Kit *k, const QString &pathOnDevice);
};
// BuildDeviceKitAspect
class PROJECTEXPLORER_EXPORT BuildDeviceKitAspect
{
public:
static Utils::Id id();
static IDeviceConstPtr device(const Kit *k);
static Utils::Id deviceId(const Kit *k);
static void setDevice(Kit *k, IDeviceConstPtr dev);
static void setDeviceId(Kit *k, Utils::Id dataId);
};
// EnvironmentKitAspect
class PROJECTEXPLORER_EXPORT EnvironmentKitAspect
{
public:

View File

@@ -6,6 +6,7 @@
#include "buildconfiguration.h"
#include "devicesupport/idevice.h"
#include "gnumakeparser.h"
#include "kit.h"
#include "kitaspects.h"
#include "processparameters.h"
#include "projectexplorer.h"

View File

@@ -208,6 +208,7 @@ QtcPlugin {
"desktopdevicefactory.cpp", "desktopdevicefactory.h",
"devicecheckbuildstep.cpp", "devicecheckbuildstep.h",
"devicefactoryselectiondialog.cpp", "devicefactoryselectiondialog.h",
"devicekitaspects.cpp", "devicekitaspects.h",
"devicemanager.cpp", "devicemanager.h",
"devicemanagermodel.cpp", "devicemanagermodel.h",
"deviceprocessesdialog.cpp", "deviceprocessesdialog.h",