forked from qt-creator/qt-creator
Project: Base IDevice on AspectContainer
This is effectively the same approach as taken with ProjectConfiguration. Having the settings separate leads to quite some boilerplate and in the end to parallel IDevice and DeviceSettings hierarchies. The unusual registration of the docker aspects are due to the multiple inheritance, we need to "dynamic" downcast. Change-Id: I50864e2009f4e525d635decf1c9beaad5e6a5f1f Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -177,7 +177,7 @@ static IDevice::Ptr createDeviceFromInfo(const CreateAvdInfo &info)
|
||||
const Id deviceId = AndroidDevice::idFromAvdInfo(info);
|
||||
dev->setupId(IDevice::AutoDetected, deviceId);
|
||||
dev->setMachineType(IDevice::Emulator);
|
||||
dev->settings()->displayName.setValue(info.name);
|
||||
dev->displayName.setValue(info.name);
|
||||
dev->setDeviceState(IDevice::DeviceConnected);
|
||||
dev->setAvdPath(avdFilePath() / (info.name + ".avd"));
|
||||
dev->setExtraData(Constants::AndroidAvdName, info.name);
|
||||
@@ -349,7 +349,7 @@ AndroidDevice::AndroidDevice()
|
||||
{
|
||||
setupId(IDevice::AutoDetected, Constants::ANDROID_DEVICE_ID);
|
||||
setType(Constants::ANDROID_DEVICE_TYPE);
|
||||
settings()->displayName.setDefaultValue(Tr::tr("Run on Android"));
|
||||
displayName.setDefaultValue(Tr::tr("Run on Android"));
|
||||
setDisplayType(Tr::tr("Android"));
|
||||
setMachineType(IDevice::Hardware);
|
||||
setOsType(OsType::OsTypeOtherUnix);
|
||||
@@ -672,7 +672,7 @@ static void handleDevicesListChange(const QString &serialNumber)
|
||||
} else {
|
||||
AndroidDevice *newDev = new AndroidDevice();
|
||||
newDev->setupId(IDevice::AutoDetected, id);
|
||||
newDev->settings()->displayName.setValue(displayName);
|
||||
newDev->displayName.setValue(displayName);
|
||||
newDev->setMachineType(IDevice::Hardware);
|
||||
newDev->setDeviceState(state);
|
||||
|
||||
@@ -758,7 +758,7 @@ static void handleAvdListChange(const AndroidDeviceInfoList &avdList)
|
||||
|
||||
AndroidDevice *newDev = new AndroidDevice;
|
||||
newDev->setupId(IDevice::AutoDetected, deviceId);
|
||||
newDev->settings()->displayName.setValue(displayName);
|
||||
newDev->displayName.setValue(displayName);
|
||||
newDev->setMachineType(item.type);
|
||||
newDev->setDeviceState(item.state);
|
||||
|
||||
|
@@ -26,7 +26,7 @@ ProjectExplorer::IDevice::Ptr BareMetalDeviceConfigurationWizard::device() const
|
||||
{
|
||||
const auto dev = BareMetalDevice::create();
|
||||
dev->setupId(ProjectExplorer::IDevice::ManuallyAdded, Utils::Id());
|
||||
dev->settings()->displayName.setDefaultValue(m_setupPage->configurationName());
|
||||
dev->displayName.setDefaultValue(m_setupPage->configurationName());
|
||||
dev->setType(Constants::BareMetalOsType);
|
||||
dev->setMachineType(ProjectExplorer::IDevice::Hardware);
|
||||
dev->setDebugServerProviderId(m_setupPage->debugServerProviderId());
|
||||
|
@@ -84,7 +84,7 @@ void DeviceDetector::handleDeviceEvent(QdbDeviceTracker::DeviceEventType eventTy
|
||||
const QString name = Tr::tr("Boot to Qt device %1").arg(serial);
|
||||
QdbDevice::Ptr device = QdbDevice::create();
|
||||
device->setupId(IDevice::AutoDetected, deviceId);
|
||||
device->settings()->displayName.setValue(name);
|
||||
device->displayName.setValue(name);
|
||||
device->setType(Qdb::Constants::QdbLinuxOsType);
|
||||
device->setMachineType(IDevice::Hardware);
|
||||
device->setExtraData(ProjectExplorer::Constants::SUPPORTS_RSYNC, true);
|
||||
|
@@ -207,7 +207,7 @@ public:
|
||||
{
|
||||
QdbDevice::Ptr device = QdbDevice::create();
|
||||
|
||||
device->settings()->displayName.setValue(settingsPage.deviceName());
|
||||
device->displayName.setValue(settingsPage.deviceName());
|
||||
device->setupId(ProjectExplorer::IDevice::ManuallyAdded, Utils::Id());
|
||||
device->setType(Constants::QdbLinuxOsType);
|
||||
device->setMachineType(ProjectExplorer::IDevice::Hardware);
|
||||
|
@@ -142,128 +142,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void DockerDeviceSettings::fromMap(const Store &map)
|
||||
{
|
||||
DeviceSettings::fromMap(map);
|
||||
|
||||
// This is the only place where we can correctly set the default name.
|
||||
// Only here do we know the image id and the repo reliably, no matter
|
||||
// where or how we were created.
|
||||
if (displayName.value() == displayName.defaultValue()) {
|
||||
displayName.setDefaultValue(
|
||||
Tr::tr("Docker Image \"%1\" (%2)").arg(repoAndTag()).arg(imageId.value()));
|
||||
}
|
||||
}
|
||||
|
||||
DockerDeviceSettings::DockerDeviceSettings()
|
||||
{
|
||||
imageId.setSettingsKey(DockerDeviceDataImageIdKey);
|
||||
imageId.setLabelText(Tr::tr("Image ID:"));
|
||||
imageId.setReadOnly(true);
|
||||
|
||||
repo.setSettingsKey(DockerDeviceDataRepoKey);
|
||||
repo.setLabelText(Tr::tr("Repository:"));
|
||||
repo.setReadOnly(true);
|
||||
|
||||
tag.setSettingsKey(DockerDeviceDataTagKey);
|
||||
tag.setLabelText(Tr::tr("Tag:"));
|
||||
tag.setReadOnly(true);
|
||||
|
||||
useLocalUidGid.setSettingsKey(DockerDeviceUseOutsideUser);
|
||||
useLocalUidGid.setLabelText(Tr::tr("Run as outside user:"));
|
||||
useLocalUidGid.setDefaultValue(true);
|
||||
useLocalUidGid.setLabelPlacement(BoolAspect::LabelPlacement::InExtraLabel);
|
||||
|
||||
keepEntryPoint.setSettingsKey(DockerDeviceKeepEntryPoint);
|
||||
keepEntryPoint.setLabelText(Tr::tr("Do not modify entry point:"));
|
||||
keepEntryPoint.setDefaultValue(false);
|
||||
keepEntryPoint.setLabelPlacement(BoolAspect::LabelPlacement::InExtraLabel);
|
||||
|
||||
enableLldbFlags.setSettingsKey(DockerDeviceEnableLldbFlags);
|
||||
enableLldbFlags.setLabelText(Tr::tr("Enable flags needed for LLDB:"));
|
||||
enableLldbFlags.setDefaultValue(false);
|
||||
enableLldbFlags.setLabelPlacement(BoolAspect::LabelPlacement::InExtraLabel);
|
||||
|
||||
mounts.setSettingsKey(DockerDeviceMappedPaths);
|
||||
mounts.setLabelText(Tr::tr("Paths to mount:"));
|
||||
mounts.setDefaultValue({Core::DocumentManager::projectsDirectory().toString()});
|
||||
mounts.setToolTip(Tr::tr("Maps paths in this list one-to-one to the docker container."));
|
||||
mounts.setPlaceHolderText(Tr::tr("Host directories to mount into the container."));
|
||||
|
||||
extraArgs.setSettingsKey(DockerDeviceExtraArgs);
|
||||
extraArgs.setLabelText(Tr::tr("Extra arguments:"));
|
||||
extraArgs.setToolTip(Tr::tr("Extra arguments to pass to docker create."));
|
||||
extraArgs.setDisplayStyle(StringAspect::LineEditDisplay);
|
||||
|
||||
clangdExecutable.setSettingsKey(DockerDeviceClangDExecutable);
|
||||
clangdExecutable.setLabelText(Tr::tr("Clangd Executable:"));
|
||||
clangdExecutable.setAllowPathFromDevice(true);
|
||||
|
||||
network.setSettingsKey("Network");
|
||||
network.setLabelText(Tr::tr("Network:"));
|
||||
network.setDefaultValue("bridge");
|
||||
network.setFillCallback([this](const StringSelectionAspect::ResultCallback &cb) {
|
||||
auto future = DockerApi::instance()->networks();
|
||||
|
||||
auto watcher = new QFutureWatcher<expected_str<QList<Network>>>(this);
|
||||
watcher->setFuture(future);
|
||||
QObject::connect(watcher,
|
||||
&QFutureWatcher<expected_str<QList<Network>>>::finished,
|
||||
this,
|
||||
[watcher, cb]() {
|
||||
expected_str<QList<Network>> result = watcher->result();
|
||||
if (result) {
|
||||
auto items = transform(*result, [](const Network &network) {
|
||||
QStandardItem *item = new QStandardItem(network.name);
|
||||
item->setData(network.name);
|
||||
item->setToolTip(network.toString());
|
||||
return item;
|
||||
});
|
||||
cb(items);
|
||||
} else {
|
||||
QStandardItem *errorItem = new QStandardItem(Tr::tr("Error"));
|
||||
errorItem->setToolTip(result.error());
|
||||
cb({errorItem});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
connect(DockerApi::instance(),
|
||||
&DockerApi::dockerDaemonAvailableChanged,
|
||||
&network,
|
||||
&StringSelectionAspect::refill);
|
||||
|
||||
clangdExecutable.setValidationFunction(
|
||||
[this](const QString &newValue) -> FancyLineEdit::AsyncValidationFuture {
|
||||
const FilePath rootPath = FilePath::fromParts(Constants::DOCKER_DEVICE_SCHEME,
|
||||
repoAndTagEncoded(),
|
||||
u"/");
|
||||
return asyncRun([rootPath, newValue]() -> expected_str<QString> {
|
||||
QString changedValue = newValue;
|
||||
FilePath path = FilePath::fromUserInput(newValue);
|
||||
if (!path.needsDevice()) {
|
||||
const FilePath onDevicePath = rootPath.withNewMappedPath(path);
|
||||
if (onDevicePath.exists()) {
|
||||
changedValue = onDevicePath.toUserOutput();
|
||||
path = onDevicePath;
|
||||
} else {
|
||||
return make_unexpected(
|
||||
Tr::tr("The path \"%1\" does not exist.").arg(onDevicePath.toUserOutput()));
|
||||
}
|
||||
}
|
||||
QString error;
|
||||
bool result = checkClangdVersion(path, &error);
|
||||
if (!result)
|
||||
return make_unexpected(error);
|
||||
return changedValue;
|
||||
});
|
||||
});
|
||||
|
||||
containerStatus.setText(Tr::tr("stopped"));
|
||||
}
|
||||
|
||||
// Used for "docker run"
|
||||
QString DockerDeviceSettings::repoAndTag() const
|
||||
QString DockerDevice::repoAndTag() const
|
||||
{
|
||||
if (repo() == "<none>")
|
||||
return imageId();
|
||||
@@ -274,12 +154,12 @@ QString DockerDeviceSettings::repoAndTag() const
|
||||
return repo() + ':' + tag();
|
||||
}
|
||||
|
||||
QString DockerDeviceSettings::repoAndTagEncoded() const
|
||||
QString DockerDevice::repoAndTagEncoded() const
|
||||
{
|
||||
return repoAndTag().replace(':', '.');
|
||||
}
|
||||
|
||||
FilePath DockerDeviceSettings::rootPath() const
|
||||
FilePath DockerDevice::rootPath() const
|
||||
{
|
||||
return FilePath::fromParts(Constants::DOCKER_DEVICE_SCHEME, repoAndTagEncoded(), u"/");
|
||||
}
|
||||
@@ -289,9 +169,8 @@ class DockerDevicePrivate : public QObject
|
||||
public:
|
||||
DockerDevicePrivate(DockerDevice *parent)
|
||||
: q(parent)
|
||||
, deviceSettings(static_cast<DockerDeviceSettings *>(q->settings()))
|
||||
{
|
||||
QObject::connect(deviceSettings, &DockerDeviceSettings::applied, this, [this] {
|
||||
QObject::connect(q, &DockerDevice::applied, this, [this] {
|
||||
if (!m_container.isEmpty()) {
|
||||
stopCurrentContainer();
|
||||
}
|
||||
@@ -310,10 +189,6 @@ public:
|
||||
|
||||
QString containerId() { return m_container; }
|
||||
|
||||
QString repoAndTag() const { return deviceSettings->repoAndTag(); }
|
||||
QString repoAndTagEncoded() const { return deviceSettings->repoAndTagEncoded(); }
|
||||
QString dockerImageId() const { return deviceSettings->imageId(); }
|
||||
|
||||
expected_str<QPair<Utils::OsType, Utils::OsArch>> osTypeAndArch() const;
|
||||
|
||||
expected_str<Environment> environment();
|
||||
@@ -337,11 +212,11 @@ public:
|
||||
|
||||
std::optional<FilePath> clangdExecutable() const
|
||||
{
|
||||
if (deviceSettings->clangdExecutable().isEmpty())
|
||||
if (q->clangdExecutableAspect().isEmpty())
|
||||
return std::nullopt;
|
||||
if (!deviceSettings->clangdExecutable().needsDevice())
|
||||
return deviceSettings->rootPath().withNewMappedPath(deviceSettings->clangdExecutable());
|
||||
return deviceSettings->clangdExecutable();
|
||||
if (!q->clangdExecutableAspect().needsDevice())
|
||||
return q->rootPath().withNewMappedPath(q->clangdExecutableAspect());
|
||||
return q->clangdExecutableAspect();
|
||||
}
|
||||
|
||||
QStringList createMountArgs() const;
|
||||
@@ -349,7 +224,6 @@ public:
|
||||
bool isImageAvailable() const;
|
||||
|
||||
DockerDevice *const q;
|
||||
DockerDeviceSettings *deviceSettings;
|
||||
|
||||
struct MountPair
|
||||
{
|
||||
@@ -569,7 +443,7 @@ Tasks DockerDevicePrivate::validateMounts() const
|
||||
{
|
||||
Tasks result;
|
||||
|
||||
for (const FilePath &mount : deviceSettings->mounts()) {
|
||||
for (const FilePath &mount : q->mounts()) {
|
||||
if (!mount.isDir()) {
|
||||
const QString message = Tr::tr("Path \"%1\" is not a directory or does not exist.")
|
||||
.arg(mount.toUserOutput());
|
||||
@@ -593,10 +467,114 @@ QString DockerDeviceFileAccess::mapToDevicePath(const QString &hostPath) const
|
||||
return newPath;
|
||||
}
|
||||
|
||||
DockerDevice::DockerDevice(std::unique_ptr<DockerDeviceSettings> deviceSettings)
|
||||
: ProjectExplorer::IDevice(std::move(deviceSettings))
|
||||
, d(new DockerDevicePrivate(this))
|
||||
DockerDevice::DockerDevice()
|
||||
: d(new DockerDevicePrivate(this))
|
||||
{
|
||||
imageId.setSettingsKey(DockerDeviceDataImageIdKey);
|
||||
imageId.setLabelText(Tr::tr("Image ID:"));
|
||||
imageId.setReadOnly(true);
|
||||
|
||||
repo.setSettingsKey(DockerDeviceDataRepoKey);
|
||||
repo.setLabelText(Tr::tr("Repository:"));
|
||||
repo.setReadOnly(true);
|
||||
|
||||
tag.setSettingsKey(DockerDeviceDataTagKey);
|
||||
tag.setLabelText(Tr::tr("Tag:"));
|
||||
tag.setReadOnly(true);
|
||||
|
||||
useLocalUidGid.setSettingsKey(DockerDeviceUseOutsideUser);
|
||||
useLocalUidGid.setLabelText(Tr::tr("Run as outside user:"));
|
||||
useLocalUidGid.setDefaultValue(true);
|
||||
useLocalUidGid.setLabelPlacement(BoolAspect::LabelPlacement::InExtraLabel);
|
||||
|
||||
keepEntryPoint.setSettingsKey(DockerDeviceKeepEntryPoint);
|
||||
keepEntryPoint.setLabelText(Tr::tr("Do not modify entry point:"));
|
||||
keepEntryPoint.setDefaultValue(false);
|
||||
keepEntryPoint.setLabelPlacement(BoolAspect::LabelPlacement::InExtraLabel);
|
||||
|
||||
enableLldbFlags.setSettingsKey(DockerDeviceEnableLldbFlags);
|
||||
enableLldbFlags.setLabelText(Tr::tr("Enable flags needed for LLDB:"));
|
||||
enableLldbFlags.setDefaultValue(false);
|
||||
enableLldbFlags.setLabelPlacement(BoolAspect::LabelPlacement::InExtraLabel);
|
||||
|
||||
mounts.setSettingsKey(DockerDeviceMappedPaths);
|
||||
mounts.setLabelText(Tr::tr("Paths to mount:"));
|
||||
mounts.setDefaultValue({Core::DocumentManager::projectsDirectory().toString()});
|
||||
mounts.setToolTip(Tr::tr("Maps paths in this list one-to-one to the docker container."));
|
||||
mounts.setPlaceHolderText(Tr::tr("Host directories to mount into the container."));
|
||||
|
||||
extraArgs.setSettingsKey(DockerDeviceExtraArgs);
|
||||
extraArgs.setLabelText(Tr::tr("Extra arguments:"));
|
||||
extraArgs.setToolTip(Tr::tr("Extra arguments to pass to docker create."));
|
||||
extraArgs.setDisplayStyle(StringAspect::LineEditDisplay);
|
||||
|
||||
clangdExecutableAspect.setSettingsKey(DockerDeviceClangDExecutable);
|
||||
clangdExecutableAspect.setLabelText(Tr::tr("Clangd Executable:"));
|
||||
clangdExecutableAspect.setAllowPathFromDevice(true);
|
||||
|
||||
network.setSettingsKey("Network");
|
||||
network.setLabelText(Tr::tr("Network:"));
|
||||
network.setDefaultValue("bridge");
|
||||
network.setFillCallback([this](const StringSelectionAspect::ResultCallback &cb) {
|
||||
auto future = DockerApi::instance()->networks();
|
||||
|
||||
auto watcher = new QFutureWatcher<expected_str<QList<Network>>>(this);
|
||||
watcher->setFuture(future);
|
||||
QObject::connect(watcher,
|
||||
&QFutureWatcher<expected_str<QList<Network>>>::finished,
|
||||
this,
|
||||
[watcher, cb]() {
|
||||
expected_str<QList<Network>> result = watcher->result();
|
||||
if (result) {
|
||||
auto items = transform(*result, [](const Network &network) {
|
||||
QStandardItem *item = new QStandardItem(network.name);
|
||||
item->setData(network.name);
|
||||
item->setToolTip(network.toString());
|
||||
return item;
|
||||
});
|
||||
cb(items);
|
||||
} else {
|
||||
QStandardItem *errorItem = new QStandardItem(Tr::tr("Error"));
|
||||
errorItem->setToolTip(result.error());
|
||||
cb({errorItem});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
connect(DockerApi::instance(),
|
||||
&DockerApi::dockerDaemonAvailableChanged,
|
||||
&network,
|
||||
&StringSelectionAspect::refill);
|
||||
|
||||
clangdExecutableAspect.setValidationFunction(
|
||||
[this](const QString &newValue) -> FancyLineEdit::AsyncValidationFuture {
|
||||
const FilePath rootPath = FilePath::fromParts(Constants::DOCKER_DEVICE_SCHEME,
|
||||
repoAndTagEncoded(),
|
||||
u"/");
|
||||
return asyncRun([rootPath, newValue]() -> expected_str<QString> {
|
||||
QString changedValue = newValue;
|
||||
FilePath path = FilePath::fromUserInput(newValue);
|
||||
if (!path.needsDevice()) {
|
||||
const FilePath onDevicePath = rootPath.withNewMappedPath(path);
|
||||
if (onDevicePath.exists()) {
|
||||
changedValue = onDevicePath.toUserOutput();
|
||||
path = onDevicePath;
|
||||
} else {
|
||||
return make_unexpected(
|
||||
Tr::tr("The path \"%1\" does not exist.").arg(onDevicePath.toUserOutput()));
|
||||
}
|
||||
}
|
||||
QString error;
|
||||
bool result = checkClangdVersion(path, &error);
|
||||
if (!result)
|
||||
return make_unexpected(error);
|
||||
return changedValue;
|
||||
});
|
||||
});
|
||||
|
||||
containerStatus.setText(Tr::tr("stopped"));
|
||||
|
||||
|
||||
auto createBridgeFileAccess = [this]() -> expected_str<std::unique_ptr<DeviceFileAccess>> {
|
||||
expected_str<FilePath> cmdBridgePath = d->getCmdBridgePath();
|
||||
|
||||
@@ -874,7 +852,7 @@ QStringList DockerDevicePrivate::createMountArgs() const
|
||||
|
||||
QStringList cmds;
|
||||
QList<MountPair> mounts;
|
||||
for (const FilePath &m : deviceSettings->mounts())
|
||||
for (const FilePath &m : q->mounts())
|
||||
mounts.append({m, m});
|
||||
|
||||
if (cmdBridgePath && cmdBridgePath->isSameDevice(settings().dockerBinaryPath()))
|
||||
@@ -893,12 +871,12 @@ bool DockerDevicePrivate::isImageAvailable() const
|
||||
Process proc;
|
||||
proc.setCommand(
|
||||
{settings().dockerBinaryPath(),
|
||||
{"image", "list", deviceSettings->repoAndTag(), "--format", "{{.Repository}}:{{.Tag}}"}});
|
||||
{"image", "list", q->repoAndTag(), "--format", "{{.Repository}}:{{.Tag}}"}});
|
||||
proc.runBlocking();
|
||||
if (proc.result() != ProcessResult::FinishedWithSuccess)
|
||||
return false;
|
||||
|
||||
if (proc.stdOut().trimmed() == deviceSettings->repoAndTag())
|
||||
if (proc.stdOut().trimmed() == q->repoAndTag())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -919,26 +897,26 @@ CommandLine DockerDevicePrivate::createCommandLine()
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
// no getuid() and getgid() on Windows.
|
||||
if (deviceSettings->useLocalUidGid())
|
||||
if (q->useLocalUidGid())
|
||||
dockerCreate.addArgs({"-u", QString("%1:%2").arg(getuid()).arg(getgid())});
|
||||
#endif
|
||||
|
||||
if (!deviceSettings->network().isEmpty()) {
|
||||
if (!q->network().isEmpty()) {
|
||||
dockerCreate.addArg("--network");
|
||||
dockerCreate.addArg(deviceSettings->network());
|
||||
dockerCreate.addArg(q->network());
|
||||
}
|
||||
|
||||
dockerCreate.addArgs(createMountArgs());
|
||||
|
||||
if (!deviceSettings->keepEntryPoint())
|
||||
if (!q->keepEntryPoint())
|
||||
dockerCreate.addArgs({"--entrypoint", "/bin/sh"});
|
||||
|
||||
if (deviceSettings->enableLldbFlags())
|
||||
if (q->enableLldbFlags())
|
||||
dockerCreate.addArgs({"--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"});
|
||||
|
||||
dockerCreate.addArgs(deviceSettings->extraArgs(), CommandLine::Raw);
|
||||
dockerCreate.addArgs(q->extraArgs(), CommandLine::Raw);
|
||||
|
||||
dockerCreate.addArg(deviceSettings->repoAndTag());
|
||||
dockerCreate.addArg(q->repoAndTag());
|
||||
|
||||
return dockerCreate;
|
||||
}
|
||||
@@ -946,7 +924,7 @@ CommandLine DockerDevicePrivate::createCommandLine()
|
||||
expected_str<QString> DockerDevicePrivate::createContainer()
|
||||
{
|
||||
if (!isImageAvailable())
|
||||
return make_unexpected(Tr::tr("Image \"%1\" is not available.").arg(repoAndTag()));
|
||||
return make_unexpected(Tr::tr("Image \"%1\" is not available.").arg(q->repoAndTag()));
|
||||
|
||||
const CommandLine cmdLine = createCommandLine();
|
||||
|
||||
@@ -1005,7 +983,7 @@ expected_str<void> DockerDevicePrivate::updateContainerAccess()
|
||||
result = make_unexpected(QString("Failed to start container: %1").arg(result.error()));
|
||||
|
||||
QTimer::singleShot(0, this, [this, containerStatus] {
|
||||
deviceSettings->containerStatus.setText(containerStatus);
|
||||
q->containerStatus.setText(containerStatus);
|
||||
});
|
||||
|
||||
return result;
|
||||
@@ -1019,13 +997,19 @@ void DockerDevice::setMounts(const QStringList &mounts) const
|
||||
void DockerDevice::fromMap(const Store &map)
|
||||
{
|
||||
ProjectExplorer::IDevice::fromMap(map);
|
||||
d->deviceSettings->fromMap(map);
|
||||
|
||||
// This is the only place where we can correctly set the default name.
|
||||
// Only here do we know the image id and the repo reliably, no matter
|
||||
// where or how we were created.
|
||||
if (displayName.value() == displayName.defaultValue()) {
|
||||
displayName.setDefaultValue(
|
||||
Tr::tr("Docker Image \"%1\" (%2)").arg(repoAndTag()).arg(imageId.value()));
|
||||
}
|
||||
}
|
||||
|
||||
void DockerDevice::toMap(Store &map) const
|
||||
{
|
||||
IDevice::toMap(map);
|
||||
d->deviceSettings->toMap(map);
|
||||
}
|
||||
|
||||
ProcessInterface *DockerDevice::createProcessInterface() const
|
||||
@@ -1046,15 +1030,10 @@ bool DockerDevice::usableAsBuildDevice() const
|
||||
FilePath DockerDevice::filePath(const QString &pathOnDevice) const
|
||||
{
|
||||
return FilePath::fromParts(Constants::DOCKER_DEVICE_SCHEME,
|
||||
d->repoAndTagEncoded(),
|
||||
repoAndTagEncoded(),
|
||||
pathOnDevice);
|
||||
}
|
||||
|
||||
FilePath DockerDevice::rootPath() const
|
||||
{
|
||||
return d->deviceSettings->rootPath();
|
||||
}
|
||||
|
||||
bool DockerDevice::handlesFile(const FilePath &filePath) const
|
||||
{
|
||||
if (filePath.scheme() == u"device" && filePath.host() == id().toString())
|
||||
@@ -1062,13 +1041,13 @@ bool DockerDevice::handlesFile(const FilePath &filePath) const
|
||||
|
||||
const bool isDockerScheme = filePath.scheme() == Constants::DOCKER_DEVICE_SCHEME;
|
||||
|
||||
if (isDockerScheme && filePath.host() == d->dockerImageId())
|
||||
if (isDockerScheme && filePath.host() == imageId())
|
||||
return true;
|
||||
|
||||
if (isDockerScheme && filePath.host() == d->repoAndTagEncoded())
|
||||
if (isDockerScheme && filePath.host() == repoAndTagEncoded())
|
||||
return true;
|
||||
|
||||
if (isDockerScheme && filePath.host() == d->repoAndTag())
|
||||
if (isDockerScheme && filePath.host() == repoAndTag())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -1301,12 +1280,10 @@ public:
|
||||
m_proxyModel->mapToSource(selectedRows.front()));
|
||||
QTC_ASSERT(item, return {});
|
||||
|
||||
auto deviceSettings = std::make_unique<DockerDeviceSettings>();
|
||||
deviceSettings->repo.setValue(item->repo);
|
||||
deviceSettings->tag.setValue(item->tag);
|
||||
deviceSettings->imageId.setValue(item->imageId);
|
||||
|
||||
auto device = DockerDevice::create(std::move(deviceSettings));
|
||||
auto device = DockerDevice::create();
|
||||
device->repo.setValue(item->repo);
|
||||
device->tag.setValue(item->tag);
|
||||
device->imageId.setValue(item->imageId);
|
||||
|
||||
return device;
|
||||
}
|
||||
@@ -1336,7 +1313,7 @@ DockerDeviceFactory::DockerDeviceFactory()
|
||||
return wizard.device();
|
||||
});
|
||||
setConstructionFunction([this] {
|
||||
auto device = DockerDevice::create(std::make_unique<DockerDeviceSettings>());
|
||||
auto device = DockerDevice::create();
|
||||
QMutexLocker lk(&m_deviceListMutex);
|
||||
m_existingDevices.push_back(device);
|
||||
return device;
|
||||
@@ -1357,7 +1334,7 @@ expected_str<QPair<Utils::OsType, Utils::OsArch>> DockerDevicePrivate::osTypeAnd
|
||||
Process proc;
|
||||
proc.setCommand(
|
||||
{settings().dockerBinaryPath(),
|
||||
{"image", "inspect", repoAndTag(), "--format", "{{.Os}}\t{{.Architecture}}"}});
|
||||
{"image", "inspect", q->repoAndTag(), "--format", "{{.Os}}\t{{.Architecture}}"}});
|
||||
proc.runBlocking();
|
||||
if (proc.result() != ProcessResult::FinishedWithSuccess)
|
||||
return make_unexpected(Tr::tr("Failed to inspect image: %1").arg(proc.allOutput()));
|
||||
@@ -1398,8 +1375,8 @@ void DockerDevicePrivate::shutdown()
|
||||
void DockerDevicePrivate::changeMounts(QStringList newMounts)
|
||||
{
|
||||
newMounts.removeDuplicates();
|
||||
if (deviceSettings->mounts.value() != newMounts) {
|
||||
deviceSettings->mounts.value() = newMounts;
|
||||
if (q->mounts.value() != newMounts) {
|
||||
q->mounts.value() = newMounts;
|
||||
stopCurrentContainer(); // Force re-start with new mounts.
|
||||
}
|
||||
}
|
||||
@@ -1407,7 +1384,7 @@ void DockerDevicePrivate::changeMounts(QStringList newMounts)
|
||||
expected_str<FilePath> DockerDevicePrivate::localSource(const FilePath &other) const
|
||||
{
|
||||
const auto devicePath = FilePath::fromString(other.path());
|
||||
for (const FilePath &mount : deviceSettings->mounts()) {
|
||||
for (const FilePath &mount : q->mounts()) {
|
||||
const FilePath mountPoint = mount;
|
||||
if (devicePath.isChildOf(mountPoint)) {
|
||||
const FilePath relativePath = devicePath.relativeChildPath(mountPoint);
|
||||
@@ -1423,7 +1400,7 @@ bool DockerDevicePrivate::ensureReachable(const FilePath &other)
|
||||
if (other.isSameDevice(q->rootPath()))
|
||||
return true;
|
||||
|
||||
for (const FilePath &mount : deviceSettings->mounts()) {
|
||||
for (const FilePath &mount : q->mounts()) {
|
||||
if (other.isChildOf(mount))
|
||||
return true;
|
||||
|
||||
|
@@ -12,46 +12,18 @@
|
||||
|
||||
namespace Docker::Internal {
|
||||
|
||||
class DockerDeviceSettings : public ProjectExplorer::DeviceSettings
|
||||
{
|
||||
public:
|
||||
DockerDeviceSettings();
|
||||
|
||||
void fromMap(const Utils::Store &map) override;
|
||||
|
||||
QString repoAndTag() const;
|
||||
QString repoAndTagEncoded() const;
|
||||
Utils::FilePath rootPath() const;
|
||||
|
||||
Utils::StringAspect imageId{this};
|
||||
Utils::StringAspect repo{this};
|
||||
Utils::StringAspect tag{this};
|
||||
Utils::BoolAspect useLocalUidGid{this};
|
||||
Utils::FilePathListAspect mounts{this};
|
||||
Utils::BoolAspect keepEntryPoint{this};
|
||||
Utils::BoolAspect enableLldbFlags{this};
|
||||
Utils::FilePathAspect clangdExecutable{this};
|
||||
Utils::StringSelectionAspect network{this};
|
||||
Utils::StringAspect extraArgs{this};
|
||||
|
||||
Utils::TextDisplay containerStatus{this};
|
||||
};
|
||||
|
||||
class DockerDevice : public ProjectExplorer::IDevice
|
||||
{
|
||||
public:
|
||||
using Ptr = std::shared_ptr<DockerDevice>;
|
||||
using ConstPtr = std::shared_ptr<const DockerDevice>;
|
||||
|
||||
explicit DockerDevice(std::unique_ptr<DockerDeviceSettings> settings);
|
||||
DockerDevice();
|
||||
~DockerDevice();
|
||||
|
||||
void shutdown();
|
||||
|
||||
static Ptr create(std::unique_ptr<DockerDeviceSettings> settings)
|
||||
{
|
||||
return Ptr(new DockerDevice(std::move(settings)));
|
||||
}
|
||||
static Ptr create() { return Ptr(new DockerDevice); }
|
||||
|
||||
Utils::CommandLine createCommandLine() const;
|
||||
|
||||
@@ -85,6 +57,22 @@ public:
|
||||
bool prepareForBuild(const ProjectExplorer::Target *target) override;
|
||||
std::optional<Utils::FilePath> clangdExecutable() const override;
|
||||
|
||||
QString repoAndTag() const;
|
||||
QString repoAndTagEncoded() const;
|
||||
|
||||
Utils::StringAspect imageId{this};
|
||||
Utils::StringAspect repo{this};
|
||||
Utils::StringAspect tag{this};
|
||||
Utils::BoolAspect useLocalUidGid{this};
|
||||
Utils::FilePathListAspect mounts{this};
|
||||
Utils::BoolAspect keepEntryPoint{this};
|
||||
Utils::BoolAspect enableLldbFlags{this};
|
||||
Utils::FilePathAspect clangdExecutableAspect{this};
|
||||
Utils::StringSelectionAspect network{this};
|
||||
Utils::StringAspect extraArgs{this};
|
||||
|
||||
Utils::TextDisplay containerStatus{this};
|
||||
|
||||
protected:
|
||||
void fromMap(const Utils::Store &map) final;
|
||||
void toMap(Utils::Store &map) const final;
|
||||
|
@@ -34,8 +34,6 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
|
||||
auto dockerDevice = std::dynamic_pointer_cast<DockerDevice>(device);
|
||||
QTC_ASSERT(dockerDevice, return);
|
||||
|
||||
DockerDeviceSettings *deviceSettings = static_cast<DockerDeviceSettings *>(device->settings());
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
auto daemonStateLabel = new QLabel(Tr::tr("Daemon state:"));
|
||||
@@ -58,13 +56,13 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
|
||||
auto pathListLabel = new InfoLabel(Tr::tr("Paths to mount:"));
|
||||
pathListLabel->setAdditionalToolTip(Tr::tr("Source directory list should not be empty."));
|
||||
|
||||
auto markupMounts = [deviceSettings, pathListLabel] {
|
||||
const bool isEmpty = deviceSettings->mounts.volatileValue().isEmpty();
|
||||
auto markupMounts = [dockerDevice, pathListLabel] {
|
||||
const bool isEmpty = dockerDevice->mounts.volatileValue().isEmpty();
|
||||
pathListLabel->setType(isEmpty ? InfoLabel::Warning : InfoLabel::None);
|
||||
};
|
||||
markupMounts();
|
||||
|
||||
connect(&deviceSettings->mounts, &FilePathListAspect::volatileValueChanged, this, markupMounts);
|
||||
connect(&dockerDevice->mounts, &FilePathListAspect::volatileValueChanged, this, markupMounts);
|
||||
|
||||
auto logView = new QTextBrowser;
|
||||
connect(&m_kitItemDetector, &KitDetector::logOutput,
|
||||
@@ -104,7 +102,7 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
|
||||
connect(autoDetectButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
[this, logView, dockerDevice, searchPaths, deviceSettings] {
|
||||
[this, logView, dockerDevice, searchPaths] {
|
||||
logView->clear();
|
||||
expected_str<void> startResult = dockerDevice->updateContainerAccess();
|
||||
|
||||
@@ -121,7 +119,7 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
|
||||
});
|
||||
|
||||
if (!clangdPath.isEmpty())
|
||||
deviceSettings->clangdExecutable.setValue(clangdPath);
|
||||
dockerDevice->clangdExecutableAspect.setValue(clangdPath);
|
||||
|
||||
m_kitItemDetector.autoDetect(dockerDevice->id().toString(), searchPaths());
|
||||
|
||||
@@ -169,20 +167,20 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
|
||||
Column {
|
||||
noMargin,
|
||||
Form {
|
||||
deviceSettings->repo, br,
|
||||
deviceSettings->tag, br,
|
||||
deviceSettings->imageId, br,
|
||||
dockerDevice->repo, br,
|
||||
dockerDevice->tag, br,
|
||||
dockerDevice->imageId, br,
|
||||
daemonStateLabel, m_daemonReset, m_daemonState, br,
|
||||
Tr::tr("Container state:"), deviceSettings->containerStatus, br,
|
||||
deviceSettings->useLocalUidGid, br,
|
||||
deviceSettings->keepEntryPoint, br,
|
||||
deviceSettings->enableLldbFlags, br,
|
||||
deviceSettings->clangdExecutable, br,
|
||||
deviceSettings->network, br,
|
||||
deviceSettings->extraArgs, br,
|
||||
Tr::tr("Container state:"), dockerDevice->containerStatus, br,
|
||||
dockerDevice->useLocalUidGid, br,
|
||||
dockerDevice->keepEntryPoint, br,
|
||||
dockerDevice->enableLldbFlags, br,
|
||||
dockerDevice->clangdExecutableAspect, br,
|
||||
dockerDevice->network, br,
|
||||
dockerDevice->extraArgs, br,
|
||||
Column {
|
||||
pathListLabel,
|
||||
deviceSettings->mounts,
|
||||
dockerDevice->mounts,
|
||||
}, br,
|
||||
If { dockerDevice->isAutoDetected(), {}, {detectionControls} },
|
||||
noMargin,
|
||||
@@ -199,7 +197,7 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
|
||||
};
|
||||
QObject::connect(searchDirsComboBox, &QComboBox::activated, this, updateDirectoriesLineEdit);
|
||||
|
||||
connect(deviceSettings, &AspectContainer::applied, this, [createLineLabel, dockerDevice] {
|
||||
connect(&*dockerDevice, &AspectContainer::applied, this, [createLineLabel, dockerDevice] {
|
||||
createLineLabel->setText(dockerDevice->createCommandLine().toUserOutput());
|
||||
});
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ IosDevice::IosDevice(CtorHelper)
|
||||
: m_lastPort(Constants::IOS_DEVICE_PORT_START)
|
||||
{
|
||||
setType(Constants::IOS_DEVICE_TYPE);
|
||||
settings()->displayName.setDefaultValue(IosDevice::name());
|
||||
displayName.setDefaultValue(IosDevice::name());
|
||||
setDisplayType(Tr::tr("iOS"));
|
||||
setMachineType(IDevice::Hardware);
|
||||
setOsType(Utils::OsTypeMac);
|
||||
@@ -248,7 +248,7 @@ void IosDeviceManager::deviceConnected(const QString &uid, const QString &name)
|
||||
if (!dev) {
|
||||
auto newDev = new IosDevice(uid);
|
||||
if (!name.isNull())
|
||||
newDev->settings()->displayName.setValue(name);
|
||||
newDev->displayName.setValue(name);
|
||||
qCDebug(detectLog) << "adding ios device " << uid;
|
||||
devManager->addDevice(IDevice::ConstPtr(newDev));
|
||||
} else if (dev->deviceState() != IDevice::DeviceConnected &&
|
||||
@@ -364,7 +364,7 @@ void IosDeviceManager::deviceInfo(const QString &uid,
|
||||
}
|
||||
if (!skipUpdate) {
|
||||
if (info.contains(kDeviceName))
|
||||
newDev->settings()->displayName.setValue(info.value(kDeviceName));
|
||||
newDev->displayName.setValue(info.value(kDeviceName));
|
||||
newDev->m_extraInfo = info;
|
||||
newDev->m_handler = handler;
|
||||
qCDebug(detectLog) << "updated info of ios device " << uid;
|
||||
|
@@ -28,7 +28,7 @@ IosSimulator::IosSimulator(Id id)
|
||||
setType(Constants::IOS_SIMULATOR_TYPE);
|
||||
setMachineType(IDevice::Emulator);
|
||||
setOsType(Utils::OsTypeMac);
|
||||
settings()->displayName.setDefaultValue(Tr::tr("iOS Simulator"));
|
||||
displayName.setDefaultValue(Tr::tr("iOS Simulator"));
|
||||
setDisplayType(Tr::tr("iOS Simulator"));
|
||||
setDeviceState(DeviceStateUnknown);
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ McuSupportDevice::McuSupportDevice()
|
||||
setupId(IDevice::AutoDetected, Constants::DEVICE_ID);
|
||||
setType(Constants::DEVICE_TYPE);
|
||||
const QString displayNameAndType = Tr::tr("MCU Device");
|
||||
settings()->displayName.setDefaultValue(displayNameAndType);
|
||||
displayName.setDefaultValue(displayNameAndType);
|
||||
setDisplayType(displayNameAndType);
|
||||
setDeviceState(IDevice::DeviceStateUnknown);
|
||||
setMachineType(IDevice::Hardware);
|
||||
|
@@ -42,7 +42,7 @@ DesktopDevice::DesktopDevice()
|
||||
|
||||
setupId(IDevice::AutoDetected, DESKTOP_DEVICE_ID);
|
||||
setType(DESKTOP_DEVICE_TYPE);
|
||||
settings()->displayName.setDefaultValue(Tr::tr("Local PC"));
|
||||
displayName.setDefaultValue(Tr::tr("Local PC"));
|
||||
setDisplayType(Tr::tr("Desktop"));
|
||||
|
||||
setDeviceState(IDevice::DeviceStateUnknown);
|
||||
|
@@ -261,8 +261,7 @@ void DeviceManager::addDevice(const IDevice::ConstPtr &_device)
|
||||
}
|
||||
|
||||
// TODO: make it thread safe?
|
||||
device->settings()->displayName.setValue(
|
||||
Utils::makeUniquelyNumbered(device->displayName(), names));
|
||||
device->displayName.setValue(Utils::makeUniquelyNumbered(device->displayName(), names));
|
||||
|
||||
const int pos = d->indexForId(device->id());
|
||||
|
||||
@@ -568,7 +567,7 @@ void ProjectExplorerTest::testDeviceManager()
|
||||
TestDeviceFactory factory;
|
||||
|
||||
TestDevice::Ptr dev = IDevice::Ptr(new TestDevice);
|
||||
dev->settings()->displayName.setValue(QLatin1String("blubbdiblubbfurz!"));
|
||||
dev->displayName.setValue(QLatin1String("blubbdiblubbfurz!"));
|
||||
QVERIFY(dev->isAutoDetected());
|
||||
QCOMPARE(dev->deviceState(), IDevice::DeviceStateUnknown);
|
||||
QCOMPARE(dev->type(), TestDevice::testTypeId());
|
||||
@@ -629,7 +628,7 @@ void ProjectExplorerTest::testDeviceManager()
|
||||
TestDevice::Ptr dev3 = IDevice::Ptr(new TestDevice);
|
||||
QVERIFY(dev->id() != dev3->id());
|
||||
|
||||
dev3->settings()->displayName.setValue(dev->displayName());
|
||||
dev3->displayName.setValue(dev->displayName());
|
||||
mgr->addDevice(dev3);
|
||||
QCOMPARE(mgr->deviceAt(mgr->deviceCount() - 1)->displayName(),
|
||||
QString(dev3->displayName() + QLatin1Char('2')));
|
||||
|
@@ -274,7 +274,7 @@ void DeviceSettingsWidget::setDeviceInfoWidgetsEnabled(bool enable)
|
||||
|
||||
void DeviceSettingsWidget::updateDeviceFromUi()
|
||||
{
|
||||
currentDevice()->settings()->apply();
|
||||
currentDevice()->doApply();
|
||||
if (m_configWidget)
|
||||
m_configWidget->updateDeviceFromUi();
|
||||
}
|
||||
@@ -340,7 +340,7 @@ void DeviceSettingsWidget::currentDeviceChanged(int index)
|
||||
}
|
||||
|
||||
Layouting::Column item{Layouting::noMargin};
|
||||
device->settings()->displayName.addToLayout(item);
|
||||
device->displayName.addToLayout(item);
|
||||
QWidget *newEdit = item.emerge();
|
||||
QLayoutItem *oldItem = m_generalFormLayout->replaceWidget(m_deviceNameEditWidget, newEdit);
|
||||
QTC_CHECK(oldItem);
|
||||
|
@@ -120,16 +120,10 @@ const IDevice::MachineType DefaultMachineType = IDevice::Hardware;
|
||||
const int DefaultTimeout = 10;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class IDevicePrivate
|
||||
{
|
||||
public:
|
||||
IDevicePrivate(std::unique_ptr<DeviceSettings> s)
|
||||
: settings(std::move(s))
|
||||
{
|
||||
if (!settings)
|
||||
settings = std::make_unique<DeviceSettings>();
|
||||
}
|
||||
|
||||
QString displayType;
|
||||
Id type;
|
||||
IDevice::Origin origin = IDevice::AutoDetected;
|
||||
@@ -153,12 +147,14 @@ public:
|
||||
QList<IDevice::DeviceAction> deviceActions;
|
||||
Store extraData;
|
||||
IDevice::OpenTerminal openTerminal;
|
||||
|
||||
std::unique_ptr<DeviceSettings> settings;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
DeviceSettings::DeviceSettings()
|
||||
DeviceTester::DeviceTester(QObject *parent) : QObject(parent) { }
|
||||
|
||||
IDevice::IDevice()
|
||||
: d(new Internal::IDevicePrivate)
|
||||
{
|
||||
setAutoApply(false);
|
||||
|
||||
@@ -201,13 +197,6 @@ DeviceSettings::DeviceSettings()
|
||||
});
|
||||
}
|
||||
|
||||
DeviceTester::DeviceTester(QObject *parent) : QObject(parent) { }
|
||||
|
||||
IDevice::IDevice(std::unique_ptr<DeviceSettings> settings)
|
||||
: d(new Internal::IDevicePrivate(std::move(settings)))
|
||||
{
|
||||
}
|
||||
|
||||
IDevice::~IDevice() = default;
|
||||
|
||||
void IDevice::setOpenTerminal(const IDevice::OpenTerminal &openTerminal)
|
||||
@@ -319,11 +308,6 @@ expected_str<Environment> IDevice::systemEnvironmentWithError() const
|
||||
return access->deviceEnvironment();
|
||||
}
|
||||
|
||||
QString IDevice::displayName() const
|
||||
{
|
||||
return d->settings->displayName();
|
||||
}
|
||||
|
||||
QString IDevice::displayType() const
|
||||
{
|
||||
return d->displayType;
|
||||
@@ -495,8 +479,8 @@ Id IDevice::idFromMap(const Store &map)
|
||||
|
||||
void IDevice::fromMap(const Store &map)
|
||||
{
|
||||
AspectContainer::fromMap(map);
|
||||
d->type = typeFromMap(map);
|
||||
settings()->fromMap(map);
|
||||
|
||||
d->id = Id::fromSetting(map.value(IdKey));
|
||||
d->osType = osTypeFromString(map.value(ClientOsTypeKey).toString()).value_or(OsTypeLinux);
|
||||
@@ -543,7 +527,7 @@ void IDevice::fromMap(const Store &map)
|
||||
|
||||
void IDevice::toMap(Store &map) const
|
||||
{
|
||||
d->settings->toMap(map);
|
||||
AspectContainer::toMap(map);
|
||||
|
||||
map.insert(TypeKey, d->type.toString());
|
||||
map.insert(ClientOsTypeKey, osTypeToString(d->osType));
|
||||
@@ -587,11 +571,6 @@ IDevice::Ptr IDevice::clone() const
|
||||
return device;
|
||||
}
|
||||
|
||||
DeviceSettings *IDevice::settings() const
|
||||
{
|
||||
return d->settings.get();
|
||||
}
|
||||
|
||||
QString IDevice::deviceStateToString() const
|
||||
{
|
||||
switch (d->deviceState) {
|
||||
@@ -725,6 +704,11 @@ std::optional<Utils::FilePath> IDevice::clangdExecutable() const
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void IDevice::doApply() const
|
||||
{
|
||||
const_cast<IDevice *>(this)->apply();
|
||||
}
|
||||
|
||||
void DeviceProcessSignalOperation::setDebuggerCommand(const FilePath &cmd)
|
||||
{
|
||||
m_debuggerCommand = cmd;
|
||||
|
@@ -83,16 +83,9 @@ public:
|
||||
std::function<QList<Utils::Port>(const QByteArray &commandOutput)> parsePorts;
|
||||
};
|
||||
|
||||
class PROJECTEXPLORER_EXPORT DeviceSettings : public Utils::AspectContainer
|
||||
{
|
||||
public:
|
||||
DeviceSettings();
|
||||
|
||||
Utils::StringAspect displayName{this};
|
||||
};
|
||||
|
||||
// See cpp file for documentation.
|
||||
class PROJECTEXPLORER_EXPORT IDevice : public std::enable_shared_from_this<IDevice>
|
||||
class PROJECTEXPLORER_EXPORT IDevice
|
||||
: public Utils::AspectContainer, public std::enable_shared_from_this<IDevice>
|
||||
{
|
||||
friend class Internal::IDevicePrivate;
|
||||
public:
|
||||
@@ -107,9 +100,7 @@ public:
|
||||
|
||||
virtual Ptr clone() const;
|
||||
|
||||
DeviceSettings *settings() const;
|
||||
|
||||
QString displayName() const;
|
||||
Utils::StringAspect displayName{this};
|
||||
|
||||
// Provide some information on the device suitable for formated
|
||||
// output, e.g. in tool tips. Get a list of name value pairs.
|
||||
@@ -229,8 +220,10 @@ public:
|
||||
|
||||
virtual void checkOsType() {}
|
||||
|
||||
void doApply() const;
|
||||
|
||||
protected:
|
||||
IDevice(std::unique_ptr<DeviceSettings> settings = nullptr);
|
||||
IDevice();
|
||||
|
||||
virtual void fromMap(const Utils::Store &map);
|
||||
virtual void toMap(Utils::Store &map) const;
|
||||
|
@@ -79,7 +79,7 @@ IDevice::Ptr IDeviceFactory::construct() const
|
||||
|
||||
IDevice::Ptr device = m_constructor();
|
||||
QTC_ASSERT(device, return {});
|
||||
device->settings()->displayName.setDefaultValue(displayName());
|
||||
device->displayName.setDefaultValue(displayName());
|
||||
return device;
|
||||
}
|
||||
|
||||
|
@@ -1313,7 +1313,7 @@ void BuildDeviceKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *ex
|
||||
});
|
||||
expander->registerVariable("BuildDevice:Name", Tr::tr("Build device name"), [kit] {
|
||||
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
|
||||
return device ? device->settings()->displayName() : QString();
|
||||
return device ? device->displayName() : QString();
|
||||
});
|
||||
expander
|
||||
->registerFileVariables("BuildDevice::Root", Tr::tr("Build device root directory"), [kit] {
|
||||
|
@@ -64,7 +64,7 @@ public:
|
||||
QnxDevice()
|
||||
{
|
||||
setDisplayType(Tr::tr("QNX"));
|
||||
settings()->displayName.setDefaultValue(Tr::tr("QNX Device"));
|
||||
displayName.setDefaultValue(Tr::tr("QNX Device"));
|
||||
setOsType(OsTypeOtherUnix);
|
||||
setupId(IDevice::ManuallyAdded);
|
||||
setType(Constants::QNX_QNX_OS_TYPE);
|
||||
|
@@ -307,12 +307,6 @@ public:
|
||||
LinuxDevicePrivate *m_dev;
|
||||
};
|
||||
|
||||
class LinuxDeviceSettings : public DeviceSettings
|
||||
{
|
||||
public:
|
||||
LinuxDeviceSettings() { displayName.setDefaultValue(Tr::tr("Remote Linux Device")); }
|
||||
};
|
||||
|
||||
class LinuxDevicePrivate
|
||||
{
|
||||
public:
|
||||
@@ -1019,12 +1013,12 @@ private:
|
||||
// LinuxDevice
|
||||
|
||||
LinuxDevice::LinuxDevice()
|
||||
: IDevice(std::make_unique<LinuxDeviceSettings>())
|
||||
, d(new LinuxDevicePrivate(this))
|
||||
: d(new LinuxDevicePrivate(this))
|
||||
{
|
||||
setFileAccess(&d->m_fileAccess);
|
||||
setDisplayType(Tr::tr("Remote Linux"));
|
||||
setOsType(OsTypeLinux);
|
||||
displayName.setDefaultValue(Tr::tr("Remote Linux Device"));
|
||||
|
||||
setupId(IDevice::ManuallyAdded, Utils::Id());
|
||||
setType(Constants::GenericLinuxOsType);
|
||||
|
@@ -77,7 +77,7 @@ private:
|
||||
&& !m_userNameLineEdit->text().trimmed().isEmpty();
|
||||
}
|
||||
bool validatePage() final {
|
||||
m_device->settings()->displayName.setValue(m_nameLineEdit->text().trimmed());
|
||||
m_device->displayName.setValue(m_nameLineEdit->text().trimmed());
|
||||
SshParameters sshParams = m_device->sshParameters();
|
||||
sshParams.setHost(m_hostNameLineEdit->text().trimmed());
|
||||
sshParams.setUserName(m_userNameLineEdit->text().trimmed());
|
||||
|
@@ -35,7 +35,7 @@ public:
|
||||
setupId(IDevice::AutoDetected, Constants::WEBASSEMBLY_DEVICE_DEVICE_ID);
|
||||
setType(Constants::WEBASSEMBLY_DEVICE_TYPE);
|
||||
const QString displayNameAndType = Tr::tr("Web Browser");
|
||||
settings()->displayName.setDefaultValue(displayNameAndType);
|
||||
displayName.setDefaultValue(displayNameAndType);
|
||||
setDisplayType(displayNameAndType);
|
||||
setDeviceState(IDevice::DeviceStateUnknown);
|
||||
setMachineType(IDevice::Hardware);
|
||||
|
Reference in New Issue
Block a user