diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp index fb187e17752..94f855f0c50 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp @@ -68,9 +68,6 @@ namespace { const QLatin1String InternalIdKey("InternalId"); const QLatin1String DefaultKeyFilePathKey("DefaultKeyFile"); - const QString DefaultKeyFile = - QDesktopServices::storageLocation(QDesktopServices::HomeLocation) - + QLatin1String("/.ssh/id_rsa"); const int DefaultSshPortHW(22); const int DefaultSshPortSim(6666); const int DefaultGdbServerPortHW(10000); @@ -274,7 +271,7 @@ MaemoDeviceConfig::MaemoDeviceConfig(const QSettings &settings, = static_cast(settings.value(AuthKey, DefaultAuthType).toInt()); m_sshParameters.pwd = settings.value(PasswordKey).toString(); m_sshParameters.privateKeyFile - = settings.value(KeyFileKey, DefaultKeyFile).toString(); + = settings.value(KeyFileKey, defaultPrivateKeyFilePath()).toString(); m_sshParameters.timeout = settings.value(TimeoutKey, DefaultTimeout).toInt(); } @@ -306,11 +303,17 @@ QString MaemoDeviceConfig::defaultPortsSpec(DeviceType type) const return QLatin1String(type == Physical ? "10000-10100" : "13219,14168"); } -QString MaemoDeviceConfig::defaultHost(DeviceType type) const +QString MaemoDeviceConfig::defaultHost(DeviceType type) { return type == Physical ? DefaultHostNameHW : DefaultHostNameSim; } +QString MaemoDeviceConfig::defaultPrivateKeyFilePath() +{ + return QDesktopServices::storageLocation(QDesktopServices::HomeLocation) + + QLatin1String("/.ssh/id_rsa"); +} + QString MaemoDeviceConfig::defaultUser(MaemoGlobal::MaemoVersion osVersion) const { switch (osVersion) { @@ -528,8 +531,8 @@ void MaemoDeviceConfigurations::load() QSettings *settings = Core::ICore::instance()->settings(); settings->beginGroup(SettingsGroup); m_nextId = settings->value(IdCounterKey, 1).toULongLong(); - m_defaultSshKeyFilePath - = settings->value(DefaultKeyFilePathKey, DefaultKeyFile).toString(); + m_defaultSshKeyFilePath = settings->value(DefaultKeyFilePathKey, + MaemoDeviceConfig::defaultPrivateKeyFilePath()).toString(); int count = settings->beginReadArray(ConfigListKey); bool hasDefault = false; for (int i = 0; i < count; ++i) { diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h index 8a89a9c8921..cebccc5bb15 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h @@ -84,6 +84,8 @@ public: QString portsSpec() const { return m_portsSpec; } bool isDefault() const { return m_isDefault; } static QString portsRegExpr(); + static QString defaultHost(DeviceType type); + static QString defaultPrivateKeyFilePath(); static const Id InvalidId; @@ -106,7 +108,6 @@ private: void save(QSettings &settings) const; int defaultSshPort(DeviceType type) const; QString defaultPortsSpec(DeviceType type) const; - QString defaultHost(DeviceType type) const; QString defaultUser(MaemoGlobal::MaemoVersion osVersion) const; Core::SshConnectionParameters m_sshParameters; diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizard.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizard.cpp new file mode 100644 index 00000000000..dc2437377a6 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizard.cpp @@ -0,0 +1,358 @@ +#include "maemodeviceconfigwizard.h" +#include "ui_maemodeviceconfigwizardkeycreationpage.h" +#include "ui_maemodeviceconfigwizardpreviouskeysetupcheckpage.h" +#include "ui_maemodeviceconfigwizardreusekeyscheckpage.h" +#include "ui_maemodeviceconfigwizardstartpage.h" + +#include "maemodeviceconfigurations.h" + +#include + +#include +#include +#include +#include +#include +#include + +namespace Qt4ProjectManager { +namespace Internal { +namespace { + +struct WizardData +{ + QString configName; + QString hostName; + MaemoGlobal::MaemoVersion maemoVersion; + MaemoDeviceConfig::DeviceType deviceType; + QString privateKeyFilePath; + QString publicKeyFilePath; +}; + +enum PageId { + StartPageId, PreviousKeySetupCheckPageId, ReuseKeysCheckPageId, + KeyCreationPageId, KeyDeploymentPageId, FinalTestPageId +}; + +class MaemoDeviceConfigWizardStartPage : public QWizardPage +{ + Q_OBJECT +public: + MaemoDeviceConfigWizardStartPage(QWidget *parent = 0) + : QWizardPage(parent), m_ui(new Ui::MaemoDeviceConfigWizardStartPage) + { + m_ui->setupUi(this); + m_ui->harmattanButton->setChecked(true); + m_ui->hwButton->setChecked(true); + QButtonGroup * const buttonGroup = new QButtonGroup(this); + buttonGroup->setExclusive(true); + buttonGroup->addButton(m_ui->hwButton); + buttonGroup->addButton(m_ui->qemuButton); + m_ui->nameLineEdit->setText(QLatin1String("(New Configuration)")); + connect(buttonGroup, SIGNAL(buttonClicked(int)), + SLOT(handleDeviceTypeChanged())); + handleDeviceTypeChanged(); + m_ui->hostNameLineEdit->setText(MaemoDeviceConfig::defaultHost(deviceType())); + connect(m_ui->nameLineEdit, SIGNAL(textChanged(QString)), this, + SIGNAL(completeChanged())); + connect(m_ui->hostNameLineEdit, SIGNAL(textChanged(QString)), this, + SIGNAL(completeChanged())); + } + + virtual bool isComplete() const + { + return !configName().isEmpty() && !hostName().isEmpty(); + } + + QString configName() const { return m_ui->nameLineEdit->text().trimmed(); } + + QString hostName() const + { + return deviceType() == MaemoDeviceConfig::Simulator + ? MaemoDeviceConfig::defaultHost(MaemoDeviceConfig::Simulator) + : m_ui->hostNameLineEdit->text().trimmed(); + } + + MaemoGlobal::MaemoVersion maemoVersion() const + { + return m_ui->fremantleButton->isChecked() ? MaemoGlobal::Maemo5 + : m_ui->harmattanButton->isChecked() ? MaemoGlobal::Maemo6 + : MaemoGlobal::Meego; + } + + MaemoDeviceConfig::DeviceType deviceType() const + { + return m_ui->hwButton->isChecked() + ? MaemoDeviceConfig::Physical : MaemoDeviceConfig::Simulator; + } + +private slots: + void handleDeviceTypeChanged() + { + const bool enable = deviceType() == MaemoDeviceConfig::Physical; + m_ui->hostNameLabel->setEnabled(enable); + m_ui->hostNameLineEdit->setEnabled(enable); + } + +private: + const QScopedPointer m_ui; +}; + +class MaemoDeviceConfigWizardPreviousKeySetupCheckPage : public QWizardPage +{ + Q_OBJECT +public: + MaemoDeviceConfigWizardPreviousKeySetupCheckPage(QWidget *parent) + : QWizardPage(parent), + m_ui(new Ui::MaemoDeviceConfigWizardCheckPreviousKeySetupPage) + { + m_ui->setupUi(this); + m_ui->keyWasNotSetUpButton->setChecked(true); + QButtonGroup * const buttonGroup = new QButtonGroup(this); + buttonGroup->setExclusive(true); + buttonGroup->addButton(m_ui->keyWasSetUpButton); + buttonGroup->addButton(m_ui->keyWasNotSetUpButton); + connect(buttonGroup, SIGNAL(buttonClicked(int)), + SLOT(handleSelectionChanged())); + handleSelectionChanged(); + connect(m_ui->privateKeyFilePathLineEdit, SIGNAL(textChanged(QString)), + this, SIGNAL(completeChanged())); + } + + virtual bool isComplete() const { + return !keyBasedLoginWasSetup() || !privateKeyFilePath().isEmpty(); + } + + bool keyBasedLoginWasSetup() const { + return m_ui->keyWasSetUpButton->isChecked(); + } + + QString privateKeyFilePath() const { + return m_ui->privateKeyFilePathLineEdit->text().trimmed(); + } + +private: + Q_SLOT void handleSelectionChanged() + { + m_ui->privateKeyFilePathLineEdit->setEnabled(keyBasedLoginWasSetup()); + emit completeChanged(); + } + + const QScopedPointer m_ui; +}; + +class MaemoDeviceConfigWizardReuseKeysCheckPage : public QWizardPage +{ + Q_OBJECT +public: + MaemoDeviceConfigWizardReuseKeysCheckPage(QWidget *parent) + : QWizardPage(parent), + m_ui(new Ui::MaemoDeviceConfigWizardReuseKeysCheckPage) + { + m_ui->setupUi(this); + m_ui->dontReuseButton->setChecked(true); + QButtonGroup * const buttonGroup = new QButtonGroup(this); + buttonGroup->setExclusive(true); + buttonGroup->addButton(m_ui->reuseButton); + buttonGroup->addButton(m_ui->dontReuseButton); + connect(buttonGroup, SIGNAL(buttonClicked(int)), + SLOT(handleSelectionChanged())); + handleSelectionChanged(); + connect(m_ui->privateKeyFilePathLineEdit, SIGNAL(textChanged(QString)), + this, SIGNAL(completeChanged())); + connect(m_ui->publicKeyFilePathLineEdit, SIGNAL(textChanged(QString)), + this, SIGNAL(completeChanged())); + } + + virtual bool isComplete() + { + return !reuseKeys() || (!privateKeyFilePath().isEmpty() + && !publicKeyFilePath().isEmpty()); + } + + bool reuseKeys() const { return m_ui->reuseButton->isChecked(); } + QString privateKeyFilePath() const { + return m_ui->privateKeyFilePathLineEdit->text().trimmed(); + } + QString publicKeyFilePath() const { + return m_ui->publicKeyFilePathLineEdit->text().trimmed(); + } + +private: + Q_SLOT void handleSelectionChanged() + { + m_ui->privateKeyFilePathLabel->setEnabled(reuseKeys()); + m_ui->privateKeyFilePathLineEdit->setEnabled(reuseKeys()); + m_ui->publicKeyFilePathLabel->setEnabled(reuseKeys()); + m_ui->publicKeyFilePathLineEdit->setEnabled(reuseKeys()); + emit completeChanged(); + } + + const QScopedPointer m_ui; +}; + +class MaemoDeviceConfigWizardKeyCreationPage : public QWizardPage +{ + Q_OBJECT +public: + MaemoDeviceConfigWizardKeyCreationPage(QWidget *parent) + : QWizardPage(parent), + m_ui(new Ui::MaemoDeviceConfigWizardKeyCreationPage), + m_isComplete(false) + { + m_ui->setupUi(this); + const QString &homeDir + = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); + m_ui->directoryLineEdit->setText(homeDir); + connect(m_ui->directoryLineEdit, SIGNAL(textChanged(QString)), + SLOT(enableOrDisableButton())); + } + + QString privateKeyFilePath() const { + return m_ui->directoryLineEdit->text() + QLatin1String("/qtc_id_rsa"); + } + + QString publicKeyFilePath() const { + return privateKeyFilePath() + QLatin1String(".pub"); + } + + virtual bool isComplete() const { return m_isComplete; } + +private: + Q_SLOT void enableOrDisableButton() + { + const QString &dir = m_ui->directoryLineEdit->text().trimmed(); + m_ui->createKeysButton->setEnabled(!dir.isEmpty()); + } + + Q_SLOT void createKeys() + { + const QString &dirName = m_ui->directoryLineEdit->text(); + QDir dir(dirName); + if (!dir.exists() || !QFileInfo(dirName).isWritable()) { + QMessageBox::critical(this, tr("Can't Create Keys"), + tr("You have not entered a writable directory.")); + return; + } + + m_ui->directoryLineEdit->setEnabled(false); + m_ui->createKeysButton->setEnabled(false); + Core::SshKeyGenerator keyGenerator; + if (!keyGenerator.generateKeys(Core::SshKeyGenerator::Rsa, + Core::SshKeyGenerator::OpenSsl, 1024)) { + QMessageBox::critical(this, tr("Can't Create Keys"), + tr("Key creation failed: %1").arg(keyGenerator.error())); + m_ui->directoryLineEdit->setEnabled(true); + m_ui->createKeysButton->setEnabled(true); + return; + } + + if (!saveFile(privateKeyFilePath(), keyGenerator.privateKey()) + || !saveFile(publicKeyFilePath(), keyGenerator.publicKey())) { + m_ui->directoryLineEdit->setEnabled(true); + m_ui->createKeysButton->setEnabled(true); + return; + } + + m_isComplete = true; + emit completeChanged(); + } + + bool saveFile(const QString &filePath, const QByteArray &data) + { + QFile file(filePath); + const bool canOpen = file.open(QIODevice::WriteOnly); + if (canOpen) + file.write(data); + if (!canOpen || file.error() != QFile::NoError) { + QMessageBox::critical(this, tr("Could Not Save File"), + tr("Failed to save key file %1: %1").arg(filePath, file.errorString())); + return false; + } + return true; + } + + const QScopedPointer m_ui; + bool m_isComplete; +}; + +} // anonymous namespace + +struct MaemoDeviceConfigWizardPrivate +{ + MaemoDeviceConfigWizardPrivate(QWidget *parent) + : startPage(parent), + previousKeySetupPage(parent), + reuseKeysCheckPage(parent), + keyCreationPage(parent) + { + } + + WizardData wizardData; + MaemoDeviceConfigWizardStartPage startPage; + MaemoDeviceConfigWizardPreviousKeySetupCheckPage previousKeySetupPage; + MaemoDeviceConfigWizardReuseKeysCheckPage reuseKeysCheckPage; + MaemoDeviceConfigWizardKeyCreationPage keyCreationPage; +}; + + +MaemoDeviceConfigWizard::MaemoDeviceConfigWizard(QWidget *parent) : + QWizard(parent), d(new MaemoDeviceConfigWizardPrivate(this)) +{ + setPage(StartPageId, &d->startPage); + setPage(PreviousKeySetupCheckPageId, &d->previousKeySetupPage); + setPage(ReuseKeysCheckPageId, &d->reuseKeysCheckPage); + setPage(KeyCreationPageId, &d->keyCreationPage); +} + +MaemoDeviceConfigWizard::~MaemoDeviceConfigWizard() {} + +int MaemoDeviceConfigWizard::nextId() const +{ + switch (currentId()) { + case StartPageId: + // TODO: Make unique (needs list of devices) + d->wizardData.configName = d->startPage.configName(); + + d->wizardData.maemoVersion = d->startPage.maemoVersion(); + d->wizardData.deviceType = d->startPage.deviceType(); + d->wizardData.hostName = d->startPage.hostName(); + + // TODO: Different paths for Qemu/HW? + return PreviousKeySetupCheckPageId; + case PreviousKeySetupCheckPageId: + if (d->previousKeySetupPage.keyBasedLoginWasSetup()) { + d->wizardData.privateKeyFilePath + = d->previousKeySetupPage.privateKeyFilePath(); + return FinalTestPageId; + } else { + return ReuseKeysCheckPageId; + } + case ReuseKeysCheckPageId: + if (d->reuseKeysCheckPage.reuseKeys()) { + d->wizardData.privateKeyFilePath + = d->reuseKeysCheckPage.privateKeyFilePath(); + d->wizardData.publicKeyFilePath + = d->reuseKeysCheckPage.publicKeyFilePath(); + return KeyDeploymentPageId; + } else { + return KeyCreationPageId; + } + case KeyCreationPageId: + d->wizardData.privateKeyFilePath + = d->keyCreationPage.privateKeyFilePath(); + d->wizardData.publicKeyFilePath + = d->keyCreationPage.publicKeyFilePath(); + return KeyDeploymentPageId; + case KeyDeploymentPageId: return FinalTestPageId; + case FinalTestPageId: return -1; + default: + Q_ASSERT(false); + return -1; + } +} + +} // namespace Internal +} // namespace Qt4ProjectManager + +#include "maemodeviceconfigwizard.moc" diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizard.h b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizard.h new file mode 100644 index 00000000000..dd08b3fcfef --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizard.h @@ -0,0 +1,29 @@ +#ifndef MAEMODEVICECONFIGWIZARD_H +#define MAEMODEVICECONFIGWIZARD_H + +#include +#include +#include + +namespace Qt4ProjectManager { +namespace Internal { +class MaemoDeviceConfig; +struct MaemoDeviceConfigWizardPrivate; + +class MaemoDeviceConfigWizard : public QWizard +{ + Q_OBJECT +public: + explicit MaemoDeviceConfigWizard(QWidget *parent = 0); + ~MaemoDeviceConfigWizard(); + QSharedPointer deviceConfig() const; + virtual int nextId() const; + +private: + const QScopedPointer d; +}; + +} // namespace Internal +} // namespace Qt4ProjectManager + +#endif // MAEMODEVICECONFIGWIZARD_H diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardkeycreationpage.ui b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardkeycreationpage.ui new file mode 100644 index 00000000000..8c96eb1bc17 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardkeycreationpage.ui @@ -0,0 +1,65 @@ + + + MaemoDeviceConfigWizardKeyCreationPage + + + + 0 + 0 + 375 + 118 + + + + WizardPage + + + + + + Qt Creator will now generate a new pair of keys. Please enter the directory to save the key files in and then press "Create Keys". + + + true + + + + + + + + + Directory: + + + + + + + + + + Create Keys + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardpreviouskeysetupcheckpage.ui b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardpreviouskeysetupcheckpage.ui new file mode 100644 index 00000000000..57e3582130b --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardpreviouskeysetupcheckpage.ui @@ -0,0 +1,86 @@ + + + MaemoDeviceConfigWizardCheckPreviousKeySetupPage + + + + 0 + 0 + 377 + 155 + + + + WizardPage + + + + + + Has a passwordless (key-based) login already been set up for this device? + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Yes, and the private key is located at + + + + + + + + + + + + No + + + + + + + + + + + Qt::Vertical + + + + 20 + 44 + + + + + + + + + diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardreusekeyscheckpage.ui b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardreusekeyscheckpage.ui new file mode 100644 index 00000000000..59821bdb3b9 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardreusekeyscheckpage.ui @@ -0,0 +1,120 @@ + + + MaemoDeviceConfigWizardReuseKeysCheckPage + + + + 0 + 0 + 370 + 188 + + + + WizardPage + + + + + + Do wou want to re-use an existing pair of keys or should a new one be created? + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Re-use existing keys + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + File containing the public key: + + + + + + + + + + File containing the private key: + + + + + + + + + + + + + + Create new keys + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardstartpage.ui b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardstartpage.ui new file mode 100644 index 00000000000..8ca9b6ed6aa --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigwizardstartpage.ui @@ -0,0 +1,98 @@ + + + MaemoDeviceConfigWizardStartPage + + + + 0 + 0 + 618 + 122 + + + + WizardPage + + + + + + The name to identify this configuration: + + + + + + + + + + The system running on the device: + + + + + + + + + Maemo 5 (Fremantle) + + + + + + + Maemo 6 (Harmattan) + + + + + + + Meego + + + + + + + + + The kind of device: + + + + + + + + + Emulator (Qemu) + + + + + + + Hardware Device + + + + + + + + + The device's host name or IP address: + + + + + + + + + + + diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri index 68304b40210..5f38c7cf34d 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri +++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri @@ -46,7 +46,8 @@ HEADERS += \ $$PWD/maemoqemusettings.h \ $$PWD/qt4maemotargetfactory.h \ $$PWD/qt4maemotarget.h \ - $$PWD/qt4maemodeployconfiguration.h + $$PWD/qt4maemodeployconfiguration.h \ + $$PWD/maemodeviceconfigwizard.h SOURCES += \ $$PWD/maemoconfigtestdialog.cpp \ @@ -93,7 +94,8 @@ SOURCES += \ $$PWD/maemoqemusettings.cpp \ $$PWD/qt4maemotargetfactory.cpp \ $$PWD/qt4maemotarget.cpp \ - $$PWD/qt4maemodeployconfiguration.cpp + $$PWD/qt4maemodeployconfiguration.cpp \ + $$PWD/maemodeviceconfigwizard.cpp FORMS += \ $$PWD/maemoconfigtestdialog.ui \ @@ -107,6 +109,10 @@ FORMS += \ $$PWD/maemopublishingfileselectiondialog.ui \ $$PWD/maemopublishinguploadsettingspagefremantlefree.ui \ $$PWD/maemopublishingresultpagefremantlefree.ui \ - $$PWD/maemoqemusettingswidget.ui + $$PWD/maemoqemusettingswidget.ui \ + $$PWD/maemodeviceconfigwizardstartpage.ui \ + $$PWD/maemodeviceconfigwizardpreviouskeysetupcheckpage.ui \ + $$PWD/maemodeviceconfigwizardreusekeyscheckpage.ui \ + $$PWD/maemodeviceconfigwizardkeycreationpage.ui RESOURCES += $$PWD/qt-maemo.qrc