Docker: Switch to aspect settings

Change-Id: Id04c48caf2ddd33e176ee424273690b80c77232b
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Marcus Tillmanns
2023-09-07 15:25:07 +02:00
parent ed0935733e
commit f6205d6cc7
4 changed files with 184 additions and 259 deletions

View File

@@ -32,7 +32,9 @@
#include <qtsupport/qtversionmanager.h>
#include <utils/algorithm.h>
#include <utils/async.h>
#include <utils/basetreeview.h>
#include <utils/clangutils.h>
#include <utils/devicefileaccess.h>
#include <utils/deviceshell.h>
#include <utils/environment.h>
@@ -87,6 +89,15 @@ Q_LOGGING_CATEGORY(dockerDeviceLog, "qtc.docker.device", QtWarningMsg);
namespace Docker::Internal {
const char DockerDeviceDataImageIdKey[] = "DockerDeviceDataImageId";
const char DockerDeviceDataRepoKey[] = "DockerDeviceDataRepo";
const char DockerDeviceDataTagKey[] = "DockerDeviceDataTag";
const char DockerDeviceUseOutsideUser[] = "DockerDeviceUseUidGid";
const char DockerDeviceMappedPaths[] = "DockerDeviceMappedPaths";
const char DockerDeviceKeepEntryPoint[] = "DockerDeviceKeepEntryPoint";
const char DockerDeviceEnableLldbFlags[] = "DockerDeviceEnableLldbFlags";
const char DockerDeviceClangDExecutable[] = "DockerDeviceClangDExecutable";
class ContainerShell : public Utils::DeviceShell
{
public:
@@ -128,19 +139,87 @@ public:
DockerDevicePrivate *m_dev = nullptr;
};
class DockerDeviceSettings : public DeviceSettings
DockerDeviceSettings::DockerDeviceSettings()
{
public:
DockerDeviceSettings() { displayName.setDefaultValue(Tr::tr("Docker Image")); }
};
displayName.setDefaultValue(Tr::tr("Docker Image"));
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()});
clangdExecutable.setSettingsKey(DockerDeviceClangDExecutable);
clangdExecutable.setLabelText(Tr::tr("Clangd Executable:"));
clangdExecutable.setAllowPathFromDevice(true);
clangdExecutable.setValidationFunction(
[](const QString &newValue) -> FancyLineEdit::AsyncValidationFuture {
return Utils::asyncRun([newValue]() -> expected_str<QString> {
QString error;
bool result = Utils::checkClangdVersion(FilePath::fromUserInput(newValue), &error);
if (!result)
return make_unexpected(error);
return newValue;
});
});
}
// Used for "docker run"
QString DockerDeviceSettings::repoAndTag() const
{
if (repo() == "<none>")
return imageId();
if (tag() == "<none>")
return repo();
return repo() + ':' + tag();
}
QString DockerDeviceSettings::repoAndTagEncoded() const
{
return repoAndTag().replace(':', '.');
}
class DockerDevicePrivate : public QObject
{
public:
DockerDevicePrivate(DockerDevice *parent, DockerDeviceData data)
DockerDevicePrivate(DockerDevice *parent)
: q(parent)
, m_data(std::move(data))
{}
, deviceSettings(static_cast<DockerDeviceSettings *>(q->settings()))
{
QObject::connect(deviceSettings, &DockerDeviceSettings::applied, this, [this] {
if (!m_container.isEmpty()) {
stopCurrentContainer();
}
});
}
~DockerDevicePrivate() { stopCurrentContainer(); }
@@ -153,12 +232,10 @@ public:
expected_str<FilePath> localSource(const FilePath &other) const;
QString containerId() { return m_container; }
DockerDeviceData data() { return m_data; }
void setData(const DockerDeviceData &data);
QString repoAndTag() const { return m_data.repoAndTag(); }
QString repoAndTagEncoded() const { return m_data.repoAndTagEncoded(); }
QString dockerImageId() const { return m_data.imageId; }
QString repoAndTag() const { return deviceSettings->repoAndTag(); }
QString repoAndTagEncoded() const { return deviceSettings->repoAndTagEncoded(); }
QString dockerImageId() const { return deviceSettings->imageId(); }
Environment environment();
@@ -179,9 +256,9 @@ public:
std::optional<FilePath> clangdExecutable() const
{
if (m_data.clangdExecutable.isEmpty())
if (deviceSettings->clangdExecutable().isEmpty())
return std::nullopt;
return m_data.clangdExecutable;
return deviceSettings->clangdExecutable();
}
bool addTemporaryMount(const FilePath &path, const FilePath &containerPath);
@@ -191,7 +268,7 @@ public:
bool isImageAvailable() const;
DockerDevice *const q;
DockerDeviceData m_data;
DockerDeviceSettings *deviceSettings;
struct TemporaryMountInfo
{
@@ -383,7 +460,7 @@ Tasks DockerDevicePrivate::validateMounts() const
{
Tasks result;
for (const QString &mount : m_data.mounts) {
for (const QString &mount : deviceSettings->mounts()) {
const FilePath path = FilePath::fromUserInput(mount);
if (!path.isDir()) {
const QString message = Tr::tr("Path \"%1\" is not a directory or does not exist.")
@@ -415,9 +492,9 @@ QString DockerDeviceFileAccess::mapToDevicePath(const QString &hostPath) const
return newPath;
}
DockerDevice::DockerDevice(const DockerDeviceData &data)
: ProjectExplorer::IDevice(std::make_unique<DockerDeviceSettings>())
, d(new DockerDevicePrivate(this, data))
DockerDevice::DockerDevice(std::unique_ptr<DockerDeviceSettings> deviceSettings)
: ProjectExplorer::IDevice(std::move(deviceSettings))
, d(new DockerDevicePrivate(this))
{
setFileAccess(&d->m_fileAccess);
setDisplayType(Tr::tr("Docker"));
@@ -425,8 +502,9 @@ DockerDevice::DockerDevice(const DockerDeviceData &data)
setupId(IDevice::ManuallyAdded);
setType(Constants::DOCKER_DEVICE_TYPE);
setMachineType(IDevice::Hardware);
settings()->displayName.setDefaultValue(
Tr::tr("Docker Image \"%1\" (%2)").arg(data.repoAndTag()).arg(data.imageId));
d->deviceSettings->displayName.setDefaultValue(Tr::tr("Docker Image \"%1\" (%2)")
.arg(d->deviceSettings->repoAndTag())
.arg(d->deviceSettings->imageId()));
setAllowEmptyCommand(true);
setOpenTerminal([this](const Environment &env, const FilePath &workingDir) {
@@ -467,21 +545,6 @@ void DockerDevice::shutdown()
d->shutdown();
}
const DockerDeviceData DockerDevice::data() const
{
return d->data();
}
DockerDeviceData DockerDevice::data()
{
return d->data();
}
void DockerDevice::setData(const DockerDeviceData &data)
{
d->setData(data);
}
bool DockerDevice::updateContainerAccess() const
{
return d->updateContainerAccess();
@@ -642,7 +705,7 @@ QStringList DockerDevicePrivate::createMountArgs() const
{
QStringList cmds;
QList<TemporaryMountInfo> mounts = m_temporaryMounts;
for (const QString &m : m_data.mounts)
for (const QString &m : deviceSettings->mounts())
mounts.append({FilePath::fromUserInput(m), FilePath::fromUserInput(m)});
for (const TemporaryMountInfo &mi : mounts) {
@@ -658,12 +721,12 @@ bool DockerDevicePrivate::isImageAvailable() const
Process proc;
proc.setCommand(
{settings().dockerBinaryPath(),
{"image", "list", m_data.repoAndTag(), "--format", "{{.Repository}}:{{.Tag}}"}});
{"image", "list", deviceSettings->repoAndTag(), "--format", "{{.Repository}}:{{.Tag}}"}});
proc.runBlocking();
if (proc.result() != ProcessResult::FinishedWithSuccess)
return false;
if (proc.stdOut().trimmed() == m_data.repoAndTag())
if (proc.stdOut().trimmed() == deviceSettings->repoAndTag())
return true;
return false;
@@ -689,19 +752,19 @@ bool DockerDevicePrivate::createContainer()
#ifdef Q_OS_UNIX
// no getuid() and getgid() on Windows.
if (m_data.useLocalUidGid)
if (deviceSettings->useLocalUidGid())
dockerCreate.addArgs({"-u", QString("%1:%2").arg(getuid()).arg(getgid())});
#endif
dockerCreate.addArgs(createMountArgs());
if (!m_data.keepEntryPoint)
if (!deviceSettings->keepEntryPoint())
dockerCreate.addArgs({"--entrypoint", "/bin/sh"});
if (m_data.enableLldbFlags)
if (deviceSettings->enableLldbFlags())
dockerCreate.addArgs({"--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"});
dockerCreate.addArg(m_data.repoAndTag());
dockerCreate.addArg(deviceSettings->repoAndTag());
qCDebug(dockerDeviceLog).noquote() << "RUNNING: " << dockerCreate.toUserOutput();
Process createProcess;
@@ -775,47 +838,16 @@ void DockerDevice::setMounts(const QStringList &mounts) const
d->changeMounts(mounts);
}
const char DockerDeviceDataImageIdKey[] = "DockerDeviceDataImageId";
const char DockerDeviceDataRepoKey[] = "DockerDeviceDataRepo";
const char DockerDeviceDataTagKey[] = "DockerDeviceDataTag";
const char DockerDeviceDataSizeKey[] = "DockerDeviceDataSize";
const char DockerDeviceUseOutsideUser[] = "DockerDeviceUseUidGid";
const char DockerDeviceMappedPaths[] = "DockerDeviceMappedPaths";
const char DockerDeviceKeepEntryPoint[] = "DockerDeviceKeepEntryPoint";
const char DockerDeviceEnableLldbFlags[] = "DockerDeviceEnableLldbFlags";
const char DockerDeviceClangDExecutable[] = "DockerDeviceClangDExecutable";
void DockerDevice::fromMap(const Store &map)
{
ProjectExplorer::IDevice::fromMap(map);
DockerDeviceData data;
data.repo = map.value(DockerDeviceDataRepoKey).toString();
data.tag = map.value(DockerDeviceDataTagKey).toString();
data.imageId = map.value(DockerDeviceDataImageIdKey).toString();
data.size = map.value(DockerDeviceDataSizeKey).toString();
data.useLocalUidGid = map.value(DockerDeviceUseOutsideUser, HostOsInfo::isLinuxHost()).toBool();
data.mounts = map.value(DockerDeviceMappedPaths).toStringList();
data.keepEntryPoint = map.value(DockerDeviceKeepEntryPoint).toBool();
data.enableLldbFlags = map.value(DockerDeviceEnableLldbFlags).toBool();
data.clangdExecutable = FilePath::fromSettings(map.value(DockerDeviceClangDExecutable));
d->setData(data);
d->deviceSettings->fromMap(map);
}
Store DockerDevice::toMap() const
{
Store map = ProjectExplorer::IDevice::toMap();
DockerDeviceData data = d->data();
map.insert(DockerDeviceDataRepoKey, data.repo);
map.insert(DockerDeviceDataTagKey, data.tag);
map.insert(DockerDeviceDataImageIdKey, data.imageId);
map.insert(DockerDeviceDataSizeKey, data.size);
map.insert(DockerDeviceUseOutsideUser, data.useLocalUidGid);
map.insert(DockerDeviceMappedPaths, data.mounts);
map.insert(DockerDeviceKeepEntryPoint, data.keepEntryPoint);
map.insert(DockerDeviceEnableLldbFlags, data.enableLldbFlags);
map.insert(DockerDeviceClangDExecutable, data.clangdExecutable.toSettings());
d->deviceSettings->toMap(map);
return map;
}
@@ -839,14 +871,6 @@ FilePath DockerDevice::filePath(const QString &pathOnDevice) const
return FilePath::fromParts(Constants::DOCKER_DEVICE_SCHEME,
d->repoAndTagEncoded(),
pathOnDevice);
// The following would work, but gives no hint on repo and tag
// result.setScheme("docker");
// result.setHost(d->m_data.imageId);
// The following would work, but gives no hint on repo, tag and imageid
// result.setScheme("device");
// result.setHost(id().toString());
}
Utils::FilePath DockerDevice::rootPath() const
@@ -940,7 +964,7 @@ RunResult DockerDevicePrivate::runInShell(const CommandLine &cmd, const QByteArr
// Factory
class DockerImageItem final : public TreeItem, public DockerDeviceData
class DockerImageItem final : public TreeItem
{
public:
DockerImageItem() {}
@@ -968,6 +992,11 @@ public:
return QVariant();
}
QString repo;
QString tag;
QString imageId;
QString size;
};
class DockerDeviceSetupWizard final : public QDialog
@@ -1099,7 +1128,12 @@ public:
m_proxyModel->mapToSource(selectedRows.front()));
QTC_ASSERT(item, return {});
auto device = DockerDevice::create(*item);
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));
return device;
}
@@ -1129,7 +1163,7 @@ DockerDeviceFactory::DockerDeviceFactory()
return wizard.device();
});
setConstructionFunction([this] {
auto device = DockerDevice::create({});
auto device = DockerDevice::create(std::make_unique<DockerDeviceSettings>());
QMutexLocker lk(&m_deviceListMutex);
m_existingDevices.push_back(device);
return device;
@@ -1155,7 +1189,7 @@ bool DockerDevicePrivate::addTemporaryMount(const FilePath &path, const FilePath
if (alreadyAdded)
return false;
const bool alreadyManuallyAdded = anyOf(m_data.mounts, [path](const QString &mount) {
const bool alreadyManuallyAdded = anyOf(deviceSettings->mounts(), [path](const QString &mount) {
return mount == path.path();
});
@@ -1191,8 +1225,8 @@ void DockerDevicePrivate::shutdown()
void DockerDevicePrivate::changeMounts(QStringList newMounts)
{
newMounts.removeDuplicates();
if (m_data.mounts != newMounts) {
m_data.mounts = newMounts;
if (deviceSettings->mounts() != newMounts) {
deviceSettings->mounts() = newMounts;
stopCurrentContainer(); // Force re-start with new mounts.
}
}
@@ -1207,7 +1241,7 @@ expected_str<FilePath> DockerDevicePrivate::localSource(const FilePath &other) c
}
}
for (const QString &mount : m_data.mounts) {
for (const QString &mount : deviceSettings->mounts()) {
const FilePath mountPoint = FilePath::fromString(mount);
if (devicePath.isChildOf(mountPoint)) {
const FilePath relativePath = devicePath.relativeChildPath(mountPoint);
@@ -1223,7 +1257,7 @@ bool DockerDevicePrivate::ensureReachable(const FilePath &other)
if (other.isSameDevice(q->rootPath()))
return true;
for (const QString &mount : m_data.mounts) {
for (const QString &mount : deviceSettings->mounts()) {
const FilePath fMount = FilePath::fromString(mount);
if (other.isChildOf(fMount))
return true;
@@ -1250,18 +1284,6 @@ bool DockerDevicePrivate::ensureReachable(const FilePath &other)
return true;
}
void DockerDevicePrivate::setData(const DockerDeviceData &data)
{
if (m_data != data) {
m_data = data;
// Force restart if the container is already running
if (!m_container.isEmpty()) {
stopCurrentContainer();
}
}
}
bool DockerDevice::prepareForBuild(const Target *target)
{
return d->prepareForBuild(target);

View File

@@ -14,42 +14,22 @@
namespace Docker::Internal {
class DockerDeviceData
class DockerDeviceSettings : public ProjectExplorer::DeviceSettings
{
public:
bool operator==(const DockerDeviceData &other) const
{
return imageId == other.imageId && repo == other.repo && tag == other.tag
&& useLocalUidGid == other.useLocalUidGid && mounts == other.mounts
&& keepEntryPoint == other.keepEntryPoint && enableLldbFlags == other.enableLldbFlags
&& clangdExecutable == other.clangdExecutable;
}
DockerDeviceSettings();
bool operator!=(const DockerDeviceData &other) const { return !(*this == other); }
QString repoAndTag() const;
QString repoAndTagEncoded() const;
// Used for "docker run"
QString repoAndTag() const
{
if (repo == "<none>")
return imageId;
if (tag == "<none>")
return repo;
return repo + ':' + tag;
}
QString repoAndTagEncoded() const { return repoAndTag().replace(':', '.'); }
QString imageId;
QString repo;
QString tag;
QString size;
bool useLocalUidGid = true;
QStringList mounts = {Core::DocumentManager::projectsDirectory().toString()};
bool keepEntryPoint = false;
bool enableLldbFlags = false;
Utils::FilePath clangdExecutable;
Utils::StringAspect imageId{this};
Utils::StringAspect repo{this};
Utils::StringAspect tag{this};
Utils::BoolAspect useLocalUidGid{this};
Utils::StringListAspect mounts{this};
Utils::BoolAspect keepEntryPoint{this};
Utils::BoolAspect enableLldbFlags{this};
Utils::FilePathAspect clangdExecutable{this};
};
class DockerDevice : public ProjectExplorer::IDevice
@@ -58,14 +38,14 @@ public:
using Ptr = QSharedPointer<DockerDevice>;
using ConstPtr = QSharedPointer<const DockerDevice>;
explicit DockerDevice(const DockerDeviceData &data);
explicit DockerDevice(std::unique_ptr<DockerDeviceSettings> settings);
~DockerDevice();
void shutdown();
static Ptr create(const DockerDeviceData &data)
static Ptr create(std::unique_ptr<DockerDeviceSettings> settings)
{
return Ptr(new DockerDevice(data));
return Ptr(new DockerDevice(std::move(settings)));
}
ProjectExplorer::IDeviceWidget *createWidget() override;
@@ -87,11 +67,6 @@ public:
Utils::Environment systemEnvironment() const override;
const DockerDeviceData data() const;
DockerDeviceData data();
void setData(const DockerDeviceData &data);
bool updateContainerAccess() const;
void setMounts(const QStringList &mounts) const;
@@ -124,5 +99,3 @@ private:
};
} // namespace Docker::Internal
Q_DECLARE_METATYPE(Docker::Internal::DockerDeviceData)

View File

@@ -33,22 +33,9 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
auto dockerDevice = device.dynamicCast<DockerDevice>();
QTC_ASSERT(dockerDevice, return);
m_data = dockerDevice->data();
DockerDeviceSettings *deviceSettings = static_cast<DockerDeviceSettings *>(device->settings());
auto repoLabel = new QLabel(Tr::tr("Repository:"));
m_repoLineEdit = new QLineEdit;
m_repoLineEdit->setText(m_data.repo);
m_repoLineEdit->setEnabled(false);
auto tagLabel = new QLabel(Tr::tr("Tag:"));
m_tagLineEdit = new QLineEdit;
m_tagLineEdit->setText(m_data.tag);
m_tagLineEdit->setEnabled(false);
auto idLabel = new QLabel(Tr::tr("Image ID:"));
m_idLineEdit = new QLineEdit;
m_idLineEdit->setText(m_data.imageId);
m_idLineEdit->setEnabled(false);
using namespace Layouting;
auto daemonStateLabel = new QLabel(Tr::tr("Daemon state:"));
m_daemonReset = new QToolButton;
@@ -67,58 +54,6 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
DockerApi::recheckDockerDaemon();
});
m_keepEntryPoint = new QCheckBox(Tr::tr("Do not modify entry point"));
m_keepEntryPoint->setToolTip(
Tr::tr("Prevents modifying the entry point of the image. Enable only if "
"the image starts into a shell."));
m_keepEntryPoint->setChecked(m_data.keepEntryPoint);
m_keepEntryPoint->setEnabled(true);
connect(m_keepEntryPoint, &QCheckBox::toggled, this, [this, dockerDevice](bool on) {
m_data.keepEntryPoint = on;
dockerDevice->setData(m_data);
});
m_enableLldbFlags = new QCheckBox(Tr::tr("Enable flags needed for LLDB"));
m_enableLldbFlags->setToolTip(Tr::tr("Adds the following flags to the container "
"to allow LLDB to run: "
"--cap-add=SYS_PTRACE --security-opt seccomp=unconfined"));
m_enableLldbFlags->setChecked(m_data.enableLldbFlags);
m_enableLldbFlags->setEnabled(true);
connect(m_enableLldbFlags, &QCheckBox::toggled, this, [this, dockerDevice](bool on) {
m_data.enableLldbFlags = on;
dockerDevice->setData(m_data);
});
m_runAsOutsideUser = new QCheckBox(Tr::tr("Run as outside user"));
m_runAsOutsideUser->setToolTip(Tr::tr("Uses user ID and group ID of the user running Qt Creator "
"in the docker container."));
m_runAsOutsideUser->setChecked(m_data.useLocalUidGid);
m_runAsOutsideUser->setEnabled(HostOsInfo::isAnyUnixHost());
connect(m_runAsOutsideUser, &QCheckBox::toggled, this, [this, dockerDevice](bool on) {
m_data.useLocalUidGid = on;
dockerDevice->setData(m_data);
});
auto clangDLabel = new QLabel(Tr::tr("Clangd Executable:"));
m_clangdExecutable = new PathChooser();
m_clangdExecutable->setExpectedKind(PathChooser::ExistingCommand);
m_clangdExecutable->setHistoryCompleter("Docker.ClangdExecutable.History");
m_clangdExecutable->setAllowPathFromDevice(true);
m_clangdExecutable->setFilePath(m_data.clangdExecutable);
m_clangdExecutable->setValidationFunction(
[chooser = m_clangdExecutable](FancyLineEdit *, QString *error) {
return Utils::checkClangdVersion(chooser->filePath(), error);
});
connect(m_clangdExecutable, &PathChooser::rawPathChanged, this, [this, dockerDevice] {
m_data.clangdExecutable = m_clangdExecutable->filePath();
dockerDevice->setData(m_data);
});
auto pathListLabel = new InfoLabel(Tr::tr("Paths to mount:"));
pathListLabel->setAdditionalToolTip(Tr::tr("Source directory list should not be empty."));
@@ -126,7 +61,7 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
m_pathsListEdit->setPlaceholderText(Tr::tr("Host directories to mount into the container"));
m_pathsListEdit->setToolTip(Tr::tr("Maps paths in this list one-to-one to the "
"docker container."));
m_pathsListEdit->setPathList(m_data.mounts);
m_pathsListEdit->setPathList(deviceSettings->mounts());
m_pathsListEdit->setMaximumHeight(100);
m_pathsListEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
@@ -136,9 +71,12 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
};
markupMounts();
connect(m_pathsListEdit, &PathListEditor::changed, this, [this, dockerDevice, markupMounts] {
m_data.mounts = m_pathsListEdit->pathList();
dockerDevice->setData(m_data);
connect(m_pathsListEdit,
&PathListEditor::changed,
this,
[this, dockerDevice, markupMounts, deviceSettings] {
deviceSettings->mounts.setVolatileValue(m_pathsListEdit->pathList());
// dockerDevice->setData(m_data);
markupMounts();
});
@@ -177,20 +115,21 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
return paths;
};
connect(autoDetectButton, &QPushButton::clicked, this,
[this, logView, dockerDevice, searchPaths] {
connect(autoDetectButton,
&QPushButton::clicked,
this,
[this, logView, dockerDevice, searchPaths, deviceSettings] {
logView->clear();
dockerDevice->updateContainerAccess();
const FilePath clangdPath = dockerDevice->filePath("clangd")
.searchInPath({},
FilePath::AppendToPath,
[](const FilePath &clangd) {
const FilePath clangdPath
= dockerDevice->filePath("clangd")
.searchInPath({}, FilePath::AppendToPath, [](const FilePath &clangd) {
return Utils::checkClangdVersion(clangd);
});
if (!clangdPath.isEmpty())
m_clangdExecutable->setFilePath(clangdPath);
deviceSettings->clangdExecutable.setValue(clangdPath);
m_kitItemDetector.autoDetect(dockerDevice->id().toString(), searchPaths());
@@ -234,19 +173,19 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device)
};
Form {
repoLabel, m_repoLineEdit, br,
tagLabel, m_tagLineEdit, br,
idLabel, m_idLineEdit, br,
deviceSettings->repo, br,
deviceSettings->tag, br,
deviceSettings->imageId, br,
daemonStateLabel, m_daemonReset, m_daemonState, br,
m_runAsOutsideUser, br,
m_keepEntryPoint, br,
m_enableLldbFlags, br,
clangDLabel, m_clangdExecutable, br,
deviceSettings->useLocalUidGid, br,
deviceSettings->keepEntryPoint, br,
deviceSettings->enableLldbFlags, br,
deviceSettings->clangdExecutable, br,
Column {
pathListLabel,
m_pathsListEdit,
}, br,
(dockerDevice->isAutoDetected() ? Column {} : std::move(detectionControls)),
If { dockerDevice->isAutoDetected(), {}, {detectionControls} },
noMargin,
}.attachTo(this);
// clang-format on

View File

@@ -31,20 +31,11 @@ public:
void updateDaemonStateTexts();
private:
QLineEdit *m_repoLineEdit;
QLineEdit *m_tagLineEdit;
QLineEdit *m_idLineEdit;
QToolButton *m_daemonReset;
QLabel *m_daemonState;
QCheckBox *m_runAsOutsideUser;
QCheckBox *m_keepEntryPoint;
QCheckBox *m_enableLldbFlags;
Utils::PathChooser *m_clangdExecutable;
Utils::PathListEditor *m_pathsListEdit;
KitDetector m_kitItemDetector;
QLabel *m_daemonState;
QToolButton *m_daemonReset;
DockerDeviceData m_data;
KitDetector m_kitItemDetector;
};
} // Docker::Internal