diff options
author | Marcus Tillmanns <[email protected]> | 2023-09-07 15:25:07 +0200 |
---|---|---|
committer | Marcus Tillmanns <[email protected]> | 2023-09-12 08:51:31 +0000 |
commit | f6205d6cc7a0f35eca25d645c68eea7f95612822 (patch) | |
tree | 55f3cf8a458c346366aa7ab91ed49c997306f8c8 /src | |
parent | ed0935733efbd4ff25a2664e3e91b672f3a645c1 (diff) |
Docker: Switch to aspect settings
Change-Id: Id04c48caf2ddd33e176ee424273690b80c77232b
Reviewed-by: <[email protected]>
Reviewed-by: hjk <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/docker/dockerdevice.cpp | 230 | ||||
-rw-r--r-- | src/plugins/docker/dockerdevice.h | 61 | ||||
-rw-r--r-- | src/plugins/docker/dockerdevicewidget.cpp | 141 | ||||
-rw-r--r-- | src/plugins/docker/dockerdevicewidget.h | 13 |
4 files changed, 185 insertions, 260 deletions
diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 1344294c2cb..5976bd1a113 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -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); diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index 59a11e436a4..821438edb8a 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -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; - } - - bool operator!=(const DockerDeviceData &other) const { return !(*this == other); } - - // 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; + DockerDeviceSettings(); + + QString repoAndTag() const; + QString repoAndTagEncoded() const; + + 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) diff --git a/src/plugins/docker/dockerdevicewidget.cpp b/src/plugins/docker/dockerdevicewidget.cpp index 259325274c0..0ec608d4538 100644 --- a/src/plugins/docker/dockerdevicewidget.cpp +++ b/src/plugins/docker/dockerdevicewidget.cpp @@ -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,11 +71,14 @@ 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); - markupMounts(); - }); + connect(m_pathsListEdit, + &PathListEditor::changed, + this, + [this, dockerDevice, markupMounts, deviceSettings] { + deviceSettings->mounts.setVolatileValue(m_pathsListEdit->pathList()); + // dockerDevice->setData(m_data); + markupMounts(); + }); auto logView = new QTextBrowser; connect(&m_kitItemDetector, &KitDetector::logOutput, @@ -177,31 +115,32 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device) return paths; }; - connect(autoDetectButton, &QPushButton::clicked, this, - [this, logView, dockerDevice, searchPaths] { - logView->clear(); - dockerDevice->updateContainerAccess(); + 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) { - return Utils::checkClangdVersion(clangd); - }); + const FilePath clangdPath + = dockerDevice->filePath("clangd") + .searchInPath({}, FilePath::AppendToPath, [](const FilePath &clangd) { + return Utils::checkClangdVersion(clangd); + }); - if (!clangdPath.isEmpty()) - m_clangdExecutable->setFilePath(clangdPath); + if (!clangdPath.isEmpty()) + deviceSettings->clangdExecutable.setValue(clangdPath); - m_kitItemDetector.autoDetect(dockerDevice->id().toString(), searchPaths()); + m_kitItemDetector.autoDetect(dockerDevice->id().toString(), searchPaths()); - if (DockerApi::instance()->dockerDaemonAvailable().value_or(false) == false) - logView->append(Tr::tr("Docker daemon appears to be stopped.")); - else - logView->append(Tr::tr("Docker daemon appears to be running.")); + if (DockerApi::instance()->dockerDaemonAvailable().value_or(false) == false) + logView->append(Tr::tr("Docker daemon appears to be stopped.")); + else + logView->append(Tr::tr("Docker daemon appears to be running.")); - logView->append(Tr::tr("Detection complete.")); - updateDaemonStateTexts(); - }); + logView->append(Tr::tr("Detection complete.")); + updateDaemonStateTexts(); + }); connect(undoAutoDetectButton, &QPushButton::clicked, this, [this, logView, device] { logView->clear(); @@ -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 diff --git a/src/plugins/docker/dockerdevicewidget.h b/src/plugins/docker/dockerdevicewidget.h index d92ac5ed218..7a15239c513 100644 --- a/src/plugins/docker/dockerdevicewidget.h +++ b/src/plugins/docker/dockerdevicewidget.h @@ -31,20 +31,11 @@ public: void updateDaemonStateTexts(); private: - QLineEdit *m_repoLineEdit; - QLineEdit *m_tagLineEdit; - QLineEdit *m_idLineEdit; - QToolButton *m_daemonReset; + Utils::PathListEditor *m_pathsListEdit; QLabel *m_daemonState; - QCheckBox *m_runAsOutsideUser; - QCheckBox *m_keepEntryPoint; - QCheckBox *m_enableLldbFlags; - Utils::PathChooser *m_clangdExecutable; + QToolButton *m_daemonReset; - Utils::PathListEditor *m_pathsListEdit; KitDetector m_kitItemDetector; - - DockerDeviceData m_data; }; } // Docker::Internal |