From 4267d6ad8130d3e3ade2d2998c08d1a1f3b185d9 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 21 Jul 2023 01:02:08 +0200 Subject: [PATCH] RemoteLinux: Inline wizard pages Change-Id: I058c001e34653f7dfa96cd8886daea84be7dc6a1 Reviewed-by: hjk --- src/plugins/remotelinux/CMakeLists.txt | 1 - .../genericlinuxdeviceconfigurationwizard.cpp | 209 +++++++++++++- ...riclinuxdeviceconfigurationwizardpages.cpp | 265 ------------------ ...nericlinuxdeviceconfigurationwizardpages.h | 78 ------ src/plugins/remotelinux/remotelinux.qbs | 2 - 5 files changed, 204 insertions(+), 351 deletions(-) delete mode 100644 src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardpages.cpp delete mode 100644 src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardpages.h diff --git a/src/plugins/remotelinux/CMakeLists.txt b/src/plugins/remotelinux/CMakeLists.txt index f81f75350ac..c49f49793be 100644 --- a/src/plugins/remotelinux/CMakeLists.txt +++ b/src/plugins/remotelinux/CMakeLists.txt @@ -8,7 +8,6 @@ add_qtc_plugin(RemoteLinux genericdirectuploadstep.cpp genericdirectuploadstep.h genericlinuxdeviceconfigurationwidget.cpp genericlinuxdeviceconfigurationwidget.h genericlinuxdeviceconfigurationwizard.cpp genericlinuxdeviceconfigurationwizard.h - genericlinuxdeviceconfigurationwizardpages.cpp genericlinuxdeviceconfigurationwizardpages.h killappstep.cpp killappstep.h linuxdevice.cpp linuxdevice.h linuxdevicetester.cpp linuxdevicetester.h diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp index b1270a276a0..314a0f518bf 100644 --- a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp +++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp @@ -3,21 +3,220 @@ #include "genericlinuxdeviceconfigurationwizard.h" -#include "genericlinuxdeviceconfigurationwizardpages.h" +#include "publickeydeploymentdialog.h" +#include "remotelinuxtr.h" +#include "sshkeycreationdialog.h" #include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace ProjectExplorer; +using namespace Utils; + namespace RemoteLinux { +class SetupPage : public QWizardPage +{ +public: + explicit SetupPage(QWidget *parent = nullptr) + : QWizardPage(parent) + { + setTitle(Tr::tr("Connection")); + setWindowTitle(Tr::tr("WizardPage")); + + m_nameLineEdit = new FancyLineEdit(this); + m_nameLineEdit->setHistoryCompleter("DeviceName"); + + m_hostNameLineEdit = new FancyLineEdit(this); + m_hostNameLineEdit->setHistoryCompleter("HostName"); + + m_sshPortSpinBox = new QSpinBox(this); + + m_userNameLineEdit = new FancyLineEdit(this); + m_userNameLineEdit->setHistoryCompleter("UserName"); + + using namespace Layouting; + Form { + Tr::tr("The name to identify this configuration:"), m_nameLineEdit, br, + Tr::tr("The device's host name or IP address:"), m_hostNameLineEdit, st, br, + Tr::tr("The device's SSH port number:"), m_sshPortSpinBox, st, br, + Tr::tr("The username to log into the device:"), m_userNameLineEdit, st, br + }.attachTo(this); + + setSubTitle(QLatin1String(" ")); // For Qt bug (background color) + connect(m_nameLineEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged); + connect(m_hostNameLineEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged); + connect(m_sshPortSpinBox, &QSpinBox::valueChanged, this, &QWizardPage::completeChanged); + connect(m_userNameLineEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged); + } + + void setDevice(const ProjectExplorer::IDevicePtr &device) { m_device = device; } + +private: + void initializePage() final { + m_nameLineEdit->setText(m_device->displayName()); + m_hostNameLineEdit->setText(m_device->sshParameters().host()); + m_sshPortSpinBox->setValue(22); + m_sshPortSpinBox->setRange(1, 65535); + m_userNameLineEdit->setText(m_device->sshParameters().userName()); + } + bool isComplete() const final { + return !configurationName().isEmpty() + && !m_hostNameLineEdit->text().trimmed().isEmpty() + && !m_userNameLineEdit->text().trimmed().isEmpty(); + + } + bool validatePage() final { + m_device->setDisplayName(configurationName()); + SshParameters sshParams = m_device->sshParameters(); + sshParams.setHost(m_hostNameLineEdit->text().trimmed()); + sshParams.setUserName(m_userNameLineEdit->text().trimmed()); + sshParams.setPort(m_sshPortSpinBox->value()); + m_device->setSshParameters(sshParams); + return true; + } + + QString configurationName() const { return m_nameLineEdit->text().trimmed(); } + + FancyLineEdit *m_nameLineEdit; + FancyLineEdit *m_hostNameLineEdit; + QSpinBox *m_sshPortSpinBox; + FancyLineEdit *m_userNameLineEdit; + IDevicePtr m_device; +}; + +class KeyDeploymentPage : public QWizardPage +{ +public: + explicit KeyDeploymentPage(QWidget *parent = nullptr) + : QWizardPage(parent) + { + setTitle(Tr::tr("Key Deployment")); + setSubTitle(" "); + const QString info = Tr::tr("We recommend that you log into your device using public key " + "authentication.\n" + "If your device is already set up for this, you do not have to do " + "anything here.\n" + "Otherwise, please deploy the public key for the private key " + "with which to connect in the future.\n" + "If you do not have a private key yet, you can also " + "create one here."); + m_keyFileChooser.setExpectedKind(PathChooser::File); + m_keyFileChooser.setHistoryCompleter("Ssh.KeyFile.History"); + m_keyFileChooser.setPromptDialogTitle(Tr::tr("Choose a Private Key File")); + auto const deployButton = new QPushButton(Tr::tr("Deploy Public Key"), this); + connect(deployButton, &QPushButton::clicked, this, [this] { + PublicKeyDeploymentDialog dlg(m_device, + m_keyFileChooser.filePath().stringAppended(".pub"), this); + m_iconLabel.setPixmap((dlg.exec() == QDialog::Accepted ? Icons::OK : Icons::BROKEN).pixmap()); + }); + auto const createButton = new QPushButton(Tr::tr("Create New Key Pair"), this); + connect(createButton, &QPushButton::clicked, this, [this] { + SshKeyCreationDialog dlg(this); + if (dlg.exec() == QDialog::Accepted) + m_keyFileChooser.setFilePath(dlg.privateKeyFilePath()); + }); + auto const mainLayout = new QVBoxLayout(this); + auto const keyLayout = new QHBoxLayout; + auto const deployLayout = new QHBoxLayout; + mainLayout->addWidget(new QLabel(info)); + keyLayout->addWidget(new QLabel(Tr::tr("Private key file:"))); + keyLayout->addWidget(&m_keyFileChooser); + keyLayout->addWidget(createButton); + keyLayout->addStretch(); + mainLayout->addLayout(keyLayout); + deployLayout->addWidget(deployButton); + deployLayout->addWidget(&m_iconLabel); + deployLayout->addStretch(); + mainLayout->addLayout(deployLayout); + connect(&m_keyFileChooser, &PathChooser::textChanged, this, [this, deployButton] { + deployButton->setEnabled(m_keyFileChooser.filePath().exists()); + m_iconLabel.clear(); + emit completeChanged(); + }); + for (const FilePath &defaultKey : defaultKeys()) { + if (defaultKey.exists()) { + m_keyFileChooser.setFilePath(defaultKey); + break; + } + } + } + + void setDevice(const ProjectExplorer::IDevicePtr &device) { m_device = device; } + +private: + void initializePage() final { + if (!m_device->sshParameters().privateKeyFile.isEmpty()) + m_keyFileChooser.setFilePath(m_keyFileChooser.filePath()); + m_iconLabel.clear(); + } + bool isComplete() const final { + return m_keyFileChooser.filePath().toString().isEmpty() + || m_keyFileChooser.filePath().exists(); + } + bool validatePage() final { + if (!defaultKeys().contains(m_keyFileChooser.filePath())) { + SshParameters sshParams = m_device->sshParameters(); + sshParams.authenticationType = SshParameters::AuthenticationTypeSpecificKey; + sshParams.privateKeyFile = m_keyFileChooser.filePath(); + m_device->setSshParameters(sshParams); + } + return true; + } + + FilePaths defaultKeys() const { + const FilePath baseDir = FileUtils::homePath() / ".ssh"; + return {baseDir / "id_rsa", baseDir / "id_ecdsa", baseDir / "id_ed25519"}; + } + + PathChooser m_keyFileChooser; + QLabel m_iconLabel; + IDevicePtr m_device; +}; + +class FinalPage final : public QWizardPage +{ +public: + FinalPage(QWidget *parent = nullptr) + : QWizardPage(parent) + { + setTitle(Tr::tr("Summary")); + setSubTitle(QLatin1String(" ")); // For Qt bug (background color) + m_infoLabel.setWordWrap(true); + auto const layout = new QVBoxLayout(this); + layout->addWidget(&m_infoLabel); + } + +private: + void initializePage() final { + m_infoLabel.setText(Tr::tr("The new device configuration will now be created.\n" + "In addition, device connectivity will be tested.")); + } + + QLabel m_infoLabel; +}; + GenericLinuxDeviceConfigurationWizard::GenericLinuxDeviceConfigurationWizard( const QString &title, const ProjectExplorer::IDevicePtr &device) - : Utils::Wizard(Core::ICore::dialogParent()) + : Wizard(Core::ICore::dialogParent()) { setWindowTitle(title); - auto setupPage = new GenericLinuxDeviceConfigurationWizardSetupPage; - auto keyDeploymentPage = new GenericLinuxDeviceConfigurationWizardKeyDeploymentPage; - auto finalPage = new GenericLinuxDeviceConfigurationWizardFinalPage; + auto setupPage = new SetupPage; + auto keyDeploymentPage = new KeyDeploymentPage; + auto finalPage = new FinalPage; addPage(setupPage); addPage(keyDeploymentPage); diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardpages.cpp b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardpages.cpp deleted file mode 100644 index 03f945098ac..00000000000 --- a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardpages.cpp +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "genericlinuxdeviceconfigurationwizardpages.h" - -#include "publickeydeploymentdialog.h" -#include "remotelinuxtr.h" -#include "sshkeycreationdialog.h" - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -using namespace ProjectExplorer; -using namespace Utils; - -namespace RemoteLinux { -namespace Internal { - -class GenericLinuxDeviceConfigurationWizardSetupPagePrivate -{ -public: - FancyLineEdit *nameLineEdit; - FancyLineEdit *hostNameLineEdit; - QSpinBox *sshPortSpinBox; - FancyLineEdit *userNameLineEdit; - - IDevicePtr device; -}; - -class GenericLinuxDeviceConfigurationWizardFinalPagePrivate -{ -public: - QLabel infoLabel; -}; - -} // namespace Internal - -GenericLinuxDeviceConfigurationWizardSetupPage::GenericLinuxDeviceConfigurationWizardSetupPage( - QWidget *parent) : - QWizardPage(parent), d(new Internal::GenericLinuxDeviceConfigurationWizardSetupPagePrivate) -{ - setTitle(Tr::tr("Connection")); - setWindowTitle(Tr::tr("WizardPage")); - - d->nameLineEdit = new FancyLineEdit(this); - d->nameLineEdit->setHistoryCompleter("DeviceName"); - - d->hostNameLineEdit = new FancyLineEdit(this); - d->hostNameLineEdit->setHistoryCompleter("HostName"); - - d->sshPortSpinBox = new QSpinBox(this); - - d->userNameLineEdit = new FancyLineEdit(this); - d->userNameLineEdit->setHistoryCompleter("UserName"); - - using namespace Layouting; - Form { - Tr::tr("The name to identify this configuration:"), d->nameLineEdit, br, - Tr::tr("The device's host name or IP address:"), d->hostNameLineEdit, st, br, - Tr::tr("The device's SSH port number:"), d->sshPortSpinBox, st, br, - Tr::tr("The username to log into the device:"), d->userNameLineEdit, st, br - }.attachTo(this); - - setSubTitle(QLatin1String(" ")); // For Qt bug (background color) - connect(d->nameLineEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged); - connect(d->hostNameLineEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged); - connect(d->sshPortSpinBox, &QSpinBox::valueChanged, this, &QWizardPage::completeChanged); - connect(d->userNameLineEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged); -} - -GenericLinuxDeviceConfigurationWizardSetupPage::~GenericLinuxDeviceConfigurationWizardSetupPage() -{ - delete d; -} - -void GenericLinuxDeviceConfigurationWizardSetupPage::initializePage() -{ - d->nameLineEdit->setText(d->device->displayName()); - d->hostNameLineEdit->setText(d->device->sshParameters().host()); - d->sshPortSpinBox->setValue(22); - d->sshPortSpinBox->setRange(1, 65535); - d->userNameLineEdit->setText(d->device->sshParameters().userName()); -} - -bool GenericLinuxDeviceConfigurationWizardSetupPage::isComplete() const -{ - return !configurationName().isEmpty() - && !d->hostNameLineEdit->text().trimmed().isEmpty() - && !d->userNameLineEdit->text().trimmed().isEmpty(); -} - -bool GenericLinuxDeviceConfigurationWizardSetupPage::validatePage() -{ - d->device->setDisplayName(configurationName()); - SshParameters sshParams = d->device->sshParameters(); - sshParams.setHost(d->hostNameLineEdit->text().trimmed()); - sshParams.setUserName(d->userNameLineEdit->text().trimmed()); - sshParams.setPort(d->sshPortSpinBox->value()); - d->device->setSshParameters(sshParams); - return true; -} - -QString GenericLinuxDeviceConfigurationWizardSetupPage::configurationName() const -{ - return d->nameLineEdit->text().trimmed(); -} - -void GenericLinuxDeviceConfigurationWizardSetupPage::setDevice( - const ProjectExplorer::IDevicePtr &device) -{ - d->device = device; -} - -GenericLinuxDeviceConfigurationWizardFinalPage::GenericLinuxDeviceConfigurationWizardFinalPage( - QWidget *parent) - : QWizardPage(parent), d(new Internal::GenericLinuxDeviceConfigurationWizardFinalPagePrivate) -{ - setTitle(Tr::tr("Summary")); - setSubTitle(QLatin1String(" ")); // For Qt bug (background color) - d->infoLabel.setWordWrap(true); - auto const layout = new QVBoxLayout(this); - layout->addWidget(&d->infoLabel); -} - -GenericLinuxDeviceConfigurationWizardFinalPage::~GenericLinuxDeviceConfigurationWizardFinalPage() -{ - delete d; -} - -void GenericLinuxDeviceConfigurationWizardFinalPage::initializePage() -{ - d->infoLabel.setText(infoText()); -} - -QString GenericLinuxDeviceConfigurationWizardFinalPage::infoText() const -{ - return Tr::tr("The new device configuration will now be created.\n" - "In addition, device connectivity will be tested."); -} - -struct GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::Private -{ - FilePaths defaultKeys() const - { - const FilePath baseDir = FileUtils::homePath() / ".ssh"; - return {baseDir / "id_rsa", baseDir / "id_ecdsa", baseDir / "id_ed25519"}; - } - - PathChooser keyFileChooser; - QLabel iconLabel; - IDevicePtr device; -}; - -GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::GenericLinuxDeviceConfigurationWizardKeyDeploymentPage(QWidget *parent) - : QWizardPage(parent), d(new Private) -{ - setTitle(Tr::tr("Key Deployment")); - setSubTitle(" "); - const QString info = Tr::tr("We recommend that you log into your device using public key " - "authentication.\n" - "If your device is already set up for this, you do not have to do " - "anything here.\n" - "Otherwise, please deploy the public key for the private key " - "with which to connect in the future.\n" - "If you do not have a private key yet, you can also " - "create one here."); - d->keyFileChooser.setExpectedKind(PathChooser::File); - d->keyFileChooser.setHistoryCompleter("Ssh.KeyFile.History"); - d->keyFileChooser.setPromptDialogTitle(Tr::tr("Choose a Private Key File")); - auto const deployButton = new QPushButton(Tr::tr("Deploy Public Key"), this); - connect(deployButton, &QPushButton::clicked, - this, &GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::deployKey); - auto const createButton = new QPushButton(Tr::tr("Create New Key Pair"), this); - connect(createButton, &QPushButton::clicked, - this, &GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::createKey); - auto const mainLayout = new QVBoxLayout(this); - auto const keyLayout = new QHBoxLayout; - auto const deployLayout = new QHBoxLayout; - mainLayout->addWidget(new QLabel(info)); - keyLayout->addWidget(new QLabel(Tr::tr("Private key file:"))); - keyLayout->addWidget(&d->keyFileChooser); - keyLayout->addWidget(createButton); - keyLayout->addStretch(); - mainLayout->addLayout(keyLayout); - deployLayout->addWidget(deployButton); - deployLayout->addWidget(&d->iconLabel); - deployLayout->addStretch(); - mainLayout->addLayout(deployLayout); - connect(&d->keyFileChooser, &PathChooser::textChanged, this, [this, deployButton] { - deployButton->setEnabled(d->keyFileChooser.filePath().exists()); - d->iconLabel.clear(); - emit completeChanged(); - }); - for (const FilePath &defaultKey : d->defaultKeys()) { - if (defaultKey.exists()) { - d->keyFileChooser.setFilePath(defaultKey); - break; - } - } -} - -GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::~GenericLinuxDeviceConfigurationWizardKeyDeploymentPage() -{ - delete d; -} - -void GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::setDevice( - const ProjectExplorer::IDevicePtr &device) -{ - d->device = device; -} - -void GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::initializePage() -{ - if (!d->device->sshParameters().privateKeyFile.isEmpty()) - d->keyFileChooser.setFilePath(privateKeyFilePath()); - d->iconLabel.clear(); -} - -bool GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::isComplete() const -{ - return d->keyFileChooser.filePath().toString().isEmpty() || d->keyFileChooser.filePath().exists(); -} - -bool GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::validatePage() -{ - if (!d->defaultKeys().contains(d->keyFileChooser.filePath())) { - SshParameters sshParams = d->device->sshParameters(); - sshParams.authenticationType = SshParameters::AuthenticationTypeSpecificKey; - sshParams.privateKeyFile = d->keyFileChooser.filePath(); - d->device->setSshParameters(sshParams); - } - return true; -} - -FilePath GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::privateKeyFilePath() const -{ - return d->keyFileChooser.filePath(); -} - -void GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::createKey() -{ - SshKeyCreationDialog dlg(this); - if (dlg.exec() == QDialog::Accepted) - d->keyFileChooser.setFilePath(dlg.privateKeyFilePath()); -} - -void GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::deployKey() -{ - PublicKeyDeploymentDialog dlg(d->device, privateKeyFilePath().stringAppended(".pub"), this); - d->iconLabel.setPixmap((dlg.exec() == QDialog::Accepted ? Icons::OK : Icons::BROKEN).pixmap()); -} - -} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardpages.h b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardpages.h deleted file mode 100644 index 4e3f15965fd..00000000000 --- a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardpages.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "remotelinux_export.h" - -#include "linuxdevice.h" - -#include - -namespace RemoteLinux { -class LinuxDevice; -namespace Internal { -class GenericLinuxDeviceConfigurationWizardSetupPagePrivate; -class GenericLinuxDeviceConfigurationWizardFinalPagePrivate; -} // namespace Internal - -class REMOTELINUX_EXPORT GenericLinuxDeviceConfigurationWizardSetupPage : public QWizardPage -{ - Q_OBJECT - -public: - explicit GenericLinuxDeviceConfigurationWizardSetupPage(QWidget *parent = nullptr); - ~GenericLinuxDeviceConfigurationWizardSetupPage() override; - - void setDevice(const ProjectExplorer::IDevicePtr &device); - -private: - void initializePage() override; - bool isComplete() const override; - bool validatePage() override; - - QString configurationName() const; - - Internal::GenericLinuxDeviceConfigurationWizardSetupPagePrivate * const d; -}; - -class REMOTELINUX_EXPORT GenericLinuxDeviceConfigurationWizardKeyDeploymentPage : public QWizardPage -{ - Q_OBJECT - -public: - explicit GenericLinuxDeviceConfigurationWizardKeyDeploymentPage(QWidget *parent = nullptr); - ~GenericLinuxDeviceConfigurationWizardKeyDeploymentPage() override; - - void setDevice(const ProjectExplorer::IDevicePtr &device); - -private: - void initializePage() override; - bool isComplete() const override; - bool validatePage() override; - - Utils::FilePath privateKeyFilePath() const; - void createKey(); - void deployKey(); - - struct Private; - Private * const d; -}; - -class REMOTELINUX_EXPORT GenericLinuxDeviceConfigurationWizardFinalPage final : public QWizardPage -{ - Q_OBJECT -public: - GenericLinuxDeviceConfigurationWizardFinalPage(QWidget *parent = nullptr); - ~GenericLinuxDeviceConfigurationWizardFinalPage() override; - -protected: - virtual QString infoText() const; - -private: - void initializePage() override; - - Internal::GenericLinuxDeviceConfigurationWizardFinalPagePrivate * const d; -}; - -} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinux.qbs b/src/plugins/remotelinux/remotelinux.qbs index 03a6afad10f..d363603cd99 100644 --- a/src/plugins/remotelinux/remotelinux.qbs +++ b/src/plugins/remotelinux/remotelinux.qbs @@ -25,8 +25,6 @@ Project { "genericlinuxdeviceconfigurationwidget.h", "genericlinuxdeviceconfigurationwizard.cpp", "genericlinuxdeviceconfigurationwizard.h", - "genericlinuxdeviceconfigurationwizardpages.cpp", - "genericlinuxdeviceconfigurationwizardpages.h", "killappstep.cpp", "killappstep.h", "linuxdevice.cpp",