diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index 01c43163ab1..b69229aabbd 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -35,6 +35,8 @@ #include "toolchain.h" #include "toolchainmanager.h" +#include + #include #include @@ -1065,6 +1067,234 @@ void DeviceKitAspect::devicesChanged() setup(k); // Set default device if necessary } +// -------------------------------------------------------------------------- +// BuildDeviceKitAspect: +// -------------------------------------------------------------------------- +namespace Internal { +class BuildDeviceKitAspectWidget final : public KitAspectWidget +{ + Q_DECLARE_TR_FUNCTIONS(ProjectExplorer::BuildDeviceKitAspect) + +public: + BuildDeviceKitAspectWidget(Kit *workingCopy, const KitAspect *ki) + : KitAspectWidget(workingCopy, ki), + m_comboBox(createSubWidget()), + m_model(new DeviceManagerModel(DeviceManager::instance())) + { + m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy()); + m_comboBox->setModel(m_model); + m_manageButton = createManageButton(Constants::DEVICE_SETTINGS_PAGE_ID); + refresh(); + m_comboBox->setToolTip(ki->description()); + + connect(m_model, &QAbstractItemModel::modelAboutToBeReset, + this, &BuildDeviceKitAspectWidget::modelAboutToReset); + connect(m_model, &QAbstractItemModel::modelReset, + this, &BuildDeviceKitAspectWidget::modelReset); + connect(m_comboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &BuildDeviceKitAspectWidget::currentDeviceChanged); + } + + ~BuildDeviceKitAspectWidget() override + { + delete m_comboBox; + delete m_model; + delete m_manageButton; + } + +private: + void addToLayout(LayoutBuilder &builder) override + { + addMutableAction(m_comboBox); + builder.addItem(m_comboBox); + builder.addItem(m_manageButton); + } + + void makeReadOnly() override { m_comboBox->setEnabled(false); } + + void refresh() override + { + QList blackList; + const DeviceManager *dm = DeviceManager::instance(); + for (int i = 0; i < dm->deviceCount(); ++i) { + IDevice::ConstPtr device = dm->deviceAt(i); + if (!(device->type() == Constants::DESKTOP_DEVICE_TYPE + || device->type() == Docker::Constants::DOCKER_DEVICE_TYPE)) + blackList.append(device->id()); + } + + m_model->setFilter(blackList); + m_comboBox->setCurrentIndex(m_model->indexOf(BuildDeviceKitAspect::device(m_kit))); + } + + void modelAboutToReset() + { + m_selectedId = m_model->deviceId(m_comboBox->currentIndex()); + m_ignoreChange = true; + } + + void modelReset() + { + m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId)); + m_ignoreChange = false; + } + + void currentDeviceChanged() + { + if (m_ignoreChange) + return; + BuildDeviceKitAspect::setDeviceId(m_kit, m_model->deviceId(m_comboBox->currentIndex())); + } + + bool m_ignoreChange = false; + QComboBox *m_comboBox; + QWidget *m_manageButton; + DeviceManagerModel *m_model; + Utils::Id m_selectedId; +}; +} // namespace Internal + +BuildDeviceKitAspect::BuildDeviceKitAspect() +{ + setObjectName("BuildDeviceInformation"); + setId(BuildDeviceKitAspect::id()); + setDisplayName(tr("Build device")); + setDescription(tr("The device used to build applications on.")); + setPriority(31900); + + connect(KitManager::instance(), &KitManager::kitsLoaded, + this, &BuildDeviceKitAspect::kitsWereLoaded); +} + +QVariant BuildDeviceKitAspect::defaultValue(const Kit *k) const +{ + Q_UNUSED(k); + IDevice::ConstPtr defaultDevice = + DeviceManager::instance()->defaultDevice(Constants::DESKTOP_DEVICE_TYPE); + return defaultDevice->id().toString(); +} + +Tasks BuildDeviceKitAspect::validate(const Kit *k) const +{ + IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k); + Tasks result; + if (dev.isNull()) + result.append(BuildSystemTask(Task::Warning, tr("No device set."))); + + return result; +} + +KitAspectWidget *BuildDeviceKitAspect::createConfigWidget(Kit *k) const +{ + QTC_ASSERT(k, return nullptr); + return new Internal::BuildDeviceKitAspectWidget(k, this); +} + +QString BuildDeviceKitAspect::displayNamePostfix(const Kit *k) const +{ + IDevice::ConstPtr dev = device(k); + return dev.isNull() ? QString() : dev->displayName(); +} + +KitAspect::ItemList BuildDeviceKitAspect::toUserOutput(const Kit *k) const +{ + IDevice::ConstPtr dev = device(k); + return {{tr("Build device"), dev.isNull() ? tr("Unconfigured") : dev->displayName()}}; +} + +void BuildDeviceKitAspect::addToMacroExpander(Kit *kit, Utils::MacroExpander *expander) const +{ + QTC_ASSERT(kit, return); + expander->registerVariable("BuildDevice:HostAddress", tr("Build host address"), + [kit]() -> QString { + const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit); + return device ? device->sshParameters().host() : QString(); + }); + expander->registerVariable("BuildDevice:SshPort", tr("Build SSH port"), + [kit]() -> QString { + const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit); + return device ? QString::number(device->sshParameters().port()) : QString(); + }); + expander->registerVariable("BuildDevice:UserName", tr("Build user name"), + [kit]() -> QString { + const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit); + return device ? device->sshParameters().userName() : QString(); + }); + expander->registerVariable("BuildDevice:KeyFile", tr("Build private key file"), + [kit]() -> QString { + const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit); + return device ? device->sshParameters().privateKeyFile : QString(); + }); + expander->registerVariable("BuildDevice:Name", tr("Build device name"), + [kit]() -> QString { + const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit); + return device ? device->displayName() : QString(); + }); +} + +Utils::Id BuildDeviceKitAspect::id() +{ + return "PE.Profile.BuildDevice"; +} + +IDevice::ConstPtr BuildDeviceKitAspect::device(const Kit *k) +{ + QTC_ASSERT(DeviceManager::instance()->isLoaded(), return IDevice::ConstPtr()); + return DeviceManager::instance()->find(deviceId(k)); +} + +Utils::Id BuildDeviceKitAspect::deviceId(const Kit *k) +{ + return k ? Utils::Id::fromSetting(k->value(BuildDeviceKitAspect::id())) : Utils::Id(); +} + +void BuildDeviceKitAspect::setDevice(Kit *k, IDevice::ConstPtr dev) +{ + setDeviceId(k, dev ? dev->id() : Utils::Id()); +} + +void BuildDeviceKitAspect::setDeviceId(Kit *k, Utils::Id id) +{ + QTC_ASSERT(k, return); + k->setValue(BuildDeviceKitAspect::id(), id.toSetting()); +} + +void BuildDeviceKitAspect::kitsWereLoaded() +{ + foreach (Kit *k, KitManager::kits()) + fix(k); + + DeviceManager *dm = DeviceManager::instance(); + connect(dm, &DeviceManager::deviceListReplaced, this, &BuildDeviceKitAspect::devicesChanged); + connect(dm, &DeviceManager::deviceAdded, this, &BuildDeviceKitAspect::devicesChanged); + connect(dm, &DeviceManager::deviceRemoved, this, &BuildDeviceKitAspect::devicesChanged); + connect(dm, &DeviceManager::deviceUpdated, this, &BuildDeviceKitAspect::deviceUpdated); + + connect(KitManager::instance(), &KitManager::kitUpdated, + this, &BuildDeviceKitAspect::kitUpdated); + connect(KitManager::instance(), &KitManager::unmanagedKitUpdated, + this, &BuildDeviceKitAspect::kitUpdated); +} + +void BuildDeviceKitAspect::deviceUpdated(Utils::Id id) +{ + foreach (Kit *k, KitManager::kits()) { + if (deviceId(k) == id) + notifyAboutUpdate(k); + } +} + +void BuildDeviceKitAspect::kitUpdated(Kit *k) +{ + setup(k); // Set default device if necessary +} + +void BuildDeviceKitAspect::devicesChanged() +{ + foreach (Kit *k, KitManager::kits()) + setup(k); // Set default device if necessary +} + // -------------------------------------------------------------------------- // EnvironmentKitAspect: // -------------------------------------------------------------------------- diff --git a/src/plugins/projectexplorer/kitinformation.h b/src/plugins/projectexplorer/kitinformation.h index 4e5708eecaa..89e64c27644 100644 --- a/src/plugins/projectexplorer/kitinformation.h +++ b/src/plugins/projectexplorer/kitinformation.h @@ -169,6 +169,42 @@ private: void kitUpdated(ProjectExplorer::Kit *k); }; +// -------------------------------------------------------------------------- +// BuildDeviceInformation: +// -------------------------------------------------------------------------- + +class PROJECTEXPLORER_EXPORT BuildDeviceKitAspect : public KitAspect +{ + Q_OBJECT + +public: + BuildDeviceKitAspect(); + + Tasks validate(const Kit *k) const override; + + KitAspectWidget *createConfigWidget(Kit *k) const override; + + QString displayNamePostfix(const Kit *k) const override; + + ItemList toUserOutput(const Kit *k) const override; + + void addToMacroExpander(ProjectExplorer::Kit *kit, Utils::MacroExpander *expander) const override; + + static Utils::Id id(); + static IDevice::ConstPtr device(const Kit *k); + static Utils::Id deviceId(const Kit *k); + static void setDevice(Kit *k, IDevice::ConstPtr dev); + static void setDeviceId(Kit *k, Utils::Id dataId); + +private: + QVariant defaultValue(const Kit *k) const; + + void kitsWereLoaded(); + void deviceUpdated(Utils::Id dataId); + void devicesChanged(); + void kitUpdated(ProjectExplorer::Kit *k); +}; + // -------------------------------------------------------------------------- // EnvironmentKitAspect: // -------------------------------------------------------------------------- diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 9ec5253cf77..337ee21c86f 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -653,7 +653,8 @@ public: IDocumentFactory m_documentFactory; DeviceTypeKitAspect deviceTypeKitAspect; - DeviceKitAspect deviceeKitAspect; + DeviceKitAspect deviceKitAspect; + BuildDeviceKitAspect buildDeviceKitAspect; ToolChainKitAspect toolChainKitAspect; SysRootKitAspect sysRootKitAspect; EnvironmentKitAspect environmentKitAspect;