diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationfactory.cpp b/src/plugins/remotelinux/genericlinuxdeviceconfigurationfactory.cpp new file mode 100644 index 00000000000..b0d7f94fbd6 --- /dev/null +++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationfactory.cpp @@ -0,0 +1,99 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "genericlinuxdeviceconfigurationfactory.h" + +#include "genericlinuxdeviceconfigurationwizard.h" +#include "maemoconfigtestdialog.h" +#include "maemoremoteprocessesdialog.h" +#include "publickeydeploymentdialog.h" + +namespace RemoteLinux { +namespace Internal { +namespace { +const char * const TestDeviceActionId = "TestDeviceAction"; +const char * const DeployKeyToDeviceActionId = "DeployKeyToDeviceAction"; +const char * const RemoteProcessesActionId = "RemoteProcessesAction"; +} // anonymous namespace; + +GenericLinuxDeviceConfigurationFactory::GenericLinuxDeviceConfigurationFactory(QObject *parent) + : ILinuxDeviceConfigurationFactory(parent) +{ +} + +QString GenericLinuxDeviceConfigurationFactory::displayName() const +{ + return tr("Generic Linux Devices"); +} + +ILinuxDeviceConfigurationWizard *GenericLinuxDeviceConfigurationFactory::createWizard(QWidget *parent) const +{ + return new GenericLinuxDeviceConfigurationWizard(parent); +} + +bool GenericLinuxDeviceConfigurationFactory::supportsOsType(const QString &osType) const +{ + return osType == LinuxDeviceConfiguration::GenericLinuxOsType; +} + +QStringList GenericLinuxDeviceConfigurationFactory::supportedDeviceActionIds() const +{ + return QStringList() << QLatin1String(TestDeviceActionId) + << QLatin1String(DeployKeyToDeviceActionId) << QLatin1String(RemoteProcessesActionId); +} + +QString GenericLinuxDeviceConfigurationFactory::displayNameForId(const QString &actionId) const +{ + Q_ASSERT(supportedDeviceActionIds().contains(actionId)); + if (actionId == QLatin1String(TestDeviceActionId)) + return tr("Test"); + if (actionId == QLatin1String(RemoteProcessesActionId)) + return tr("Remote Processes"); + if (actionId == QLatin1String(DeployKeyToDeviceActionId)) + return tr("Deploy Public Key"); + return QString(); // Can't happen. +} + +QDialog *GenericLinuxDeviceConfigurationFactory::createDeviceAction(const QString &actionId, + const LinuxDeviceConfiguration::ConstPtr &deviceConfig, QWidget *parent) const +{ + Q_ASSERT(supportedDeviceActionIds().contains(actionId)); + if (actionId == QLatin1String(TestDeviceActionId)) + return new MaemoConfigTestDialog(deviceConfig, parent); + if (actionId == QLatin1String(RemoteProcessesActionId)) + return new MaemoRemoteProcessesDialog(deviceConfig, parent); + if (actionId == QLatin1String(DeployKeyToDeviceActionId)) + return new PublicKeyDeploymentDialog(deviceConfig, parent); + return 0; // Can't happen. +} + +} // namespace Internal +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationfactory.h b/src/plugins/remotelinux/genericlinuxdeviceconfigurationfactory.h new file mode 100644 index 00000000000..f04e610cd6c --- /dev/null +++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationfactory.h @@ -0,0 +1,59 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#ifndef GENERICLINUXDEVICECONFIGURATIONFACTORY_H +#define GENERICLINUXDEVICECONFIGURATIONFACTORY_H + +#include "linuxdeviceconfiguration.h" + +namespace RemoteLinux { +namespace Internal { + +class GenericLinuxDeviceConfigurationFactory : public ILinuxDeviceConfigurationFactory +{ + Q_OBJECT + Q_DISABLE_COPY(GenericLinuxDeviceConfigurationFactory) +public: + GenericLinuxDeviceConfigurationFactory(QObject *parent = 0); + + QString displayName() const; + ILinuxDeviceConfigurationWizard *createWizard(QWidget *parent) const; + bool supportsOsType(const QString &osType) const; + QStringList supportedDeviceActionIds() const; + QString displayNameForId(const QString &actionId) const; + QDialog *createDeviceAction(const QString &actionId, + const LinuxDeviceConfiguration::ConstPtr &deviceConfig, QWidget *parent) const; +}; + +} // namespace Internal +} // namespace RemoteLinux + +#endif // GENERICLINUXDEVICECONFIGURATIONFACTORY_H diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp new file mode 100644 index 00000000000..6f3002430d2 --- /dev/null +++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp @@ -0,0 +1,121 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "genericlinuxdeviceconfigurationwizard.h" + +#include "genericlinuxdeviceconfigurationwizardsetuppage.h" +#include "maemoconfigtestdialog.h" + +#include +#include + +using namespace Utils; + +namespace RemoteLinux { +namespace Internal { +namespace { + +enum PageId { SetupPageId, FinalPageId }; + +class GenericLinuxDeviceConfigurationWizardFinalPage : public QWizardPage +{ + Q_OBJECT +public: + GenericLinuxDeviceConfigurationWizardFinalPage(QWidget *parent) + : QWizardPage(parent), m_infoLabel(new QLabel(this)) + { + setTitle(tr("Setup Finished")); + setSubTitle(QLatin1String(" ")); // For Qt bug (background color) + m_infoLabel->setWordWrap(true); + QVBoxLayout * const layout = new QVBoxLayout(this); + layout->addWidget(m_infoLabel); + } + + virtual void initializePage() + { + const QString infoText = tr("The new device configuration will now be " + "created. In addition, a test procedure will be run to check whether " + "Qt Creator can connect to the device and to provide some information about it."); + m_infoLabel->setText(infoText); + } + +private: + QLabel * const m_infoLabel; +}; + +} // anonymous namespace + +class GenericLinuxDeviceConfigurationWizardPrivate +{ +public: + GenericLinuxDeviceConfigurationWizardPrivate(QWidget *parent) + : setupPage(parent), finalPage(parent) + { + } + + GenericLinuxDeviceConfigurationWizardSetupPage setupPage; + GenericLinuxDeviceConfigurationWizardFinalPage finalPage; +}; +} // namespace Internal + +GenericLinuxDeviceConfigurationWizard::GenericLinuxDeviceConfigurationWizard(QWidget *parent) + : ILinuxDeviceConfigurationWizard(parent), + m_d(new Internal::GenericLinuxDeviceConfigurationWizardPrivate(this)) +{ + setWindowTitle(tr("New Generic Linux Device Configuration Setup")); + setPage(Internal::SetupPageId, &m_d->setupPage); + setPage(Internal::FinalPageId, &m_d->finalPage); + m_d->finalPage.setCommitPage(true); +} + +GenericLinuxDeviceConfigurationWizard::~GenericLinuxDeviceConfigurationWizard() +{ + delete m_d; +} + +LinuxDeviceConfiguration::Ptr GenericLinuxDeviceConfigurationWizard::deviceConfiguration() +{ + LinuxDeviceConfiguration::Ptr devConf; + if (m_d->setupPage.authenticationType() == SshConnectionParameters::AuthenticationByPassword) { + devConf = LinuxDeviceConfiguration::createGenericLinuxConfigUsingPassword(m_d->setupPage.configurationName(), + m_d->setupPage.hostName(), m_d->setupPage.userName(), m_d->setupPage.password()); + } else { + devConf = LinuxDeviceConfiguration::createGenericLinuxConfigUsingKey(m_d->setupPage.configurationName(), + m_d->setupPage.hostName(), m_d->setupPage.userName(), m_d->setupPage.privateKeyFilePath()); + } + + Internal::MaemoConfigTestDialog dlg(devConf, this); + dlg.exec(); + return devConf; +} + +} // namespace RemoteLinux + +#include "genericlinuxdeviceconfigurationwizard.moc" diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.h b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.h new file mode 100644 index 00000000000..d639dd2552a --- /dev/null +++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.h @@ -0,0 +1,58 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#ifndef GENERICLINUXDEVICECONFIGURATIONWIZARD_H +#define GENERICLINUXDEVICECONFIGURATIONWIZARD_H + +#include "linuxdeviceconfiguration.h" + +namespace RemoteLinux { +namespace Internal { +class GenericLinuxDeviceConfigurationWizardPrivate; +} // namespace Internal + +class REMOTELINUX_EXPORT GenericLinuxDeviceConfigurationWizard + : public ILinuxDeviceConfigurationWizard +{ + Q_OBJECT + Q_DISABLE_COPY(GenericLinuxDeviceConfigurationWizard) +public: + GenericLinuxDeviceConfigurationWizard(QWidget *parent = 0); + ~GenericLinuxDeviceConfigurationWizard(); + + LinuxDeviceConfiguration::Ptr deviceConfiguration(); + +private: + Internal::GenericLinuxDeviceConfigurationWizardPrivate * const m_d; +}; + +} // namespace RemoteLinux + +#endif // GENERICLINUXDEVICECONFIGURATIONWIZARD_H diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardsetuppage.cpp b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardsetuppage.cpp new file mode 100644 index 00000000000..a9396ae60e3 --- /dev/null +++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardsetuppage.cpp @@ -0,0 +1,135 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "genericlinuxdeviceconfigurationwizardsetuppage.h" +#include "ui_genericlinuxdeviceconfigurationwizardsetuppage.h" + +#include "linuxdeviceconfiguration.h" + +namespace RemoteLinux { +namespace Internal { + +class GenericLinuxDeviceConfigurationWizardSetupPagePrivate +{ +public: + Ui::GenericLinuxDeviceConfigurationWizardSetupPage ui; +}; + +} // namespace Internal + +using namespace Utils; + +GenericLinuxDeviceConfigurationWizardSetupPage::GenericLinuxDeviceConfigurationWizardSetupPage(QWidget *parent) : + QWizardPage(parent), m_d(new Internal::GenericLinuxDeviceConfigurationWizardSetupPagePrivate) +{ + m_d->ui.setupUi(this); + setTitle(tr("Connection Data")); + setSubTitle(QLatin1String(" ")); // For Qt bug (background color) + m_d->ui.privateKeyPathChooser->setExpectedKind(PathChooser::File); + connect(m_d->ui.nameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged())); + connect(m_d->ui.hostNameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged())); + connect(m_d->ui.userNameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged())); + connect(m_d->ui.privateKeyPathChooser, SIGNAL(validChanged()), SIGNAL(completeChanged())); + connect(m_d->ui.passwordButton, SIGNAL(toggled(bool)), SLOT(handleAuthTypeChanged())); +} + +GenericLinuxDeviceConfigurationWizardSetupPage::~GenericLinuxDeviceConfigurationWizardSetupPage() +{ + delete m_d; +} + +void GenericLinuxDeviceConfigurationWizardSetupPage::initializePage() +{ + m_d->ui.nameLineEdit->setText(QLatin1String("(New Configuration)")); + m_d->ui.hostNameLineEdit->setText(defaultHostName()); + m_d->ui.userNameLineEdit->setText(defaultUserName()); + m_d->ui.passwordButton->setChecked(true); + m_d->ui.passwordLineEdit->clear(); + m_d->ui.privateKeyPathChooser->setPath(LinuxDeviceConfiguration::defaultPrivateKeyFilePath()); + handleAuthTypeChanged(); +} + +bool GenericLinuxDeviceConfigurationWizardSetupPage::isComplete() const +{ + return !configurationName().isEmpty() && !hostName().isEmpty() && !userName().isEmpty() + && (authenticationType() == SshConnectionParameters::AuthenticationByPassword + || !m_d->ui.privateKeyPathChooser->isValid()); +} + +QString GenericLinuxDeviceConfigurationWizardSetupPage::configurationName() const +{ + return m_d->ui.nameLineEdit->text().trimmed(); +} + +QString GenericLinuxDeviceConfigurationWizardSetupPage::hostName() const +{ + return m_d->ui.hostNameLineEdit->text().trimmed(); +} + +QString GenericLinuxDeviceConfigurationWizardSetupPage::userName() const +{ + return m_d->ui.userNameLineEdit->text().trimmed(); +} + +SshConnectionParameters::AuthenticationType GenericLinuxDeviceConfigurationWizardSetupPage::authenticationType() const +{ + return m_d->ui.passwordButton->isChecked() + ? SshConnectionParameters::AuthenticationByPassword + : SshConnectionParameters::AuthenticationByKey; +} + +QString GenericLinuxDeviceConfigurationWizardSetupPage::password() const +{ + return m_d->ui.passwordLineEdit->text(); +} + +QString GenericLinuxDeviceConfigurationWizardSetupPage::privateKeyFilePath() const +{ + return m_d->ui.privateKeyPathChooser->path(); +} + +QString GenericLinuxDeviceConfigurationWizardSetupPage::defaultHostName() const +{ + return QString(); +} + +QString GenericLinuxDeviceConfigurationWizardSetupPage::defaultUserName() const +{ + return QString(); +} + +void GenericLinuxDeviceConfigurationWizardSetupPage::handleAuthTypeChanged() +{ + m_d->ui.passwordLineEdit->setEnabled(authenticationType() == SshConnectionParameters::AuthenticationByPassword); + m_d->ui.privateKeyPathChooser->setEnabled(authenticationType() == SshConnectionParameters::AuthenticationByKey); + emit completeChanged(); +} + +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardsetuppage.h b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardsetuppage.h new file mode 100644 index 00000000000..dd44f4677fb --- /dev/null +++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardsetuppage.h @@ -0,0 +1,75 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#ifndef GENERICLINUXDEVICECONFIGURATIONWIZARDSETUPPAGE_H +#define GENERICLINUXDEVICECONFIGURATIONWIZARDSETUPPAGE_H + +#include "remotelinux_export.h" + +#include + +#include + +namespace RemoteLinux { +namespace Internal { +class GenericLinuxDeviceConfigurationWizardSetupPagePrivate; +} // namespace Internal + +class REMOTELINUX_EXPORT GenericLinuxDeviceConfigurationWizardSetupPage : public QWizardPage +{ + Q_OBJECT + Q_DISABLE_COPY(GenericLinuxDeviceConfigurationWizardSetupPage) + +public: + explicit GenericLinuxDeviceConfigurationWizardSetupPage(QWidget *parent = 0); + ~GenericLinuxDeviceConfigurationWizardSetupPage(); + + void initializePage(); + bool isComplete() const; + + QString configurationName() const; + QString hostName() const; + QString userName() const; + Utils::SshConnectionParameters::AuthenticationType authenticationType() const; + QString password() const; + QString privateKeyFilePath() const; + + virtual QString defaultHostName() const; + virtual QString defaultUserName() const; + +private: + Q_SLOT void handleAuthTypeChanged(); + + Internal::GenericLinuxDeviceConfigurationWizardSetupPagePrivate * const m_d; +}; + +} // namespace RemoteLinux + +#endif // GENERICLINUXDEVICECONFIGURATIONWIZARDSETUPPAGE_H diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardsetuppage.ui b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardsetuppage.ui new file mode 100644 index 00000000000..c2638dc9ce3 --- /dev/null +++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizardsetuppage.ui @@ -0,0 +1,210 @@ + + + GenericLinuxDeviceConfigurationWizardSetupPage + + + + 0 + 0 + 542 + 201 + + + + WizardPage + + + + + + The name to identify this configuration: + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + The device's host name or IP address: + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + User name: + + + + + + + + + + + + Qt::Horizontal + + + + 153 + 21 + + + + + + + + + + Authentication type: + + + + + + + + + Password + + + + + + + Key + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Password: + + + + + + + + + QLineEdit::Password + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Private key: + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Utils::PathChooser + QWidget +
utils/pathchooser.h
+ 1 + + editingFinished() + browsingFinished() + +
+
+ + +
diff --git a/src/plugins/remotelinux/linuxdeviceconfiguration.h b/src/plugins/remotelinux/linuxdeviceconfiguration.h index 897ad2e9be8..68615fec4fa 100644 --- a/src/plugins/remotelinux/linuxdeviceconfiguration.h +++ b/src/plugins/remotelinux/linuxdeviceconfiguration.h @@ -90,11 +90,11 @@ public: QString name() const { return m_name; } void setName(const QString &name) { m_name = name; } QString osType() const { return m_osType; } + QString osTypeDisplayName() const { return m_osTypeDisplayName; } DeviceType type() const { return m_type; } QString portsSpec() const { return m_portsSpec; } Id internalId() const { return m_internalId; } bool isDefault() const { return m_isDefault; } - QString displayName() const { return m_displayName; } static QString portsRegExpr(); static QString defaultHost(DeviceType type, const QString &osType); @@ -135,7 +135,7 @@ private: DeviceType m_type; QString m_portsSpec; bool m_isDefault; - QString m_displayName; + QString m_osTypeDisplayName; Id m_internalId; }; diff --git a/src/plugins/remotelinux/linuxdeviceconfigurations.cpp b/src/plugins/remotelinux/linuxdeviceconfigurations.cpp index 5c31d625095..d19c685e6bd 100644 --- a/src/plugins/remotelinux/linuxdeviceconfigurations.cpp +++ b/src/plugins/remotelinux/linuxdeviceconfigurations.cpp @@ -120,6 +120,17 @@ void LinuxDeviceConfigurations::save() void LinuxDeviceConfigurations::addConfiguration(const LinuxDeviceConfiguration::Ptr &devConfig) { + // Ensure uniqueness of name. + QString name = devConfig->name(); + if (hasConfig(name)) { + const QString nameTemplate = name + QLatin1String(" (%1)"); + int suffix = 2; + do + name = nameTemplate.arg(QString::number(suffix++)); + while (hasConfig(name)); + } + devConfig->m_name = name; + devConfig->m_internalId = m_nextId++; beginInsertRows(QModelIndex(), rowCount(), rowCount()); if (!defaultDeviceConfig(devConfig->osType())) diff --git a/src/plugins/remotelinux/linuxdevicefactoryselectiondialog.ui b/src/plugins/remotelinux/linuxdevicefactoryselectiondialog.ui index 59c137654d7..c407003f1ba 100644 --- a/src/plugins/remotelinux/linuxdevicefactoryselectiondialog.ui +++ b/src/plugins/remotelinux/linuxdevicefactoryselectiondialog.ui @@ -6,12 +6,12 @@ 0 0 - 276 - 324 + 414 + 331 - Publishing Wizard Selection + Device Configuration Wizard Selection @@ -22,7 +22,14 @@ - + + + QListView::Adjust + + + true + + diff --git a/src/plugins/remotelinux/maddedeviceconfigurationfactory.cpp b/src/plugins/remotelinux/maddedeviceconfigurationfactory.cpp new file mode 100644 index 00000000000..a160da28b84 --- /dev/null +++ b/src/plugins/remotelinux/maddedeviceconfigurationfactory.cpp @@ -0,0 +1,62 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "maddedeviceconfigurationfactory.h" + +#include "maemodeviceconfigwizard.h" + +namespace RemoteLinux { +namespace Internal { + +MaddeDeviceConfigurationFactory::MaddeDeviceConfigurationFactory(QObject *parent) + : GenericLinuxDeviceConfigurationFactory(parent) +{ +} + +QString MaddeDeviceConfigurationFactory::displayName() const +{ + return tr("Devices with MADDE support (Fremantle, Harmattan, MeeGo)"); +} + +ILinuxDeviceConfigurationWizard *MaddeDeviceConfigurationFactory::createWizard(QWidget *parent) const +{ + return new MaemoDeviceConfigWizard(parent); +} + +bool MaddeDeviceConfigurationFactory::supportsOsType(const QString &osType) const +{ + return osType == LinuxDeviceConfiguration::Maemo5OsType + || osType == LinuxDeviceConfiguration::HarmattanOsType + || osType == LinuxDeviceConfiguration::MeeGoOsType; +} + +} // namespace Internal +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/maddedeviceconfigurationfactory.h b/src/plugins/remotelinux/maddedeviceconfigurationfactory.h new file mode 100644 index 00000000000..a7a183d7214 --- /dev/null +++ b/src/plugins/remotelinux/maddedeviceconfigurationfactory.h @@ -0,0 +1,53 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#ifndef MADDEDEVICECONFIGURATIONFACTORY_H +#define MADDEDEVICECONFIGURATIONFACTORY_H + +#include "genericlinuxdeviceconfigurationfactory.h" + +namespace RemoteLinux { +namespace Internal { + +class MaddeDeviceConfigurationFactory : public GenericLinuxDeviceConfigurationFactory +{ +public: + MaddeDeviceConfigurationFactory(QObject *parent = 0); + + QString displayName() const; + ILinuxDeviceConfigurationWizard *createWizard(QWidget *parent) const; + bool supportsOsType(const QString &osType) const; +}; + +} // namespace Internal +} // namespace RemoteLinux + +#endif // MADDEDEVICECONFIGURATIONFACTORY_H diff --git a/src/plugins/remotelinux/maemoconstants.h b/src/plugins/remotelinux/maemoconstants.h index acada157ed6..e7309f40fe0 100644 --- a/src/plugins/remotelinux/maemoconstants.h +++ b/src/plugins/remotelinux/maemoconstants.h @@ -59,7 +59,6 @@ static const QLatin1String ExportedLocalDirsKey(PREFIX ".ExportedLocalDirs"); static const QLatin1String RemoteMountPointsKey(PREFIX ".RemoteMountPoints"); static const QLatin1String BaseEnvironmentBaseKey(PREFIX ".BaseEnvironmentBase"); static const QLatin1String UserEnvironmentChangesKey(PREFIX ".UserEnvironmentChanges"); -static const QLatin1String UseRemoteGdbKey(PREFIX ".UseRemoteGdb"); } // namespace Internal diff --git a/src/plugins/remotelinux/maemodebugsupport.cpp b/src/plugins/remotelinux/maemodebugsupport.cpp index 358e7242363..b532775ec9a 100644 --- a/src/plugins/remotelinux/maemodebugsupport.cpp +++ b/src/plugins/remotelinux/maemodebugsupport.cpp @@ -31,259 +31,22 @@ #include "maemodebugsupport.h" -#include "maemodeployables.h" -#include "maemoglobal.h" #include "maemosshrunner.h" -#include "maemousedportsgatherer.h" -#include "qt4maemotarget.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(State, state, m_state) - -using namespace Utils; -using namespace Debugger; -using namespace ProjectExplorer; namespace RemoteLinux { namespace Internal { -RunControl *MaemoDebugSupport::createDebugRunControl(RemoteLinuxRunConfiguration *runConfig) +MaemoDebugSupport::MaemoDebugSupport(MaemoRunConfiguration *runConfig, Debugger::DebuggerEngine *engine) + : AbstractRemoteLinuxDebugSupport(runConfig, engine), + m_runner(new MaemoSshRunner(this, runConfig)) { - DebuggerStartParameters params; - const LinuxDeviceConfiguration::ConstPtr &devConf = runConfig->deviceConfig(); - - const RemoteLinuxRunConfiguration::DebuggingType debuggingType - = runConfig->debuggingType(); - if (debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) { - params.qmlServerAddress = runConfig->deviceConfig()->sshParameters().host; - params.qmlServerPort = -1; - } - if (debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) { - params.processArgs = runConfig->arguments(); - if (runConfig->activeQt4BuildConfiguration()->qtVersion()) - params.sysroot = runConfig->activeQt4BuildConfiguration()->qtVersion()->systemRoot(); - params.toolChainAbi = runConfig->abi(); - params.startMode = AttachToRemote; - params.executable = runConfig->localExecutableFilePath(); - params.debuggerCommand = runConfig->gdbCmd(); - params.remoteChannel = devConf->sshParameters().host + QLatin1String(":-1"); - params.useServerStartScript = true; - - // TODO: This functionality should be inside the debugger. - const ProjectExplorer::Abi &abi = runConfig->target() - ->activeBuildConfiguration()->toolChain()->targetAbi(); - params.remoteArchitecture = abi.toString(); - params.gnuTarget = QLatin1String(abi.architecture() == ProjectExplorer::Abi::ArmArchitecture - ? "arm-none-linux-gnueabi": "i386-unknown-linux-gnu"); - } else { - params.startMode = AttachToRemote; - } - params.displayName = runConfig->displayName(); - - if (const ProjectExplorer::Project *project = runConfig->target()->project()) { - params.projectSourceDirectory = project->projectDirectory(); - if (const ProjectExplorer::BuildConfiguration *buildConfig = runConfig->target()->activeBuildConfiguration()) { - params.projectBuildDirectory = buildConfig->buildDirectory(); - } - params.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); - } - - DebuggerRunControl * const runControl = - DebuggerPlugin::createDebugger(params, runConfig); - MaemoDebugSupport *debugSupport = - new MaemoDebugSupport(runConfig, runControl->engine()); - connect(runControl, SIGNAL(finished()), - debugSupport, SLOT(handleDebuggingFinished())); - return runControl; -} - -MaemoDebugSupport::MaemoDebugSupport(RemoteLinuxRunConfiguration *runConfig, DebuggerEngine *engine) - : QObject(engine), m_engine(engine), m_runConfig(runConfig), - m_deviceConfig(m_runConfig->deviceConfig()), - m_runner(new MaemoSshRunner(this, runConfig)), - m_debuggingType(runConfig->debuggingType()), - m_state(Inactive), m_gdbServerPort(-1), m_qmlPort(-1) -{ - connect(m_engine, SIGNAL(requestRemoteSetup()), this, - SLOT(handleAdapterSetupRequested())); } MaemoDebugSupport::~MaemoDebugSupport() { - setState(Inactive); } -void MaemoDebugSupport::showMessage(const QString &msg, int channel) -{ - if (m_engine) - m_engine->showMessage(msg, channel); -} - -void MaemoDebugSupport::handleAdapterSetupRequested() -{ - ASSERT_STATE(Inactive); - - setState(StartingRunner); - showMessage(tr("Preparing remote side ...\n"), AppStuff); - disconnect(m_runner, 0, this, 0); - connect(m_runner, SIGNAL(error(QString)), this, - SLOT(handleSshError(QString))); - connect(m_runner, SIGNAL(readyForExecution()), this, - SLOT(startExecution())); - connect(m_runner, SIGNAL(reportProgress(QString)), this, - SLOT(handleProgressReport(QString))); - m_runner->start(); -} - -void MaemoDebugSupport::handleSshError(const QString &error) -{ - if (m_state == Debugging) { - showMessage(error, AppError); - if (m_engine) - m_engine->notifyInferiorIll(); - } else if (m_state != Inactive) { - handleAdapterSetupFailed(error); - } -} - -void MaemoDebugSupport::startExecution() -{ - if (m_state == Inactive) - return; - - ASSERT_STATE(StartingRunner); - - if (m_debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) { - if (!setPort(m_gdbServerPort)) - return; - } - if (m_debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) { - if (!setPort(m_qmlPort)) - return; - } - - setState(StartingRemoteProcess); - m_gdbserverOutput.clear(); - connect(m_runner, SIGNAL(remoteErrorOutput(QByteArray)), this, - SLOT(handleRemoteErrorOutput(QByteArray))); - connect(m_runner, SIGNAL(remoteOutput(QByteArray)), this, - SLOT(handleRemoteOutput(QByteArray))); - if (m_debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly) { - connect(m_runner, SIGNAL(remoteProcessStarted()), - SLOT(handleRemoteProcessStarted())); - } - const QString &remoteExe = m_runner->remoteExecutable(); - QString args = m_runner->arguments(); - if (m_debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) { - args += QString(QLatin1String(" -qmljsdebugger=port:%1,block")) - .arg(m_qmlPort); - } - - const QString remoteCommandLine = m_debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly - ? QString::fromLocal8Bit("%1 %2 %3").arg(m_runner->commandPrefix()).arg(remoteExe).arg(args) - : QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4").arg(m_runner->commandPrefix()) - .arg(m_gdbServerPort).arg(remoteExe).arg(args); - connect(m_runner, SIGNAL(remoteProcessFinished(qint64)), - SLOT(handleRemoteProcessFinished(qint64))); - m_runner->startExecution(remoteCommandLine.toUtf8()); -} - -void MaemoDebugSupport::handleRemoteProcessFinished(qint64 exitCode) -{ - if (!m_engine || m_state == Inactive || exitCode == 0) - return; - - if (m_state == Debugging) { - if (m_debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) - m_engine->notifyInferiorIll(); - } else { - const QString errorMsg = m_debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly - ? tr("Remote application failed with exit code %1.").arg(exitCode) - : tr("The gdbserver process closed unexpectedly."); - m_engine->handleRemoteSetupFailed(errorMsg); - } -} - -void MaemoDebugSupport::handleDebuggingFinished() -{ - setState(Inactive); -} - -void MaemoDebugSupport::handleRemoteOutput(const QByteArray &output) -{ - ASSERT_STATE(QList() << Inactive << Debugging); - showMessage(QString::fromUtf8(output), AppOutput); -} - -void MaemoDebugSupport::handleRemoteErrorOutput(const QByteArray &output) -{ - ASSERT_STATE(QList() << Inactive << StartingRemoteProcess << Debugging); - - if (!m_engine) - return; - - showMessage(QString::fromUtf8(output), AppOutput); - if (m_state == StartingRemoteProcess - && m_debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) { - m_gdbserverOutput += output; - if (m_gdbserverOutput.contains("Listening on port")) { - handleAdapterSetupDone(); - m_gdbserverOutput.clear(); - } - } -} - -void MaemoDebugSupport::handleProgressReport(const QString &progressOutput) -{ - showMessage(progressOutput + QLatin1Char('\n'), AppStuff); -} - -void MaemoDebugSupport::handleAdapterSetupFailed(const QString &error) -{ - setState(Inactive); - m_engine->handleRemoteSetupFailed(tr("Initial setup failed: %1").arg(error)); -} - -void MaemoDebugSupport::handleAdapterSetupDone() -{ - setState(Debugging); - m_engine->handleRemoteSetupDone(m_gdbServerPort, m_qmlPort); -} - -void MaemoDebugSupport::handleRemoteProcessStarted() -{ - Q_ASSERT(m_debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly); - ASSERT_STATE(StartingRemoteProcess); - handleAdapterSetupDone(); -} - -void MaemoDebugSupport::setState(State newState) -{ - if (m_state == newState) - return; - m_state = newState; - if (m_state == Inactive) - m_runner->stop(); -} - -bool MaemoDebugSupport::setPort(int &port) -{ - port = m_runner->usedPortsGatherer()->getNextFreePort(m_runner->freePorts()); - if (port == -1) { - handleAdapterSetupFailed(tr("Not enough free ports on device for debugging.")); - return false; - } - return true; -} +RemoteLinuxApplicationRunner *MaemoDebugSupport::runner() const { return m_runner; } } // namespace Internal } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/maemodebugsupport.h b/src/plugins/remotelinux/maemodebugsupport.h index 8e73afecdee..1375d0f1817 100644 --- a/src/plugins/remotelinux/maemodebugsupport.h +++ b/src/plugins/remotelinux/maemodebugsupport.h @@ -32,65 +32,24 @@ #ifndef MAEMODEBUGSUPPORT_H #define MAEMODEBUGSUPPORT_H -#include "remotelinuxrunconfiguration.h" - -#include -#include -#include - -namespace Debugger { -class DebuggerEngine; -} -namespace ProjectExplorer { class RunControl; } +#include namespace RemoteLinux { -class LinuxDeviceConfiguration; -class RemoteLinuxRunConfiguration; - namespace Internal { +class MaemoRunConfiguration; class MaemoSshRunner; -class MaemoDebugSupport : public QObject +class MaemoDebugSupport : public AbstractRemoteLinuxDebugSupport { Q_OBJECT public: - static ProjectExplorer::RunControl *createDebugRunControl(RemoteLinuxRunConfiguration *runConfig); - - MaemoDebugSupport(RemoteLinuxRunConfiguration *runConfig, Debugger::DebuggerEngine *engine); + MaemoDebugSupport(MaemoRunConfiguration *runConfig, Debugger::DebuggerEngine *engine); ~MaemoDebugSupport(); -private slots: - void handleAdapterSetupRequested(); - void handleSshError(const QString &error); - void startExecution(); - void handleDebuggingFinished(); - void handleRemoteOutput(const QByteArray &output); - void handleRemoteErrorOutput(const QByteArray &output); - void handleProgressReport(const QString &progressOutput); - void handleRemoteProcessStarted(); - void handleRemoteProcessFinished(qint64 exitCode); - private: - enum State { - Inactive, StartingRunner, StartingRemoteProcess, Debugging - }; + RemoteLinuxApplicationRunner *runner() const; - void handleAdapterSetupFailed(const QString &error); - void handleAdapterSetupDone(); - void setState(State newState); - bool setPort(int &port); - void showMessage(const QString &msg, int channel); - - const QPointer m_engine; - const QPointer m_runConfig; - const QSharedPointer m_deviceConfig; MaemoSshRunner * const m_runner; - const RemoteLinuxRunConfiguration::DebuggingType m_debuggingType; - - QByteArray m_gdbserverOutput; - State m_state; - int m_gdbServerPort; - int m_qmlPort; }; } // namespace Internal diff --git a/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.cpp b/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.cpp index ff2cabe9ffa..05c6e5435d2 100644 --- a/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.cpp +++ b/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.cpp @@ -36,7 +36,6 @@ #include "linuxdeviceconfigurations.h" #include "linuxdevicefactoryselectiondialog.h" #include "maemoglobal.h" -#include "maemokeydeployer.h" #include "maemosshconfigdialog.h" #include @@ -102,15 +101,10 @@ MaemoDeviceConfigurationsSettingsWidget::MaemoDeviceConfigurationsSettingsWidget m_ui(new Ui_MaemoDeviceConfigurationsSettingsWidget), m_devConfigs(LinuxDeviceConfigurations::cloneInstance()), m_nameValidator(new NameValidator(m_devConfigs.data(), this)), - m_keyDeployer(new MaemoKeyDeployer(this)), m_saveSettingsRequested(false), m_additionalActionsMapper(new QSignalMapper(this)) { initGui(); - connect(m_keyDeployer, SIGNAL(error(QString)), this, - SLOT(handleDeploymentError(QString)), Qt::QueuedConnection); - connect(m_keyDeployer, SIGNAL(finishedSuccessfully()), - SLOT(handleDeploymentSuccess())); connect(m_additionalActionsMapper, SIGNAL(mapped(QString)), SLOT(handleAdditionalActionRequest(QString))); } @@ -183,38 +177,17 @@ void MaemoDeviceConfigurationsSettingsWidget::addConfig() if (factories.isEmpty()) // Can't happen, because this plugin provides the generic one. return; - const ILinuxDeviceConfigurationFactory *factory; + LinuxDeviceFactorySelectionDialog d; + if (d.exec() != QDialog::Accepted) + return; - if (factories.count() == 1) { - // Don't show dialog when there's nothing to choose from. - // TODO: This is transitional. Remove it once the MADDE plugin exists. - factory = factories.first(); - } else { - LinuxDeviceFactorySelectionDialog d; - if (d.exec() != QDialog::Accepted) - return; - factory = d.selectedFactory(); - } - - ILinuxDeviceConfigurationWizard *wizard = factory->createWizard(); + const QScopedPointer wizard(d.selectedFactory()->createWizard(this)); if (wizard->exec() != QDialog::Accepted) return; - LinuxDeviceConfiguration::Ptr devConf = wizard->deviceConfiguration(); - QString name = devConf->name(); - if (m_devConfigs->hasConfig(name)) { - const QString nameTemplate = name + QLatin1String(" (%1)"); - int suffix = 2; - do - name = nameTemplate.arg(QString::number(suffix++)); - while (m_devConfigs->hasConfig(name)); - } - devConf->setName(name); - m_devConfigs->addConfiguration(devConf); + m_devConfigs->addConfiguration(wizard->deviceConfiguration()); m_ui->removeConfigButton->setEnabled(true); m_ui->configurationComboBox->setCurrentIndex(m_ui->configurationComboBox->count()-1); - - delete wizard; } void MaemoDeviceConfigurationsSettingsWidget::deleteConfig() @@ -385,60 +358,19 @@ void MaemoDeviceConfigurationsSettingsWidget::setPrivateKey(const QString &path) keyFileEditingFinished(); } -void MaemoDeviceConfigurationsSettingsWidget::deployKey() -{ - const SshConnectionParameters sshParams = currentConfig()->sshParameters(); - const QString &dir = QFileInfo(sshParams.privateKeyFile).path(); - QString publicKeyFileName = QFileDialog::getOpenFileName(this, - tr("Choose Public Key File"), dir, - tr("Public Key Files(*.pub);;All Files (*)")); - if (publicKeyFileName.isEmpty()) - return; - - disconnect(m_ui->deployKeyButton, 0, this, 0); - m_ui->deployKeyButton->setText(tr("Stop Deploying")); - connect(m_ui->deployKeyButton, SIGNAL(clicked()), this, - SLOT(finishDeployment())); - m_keyDeployer->deployPublicKey(sshParams, publicKeyFileName); -} - -void MaemoDeviceConfigurationsSettingsWidget::handleDeploymentError(const QString &errorMsg) -{ - QMessageBox::critical(this, tr("Deployment Failed"), errorMsg); - finishDeployment(); -} - -void MaemoDeviceConfigurationsSettingsWidget::handleDeploymentSuccess() -{ - QMessageBox::information(this, tr("Deployment Succeeded"), - tr("Key was successfully deployed.")); - finishDeployment(); -} - -void MaemoDeviceConfigurationsSettingsWidget::finishDeployment() -{ - m_keyDeployer->stopDeployment(); - m_ui->deployKeyButton->disconnect(); - m_ui->deployKeyButton->setText(tr("&Deploy Public Key...")); - connect(m_ui->deployKeyButton, SIGNAL(clicked()), this, SLOT(deployKey())); -} - void MaemoDeviceConfigurationsSettingsWidget::currentConfigChanged(int index) { - finishDeployment(); qDeleteAll(m_additionalActionButtons); m_additionalActionButtons.clear(); if (index == -1) { m_ui->removeConfigButton->setEnabled(false); m_ui->generateKeyButton->setEnabled(false); - m_ui->deployKeyButton->setEnabled(false); clearDetails(); m_ui->detailsWidget->setEnabled(false); m_ui->defaultDeviceButton->setEnabled(false); } else { m_ui->removeConfigButton->setEnabled(true); m_ui->generateKeyButton->setEnabled(true); - m_ui->deployKeyButton->setEnabled(true); const ILinuxDeviceConfigurationFactory * const factory = factoryForCurrentConfig(); if (factory) { const QStringList &actionIds = factory->supportedDeviceActionIds(); diff --git a/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.h b/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.h index 1f4e1ff38df..e405053d345 100644 --- a/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.h +++ b/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.h @@ -45,10 +45,6 @@ class QSignalMapper; class Ui_MaemoDeviceConfigurationsSettingsWidget; QT_END_NAMESPACE -namespace Utils { -class SshRemoteProcessRunner; -} - namespace RemoteLinux { class ILinuxDeviceConfigurationFactory; class LinuxDeviceConfiguration; @@ -57,7 +53,6 @@ namespace Internal { class NameValidator; class LinuxDeviceConfigurations; -class MaemoKeyDeployer; class MaemoDeviceConfigurationsSettingsWidget : public QWidget { @@ -91,12 +86,6 @@ private slots: void handleAdditionalActionRequest(const QString &actionId); - // For key deploying. - void deployKey(); - void finishDeployment(); - void handleDeploymentError(const QString &errorMsg); - void handleDeploymentSuccess(); - private: void initGui(); void displayCurrent(); @@ -111,7 +100,6 @@ private: Ui_MaemoDeviceConfigurationsSettingsWidget *m_ui; const QScopedPointer m_devConfigs; NameValidator * const m_nameValidator; - MaemoKeyDeployer *const m_keyDeployer; bool m_saveSettingsRequested; QList m_additionalActionButtons; QSignalMapper * const m_additionalActionsMapper; diff --git a/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.ui b/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.ui index 4a336bd2499..83928a2e05b 100644 --- a/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.ui +++ b/src/plugins/remotelinux/maemodeviceconfigurationssettingswidget.ui @@ -387,6 +387,19 @@ + + + + false + + + Qt::StrongFocus + + + Set As Default + + + @@ -403,35 +416,6 @@ - - - - false - - - Qt::StrongFocus - - - This will enable you to log into the device without a password. - - - &Deploy Public Key... - - - - - - - false - - - Qt::StrongFocus - - - Set As Default - - - @@ -582,22 +566,6 @@ - - deployKeyButton - clicked() - MaemoDeviceConfigurationsSettingsWidget - deployKey() - - - 697 - 163 - - - 510 - 351 - - - keyButton toggled(bool) diff --git a/src/plugins/remotelinux/maemodeviceconfigwizard.cpp b/src/plugins/remotelinux/maemodeviceconfigwizard.cpp index 69d26b6bf43..46d9a6a1f35 100644 --- a/src/plugins/remotelinux/maemodeviceconfigwizard.cpp +++ b/src/plugins/remotelinux/maemodeviceconfigwizard.cpp @@ -89,7 +89,6 @@ public: m_ui->fremantleButton->setText(MaemoGlobal::osTypeToString(LinuxDeviceConfiguration::Maemo5OsType)); m_ui->harmattanButton->setText(MaemoGlobal::osTypeToString(LinuxDeviceConfiguration::HarmattanOsType)); m_ui->meegoButton->setText(MaemoGlobal::osTypeToString(LinuxDeviceConfiguration::MeeGoOsType)); - m_ui->genericLinuxButton->setText(MaemoGlobal::osTypeToString(LinuxDeviceConfiguration::GenericLinuxOsType)); QButtonGroup *buttonGroup = new QButtonGroup(this); buttonGroup->setExclusive(true); @@ -103,9 +102,6 @@ public: buttonGroup->addButton(m_ui->fremantleButton); buttonGroup->addButton(m_ui->harmattanButton); buttonGroup->addButton(m_ui->meegoButton); - buttonGroup->addButton(m_ui->genericLinuxButton); - connect(buttonGroup, SIGNAL(buttonClicked(int)), - SLOT(handleOsTypeChanged())); m_ui->nameLineEdit->setText(QLatin1String("(New Configuration)")); m_ui->harmattanButton->setChecked(true); @@ -137,8 +133,7 @@ public: { return m_ui->fremantleButton->isChecked() ? LinuxDeviceConfiguration::Maemo5OsType : m_ui->harmattanButton->isChecked() ? LinuxDeviceConfiguration::HarmattanOsType - : m_ui->meegoButton->isChecked() ? LinuxDeviceConfiguration::MeeGoOsType - : LinuxDeviceConfiguration::GenericLinuxOsType; + : LinuxDeviceConfiguration::MeeGoOsType; } LinuxDeviceConfiguration::DeviceType deviceType() const @@ -155,19 +150,6 @@ private slots: m_ui->hostNameLineEdit->setEnabled(enable); } - void handleOsTypeChanged() - { - if (osType() == LinuxDeviceConfiguration::GenericLinuxOsType) { - m_ui->hwButton->setChecked(true); - m_ui->hwButton->setEnabled(false); - m_ui->qemuButton->setEnabled(false); - } else { - m_ui->hwButton->setEnabled(true); - m_ui->qemuButton->setEnabled(true); - } - handleDeviceTypeChanged(); - } - private: const QScopedPointer m_ui; }; @@ -630,28 +612,16 @@ MaemoDeviceConfigWizard::~MaemoDeviceConfigWizard() {} LinuxDeviceConfiguration::Ptr MaemoDeviceConfigWizard::deviceConfiguration() { - LinuxDeviceConfiguration::Ptr devConf; - - if (d->wizardData.osType == LinuxDeviceConfiguration::GenericLinuxOsType) { - if (d->wizardData.authType == SshConnectionParameters::AuthenticationByPassword) { - devConf = LinuxDeviceConfiguration::createGenericLinuxConfigUsingPassword(d->wizardData.configName, - d->wizardData.hostName, d->wizardData.userName, d->wizardData.password); - } else { - devConf = LinuxDeviceConfiguration::createGenericLinuxConfigUsingKey(d->wizardData.configName, - d->wizardData.hostName, d->wizardData.userName, d->wizardData.privateKeyFilePath); - } - } else if (d->wizardData.deviceType == LinuxDeviceConfiguration::Physical) { - devConf = LinuxDeviceConfiguration::createHardwareConfig(d->wizardData.configName, - d->wizardData.osType, d->wizardData.hostName, d->wizardData.privateKeyFilePath); - } else { - devConf = LinuxDeviceConfiguration::createEmulatorConfig(d->wizardData.configName, + if (d->wizardData.deviceType == LinuxDeviceConfiguration::Emulator) { + return LinuxDeviceConfiguration::createEmulatorConfig(d->wizardData.configName, d->wizardData.osType); } - if (devConf->type() != LinuxDeviceConfiguration::Emulator) { - MaemoConfigTestDialog dlg(devConf, this); - dlg.exec(); - } + const LinuxDeviceConfiguration::Ptr devConf + = LinuxDeviceConfiguration::createHardwareConfig(d->wizardData.configName, + d->wizardData.osType, d->wizardData.hostName, d->wizardData.privateKeyFilePath); + MaemoConfigTestDialog dlg(devConf, this); + dlg.exec(); return devConf; } @@ -664,13 +634,9 @@ int MaemoDeviceConfigWizard::nextId() const d->wizardData.deviceType = d->startPage.deviceType(); d->wizardData.hostName = d->startPage.hostName(); - if (d->wizardData.deviceType == LinuxDeviceConfiguration::Emulator) { + if (d->wizardData.deviceType == LinuxDeviceConfiguration::Emulator) return FinalPageId; - } else if (d->wizardData.osType == LinuxDeviceConfiguration::GenericLinuxOsType) { - return LoginDataPageId; - } else { - return PreviousKeySetupCheckPageId; - } + return PreviousKeySetupCheckPageId; case LoginDataPageId: d->wizardData.userName = d->loginDataPage.userName(); d->wizardData.authType = d->loginDataPage.authType(); diff --git a/src/plugins/remotelinux/maemodeviceconfigwizardstartpage.ui b/src/plugins/remotelinux/maemodeviceconfigwizardstartpage.ui index 443ca96de7f..3679b1a4d6c 100644 --- a/src/plugins/remotelinux/maemodeviceconfigwizardstartpage.ui +++ b/src/plugins/remotelinux/maemodeviceconfigwizardstartpage.ui @@ -57,13 +57,6 @@ - - - - Generic Linux - - - diff --git a/src/plugins/remotelinux/maemoglobal.cpp b/src/plugins/remotelinux/maemoglobal.cpp index 95a90e04a62..32200e62046 100644 --- a/src/plugins/remotelinux/maemoglobal.cpp +++ b/src/plugins/remotelinux/maemoglobal.cpp @@ -190,15 +190,6 @@ QString MaemoGlobal::remoteSourceProfilesCommand() return QString::fromAscii(remoteCall); } -QString MaemoGlobal::remoteEnvironment(const QList &list) -{ - QString env; - QString placeHolder = QLatin1String("%1=%2 "); - foreach (const Utils::EnvironmentItem &item, list) - env.append(placeHolder.arg(item.name).arg(item.value)); - return env.mid(0, env.size() - 1); -} - QString MaemoGlobal::failedToConnectToServerMessage(const Utils::SshConnection::Ptr &connection, const LinuxDeviceConfiguration::ConstPtr &deviceConfig) { diff --git a/src/plugins/remotelinux/maemoglobal.h b/src/plugins/remotelinux/maemoglobal.h index 741f4baea1a..c185acce5d3 100644 --- a/src/plugins/remotelinux/maemoglobal.h +++ b/src/plugins/remotelinux/maemoglobal.h @@ -109,7 +109,6 @@ public: static int applicationIconSize(const QString &osType); static QString remoteSudo(const QString &osType, const QString &uname); static QString remoteCommandPrefix(const QString &osType); - static QString remoteEnvironment(const QList &list); static QString remoteSourceProfilesCommand(); static QString failedToConnectToServerMessage(const QSharedPointer &connection, const QSharedPointer &deviceConfig); diff --git a/src/plugins/remotelinux/maemorunconfiguration.cpp b/src/plugins/remotelinux/maemorunconfiguration.cpp new file mode 100644 index 00000000000..b5efddcde73 --- /dev/null +++ b/src/plugins/remotelinux/maemorunconfiguration.cpp @@ -0,0 +1,193 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "maemorunconfiguration.h" + +#include "abstractlinuxdevicedeploystep.h" +#include "qt4maemotarget.h" +#include "maemoconstants.h" +#include "maemoglobal.h" +#include "maemoremotemountsmodel.h" +#include "maemorunconfigurationwidget.h" + +#include +#include +#include +#include + +#include +#include + +using namespace ProjectExplorer; +using namespace Qt4ProjectManager; + +namespace RemoteLinux { +namespace Internal { + +MaemoRunConfiguration::MaemoRunConfiguration(AbstractQt4MaemoTarget *parent, + const QString &proFilePath) + : RemoteLinuxRunConfiguration(parent, Id, proFilePath) +{ + init(); +} + +MaemoRunConfiguration::MaemoRunConfiguration(AbstractQt4MaemoTarget *parent, + MaemoRunConfiguration *source) + : RemoteLinuxRunConfiguration(parent, source) +{ + init(); +} + +void MaemoRunConfiguration::init() +{ + m_remoteMounts = new MaemoRemoteMountsModel(this); + connect(m_remoteMounts, SIGNAL(rowsInserted(QModelIndex, int, int)), this, + SLOT(handleRemoteMountsChanged())); + connect(m_remoteMounts, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, + SLOT(handleRemoteMountsChanged())); + connect(m_remoteMounts, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, + SLOT(handleRemoteMountsChanged())); + connect(m_remoteMounts, SIGNAL(modelReset()), SLOT(handleRemoteMountsChanged())); +} + +bool MaemoRunConfiguration::isEnabled() const +{ + if (!RemoteLinuxRunConfiguration::isEnabled()) + return false; + if (!hasEnoughFreePorts(ProjectExplorer::Constants::RUNMODE)) { + setDisabledReason(tr("Not enough free ports on the device.")); + return false; + } + return true; +} + +QWidget *MaemoRunConfiguration::createConfigurationWidget() +{ + return new MaemoRunConfigurationWidget(this); +} + +QVariantMap MaemoRunConfiguration::toMap() const +{ + QVariantMap map = RemoteLinuxRunConfiguration::toMap(); + map.unite(m_remoteMounts->toMap()); + return map; +} + +bool MaemoRunConfiguration::fromMap(const QVariantMap &map) +{ + if (!RemoteLinuxRunConfiguration::fromMap(map)) + return false; + m_remoteMounts->fromMap(map); + return true; +} + +QString MaemoRunConfiguration::commandPrefix() const +{ + if (!deviceConfig()) + return QString(); + + return QString::fromLocal8Bit("%1 %2") + .arg(MaemoGlobal::remoteCommandPrefix(deviceConfig()->osType()), + userEnvironmentChangesAsString()); +} + +PortList MaemoRunConfiguration::freePorts() const +{ + const Qt4BuildConfiguration * const bc = activeQt4BuildConfiguration(); + const AbstractLinuxDeviceDeployStep * const step = deployStep(); + return bc && step + ? MaemoGlobal::freePorts(deployStep()->helper().deviceConfig(), bc->qtVersion()) + : PortList(); +} + +RemoteLinuxRunConfiguration::DebuggingType MaemoRunConfiguration::debuggingType() const +{ + if (!maemoTarget()->allowsQmlDebugging()) + return DebugCppOnly; + return RemoteLinuxRunConfiguration::debuggingType(); +} + +QString MaemoRunConfiguration::localDirToMountForRemoteGdb() const +{ + const QString projectDir + = QDir::fromNativeSeparators(QDir::cleanPath(activeBuildConfiguration() + ->target()->project()->projectDirectory())); + const QString execDir + = QDir::fromNativeSeparators(QFileInfo(localExecutableFilePath()).path()); + const int length = qMin(projectDir.length(), execDir.length()); + int lastSeparatorPos = 0; + for (int i = 0; i < length; ++i) { + if (projectDir.at(i) != execDir.at(i)) + return projectDir.left(lastSeparatorPos); + if (projectDir.at(i) == QLatin1Char('/')) + lastSeparatorPos = i; + } + return projectDir.length() == execDir.length() + ? projectDir : projectDir.left(lastSeparatorPos); +} + +QString MaemoRunConfiguration::remoteProjectSourcesMountPoint() const +{ + return MaemoGlobal::homeDirOnDevice(deviceConfig()->sshParameters().userName) + + QLatin1String("/gdbSourcesDir_") + + QFileInfo(localExecutableFilePath()).fileName(); +} + +bool MaemoRunConfiguration::hasEnoughFreePorts(const QString &mode) const +{ + const int freePortCount = freePorts().count(); + const bool remoteMountsAllowed = maemoTarget()->allowsRemoteMounts(); + const int mountDirCount = remoteMountsAllowed + ? remoteMounts()->validMountSpecificationCount() : 0; + if (mode == Debugger::Constants::DEBUGMODE) + return freePortCount >= mountDirCount + portsUsedByDebuggers(); + if (mode == ProjectExplorer::Constants::RUNMODE) + return freePortCount >= mountDirCount; + return false; +} + +void MaemoRunConfiguration::handleRemoteMountsChanged() +{ + emit remoteMountsChanged(); + updateEnabledState(); +} + +const AbstractQt4MaemoTarget *MaemoRunConfiguration::maemoTarget() const +{ + const AbstractQt4MaemoTarget * const maemoTarget + = qobject_cast(target()); + Q_ASSERT(maemoTarget); + return maemoTarget; +} + +const QString MaemoRunConfiguration::Id = QLatin1String(MAEMO_RC_ID); + +} // namespace Internal +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/maemorunconfiguration.h b/src/plugins/remotelinux/maemorunconfiguration.h new file mode 100644 index 00000000000..f80adcc44b6 --- /dev/null +++ b/src/plugins/remotelinux/maemorunconfiguration.h @@ -0,0 +1,80 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#ifndef MAEMORUNCONFIGURATION_H +#define MAEMORUNCONFIGURATION_H + +#include "remotelinuxrunconfiguration.h" + +namespace RemoteLinux { +namespace Internal { +class AbstractQt4MaemoTarget; +class MaemoRemoteMountsModel; + +class MaemoRunConfiguration : public RemoteLinuxRunConfiguration +{ + Q_OBJECT + Q_DISABLE_COPY(MaemoRunConfiguration) +public: + MaemoRunConfiguration(AbstractQt4MaemoTarget *parent, const QString &proFilePath); + MaemoRunConfiguration(AbstractQt4MaemoTarget *parent, MaemoRunConfiguration *source); + + QVariantMap toMap() const; + bool fromMap(const QVariantMap &map); + bool isEnabled() const; + QWidget *createConfigurationWidget(); + QString commandPrefix() const; + PortList freePorts() const; + DebuggingType debuggingType() const; + + Internal::MaemoRemoteMountsModel *remoteMounts() const { return m_remoteMounts; } + bool hasEnoughFreePorts(const QString &mode) const; + QString localDirToMountForRemoteGdb() const; + QString remoteProjectSourcesMountPoint() const; + + static const QString Id; + +signals: + void remoteMountsChanged(); + +private slots: + void handleRemoteMountsChanged(); + +private: + void init(); + const AbstractQt4MaemoTarget *maemoTarget() const; + + MaemoRemoteMountsModel *m_remoteMounts; +}; + +} // namespace Internal +} // namespace RemoteLinux + +#endif // MAEMORUNCONFIGURATION_H diff --git a/src/plugins/remotelinux/maemorunconfigurationwidget.cpp b/src/plugins/remotelinux/maemorunconfigurationwidget.cpp index 9caf7b9185c..b7a64cbd3da 100644 --- a/src/plugins/remotelinux/maemorunconfigurationwidget.cpp +++ b/src/plugins/remotelinux/maemorunconfigurationwidget.cpp @@ -31,13 +31,9 @@ #include "maemorunconfigurationwidget.h" -#include "maemodeployables.h" -#include "maemodeviceenvreader.h" #include "maemoglobal.h" #include "maemoremotemountsmodel.h" -#include "remotelinuxrunconfiguration.h" -#include "maemosettingspages.h" -#include "qt4maemodeployconfiguration.h" +#include "maemorunconfiguration.h" #include "qt4maemotarget.h" #include @@ -45,6 +41,7 @@ #include #include #include +#include #include #include @@ -67,151 +64,47 @@ using namespace Qt4ProjectManager; namespace RemoteLinux { namespace Internal { -namespace { -const QString FetchEnvButtonText - = QCoreApplication::translate("ReoteLinux::Internal::MaemoRunConfigurationWidget", - "Fetch Device Environment"); -} // anonymous namespace MaemoRunConfigurationWidget::MaemoRunConfigurationWidget( - RemoteLinuxRunConfiguration *runConfiguration, QWidget *parent) - : QWidget(parent), - m_runConfiguration(runConfiguration), - m_ignoreChange(false), - m_deviceEnvReader(new MaemoDeviceEnvReader(this, runConfiguration)), - m_deployablesConnected(false) + MaemoRunConfiguration *runConfiguration, QWidget *parent) + : QWidget(parent), m_runConfiguration(runConfiguration) { QVBoxLayout *topLayout = new QVBoxLayout(this); topLayout->setMargin(0); - addDisabledLabel(topLayout); - - topWidget = new QWidget; + QWidget *topWidget = new QWidget; topLayout->addWidget(topWidget); - QVBoxLayout *mainLayout = new QVBoxLayout(topWidget); - addGenericWidgets(mainLayout); - mainLayout->addSpacing(20); - addMountWidgets(mainLayout); - addEnvironmentWidgets(mainLayout); - connect(m_runConfiguration, - SIGNAL(deviceConfigurationChanged(ProjectExplorer::Target*)), - this, SLOT(handleCurrentDeviceConfigChanged())); - handleCurrentDeviceConfigChanged(); - - connect(m_runConfiguration, SIGNAL(isEnabledChanged(bool)), - this, SLOT(runConfigurationEnabledChange(bool))); + mainLayout->setMargin(0); + m_remoteLinuxRunConfigWidget = new RemoteLinuxRunConfigurationWidget(runConfiguration, parent); + mainLayout->addWidget(m_remoteLinuxRunConfigWidget); + m_subWidget = new QWidget; + mainLayout->addWidget(m_subWidget); + QVBoxLayout *subLayout = new QVBoxLayout(m_subWidget); + subLayout->setMargin(0); + addMountWidgets(subLayout); + connect(m_runConfiguration, SIGNAL(deviceConfigurationChanged(ProjectExplorer::Target*)), + this, SLOT(updateMountWarning())); + connect(m_runConfiguration, SIGNAL(debuggersChanged()), SLOT(updateMountWarning())); + updateMountWarning(); const AbstractQt4MaemoTarget * const maemoTarget = qobject_cast(runConfiguration->target()); - const bool remoteMountsAvailable - = maemoTarget && maemoTarget->allowsRemoteMounts(); - m_mountDetailsContainer->setVisible(remoteMountsAvailable); - const bool qmlDebuggingAvailable - = !maemoTarget || maemoTarget->allowsQmlDebugging(); - m_debuggingLanguagesLabel->setVisible(qmlDebuggingAvailable); - m_debugCppOnlyButton->setVisible(qmlDebuggingAvailable); - m_debugQmlOnlyButton->setVisible(qmlDebuggingAvailable); - m_debugCppAndQmlButton->setVisible(qmlDebuggingAvailable); + m_mountDetailsContainer->setVisible(maemoTarget->allowsRemoteMounts()); + if (!maemoTarget->allowsQmlDebugging()) + m_remoteLinuxRunConfigWidget->suppressQmlDebuggingOptions(); + connect(m_runConfiguration, SIGNAL(isEnabledChanged(bool)), + this, SLOT(runConfigurationEnabledChange(bool))); runConfigurationEnabledChange(m_runConfiguration->isEnabled()); } void MaemoRunConfigurationWidget::runConfigurationEnabledChange(bool enabled) { - topWidget->setEnabled(enabled); - m_disabledIcon->setVisible(!enabled); - m_disabledReason->setVisible(!enabled); - m_disabledReason->setText(m_runConfiguration->disabledReason()); -} - -void MaemoRunConfigurationWidget::addDisabledLabel(QVBoxLayout *topLayout) -{ - QHBoxLayout *hl = new QHBoxLayout(); - hl->addStretch(); - m_disabledIcon = new QLabel(this); - m_disabledIcon->setPixmap(QPixmap(QString::fromUtf8(":/projectexplorer/images/compile_warning.png"))); - hl->addWidget(m_disabledIcon); - m_disabledReason = new QLabel(this); - m_disabledReason->setVisible(false); - hl->addWidget(m_disabledReason); - hl->addStretch(); - topLayout->addLayout(hl); -} - -void MaemoRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayout) -{ - QFormLayout *formLayout = new QFormLayout; - mainLayout->addLayout(formLayout); - formLayout->setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter); - - QWidget *devConfWidget = new QWidget; - QHBoxLayout *devConfLayout = new QHBoxLayout(devConfWidget); - m_devConfLabel = new QLabel; - devConfLayout->setMargin(0); - devConfLayout->addWidget(m_devConfLabel); - QLabel *addDevConfLabel= new QLabel(tr("Manage device configurations") - .arg(QLatin1String("deviceconfig"))); - addDevConfLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); - devConfLayout->addWidget(addDevConfLabel); - - QLabel *debuggerConfLabel = new QLabel(tr("Set Debugger") - .arg(QLatin1String("debugger"))); - debuggerConfLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); - devConfLayout->addWidget(debuggerConfLabel); - - formLayout->addRow(new QLabel(tr("Device configuration:")), devConfWidget); - m_localExecutableLabel - = new QLabel(m_runConfiguration->localExecutableFilePath()); - formLayout->addRow(tr("Executable on host:"), m_localExecutableLabel); - m_remoteExecutableLabel = new QLabel; - formLayout->addRow(tr("Executable on device:"), m_remoteExecutableLabel); - m_argsLineEdit = new QLineEdit(m_runConfiguration->arguments()); - formLayout->addRow(tr("Arguments:"), m_argsLineEdit); - - QHBoxLayout * const debugButtonsLayout = new QHBoxLayout; - m_debugCppOnlyButton = new QRadioButton(tr("C++ only")); - m_debugQmlOnlyButton = new QRadioButton(tr("QML only")); - m_debugCppAndQmlButton = new QRadioButton(tr("C++ and QML")); - m_debuggingLanguagesLabel = new QLabel(tr("Debugging type:")); - QButtonGroup * const buttonGroup = new QButtonGroup; - buttonGroup->addButton(m_debugCppOnlyButton); - buttonGroup->addButton(m_debugQmlOnlyButton); - buttonGroup->addButton(m_debugCppAndQmlButton); - debugButtonsLayout->addWidget(m_debugCppOnlyButton); - debugButtonsLayout->addWidget(m_debugQmlOnlyButton); - debugButtonsLayout->addWidget(m_debugCppAndQmlButton); - debugButtonsLayout->addStretch(1); - formLayout->addRow(m_debuggingLanguagesLabel, debugButtonsLayout); - if (m_runConfiguration->useCppDebugger()) { - if (m_runConfiguration->useQmlDebugger()) - m_debugCppAndQmlButton->setChecked(true); - else - m_debugCppOnlyButton->setChecked(true); - } else { - m_debugQmlOnlyButton->setChecked(true); - } - - connect(addDevConfLabel, SIGNAL(linkActivated(QString)), this, - SLOT(showDeviceConfigurationsDialog(QString))); - connect(debuggerConfLabel, SIGNAL(linkActivated(QString)), this, - SLOT(showDeviceConfigurationsDialog(QString))); - connect(m_argsLineEdit, SIGNAL(textEdited(QString)), this, - SLOT(argumentsEdited(QString))); - connect(m_debugCppOnlyButton, SIGNAL(toggled(bool)), this, - SLOT(handleDebuggingTypeChanged())); - connect(m_debugQmlOnlyButton, SIGNAL(toggled(bool)), this, - SLOT(handleDebuggingTypeChanged())); - connect(m_debugCppAndQmlButton, SIGNAL(toggled(bool)), this, - SLOT(handleDebuggingTypeChanged())); - connect(m_runConfiguration, SIGNAL(targetInformationChanged()), this, - SLOT(updateTargetInformation())); - connect(m_runConfiguration, SIGNAL(deploySpecsChanged()), SLOT(handleDeploySpecsChanged())); - handleDeploySpecsChanged(); + m_subWidget->setEnabled(enabled); } void MaemoRunConfigurationWidget::addMountWidgets(QVBoxLayout *mainLayout) { - m_mountDetailsContainer = new Utils::DetailsWidget(this); QWidget *mountViewWidget = new QWidget; m_mountDetailsContainer->setWidget(mountViewWidget); @@ -252,79 +145,6 @@ void MaemoRunConfigurationWidget::addMountWidgets(QVBoxLayout *mainLayout) handleRemoteMountsChanged(); } -void MaemoRunConfigurationWidget::addEnvironmentWidgets(QVBoxLayout *mainLayout) -{ - QWidget *baseEnvironmentWidget = new QWidget; - QHBoxLayout *baseEnvironmentLayout = new QHBoxLayout(baseEnvironmentWidget); - baseEnvironmentLayout->setMargin(0); - QLabel *label = new QLabel(tr("Base environment for this run configuration:"), this); - baseEnvironmentLayout->addWidget(label); - m_baseEnvironmentComboBox = new QComboBox(this); - m_baseEnvironmentComboBox->addItems(QStringList() << tr("Clean Environment") - << tr("System Environment")); - m_baseEnvironmentComboBox->setCurrentIndex(m_runConfiguration->baseEnvironmentType()); - baseEnvironmentLayout->addWidget(m_baseEnvironmentComboBox); - - m_fetchEnv = new QPushButton(FetchEnvButtonText); - baseEnvironmentLayout->addWidget(m_fetchEnv); - baseEnvironmentLayout->addStretch(10); - - m_environmentWidget = new ProjectExplorer::EnvironmentWidget(this, baseEnvironmentWidget); - m_environmentWidget->setBaseEnvironment(m_deviceEnvReader->deviceEnvironment()); - m_environmentWidget->setBaseEnvironmentText(m_runConfiguration->baseEnvironmentText()); - m_environmentWidget->setUserChanges(m_runConfiguration->userEnvironmentChanges()); - mainLayout->addWidget(m_environmentWidget); - - connect(m_environmentWidget, SIGNAL(userChangesChanged()), this, - SLOT(userChangesEdited())); - connect(m_baseEnvironmentComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(baseEnvironmentSelected(int))); - connect(m_runConfiguration, SIGNAL(baseEnvironmentChanged()), - this, SLOT(baseEnvironmentChanged())); - connect(m_runConfiguration, SIGNAL(systemEnvironmentChanged()), - this, SLOT(systemEnvironmentChanged())); - connect(m_runConfiguration, - SIGNAL(userEnvironmentChangesChanged(QList)), - this, SLOT(userEnvironmentChangesChanged(QList))); - connect(m_fetchEnv, SIGNAL(clicked()), this, SLOT(fetchEnvironment())); - connect(m_deviceEnvReader, SIGNAL(finished()), this, SLOT(fetchEnvironmentFinished())); - connect(m_deviceEnvReader, SIGNAL(error(QString)), this, - SLOT(fetchEnvironmentError(QString))); -} - -void MaemoRunConfigurationWidget::argumentsEdited(const QString &text) -{ - m_runConfiguration->setArguments(text); -} - -void MaemoRunConfigurationWidget::updateTargetInformation() -{ - m_localExecutableLabel - ->setText(QDir::toNativeSeparators(m_runConfiguration->localExecutableFilePath())); -} - -void MaemoRunConfigurationWidget::handleDeploySpecsChanged() -{ - m_remoteExecutableLabel->setText(m_runConfiguration->remoteExecutableFilePath()); -} - -void MaemoRunConfigurationWidget::showDeviceConfigurationsDialog(const QString &link) -{ - if (link == QLatin1String("deviceconfig")) { - Core::ICore::instance()->showOptionsDialog(MaemoDeviceConfigurationsSettingsPage::Category, - MaemoDeviceConfigurationsSettingsPage::Id); - } else if (link == QLatin1String("debugger")) { - Core::ICore::instance()->showOptionsDialog(QLatin1String("O.Debugger"), - QLatin1String("M.Gdb")); - } -} - -void MaemoRunConfigurationWidget::handleCurrentDeviceConfigChanged() -{ - m_devConfLabel->setText(MaemoGlobal::deviceConfigurationName(m_runConfiguration->deviceConfig())); - updateMountWarning(); -} - void MaemoRunConfigurationWidget::enableOrDisableRemoveMountSpecButton() { const QModelIndexList selectedRows @@ -369,74 +189,6 @@ void MaemoRunConfigurationWidget::changeLocalMountDir(const QModelIndex &index) } } -void MaemoRunConfigurationWidget::fetchEnvironment() -{ - disconnect(m_fetchEnv, SIGNAL(clicked()), this, SLOT(fetchEnvironment())); - connect(m_fetchEnv, SIGNAL(clicked()), this, SLOT(stopFetchEnvironment())); - m_fetchEnv->setText(tr("Cancel Fetch Operation")); - m_deviceEnvReader->start(); -} - -void MaemoRunConfigurationWidget::stopFetchEnvironment() -{ - m_deviceEnvReader->stop(); - fetchEnvironmentFinished(); -} - -void MaemoRunConfigurationWidget::fetchEnvironmentFinished() -{ - disconnect(m_fetchEnv, SIGNAL(clicked()), this, - SLOT(stopFetchEnvironment())); - connect(m_fetchEnv, SIGNAL(clicked()), this, SLOT(fetchEnvironment())); - m_fetchEnv->setText(FetchEnvButtonText); - m_runConfiguration->setSystemEnvironment(m_deviceEnvReader->deviceEnvironment()); -} - -void MaemoRunConfigurationWidget::fetchEnvironmentError(const QString &error) -{ - QMessageBox::warning(this, tr("Device error"), - tr("Fetching environment failed: %1").arg(error)); -} - -void MaemoRunConfigurationWidget::userChangesEdited() -{ - m_ignoreChange = true; - m_runConfiguration->setUserEnvironmentChanges(m_environmentWidget->userChanges()); - m_ignoreChange = false; -} - -void MaemoRunConfigurationWidget::baseEnvironmentSelected(int index) -{ - m_ignoreChange = true; - m_runConfiguration->setBaseEnvironmentType(RemoteLinuxRunConfiguration::BaseEnvironmentType(index)); - - m_environmentWidget->setBaseEnvironment(m_runConfiguration->baseEnvironment()); - m_environmentWidget->setBaseEnvironmentText(m_runConfiguration->baseEnvironmentText()); - m_ignoreChange = false; -} - -void MaemoRunConfigurationWidget::baseEnvironmentChanged() -{ - if (m_ignoreChange) - return; - - m_baseEnvironmentComboBox->setCurrentIndex(m_runConfiguration->baseEnvironmentType()); - m_environmentWidget->setBaseEnvironment(m_runConfiguration->baseEnvironment()); - m_environmentWidget->setBaseEnvironmentText(m_runConfiguration->baseEnvironmentText()); -} - -void MaemoRunConfigurationWidget::systemEnvironmentChanged() -{ - m_environmentWidget->setBaseEnvironment(m_runConfiguration->systemEnvironment()); -} - -void MaemoRunConfigurationWidget::userEnvironmentChangesChanged(const QList &userChanges) -{ - if (m_ignoreChange) - return; - m_environmentWidget->setUserChanges(userChanges); -} - void MaemoRunConfigurationWidget::handleRemoteMountsChanged() { const int mountCount @@ -459,15 +211,6 @@ void MaemoRunConfigurationWidget::handleRemoteMountsChanged() updateMountWarning(); } -void MaemoRunConfigurationWidget::handleDebuggingTypeChanged() -{ - m_runConfiguration->setUseCppDebugger(m_debugCppOnlyButton->isChecked() - || m_debugCppAndQmlButton->isChecked()); - m_runConfiguration->setUseQmlDebugger(m_debugQmlOnlyButton->isChecked() - || m_debugCppAndQmlButton->isChecked()); - updateMountWarning(); -} - void MaemoRunConfigurationWidget::updateMountWarning() { QString mountWarning; diff --git a/src/plugins/remotelinux/maemorunconfigurationwidget.h b/src/plugins/remotelinux/maemorunconfigurationwidget.h index 8a485a4ecf0..c3349e94b75 100644 --- a/src/plugins/remotelinux/maemorunconfigurationwidget.h +++ b/src/plugins/remotelinux/maemorunconfigurationwidget.h @@ -35,96 +35,47 @@ #include QT_BEGIN_NAMESPACE -class QComboBox; class QLabel; -class QLineEdit; class QModelIndex; -class QPushButton; -class QRadioButton; class QTableView; class QToolButton; class QVBoxLayout; QT_END_NAMESPACE -namespace Utils { -class DetailsWidget; -class EnvironmentItem; -} - -namespace ProjectExplorer { -class EnvironmentWidget; -} - -namespace Qt4ProjectManager { -class Qt4BuildConfiguration; -} +namespace Utils { class DetailsWidget; } namespace RemoteLinux { -class RemoteLinuxRunConfiguration; +class RemoteLinuxRunConfigurationWidget; namespace Internal { -class MaemoDeviceEnvReader; +class MaemoRunConfiguration; class MaemoRunConfigurationWidget : public QWidget { Q_OBJECT public: - explicit MaemoRunConfigurationWidget(RemoteLinuxRunConfiguration *runConfiguration, - QWidget *parent = 0); + explicit MaemoRunConfigurationWidget(MaemoRunConfiguration *runConfiguration, + QWidget *parent = 0); private slots: - void runConfigurationEnabledChange(bool enabled); - void argumentsEdited(const QString &args); - void showDeviceConfigurationsDialog(const QString &link); - void updateTargetInformation(); - void handleCurrentDeviceConfigChanged(); void addMount(); void removeMount(); void changeLocalMountDir(const QModelIndex &index); void enableOrDisableRemoveMountSpecButton(); - void fetchEnvironment(); - void fetchEnvironmentFinished(); - void fetchEnvironmentError(const QString &error); - void stopFetchEnvironment(); - void userChangesEdited(); - void baseEnvironmentSelected(int index); - void baseEnvironmentChanged(); - void systemEnvironmentChanged(); - void userEnvironmentChangesChanged(const QList &userChanges); void handleRemoteMountsChanged(); - void handleDebuggingTypeChanged(); - void handleDeploySpecsChanged(); + void updateMountWarning(); + void runConfigurationEnabledChange(bool enabled); private: - void addDisabledLabel(QVBoxLayout *topLayout); - void addGenericWidgets(QVBoxLayout *mainLayout); void addMountWidgets(QVBoxLayout *mainLayout); - void addEnvironmentWidgets(QVBoxLayout *mainLayout); - void updateMountWarning(); - QWidget *topWidget; - QLabel *m_disabledIcon; - QLabel *m_disabledReason; - QLineEdit *m_argsLineEdit; - QLabel *m_localExecutableLabel; - QLabel *m_remoteExecutableLabel; - QLabel *m_devConfLabel; - QLabel *m_debuggingLanguagesLabel; - QRadioButton *m_debugCppOnlyButton; - QRadioButton *m_debugQmlOnlyButton; - QRadioButton *m_debugCppAndQmlButton; + QWidget *m_subWidget; QLabel *m_mountWarningLabel; QTableView *m_mountView; QToolButton *m_removeMountButton; Utils::DetailsWidget *m_mountDetailsContainer; - RemoteLinuxRunConfiguration *m_runConfiguration; - - bool m_ignoreChange; - QPushButton *m_fetchEnv; - QComboBox *m_baseEnvironmentComboBox; - MaemoDeviceEnvReader *m_deviceEnvReader; - ProjectExplorer::EnvironmentWidget *m_environmentWidget; - bool m_deployablesConnected; + RemoteLinuxRunConfigurationWidget *m_remoteLinuxRunConfigWidget; + MaemoRunConfiguration *m_runConfiguration; }; } // namespace Internal diff --git a/src/plugins/remotelinux/maemoruncontrol.cpp b/src/plugins/remotelinux/maemoruncontrol.cpp index 50339d53a93..fcdf24dcb45 100644 --- a/src/plugins/remotelinux/maemoruncontrol.cpp +++ b/src/plugins/remotelinux/maemoruncontrol.cpp @@ -32,98 +32,28 @@ #include "maemoruncontrol.h" #include "maemoglobal.h" -#include "remotelinuxrunconfiguration.h" +#include "maemorunconfiguration.h" #include "maemosshrunner.h" -#include -#include - -#include - -using namespace ProjectExplorer; - namespace RemoteLinux { namespace Internal { using ProjectExplorer::RunConfiguration; MaemoRunControl::MaemoRunControl(RunConfiguration *rc) - : RunControl(rc, ProjectExplorer::Constants::RUNMODE) - , m_runner(new MaemoSshRunner(this, qobject_cast(rc))) - , m_running(false) + : AbstractRemoteLinuxRunControl(rc) + , m_runner(new MaemoSshRunner(this, qobject_cast(rc))) { } MaemoRunControl::~MaemoRunControl() { - stop(); } void MaemoRunControl::start() { - m_running = true; - emit started(); - disconnect(m_runner, 0, this, 0); - connect(m_runner, SIGNAL(error(QString)), SLOT(handleSshError(QString))); - connect(m_runner, SIGNAL(readyForExecution()), SLOT(startExecution())); - connect(m_runner, SIGNAL(remoteErrorOutput(QByteArray)), - SLOT(handleRemoteErrorOutput(QByteArray))); - connect(m_runner, SIGNAL(remoteOutput(QByteArray)), - SLOT(handleRemoteOutput(QByteArray))); - connect(m_runner, SIGNAL(remoteProcessStarted()), - SLOT(handleRemoteProcessStarted())); - connect(m_runner, SIGNAL(remoteProcessFinished(qint64)), - SLOT(handleRemoteProcessFinished(qint64))); - connect(m_runner, SIGNAL(reportProgress(QString)), - SLOT(handleProgressReport(QString))); - connect(m_runner, SIGNAL(mountDebugOutput(QString)), - SLOT(handleMountDebugOutput(QString))); - m_runner->start(); -} - -RunControl::StopResult MaemoRunControl::stop() -{ - m_runner->stop(); - return StoppedSynchronously; -} - -void MaemoRunControl::handleSshError(const QString &error) -{ - handleError(error); - setFinished(); -} - -void MaemoRunControl::startExecution() -{ - appendMessage(tr("Starting remote process ...\n"), Utils::NormalMessageFormat); - m_runner->startExecution(QString::fromLocal8Bit("%1 %2 %3") - .arg(m_runner->commandPrefix()) - .arg(m_runner->remoteExecutable()) - .arg(m_runner->arguments()).toUtf8()); -} - -void MaemoRunControl::handleRemoteProcessFinished(qint64 exitCode) -{ - if (exitCode != MaemoSshRunner::InvalidExitCode) { - appendMessage(tr("Finished running remote process. Exit code was %1.\n") - .arg(exitCode), Utils::NormalMessageFormat); - } - setFinished(); -} - -void MaemoRunControl::handleRemoteOutput(const QByteArray &output) -{ - appendMessage(QString::fromUtf8(output), Utils::StdOutFormatSameLine); -} - -void MaemoRunControl::handleRemoteErrorOutput(const QByteArray &output) -{ - appendMessage(QString::fromUtf8(output), Utils::StdErrFormatSameLine); -} - -void MaemoRunControl::handleProgressReport(const QString &progressString) -{ - appendMessage(progressString + QLatin1Char('\n'), Utils::NormalMessageFormat); + AbstractRemoteLinuxRunControl::start(); + connect(m_runner, SIGNAL(mountDebugOutput(QString)), SLOT(handleMountDebugOutput(QString))); } void MaemoRunControl::handleMountDebugOutput(const QString &output) @@ -131,29 +61,7 @@ void MaemoRunControl::handleMountDebugOutput(const QString &output) appendMessage(output, Utils::StdErrFormatSameLine); } -bool MaemoRunControl::isRunning() const -{ - return m_running; -} - -QIcon MaemoRunControl::icon() const -{ - return QIcon(ProjectExplorer::Constants::ICON_RUN_SMALL); -} - -void MaemoRunControl::handleError(const QString &errString) -{ - stop(); - appendMessage(errString, Utils::ErrorMessageFormat); - QMessageBox::critical(0, tr("Remote Execution Failure"), errString); -} - -void MaemoRunControl::setFinished() -{ - disconnect(m_runner, 0, this, 0); - m_running = false; - emit finished(); -} +RemoteLinuxApplicationRunner *MaemoRunControl::runner() const { return m_runner; } } // namespace Internal } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/maemoruncontrol.h b/src/plugins/remotelinux/maemoruncontrol.h index 27e57f66fd5..ea0c7cfe9b0 100644 --- a/src/plugins/remotelinux/maemoruncontrol.h +++ b/src/plugins/remotelinux/maemoruncontrol.h @@ -32,45 +32,30 @@ #ifndef MAEMORUNCONTROL_H #define MAEMORUNCONTROL_H -#include - -#include +#include namespace RemoteLinux { class RemoteLinuxRunConfiguration; namespace Internal { - class MaemoSshRunner; -class MaemoRunControl : public ProjectExplorer::RunControl +class MaemoRunControl : public AbstractRemoteLinuxRunControl { Q_OBJECT public: explicit MaemoRunControl(ProjectExplorer::RunConfiguration *runConfig); virtual ~MaemoRunControl(); - virtual void start(); - virtual StopResult stop(); - virtual bool isRunning() const; - virtual QIcon icon() const; + void start(); private slots: - void startExecution(); - void handleSshError(const QString &error); - void handleRemoteProcessStarted() {} - void handleRemoteProcessFinished(qint64 exitCode); - void handleRemoteOutput(const QByteArray &output); - void handleRemoteErrorOutput(const QByteArray &output); - void handleProgressReport(const QString &progressString); void handleMountDebugOutput(const QString &output); private: - void setFinished(); - void handleError(const QString &errString); + virtual RemoteLinuxApplicationRunner *runner() const; MaemoSshRunner * const m_runner; - bool m_running; }; } // namespace Internal diff --git a/src/plugins/remotelinux/maemorunfactories.cpp b/src/plugins/remotelinux/maemorunfactories.cpp index bb49363ca4a..9546f28b630 100644 --- a/src/plugins/remotelinux/maemorunfactories.cpp +++ b/src/plugins/remotelinux/maemorunfactories.cpp @@ -33,17 +33,19 @@ #include "maemoconstants.h" #include "maemodebugsupport.h" -#include "maemoglobal.h" #include "maemoremotemountsmodel.h" -#include "remotelinuxrunconfiguration.h" +#include "maemorunconfiguration.h" #include "maemoruncontrol.h" #include "maemotoolchain.h" #include "qt4maemotarget.h" -#include #include +#include +#include +#include #include +using namespace Debugger; using namespace ProjectExplorer; using namespace Qt4ProjectManager; @@ -73,8 +75,6 @@ MaemoRunConfigurationFactory::~MaemoRunConfigurationFactory() bool MaemoRunConfigurationFactory::canCreate(Target *parent, const QString &id) const { - if (!MaemoGlobal::hasLinuxQt(parent)) - return false; return qobject_cast(parent)->qt4Project() ->hasApplicationProFile(pathFromId(id)); } @@ -82,8 +82,7 @@ bool MaemoRunConfigurationFactory::canCreate(Target *parent, bool MaemoRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const { - if (!MaemoGlobal::hasLinuxQt(parent)) - return false; + Q_UNUSED(parent); return ProjectExplorer::idFromMap(map) .startsWith(QLatin1String(MAEMO_RC_ID)); } @@ -96,19 +95,15 @@ bool MaemoRunConfigurationFactory::canClone(Target *parent, QStringList MaemoRunConfigurationFactory::availableCreationIds(Target *parent) const { - if (Qt4BaseTarget *t = qobject_cast(parent)) { - if (t && MaemoGlobal::hasLinuxQt(t)) { - return t->qt4Project()-> - applicationProFilePathes(QLatin1String(MAEMO_RC_ID_PREFIX)); - } - } + if (AbstractQt4MaemoTarget *t = qobject_cast(parent)) + return t->qt4Project()->applicationProFilePathes(QLatin1String(MAEMO_RC_ID_PREFIX)); return QStringList(); } QString MaemoRunConfigurationFactory::displayNameForId(const QString &id) const { return QFileInfo(pathFromId(id)).completeBaseName() - + QLatin1String(" (remote)"); + + QLatin1String(" (on remote Maemo device)"); } RunConfiguration *MaemoRunConfigurationFactory::create(Target *parent, @@ -116,7 +111,7 @@ RunConfiguration *MaemoRunConfigurationFactory::create(Target *parent, { if (!canCreate(parent, id)) return 0; - return new RemoteLinuxRunConfiguration(qobject_cast(parent), + return new MaemoRunConfiguration(qobject_cast(parent), pathFromId(id)); } @@ -125,8 +120,8 @@ RunConfiguration *MaemoRunConfigurationFactory::restore(Target *parent, { if (!canRestore(parent, map)) return 0; - RemoteLinuxRunConfiguration *rc - = new RemoteLinuxRunConfiguration(qobject_cast(parent), QString()); + MaemoRunConfiguration *rc + = new MaemoRunConfiguration(qobject_cast(parent), QString()); if (rc->fromMap(map)) return rc; @@ -140,8 +135,8 @@ RunConfiguration *MaemoRunConfigurationFactory::clone(Target *parent, if (!canClone(parent, source)) return 0; - RemoteLinuxRunConfiguration *old = static_cast(source); - return new RemoteLinuxRunConfiguration(static_cast(parent), old); + MaemoRunConfiguration *old = static_cast(source); + return new MaemoRunConfiguration(static_cast(parent), old); } // #pragma mark -- MaemoRunControlFactory @@ -158,8 +153,8 @@ MaemoRunControlFactory::~MaemoRunControlFactory() bool MaemoRunControlFactory::canRun(RunConfiguration *runConfiguration, const QString &mode) const { - const RemoteLinuxRunConfiguration * const maemoRunConfig - = qobject_cast(runConfiguration); + const MaemoRunConfiguration * const maemoRunConfig + = qobject_cast(runConfiguration); if (!maemoRunConfig || !maemoRunConfig->isEnabled()) return false; return maemoRunConfig->hasEnoughFreePorts(mode); @@ -168,14 +163,21 @@ bool MaemoRunControlFactory::canRun(RunConfiguration *runConfiguration, RunControl* MaemoRunControlFactory::create(RunConfiguration *runConfig, const QString &mode) { - Q_ASSERT(mode == ProjectExplorer::Constants::RUNMODE - || mode == Debugger::Constants::DEBUGMODE); + Q_ASSERT(mode == ProjectExplorer::Constants::RUNMODE || mode == Debugger::Constants::DEBUGMODE); Q_ASSERT(canRun(runConfig, mode)); - RemoteLinuxRunConfiguration *rc = qobject_cast(runConfig); + + MaemoRunConfiguration *rc = qobject_cast(runConfig); Q_ASSERT(rc); + if (mode == ProjectExplorer::Constants::RUNMODE) return new MaemoRunControl(rc); - return MaemoDebugSupport::createDebugRunControl(rc); + + const DebuggerStartParameters params + = AbstractRemoteLinuxDebugSupport::startParameters(rc); + DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc); + MaemoDebugSupport *debugSupport = new MaemoDebugSupport(rc, runControl->engine()); + connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished())); + return runControl; } QString MaemoRunControlFactory::displayName() const diff --git a/src/plugins/remotelinux/maemosshrunner.cpp b/src/plugins/remotelinux/maemosshrunner.cpp index a5dc7f70f5e..0a1d8335f4f 100644 --- a/src/plugins/remotelinux/maemosshrunner.cpp +++ b/src/plugins/remotelinux/maemosshrunner.cpp @@ -36,17 +36,8 @@ #include "maemoremotemounter.h" #include "maemoremotemountsmodel.h" #include "remotelinuxrunconfiguration.h" -#include "maemousedportsgatherer.h" -#include -#include -#include - -#include - -#include - -#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(State, state, m_state) +#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(MountState, state, m_mountState) using namespace Qt4ProjectManager; using namespace Utils; @@ -54,20 +45,13 @@ using namespace Utils; namespace RemoteLinux { namespace Internal { -MaemoSshRunner::MaemoSshRunner(QObject *parent, RemoteLinuxRunConfiguration *runConfig) - : QObject(parent), +MaemoSshRunner::MaemoSshRunner(QObject *parent, MaemoRunConfiguration *runConfig) + : RemoteLinuxApplicationRunner(parent, runConfig), m_mounter(new MaemoRemoteMounter(this)), - m_portsGatherer(new MaemoUsedPortsGatherer(this)), - m_devConfig(runConfig->deviceConfig()), - m_remoteExecutable(runConfig->remoteExecutableFilePath()), - m_appArguments(runConfig->arguments()), - m_commandPrefix(runConfig->commandPrefix()), - m_initialFreePorts(runConfig->freePorts()), m_mountSpecs(runConfig->remoteMounts()->mountSpecs()), - m_state(Inactive) + m_mountState(InactiveMountState) { m_mounter->setBuildConfiguration(runConfig->activeQt4BuildConfiguration()); - m_procsToKill << QFileInfo(m_remoteExecutable).fileName(); connect(m_mounter, SIGNAL(mounted()), this, SLOT(handleMounted())); connect(m_mounter, SIGNAL(unmounted()), this, SLOT(handleUnmounted())); connect(m_mounter, SIGNAL(error(QString)), this, @@ -76,261 +60,112 @@ MaemoSshRunner::MaemoSshRunner(QObject *parent, RemoteLinuxRunConfiguration *run SIGNAL(reportProgress(QString))); connect(m_mounter, SIGNAL(debugOutput(QString)), this, SIGNAL(mountDebugOutput(QString))); - connect(m_portsGatherer, SIGNAL(error(QString)), this, - SLOT(handlePortsGathererError(QString))); - connect(m_portsGatherer, SIGNAL(portListReady()), this, - SLOT(handleUsedPortsAvailable())); } MaemoSshRunner::~MaemoSshRunner() {} -void MaemoSshRunner::start() +bool MaemoSshRunner::canRun(QString &whyNot) const { - ASSERT_STATE(QList() << Inactive << StopRequested); + if (!RemoteLinuxApplicationRunner::canRun(whyNot)) + return false; - if (m_remoteExecutable.isEmpty()) { - emitError(tr("Cannot run: No remote executable set."), true); - return; - } - if (!m_devConfig) { - emitError(tr("Cannot run: No device configuration set."), true); - return; - } - - if (m_devConfig->type() == LinuxDeviceConfiguration::Emulator + if (devConfig()->type() == LinuxDeviceConfiguration::Emulator && !MaemoQemuManager::instance().qemuIsRunning()) { MaemoQemuManager::instance().startRuntime(); - emitError(tr("Cannot run: Qemu was not running. " - "It has now been started up for you, but it will take " - "a bit of time until it is ready."), true); - return; + whyNot = tr("Qemu was not running. It has now been started up for you, but it will take " + "a bit of time until it is ready."); + return false; } - m_connection = SshConnectionManager::instance().acquireConnection(m_devConfig->sshParameters()); - setState(Connecting); - m_exitStatus = -1; - m_freePorts = m_initialFreePorts; - connect(m_connection.data(), SIGNAL(connected()), this, - SLOT(handleConnected())); - connect(m_connection.data(), SIGNAL(error(Utils::SshError)), this, - SLOT(handleConnectionFailure())); - if (isConnectionUsable()) { - handleConnected(); - } else { - emit reportProgress(tr("Connecting to device...")); - m_connection->connectToHost(); - } + return true; } -void MaemoSshRunner::stop() +void MaemoSshRunner::doAdditionalInitialCleanup() { - if (m_state == PostRunCleaning || m_state == StopRequested - || m_state == Inactive) - return; - if (m_state == Connecting) { - setState(Inactive); - emit remoteProcessFinished(InvalidExitCode); - return; - } + ASSERT_STATE(InactiveMountState); - setState(StopRequested); - cleanup(); + m_mounter->setConnection(connection(), devConfig()); + m_mounter->resetMountSpecifications(); + for (int i = 0; i < m_mountSpecs.count(); ++i) + m_mounter->addMountSpecification(m_mountSpecs.at(i), false); + m_mountState = InitialUnmounting; + unmount(); } -void MaemoSshRunner::handleConnected() +void MaemoSshRunner::doAdditionalInitializations() { - ASSERT_STATE(QList() << Connecting << StopRequested); - if (m_state == StopRequested) { - setState(Inactive); - } else { - setState(PreRunCleaning); - cleanup(); - } + mount(); } -void MaemoSshRunner::handleConnectionFailure() +void MaemoSshRunner::doAdditionalPostRunCleanup() { - if (m_state == Inactive) - qWarning("Unexpected state %d in %s.", m_state, Q_FUNC_INFO); - - const QString errorMsg = m_state == Connecting - ? MaemoGlobal::failedToConnectToServerMessage(m_connection, m_devConfig) - : tr("Connection error: %1").arg(m_connection->errorString()); - emitError(errorMsg); -} - -void MaemoSshRunner::cleanup() -{ - ASSERT_STATE(QList() << PreRunCleaning << PostRunCleaning - << StopRequested); - - emit reportProgress(tr("Killing remote process(es)...")); - - // pkill behaves differently on Fremantle and Harmattan. - const char *const killTemplate = "pkill -%2 '^%1$'; pkill -%2 '/%1$';"; - QString niceKill; - QString brutalKill; - foreach (const QString &proc, m_procsToKill) { - niceKill += QString::fromLocal8Bit(killTemplate).arg(proc).arg("SIGTERM"); - brutalKill += QString::fromLocal8Bit(killTemplate).arg(proc).arg("SIGKILL"); - } - QString remoteCall = niceKill + QLatin1String("sleep 1; ") + brutalKill; - remoteCall.remove(remoteCall.count() - 1, 1); // Get rid of trailing semicolon. - - m_cleaner = m_connection->createRemoteProcess(remoteCall.toUtf8()); - connect(m_cleaner.data(), SIGNAL(closed(int)), this, - SLOT(handleCleanupFinished(int))); - m_cleaner->start(); -} - -void MaemoSshRunner::handleCleanupFinished(int exitStatus) -{ - Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart - || exitStatus == SshRemoteProcess::KilledBySignal - || exitStatus == SshRemoteProcess::ExitedNormally); - - ASSERT_STATE(QList() << PreRunCleaning << PostRunCleaning - << StopRequested << Inactive); - - if (m_state == Inactive) - return; - if (m_state == StopRequested || m_state == PostRunCleaning) { - unmount(); - return; - } - - if (exitStatus != SshRemoteProcess::ExitedNormally) { - emitError(tr("Initial cleanup failed: %1") - .arg(m_cleaner->errorString())); - } else { - m_mounter->setConnection(m_connection, m_devConfig); - unmount(); - } + ASSERT_STATE(Mounted); + m_mountState = PostRunUnmounting; + unmount(); } void MaemoSshRunner::handleUnmounted() { - ASSERT_STATE(QList() << PreRunCleaning << PreMountUnmounting - << PostRunCleaning << StopRequested); + ASSERT_STATE(QList() << InitialUnmounting << PostRunUnmounting); - switch (m_state) { - case PreRunCleaning: { - for (int i = 0; i < m_mountSpecs.count(); ++i) - m_mounter->addMountSpecification(m_mountSpecs.at(i), false); - setState(PreMountUnmounting); - unmount(); + switch (m_mountState) { + case InitialUnmounting: + m_mountState = InactiveMountState; + handleInitialCleanupDone(true); + break; + case PostRunUnmounting: + m_mountState = InactiveMountState; + handlePostRunCleanupDone(); + break; + default: break; } - case PreMountUnmounting: - setState(GatheringPorts); - m_portsGatherer->start(m_connection, m_devConfig); - break; - case PostRunCleaning: - case StopRequested: { - m_mounter->resetMountSpecifications(); - const bool stopRequested = m_state == StopRequested; - setState(Inactive); - if (stopRequested) { - emit remoteProcessFinished(InvalidExitCode); - } else if (m_exitStatus == SshRemoteProcess::ExitedNormally) { - emit remoteProcessFinished(m_runner->exitCode()); - } else { - emit error(tr("Error running remote process: %1") - .arg(m_runner->errorString())); - } - break; - } - default: ; - } + m_mountState = InactiveMountState; +} + +void MaemoSshRunner::doAdditionalConnectionErrorHandling() +{ + m_mountState = InactiveMountState; } void MaemoSshRunner::handleMounted() { - ASSERT_STATE(QList() << Mounting << StopRequested); + ASSERT_STATE(Mounting); - if (m_state == Mounting) { - setState(ReadyForExecution); - emit readyForExecution(); + if (m_mountState == Mounting) { + m_mountState = Mounted; + handleInitializationsDone(true); } } void MaemoSshRunner::handleMounterError(const QString &errorMsg) { - ASSERT_STATE(QList() << PreRunCleaning << PostRunCleaning - << PreMountUnmounting << Mounting << StopRequested << Inactive); + ASSERT_STATE(QList() << InitialUnmounting << Mounting << PostRunUnmounting); - emitError(errorMsg); -} - -void MaemoSshRunner::startExecution(const QByteArray &remoteCall) -{ - ASSERT_STATE(ReadyForExecution); - - m_runner = m_connection->createRemoteProcess(remoteCall); - connect(m_runner.data(), SIGNAL(started()), this, - SIGNAL(remoteProcessStarted())); - connect(m_runner.data(), SIGNAL(closed(int)), this, - SLOT(handleRemoteProcessFinished(int))); - connect(m_runner.data(), SIGNAL(outputAvailable(QByteArray)), this, - SIGNAL(remoteOutput(QByteArray))); - connect(m_runner.data(), SIGNAL(errorOutputAvailable(QByteArray)), this, - SIGNAL(remoteErrorOutput(QByteArray))); - setState(ProcessStarting); - m_runner->start(); -} - -void MaemoSshRunner::handleRemoteProcessFinished(int exitStatus) -{ - Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart - || exitStatus == SshRemoteProcess::KilledBySignal - || exitStatus == SshRemoteProcess::ExitedNormally); - ASSERT_STATE(QList() << ProcessStarting << StopRequested << Inactive); - - m_exitStatus = exitStatus; - if (m_state != StopRequested && m_state != Inactive) { - setState(PostRunCleaning); - cleanup(); - } -} - -bool MaemoSshRunner::isConnectionUsable() const -{ - return m_connection && m_connection->state() == SshConnection::Connected - && m_connection->connectionParameters() == m_devConfig->sshParameters(); -} - -void MaemoSshRunner::setState(State newState) -{ - if (newState == Inactive) { - m_mounter->setConnection(SshConnection::Ptr(), m_devConfig); - m_portsGatherer->stop(); - if (m_connection) { - disconnect(m_connection.data(), 0, this, 0); - SshConnectionManager::instance().releaseConnection(m_connection); - m_connection = SshConnection::Ptr(); - } - if (m_cleaner) - disconnect(m_cleaner.data(), 0, this, 0); - } - m_state = newState; -} - -void MaemoSshRunner::emitError(const QString &errorMsg, bool force) -{ - if (m_state != Inactive) { - setState(Inactive); - emit error(errorMsg); - } else if (force) { - emit error(errorMsg); + const MountState oldMountState = m_mountState; + m_mountState = InactiveMountState; + emit error(errorMsg); + switch (oldMountState) { + case InitialUnmounting: + handleInitialCleanupDone(false); + break; + case Mounting: + handleInitializationsDone(false); + break; + case PostRunUnmounting: + handlePostRunCleanupDone(); + break; + default: + break; } } void MaemoSshRunner::mount() { - setState(Mounting); + m_mountState = Mounting; if (m_mounter->hasValidMountSpecifications()) { emit reportProgress(tr("Mounting host directories...")); - m_mounter->mount(freePorts(), m_portsGatherer); + m_mounter->mount(freePorts(), usedPortsGatherer()); } else { handleMounted(); } @@ -338,17 +173,14 @@ void MaemoSshRunner::mount() void MaemoSshRunner::unmount() { - ASSERT_STATE(QList() << PreRunCleaning << PreMountUnmounting - << PostRunCleaning << StopRequested); + ASSERT_STATE(QList() << InitialUnmounting << PostRunUnmounting); if (m_mounter->hasValidMountSpecifications()) { QString message; - switch (m_state) { - case PreRunCleaning: - message = tr("Unmounting left-over host directory mounts..."); - break; - case PreMountUnmounting: + switch (m_mountState) { + case InitialUnmounting: message = tr("Potentially unmounting left-over host directory mounts..."); - case StopRequested: case PostRunCleaning: + break; + case PostRunUnmounting: message = tr("Unmounting host directories..."); break; default: @@ -361,25 +193,6 @@ void MaemoSshRunner::unmount() } } -void MaemoSshRunner::handlePortsGathererError(const QString &errorMsg) -{ - emitError(errorMsg); -} - -void MaemoSshRunner::handleUsedPortsAvailable() -{ - ASSERT_STATE(QList() << GatheringPorts << StopRequested); - - if (m_state == StopRequested) { - setState(Inactive); - } else { - mount(); - } -} - -const qint64 MaemoSshRunner::InvalidExitCode - = std::numeric_limits::min(); - } // namespace Internal } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/maemosshrunner.h b/src/plugins/remotelinux/maemosshrunner.h index c8f2793ff6d..19649de36a1 100644 --- a/src/plugins/remotelinux/maemosshrunner.h +++ b/src/plugins/remotelinux/maemosshrunner.h @@ -32,99 +32,45 @@ #ifndef MAEMOSSHRUNNER_H #define MAEMOSSHRUNNER_H -#include "linuxdeviceconfiguration.h" +#include "remotelinuxapplicationrunner.h" #include "maemomountspecification.h" - -#include -#include -#include - -namespace Utils { - class SshConnection; - class SshRemoteProcess; -} +#include "maemorunconfiguration.h" namespace RemoteLinux { -class RemoteLinuxRunConfiguration; - namespace Internal { class MaemoRemoteMounter; -class MaemoUsedPortsGatherer; -class MaemoSshRunner : public QObject +class MaemoSshRunner : public RemoteLinuxApplicationRunner { Q_OBJECT public: - MaemoSshRunner(QObject *parent, RemoteLinuxRunConfiguration *runConfig); + MaemoSshRunner(QObject *parent, MaemoRunConfiguration *runConfig); ~MaemoSshRunner(); - void start(); - void stop(); - - void startExecution(const QByteArray &remoteCall); - - QSharedPointer connection() const { return m_connection; } - const MaemoUsedPortsGatherer *usedPortsGatherer() const { return m_portsGatherer; } - PortList *freePorts() { return &m_freePorts; } - QString remoteExecutable() const { return m_remoteExecutable; } - QString arguments() const { return m_appArguments; } - QString commandPrefix() const { return m_commandPrefix; } - const QSharedPointer devConfig() const { return m_devConfig; } - - static const qint64 InvalidExitCode; - signals: - void error(const QString &error); void mountDebugOutput(const QString &output); - void readyForExecution(); - void remoteOutput(const QByteArray &output); - void remoteErrorOutput(const QByteArray &output); - void reportProgress(const QString &progressOutput); - void remoteProcessStarted(); - void remoteProcessFinished(qint64 exitCode); private slots: - void handleConnected(); - void handleConnectionFailure(); - void handleCleanupFinished(int exitStatus); - void handleRemoteProcessFinished(int exitStatus); void handleMounted(); void handleUnmounted(); void handleMounterError(const QString &errorMsg); - void handlePortsGathererError(const QString &errorMsg); - void handleUsedPortsAvailable(); private: - enum State { Inactive, Connecting, PreRunCleaning, PostRunCleaning, - PreMountUnmounting, Mounting, ReadyForExecution, - ProcessStarting, StopRequested, GatheringPorts - }; + enum MountState { InactiveMountState, InitialUnmounting, Mounting, Mounted, PostRunUnmounting }; - void setState(State newState); - void emitError(const QString &errorMsg, bool force = false); + bool canRun(QString &whyNot) const; + void doAdditionalInitialCleanup(); + void doAdditionalInitializations(); + void doAdditionalPostRunCleanup(); + void doAdditionalConnectionErrorHandling(); - void cleanup(); - bool isConnectionUsable() const; void mount(); void unmount(); MaemoRemoteMounter * const m_mounter; - MaemoUsedPortsGatherer * const m_portsGatherer; - const QSharedPointer m_devConfig; - const QString m_remoteExecutable; - const QString m_appArguments; - const QString m_commandPrefix; - const PortList m_initialFreePorts; QList m_mountSpecs; - QSharedPointer m_connection; - QSharedPointer m_runner; - QSharedPointer m_cleaner; - QStringList m_procsToKill; - PortList m_freePorts; - - int m_exitStatus; - State m_state; + MountState m_mountState; }; } // namespace Internal diff --git a/src/plugins/remotelinux/publickeydeploymentdialog.cpp b/src/plugins/remotelinux/publickeydeploymentdialog.cpp new file mode 100644 index 00000000000..9fe831e1a57 --- /dev/null +++ b/src/plugins/remotelinux/publickeydeploymentdialog.cpp @@ -0,0 +1,123 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "publickeydeploymentdialog.h" + +#include "linuxdeviceconfiguration.h" +#include "maemokeydeployer.h" + +#include + +namespace RemoteLinux { +namespace Internal { +class PublicKeyDeploymentDialogPrivate +{ +public: + MaemoKeyDeployer *keyDeployer; + bool done; +}; +} // namespace Internal; + +using namespace Internal; + +PublicKeyDeploymentDialog::PublicKeyDeploymentDialog(const LinuxDeviceConfiguration::ConstPtr &deviceConfig, + QWidget *parent) + : QProgressDialog(parent), m_d(new PublicKeyDeploymentDialogPrivate) +{ + setAutoReset(false); + setAutoClose(false); + setMinimumDuration(0); + setMaximum(1); + + m_d->keyDeployer = new MaemoKeyDeployer(this); + m_d->done = false; + + setLabelText(tr("Waiting for file name...")); + const Utils::SshConnectionParameters sshParams = deviceConfig->sshParameters(); + const QString &dir = QFileInfo(sshParams.privateKeyFile).path(); + QString publicKeyFileName = QFileDialog::getOpenFileName(this, + tr("Choose Public Key File"), dir, + tr("Public Key Files(*.pub);;All Files (*)")); + if (publicKeyFileName.isEmpty()) { + reject(); + return; + } + + setLabelText(tr("Deploying...")); + setValue(0); + connect(this, SIGNAL(canceled()), SLOT(handleCanceled())); + connect(m_d->keyDeployer, SIGNAL(error(QString)), SLOT(handleDeploymentError(QString))); + connect(m_d->keyDeployer, SIGNAL(finishedSuccessfully()), SLOT(handleDeploymentSuccess())); + m_d->keyDeployer->deployPublicKey(sshParams, publicKeyFileName); +} + +PublicKeyDeploymentDialog::~PublicKeyDeploymentDialog() +{ + delete m_d; +} + +void PublicKeyDeploymentDialog::handleDeploymentSuccess() +{ + handleDeploymentFinished(QString()); + setValue(1); + m_d->done = true; +} + +void PublicKeyDeploymentDialog::handleDeploymentError(const QString &errorMsg) +{ + handleDeploymentFinished(errorMsg); +} + +void PublicKeyDeploymentDialog::handleDeploymentFinished(const QString &errorMsg) +{ + QString buttonText; + const char *textColor; + if (errorMsg.isEmpty()) { + buttonText = tr("Deployment finished successfully."); + textColor = "blue"; + } else { + buttonText = errorMsg; + textColor = "red"; + } + setLabelText(QString::fromLocal8Bit("%2").arg(textColor, buttonText)); + setCancelButtonText(tr("Close")); +} + +void PublicKeyDeploymentDialog::handleCanceled() +{ + disconnect(m_d->keyDeployer, 0, this, 0); + m_d->keyDeployer->stopDeployment(); + if (m_d->done) + accept(); + else + reject(); +} + +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/publickeydeploymentdialog.h b/src/plugins/remotelinux/publickeydeploymentdialog.h new file mode 100644 index 00000000000..b9ec9e8e15a --- /dev/null +++ b/src/plugins/remotelinux/publickeydeploymentdialog.h @@ -0,0 +1,71 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#ifndef PUBLICKEYDEPLOYMENTDIALOG_H +#define PUBLICKEYDEPLOYMENTDIALOG_H + +#include "remotelinux_export.h" + +#include +#include + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +namespace RemoteLinux { +class LinuxDeviceConfiguration; + +namespace Internal { +class PublicKeyDeploymentDialogPrivate; +} // namespace Internal + +class REMOTELINUX_EXPORT PublicKeyDeploymentDialog : public QProgressDialog +{ + Q_OBJECT +public: + explicit PublicKeyDeploymentDialog(const QSharedPointer &deviceConfig, + QWidget *parent = 0); + ~PublicKeyDeploymentDialog(); + +private slots: + void handleDeploymentError(const QString &errorMsg); + void handleDeploymentSuccess(); + void handleCanceled(); + +private: + void handleDeploymentFinished(const QString &errorMsg); + + Internal::PublicKeyDeploymentDialogPrivate * const m_d; +}; + +} // namespace RemoteLinux + +#endif // PUBLICKEYDEPLOYMENTDIALOG_H diff --git a/src/plugins/remotelinux/qt4maemotarget.cpp b/src/plugins/remotelinux/qt4maemotarget.cpp index 96324289a68..cb0fb20f832 100644 --- a/src/plugins/remotelinux/qt4maemotarget.cpp +++ b/src/plugins/remotelinux/qt4maemotarget.cpp @@ -34,7 +34,7 @@ #include "maemoglobal.h" #include "maemopackagecreationstep.h" -#include "remotelinuxrunconfiguration.h" +#include "maemorunconfiguration.h" #include "maemotoolchain.h" #include "qt4maemodeployconfiguration.h" @@ -166,12 +166,12 @@ void AbstractQt4MaemoTarget::createApplicationProFiles() paths << pro->path(); foreach (ProjectExplorer::RunConfiguration *rc, runConfigurations()) - if (RemoteLinuxRunConfiguration *qt4rc = qobject_cast(rc)) + if (MaemoRunConfiguration *qt4rc = qobject_cast(rc)) paths.remove(qt4rc->proFilePath()); // Only add new runconfigurations if there are none. foreach (const QString &path, paths) - addRunConfiguration(new RemoteLinuxRunConfiguration(this, path)); + addRunConfiguration(new MaemoRunConfiguration(this, path)); // Oh still none? Add a custom executable runconfiguration if (runConfigurations().isEmpty()) { @@ -183,7 +183,7 @@ QList AbstractQt4MaemoTarget::runConfigurat { QList result; foreach (ProjectExplorer::RunConfiguration *rc, runConfigurations()) - if (RemoteLinuxRunConfiguration *mrc = qobject_cast(rc)) + if (MaemoRunConfiguration *mrc = qobject_cast(rc)) if (mrc->proFilePath() == n->path()) result << rc; return result; diff --git a/src/plugins/remotelinux/remotelinux.pro b/src/plugins/remotelinux/remotelinux.pro index 42142d7edc7..eb9fb155777 100644 --- a/src/plugins/remotelinux/remotelinux.pro +++ b/src/plugins/remotelinux/remotelinux.pro @@ -73,7 +73,18 @@ HEADERS += \ linuxdeviceconfigurations.h \ remotelinuxrunconfiguration.h \ linuxdevicefactoryselectiondialog.h \ - deviceconfigurationfactory.h + publickeydeploymentdialog.h \ + genericlinuxdeviceconfigurationwizard.h \ + genericlinuxdeviceconfigurationwizardsetuppage.h \ + genericlinuxdeviceconfigurationfactory.h \ + maddedeviceconfigurationfactory.h \ + maemorunconfiguration.h \ + remotelinuxrunconfigurationwidget.h \ + remotelinuxrunconfigurationfactory.h \ + remotelinuxapplicationrunner.h \ + remotelinuxruncontrol.h \ + remotelinuxruncontrolfactory.h \ + remotelinuxdebugsupport.h SOURCES += \ remotelinuxplugin.cpp \ @@ -138,7 +149,18 @@ SOURCES += \ linuxdeviceconfigurations.cpp \ remotelinuxrunconfiguration.cpp \ linuxdevicefactoryselectiondialog.cpp \ - deviceconfigurationfactory.cpp + publickeydeploymentdialog.cpp \ + genericlinuxdeviceconfigurationwizard.cpp \ + genericlinuxdeviceconfigurationwizardsetuppage.cpp \ + genericlinuxdeviceconfigurationfactory.cpp \ + maddedeviceconfigurationfactory.cpp \ + maemorunconfiguration.cpp \ + remotelinuxrunconfigurationwidget.cpp \ + remotelinuxrunconfigurationfactory.cpp \ + remotelinuxapplicationrunner.cpp \ + remotelinuxruncontrol.cpp \ + remotelinuxruncontrolfactory.cpp \ + remotelinuxdebugsupport.cpp FORMS += \ maemoconfigtestdialog.ui \ @@ -160,7 +182,8 @@ FORMS += \ maemodeviceconfigwizardkeydeploymentpage.ui \ maemodeployconfigurationwidget.ui \ maemodeviceconfigwizardlogindatapage.ui \ - linuxdevicefactoryselectiondialog.ui + linuxdevicefactoryselectiondialog.ui \ + genericlinuxdeviceconfigurationwizardsetuppage.ui RESOURCES += qt-maemo.qrc DEFINES += QT_NO_CAST_TO_ASCII diff --git a/src/plugins/remotelinux/remotelinuxapplicationrunner.cpp b/src/plugins/remotelinux/remotelinuxapplicationrunner.cpp new file mode 100644 index 00000000000..02cb92e9bc5 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxapplicationrunner.cpp @@ -0,0 +1,403 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "remotelinuxapplicationrunner.h" + +#include "maemoglobal.h" +#include "remotelinuxrunconfiguration.h" +#include "maemousedportsgatherer.h" + +#include +#include +#include +#include + +#include + +#include + +#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(State, state, m_state) + +using namespace Qt4ProjectManager; +using namespace Utils; + +namespace RemoteLinux { +using namespace Internal; + +RemoteLinuxApplicationRunner::RemoteLinuxApplicationRunner(QObject *parent, + RemoteLinuxRunConfiguration *runConfig) + : QObject(parent), + m_portsGatherer(new MaemoUsedPortsGatherer(this)), + m_devConfig(runConfig->deviceConfig()), + m_remoteExecutable(runConfig->remoteExecutableFilePath()), + m_appArguments(runConfig->arguments()), + m_commandPrefix(runConfig->commandPrefix()), + m_initialFreePorts(runConfig->freePorts()), + m_stopRequested(false), + m_state(Inactive) +{ + m_procsToKill << QFileInfo(m_remoteExecutable).fileName(); + connect(m_portsGatherer, SIGNAL(error(QString)), SLOT(handlePortsGathererError(QString))); + connect(m_portsGatherer, SIGNAL(portListReady()), SLOT(handleUsedPortsAvailable())); +} + +RemoteLinuxApplicationRunner::~RemoteLinuxApplicationRunner() {} + +void RemoteLinuxApplicationRunner::start() +{ + QTC_ASSERT(!m_stopRequested, return); + ASSERT_STATE(Inactive); + + QString errorMsg; + if (!canRun(errorMsg)) { + emitError(tr("Cannot run: %1").arg(errorMsg), true); + return; + } + + m_connection = SshConnectionManager::instance().acquireConnection(m_devConfig->sshParameters()); + setState(Connecting); + m_exitStatus = -1; + m_freePorts = m_initialFreePorts; + connect(m_connection.data(), SIGNAL(connected()), this, + SLOT(handleConnected())); + connect(m_connection.data(), SIGNAL(error(Utils::SshError)), this, + SLOT(handleConnectionFailure())); + if (isConnectionUsable()) { + handleConnected(); + } else { + emit reportProgress(tr("Connecting to device...")); + m_connection->connectToHost(); + } +} + +void RemoteLinuxApplicationRunner::stop() +{ + if (m_stopRequested) + return; + + switch (m_state) { + case Connecting: + setState(Inactive); + emit remoteProcessFinished(InvalidExitCode); + break; + case GatheringPorts: + m_portsGatherer->stop(); + setState(Inactive); + emit remoteProcessFinished(InvalidExitCode); + break; + case PreRunCleaning: + case AdditionalPreRunCleaning: + case AdditionalInitializing: + case ProcessStarting: + case PostRunCleaning: + case AdditionalPostRunCleaning: + m_stopRequested = true; + break; + case ReadyForExecution: + m_stopRequested = true; + setState(AdditionalPostRunCleaning); + doAdditionalPostRunCleanup(); + break; + case ProcessStarted: + m_stopRequested = true; + cleanup(); + break; + case Inactive: + break; + } +} + +void RemoteLinuxApplicationRunner::handleConnected() +{ + ASSERT_STATE(Connecting); + if (m_stopRequested) { + emit remoteProcessFinished(InvalidExitCode); + setState(Inactive); + } else { + setState(PreRunCleaning); + cleanup(); + } +} + +void RemoteLinuxApplicationRunner::handleConnectionFailure() +{ + if (m_state == Inactive) { + qWarning("Unexpected state %d in %s.", m_state, Q_FUNC_INFO); + return; + } + + if (m_state != Connecting || m_state != PreRunCleaning) + doAdditionalConnectionErrorHandling(); + + const QString errorMsg = m_state == Connecting + ? MaemoGlobal::failedToConnectToServerMessage(m_connection, m_devConfig) + : tr("Connection error: %1").arg(m_connection->errorString()); + emitError(errorMsg); +} + +void RemoteLinuxApplicationRunner::cleanup() +{ + ASSERT_STATE(QList() << PreRunCleaning << PostRunCleaning << ProcessStarted); + + emit reportProgress(tr("Killing remote process(es)...")); + + // pkill behaves differently on Fremantle and Harmattan. + const char *const killTemplate = "pkill -%2 '^%1$'; pkill -%2 '/%1$';"; + QString niceKill; + QString brutalKill; + foreach (const QString &proc, m_procsToKill) { + niceKill += QString::fromLocal8Bit(killTemplate).arg(proc).arg("SIGTERM"); + brutalKill += QString::fromLocal8Bit(killTemplate).arg(proc).arg("SIGKILL"); + } + QString remoteCall = niceKill + QLatin1String("sleep 1; ") + brutalKill; + remoteCall.remove(remoteCall.count() - 1, 1); // Get rid of trailing semicolon. + + m_cleaner = m_connection->createRemoteProcess(remoteCall.toUtf8()); + connect(m_cleaner.data(), SIGNAL(closed(int)), this, + SLOT(handleCleanupFinished(int))); + m_cleaner->start(); +} + +void RemoteLinuxApplicationRunner::handleCleanupFinished(int exitStatus) +{ + Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart + || exitStatus == SshRemoteProcess::KilledBySignal + || exitStatus == SshRemoteProcess::ExitedNormally); + + ASSERT_STATE(QList() << PreRunCleaning << PostRunCleaning << ProcessStarted << Inactive); + + if (m_state == Inactive) + return; + if (m_stopRequested && m_state == PreRunCleaning) { + setState(Inactive); + emit remoteProcessFinished(InvalidExitCode); + return; + } + if (m_stopRequested || m_state == PostRunCleaning) { + setState(AdditionalPostRunCleaning); + doAdditionalPostRunCleanup(); + return; + } + + if (exitStatus != SshRemoteProcess::ExitedNormally) { + emitError(tr("Initial cleanup failed: %1").arg(m_cleaner->errorString())); + return; + } + + setState(AdditionalPreRunCleaning); + doAdditionalInitialCleanup(); +} + +void RemoteLinuxApplicationRunner::startExecution(const QByteArray &remoteCall) +{ + ASSERT_STATE(ReadyForExecution); + + if (m_stopRequested) + return; + + m_runner = m_connection->createRemoteProcess(remoteCall); + connect(m_runner.data(), SIGNAL(started()), this, + SLOT(handleRemoteProcessStarted())); + connect(m_runner.data(), SIGNAL(closed(int)), this, + SLOT(handleRemoteProcessFinished(int))); + connect(m_runner.data(), SIGNAL(outputAvailable(QByteArray)), this, + SIGNAL(remoteOutput(QByteArray))); + connect(m_runner.data(), SIGNAL(errorOutputAvailable(QByteArray)), this, + SIGNAL(remoteErrorOutput(QByteArray))); + setState(ProcessStarting); + m_runner->start(); +} + +void RemoteLinuxApplicationRunner::handleRemoteProcessStarted() +{ + ASSERT_STATE(ProcessStarting); + + setState(ProcessStarted); + if (m_stopRequested) { + cleanup(); + return; + } + + emit reportProgress(tr("Remote process started.")); + emit remoteProcessStarted(); +} + +void RemoteLinuxApplicationRunner::handleRemoteProcessFinished(int exitStatus) +{ + Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart + || exitStatus == SshRemoteProcess::KilledBySignal + || exitStatus == SshRemoteProcess::ExitedNormally); + ASSERT_STATE(QList() << ProcessStarted << Inactive); + + m_exitStatus = exitStatus; + if (!m_stopRequested && m_state != Inactive) { + setState(PostRunCleaning); + cleanup(); + } +} + +bool RemoteLinuxApplicationRunner::isConnectionUsable() const +{ + return m_connection && m_connection->state() == SshConnection::Connected + && m_connection->connectionParameters() == m_devConfig->sshParameters(); +} + +void RemoteLinuxApplicationRunner::setState(State newState) +{ + if (newState == Inactive) { + m_portsGatherer->stop(); + if (m_connection) { + disconnect(m_connection.data(), 0, this, 0); + SshConnectionManager::instance().releaseConnection(m_connection); + m_connection = SshConnection::Ptr(); + } + if (m_cleaner) + disconnect(m_cleaner.data(), 0, this, 0); + m_stopRequested = false; + } + m_state = newState; +} + +void RemoteLinuxApplicationRunner::emitError(const QString &errorMsg, bool force) +{ + if (m_state != Inactive) { + setState(Inactive); + emit error(errorMsg); + } else if (force) { + emit error(errorMsg); + } +} + +void RemoteLinuxApplicationRunner::handlePortsGathererError(const QString &errorMsg) +{ + if (m_state != Inactive) + emitError(errorMsg); +} + +void RemoteLinuxApplicationRunner::handleUsedPortsAvailable() +{ + ASSERT_STATE(GatheringPorts); + + if (m_stopRequested) { + setState(Inactive); + emit remoteProcessFinished(InvalidExitCode); + return; + } + + setState(AdditionalInitializing); + doAdditionalInitializations(); +} + +bool RemoteLinuxApplicationRunner::canRun(QString &whyNot) const +{ + if (m_remoteExecutable.isEmpty()) { + whyNot = tr("No remote executable set."); + return false; + } + + if (!m_devConfig) { + whyNot = tr("No device configuration set."); + return false; + } + + return true; +} + +void RemoteLinuxApplicationRunner::doAdditionalInitialCleanup() +{ + handleInitialCleanupDone(true); +} + +void RemoteLinuxApplicationRunner::doAdditionalInitializations() +{ + handleInitializationsDone(true); +} + +void RemoteLinuxApplicationRunner::doAdditionalPostRunCleanup() +{ + handlePostRunCleanupDone(); +} + +void RemoteLinuxApplicationRunner::handleInitialCleanupDone(bool success) +{ + ASSERT_STATE(AdditionalPreRunCleaning); + + if (m_state != AdditionalPreRunCleaning) + return; + if (!success || m_stopRequested) { + setState(Inactive); + emit remoteProcessFinished(InvalidExitCode); + return; + } + + setState(GatheringPorts); + m_portsGatherer->start(m_connection, m_devConfig); +} + +void RemoteLinuxApplicationRunner::handleInitializationsDone(bool success) +{ + ASSERT_STATE(AdditionalInitializing); + + if (m_state != AdditionalInitializing) + return; + if (!success) { + setState(Inactive); + emit remoteProcessFinished(InvalidExitCode); + return; + } + if (m_stopRequested) { + setState(AdditionalPostRunCleaning); + doAdditionalPostRunCleanup(); + return; + } + + setState(ReadyForExecution); + emit readyForExecution(); +} + +void RemoteLinuxApplicationRunner::handlePostRunCleanupDone() +{ + ASSERT_STATE(AdditionalPostRunCleaning); + + const bool wasStopRequested = m_stopRequested; + setState(Inactive); + if (wasStopRequested) + emit remoteProcessFinished(InvalidExitCode); + else if (m_exitStatus == SshRemoteProcess::ExitedNormally) + emit remoteProcessFinished(m_runner->exitCode()); + else + emit error(tr("Error running remote process: %1").arg(m_runner->errorString())); +} + +const qint64 RemoteLinuxApplicationRunner::InvalidExitCode = std::numeric_limits::min(); + +} // namespace RemoteLinux + diff --git a/src/plugins/remotelinux/remotelinuxapplicationrunner.h b/src/plugins/remotelinux/remotelinuxapplicationrunner.h new file mode 100644 index 00000000000..12a1bd599d2 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxapplicationrunner.h @@ -0,0 +1,143 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef REMOTELINUXAPPLICATIONRUNNER_H +#define REMOTELINUXAPPLICATIONRUNNER_H + +#include "linuxdeviceconfiguration.h" +#include "remotelinux_export.h" + +#include +#include +#include + +namespace Utils { +class SshConnection; +class SshRemoteProcess; +} + +namespace RemoteLinux { +class RemoteLinuxRunConfiguration; + +namespace Internal { class MaemoUsedPortsGatherer; } + +class REMOTELINUX_EXPORT RemoteLinuxApplicationRunner : public QObject +{ + Q_OBJECT +public: + RemoteLinuxApplicationRunner(QObject *parent, RemoteLinuxRunConfiguration *runConfig); + ~RemoteLinuxApplicationRunner(); + + void start(); + void stop(); + + void startExecution(const QByteArray &remoteCall); + + QSharedPointer connection() const { return m_connection; } + const Internal::MaemoUsedPortsGatherer *usedPortsGatherer() const { return m_portsGatherer; } + PortList *freePorts() { return &m_freePorts; } + QString remoteExecutable() const { return m_remoteExecutable; } + QString arguments() const { return m_appArguments; } + QString commandPrefix() const { return m_commandPrefix; } + const QSharedPointer devConfig() const { return m_devConfig; } + + static const qint64 InvalidExitCode; + +signals: + void error(const QString &error); + void readyForExecution(); + void remoteOutput(const QByteArray &output); + void remoteErrorOutput(const QByteArray &output); + void reportProgress(const QString &progressOutput); + void remoteProcessStarted(); + void remoteProcessFinished(qint64 exitCode); + +protected: + // Override to to additional checks. + virtual bool canRun(QString &whyNot) const; + + void handleInitialCleanupDone(bool success); + void handleInitializationsDone(bool success); + void handlePostRunCleanupDone(); + +private slots: + void handleConnected(); + void handleConnectionFailure(); + void handleCleanupFinished(int exitStatus); + void handleRemoteProcessStarted(); + void handleRemoteProcessFinished(int exitStatus); + void handlePortsGathererError(const QString &errorMsg); + void handleUsedPortsAvailable(); + +private: + enum State { Inactive, Connecting, PreRunCleaning, AdditionalPreRunCleaning, GatheringPorts, + AdditionalInitializing, ReadyForExecution, ProcessStarting, ProcessStarted, PostRunCleaning, + AdditionalPostRunCleaning + }; + + // Override to do additional pre-run cleanup and call handleInitialCleanupDone(). + virtual void doAdditionalInitialCleanup(); + + // Override to do additional initializations right before the application is ready. + // Call handleInitializationsDone() afterwards. + virtual void doAdditionalInitializations(); + + // Override for additional cleanups after application exit and call handlePostRunCleanupDone(); + virtual void doAdditionalPostRunCleanup(); + + virtual void doAdditionalConnectionErrorHandling() {} + + void setState(State newState); + void emitError(const QString &errorMsg, bool force = false); + void cleanup(); + bool isConnectionUsable() const; + + Internal::MaemoUsedPortsGatherer * const m_portsGatherer; + const QSharedPointer m_devConfig; + const QString m_remoteExecutable; + const QString m_appArguments; + const QString m_commandPrefix; + const PortList m_initialFreePorts; + + QSharedPointer m_connection; + QSharedPointer m_runner; + QSharedPointer m_cleaner; + QStringList m_procsToKill; + PortList m_freePorts; + + int m_exitStatus; + bool m_stopRequested; + State m_state; +}; + +} // namespace RemoteLinux + +#endif // REMOTELINUXAPPLICATIONRUNNER_H diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp new file mode 100644 index 00000000000..1940b3debce --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -0,0 +1,282 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "remotelinuxdebugsupport.h" + +#include "maemodeployables.h" +#include "maemoglobal.h" +#include "maemousedportsgatherer.h" +#include "qt4maemotarget.h" +#include "remotelinuxapplicationrunner.h" + +#include +#include +#include + +#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(State, state, m_state) + +using namespace Utils; +using namespace Debugger; +using namespace ProjectExplorer; + +namespace RemoteLinux { +using namespace Internal; + +DebuggerStartParameters AbstractRemoteLinuxDebugSupport::startParameters(const RemoteLinuxRunConfiguration *runConfig) +{ + DebuggerStartParameters params; + const LinuxDeviceConfiguration::ConstPtr &devConf = runConfig->deviceConfig(); + const RemoteLinuxRunConfiguration::DebuggingType debuggingType + = runConfig->debuggingType(); + if (debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) { + params.qmlServerAddress = runConfig->deviceConfig()->sshParameters().host; + params.qmlServerPort = -1; + } + if (debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) { + params.processArgs = runConfig->arguments(); + if (runConfig->activeQt4BuildConfiguration()->qtVersion()) + params.sysroot = runConfig->activeQt4BuildConfiguration()->qtVersion()->systemRoot(); + params.toolChainAbi = runConfig->abi(); + params.startMode = AttachToRemote; + params.executable = runConfig->localExecutableFilePath(); + params.debuggerCommand = runConfig->gdbCmd(); + params.remoteChannel = devConf->sshParameters().host + QLatin1String(":-1"); + params.useServerStartScript = true; + + // TODO: This functionality should be inside the debugger. + const ProjectExplorer::Abi &abi = runConfig->target() + ->activeBuildConfiguration()->toolChain()->targetAbi(); + params.remoteArchitecture = abi.toString(); + params.gnuTarget = QLatin1String(abi.architecture() == ProjectExplorer::Abi::ArmArchitecture + ? "arm-none-linux-gnueabi": "i386-unknown-linux-gnu"); + } else { + params.startMode = AttachToRemote; + } + params.displayName = runConfig->displayName(); + + if (const ProjectExplorer::Project *project = runConfig->target()->project()) { + params.projectSourceDirectory = project->projectDirectory(); + if (const ProjectExplorer::BuildConfiguration *buildConfig = runConfig->target()->activeBuildConfiguration()) { + params.projectBuildDirectory = buildConfig->buildDirectory(); + } + params.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); + } + + return params; +} + +AbstractRemoteLinuxDebugSupport::AbstractRemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig, DebuggerEngine *engine) + : QObject(engine), m_engine(engine), m_runConfig(runConfig), + m_deviceConfig(m_runConfig->deviceConfig()), + m_debuggingType(runConfig->debuggingType()), + m_state(Inactive), m_gdbServerPort(-1), m_qmlPort(-1) +{ + connect(m_engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleAdapterSetupRequested())); +} + +AbstractRemoteLinuxDebugSupport::~AbstractRemoteLinuxDebugSupport() +{ + setState(Inactive); +} + +void AbstractRemoteLinuxDebugSupport::showMessage(const QString &msg, int channel) +{ + if (m_engine) + m_engine->showMessage(msg, channel); +} + +void AbstractRemoteLinuxDebugSupport::handleAdapterSetupRequested() +{ + ASSERT_STATE(Inactive); + + setState(StartingRunner); + showMessage(tr("Preparing remote side ...\n"), AppStuff); + disconnect(runner(), 0, this, 0); + connect(runner(), SIGNAL(error(QString)), this, SLOT(handleSshError(QString))); + connect(runner(), SIGNAL(readyForExecution()), this, SLOT(startExecution())); + connect(runner(), SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString))); + runner()->start(); +} + +void AbstractRemoteLinuxDebugSupport::handleSshError(const QString &error) +{ + if (m_state == Debugging) { + showMessage(error, AppError); + if (m_engine) + m_engine->notifyInferiorIll(); + } else if (m_state != Inactive) { + handleAdapterSetupFailed(error); + } +} + +void AbstractRemoteLinuxDebugSupport::startExecution() +{ + if (m_state == Inactive) + return; + + ASSERT_STATE(StartingRunner); + + if (m_debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) { + if (!setPort(m_gdbServerPort)) + return; + } + if (m_debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) { + if (!setPort(m_qmlPort)) + return; + } + + setState(StartingRemoteProcess); + m_gdbserverOutput.clear(); + connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)), this, + SLOT(handleRemoteErrorOutput(QByteArray))); + connect(runner(), SIGNAL(remoteOutput(QByteArray)), this, + SLOT(handleRemoteOutput(QByteArray))); + if (m_debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly) { + connect(runner(), SIGNAL(remoteProcessStarted()), + SLOT(handleRemoteProcessStarted())); + } + const QString &remoteExe = runner()->remoteExecutable(); + QString args = runner()->arguments(); + if (m_debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) { + args += QString(QLatin1String(" -qmljsdebugger=port:%1,block")) + .arg(m_qmlPort); + } + + const QString remoteCommandLine = m_debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly + ? QString::fromLocal8Bit("%1 %2 %3").arg(runner()->commandPrefix()).arg(remoteExe).arg(args) + : QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4").arg(runner()->commandPrefix()) + .arg(m_gdbServerPort).arg(remoteExe).arg(args); + connect(runner(), SIGNAL(remoteProcessFinished(qint64)), + SLOT(handleRemoteProcessFinished(qint64))); + runner()->startExecution(remoteCommandLine.toUtf8()); +} + +void AbstractRemoteLinuxDebugSupport::handleRemoteProcessFinished(qint64 exitCode) +{ + if (!m_engine || m_state == Inactive || exitCode == 0) + return; + + if (m_state == Debugging) { + if (m_debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) + m_engine->notifyInferiorIll(); + } else { + const QString errorMsg = m_debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly + ? tr("Remote application failed with exit code %1.").arg(exitCode) + : tr("The gdbserver process closed unexpectedly."); + m_engine->handleRemoteSetupFailed(errorMsg); + } +} + +void AbstractRemoteLinuxDebugSupport::handleDebuggingFinished() +{ + setState(Inactive); +} + +void AbstractRemoteLinuxDebugSupport::handleRemoteOutput(const QByteArray &output) +{ + ASSERT_STATE(QList() << Inactive << Debugging); + showMessage(QString::fromUtf8(output), AppOutput); +} + +void AbstractRemoteLinuxDebugSupport::handleRemoteErrorOutput(const QByteArray &output) +{ + ASSERT_STATE(QList() << Inactive << StartingRemoteProcess << Debugging); + + if (!m_engine) + return; + + showMessage(QString::fromUtf8(output), AppOutput); + if (m_state == StartingRemoteProcess + && m_debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) { + m_gdbserverOutput += output; + if (m_gdbserverOutput.contains("Listening on port")) { + handleAdapterSetupDone(); + m_gdbserverOutput.clear(); + } + } +} + +void AbstractRemoteLinuxDebugSupport::handleProgressReport(const QString &progressOutput) +{ + showMessage(progressOutput + QLatin1Char('\n'), AppStuff); +} + +void AbstractRemoteLinuxDebugSupport::handleAdapterSetupFailed(const QString &error) +{ + setState(Inactive); + m_engine->handleRemoteSetupFailed(tr("Initial setup failed: %1").arg(error)); +} + +void AbstractRemoteLinuxDebugSupport::handleAdapterSetupDone() +{ + setState(Debugging); + m_engine->handleRemoteSetupDone(m_gdbServerPort, m_qmlPort); +} + +void AbstractRemoteLinuxDebugSupport::handleRemoteProcessStarted() +{ + Q_ASSERT(m_debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly); + ASSERT_STATE(StartingRemoteProcess); + handleAdapterSetupDone(); +} + +void AbstractRemoteLinuxDebugSupport::setState(State newState) +{ + if (m_state == newState) + return; + m_state = newState; + if (m_state == Inactive) + runner()->stop(); +} + +bool AbstractRemoteLinuxDebugSupport::setPort(int &port) +{ + port = runner()->usedPortsGatherer()->getNextFreePort(runner()->freePorts()); + if (port == -1) { + handleAdapterSetupFailed(tr("Not enough free ports on device for debugging.")); + return false; + } + return true; +} + + +RemoteLinuxDebugSupport::RemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig, + DebuggerEngine *engine) + : AbstractRemoteLinuxDebugSupport(runConfig, engine), + m_runner(new RemoteLinuxApplicationRunner(this, runConfig)) +{ +} + +RemoteLinuxDebugSupport::~RemoteLinuxDebugSupport() +{ +} + +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.h b/src/plugins/remotelinux/remotelinuxdebugsupport.h new file mode 100644 index 00000000000..b8c1b6e4f28 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.h @@ -0,0 +1,112 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef REMOTELINUXDEBUGSUPPORT_H +#define REMOTELINUXDEBUGSUPPORT_H + +#include "remotelinux_export.h" +#include "remotelinuxrunconfiguration.h" + +#include + +#include +#include +#include + +namespace Debugger { +class DebuggerEngine; +} +namespace ProjectExplorer { class RunControl; } + +namespace RemoteLinux { +class LinuxDeviceConfiguration; +class RemoteLinuxRunConfiguration; +class RemoteLinuxApplicationRunner; + +class REMOTELINUX_EXPORT AbstractRemoteLinuxDebugSupport : public QObject +{ + Q_OBJECT +public: + static Debugger::DebuggerStartParameters startParameters(const RemoteLinuxRunConfiguration *runConfig); + + AbstractRemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig, Debugger::DebuggerEngine *engine); + ~AbstractRemoteLinuxDebugSupport(); + +private slots: + void handleAdapterSetupRequested(); + void handleSshError(const QString &error); + void startExecution(); + void handleDebuggingFinished(); + void handleRemoteOutput(const QByteArray &output); + void handleRemoteErrorOutput(const QByteArray &output); + void handleProgressReport(const QString &progressOutput); + void handleRemoteProcessStarted(); + void handleRemoteProcessFinished(qint64 exitCode); + +private: + enum State { Inactive, StartingRunner, StartingRemoteProcess, Debugging }; + + virtual RemoteLinuxApplicationRunner *runner() const=0; + + void handleAdapterSetupFailed(const QString &error); + void handleAdapterSetupDone(); + void setState(State newState); + bool setPort(int &port); + void showMessage(const QString &msg, int channel); + + const QPointer m_engine; + const QPointer m_runConfig; + const QSharedPointer m_deviceConfig; + const RemoteLinuxRunConfiguration::DebuggingType m_debuggingType; + + QByteArray m_gdbserverOutput; + State m_state; + int m_gdbServerPort; + int m_qmlPort; +}; + + +class REMOTELINUX_EXPORT RemoteLinuxDebugSupport : public AbstractRemoteLinuxDebugSupport +{ + Q_OBJECT +public: + RemoteLinuxDebugSupport(RemoteLinuxRunConfiguration * runConfig, Debugger::DebuggerEngine *engine); + ~RemoteLinuxDebugSupport(); + +private: + RemoteLinuxApplicationRunner *runner() const { return m_runner; } + + RemoteLinuxApplicationRunner * const m_runner; +}; + +} // namespace RemoteLinux + +#endif // REMOTELINUXDEBUGSUPPORT_H diff --git a/src/plugins/remotelinux/remotelinuxplugin.cpp b/src/plugins/remotelinux/remotelinuxplugin.cpp index 5169e2855fc..3ee7d6be190 100644 --- a/src/plugins/remotelinux/remotelinuxplugin.cpp +++ b/src/plugins/remotelinux/remotelinuxplugin.cpp @@ -32,6 +32,8 @@ #include "remotelinuxplugin.h" +#include "genericlinuxdeviceconfigurationfactory.h" +#include "maddedeviceconfigurationfactory.h" #include "maemoconstants.h" #include "maemodeployable.h" #include "maemodeploystepfactory.h" @@ -48,6 +50,8 @@ #include "maemoqtversionfactory.h" #include "qt4maemotargetfactory.h" #include "qt4projectmanager/qt4projectmanagerconstants.h" +#include "remotelinuxrunconfigurationfactory.h" +#include "remotelinuxruncontrolfactory.h" #include @@ -82,7 +86,10 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments, addAutoReleasedObject(new MaemoPublishingWizardFactoryFremantleFree); addAutoReleasedObject(new Qt4MaemoTargetFactory); addAutoReleasedObject(new MaemoQtVersionFactory); - addAutoReleasedObject(new DeviceConfigurationFactory); + addAutoReleasedObject(new GenericLinuxDeviceConfigurationFactory); + addAutoReleasedObject(new MaddeDeviceConfigurationFactory); + addAutoReleasedObject(new RemoteLinuxRunConfigurationFactory); + addAutoReleasedObject(new RemoteLinuxRunControlFactory); qRegisterMetaType("MaemoDeployable"); diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp index ed17359b8cf..cb5132f3c43 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp @@ -35,21 +35,13 @@ #include "abstractlinuxdevicedeploystep.h" #include "maemodeployables.h" #include "maemoglobal.h" -#include "maemoqemumanager.h" -#include "maemoremotemountsmodel.h" -#include "maemorunconfigurationwidget.h" +#include "maemoqtversion.h" #include "maemotoolchain.h" #include "qt4maemodeployconfiguration.h" #include "qt4maemotarget.h" -#include "maemoqtversion.h" - -#include -#include - -#include +#include "remotelinuxrunconfigurationwidget.h" #include -#include #include #include @@ -91,7 +83,6 @@ public: QString proFilePath; QString gdbPath; - MaemoRemoteMountsModel *remoteMounts; QString arguments; RemoteLinuxRunConfiguration::BaseEnvironmentType baseEnvironmentType; Utils::Environment systemEnvironment; @@ -104,9 +95,9 @@ public: using namespace Internal; -RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Qt4BaseTarget *parent, +RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Qt4BaseTarget *parent, const QString &id, const QString &proFilePath) - : RunConfiguration(parent, QLatin1String(MAEMO_RC_ID)), + : RunConfiguration(parent, id), m_d(new RemoteLinuxRunConfigurationPrivate(proFilePath, parent)) { init(); @@ -125,7 +116,6 @@ void RemoteLinuxRunConfiguration::init() setDefaultDisplayName(defaultDisplayName()); setUseCppDebugger(true); setUseQmlDebugger(false); - m_d->remoteMounts = new MaemoRemoteMountsModel(this); connect(target(), SIGNAL(activeDeployConfigurationChanged(ProjectExplorer::DeployConfiguration*)), @@ -136,13 +126,6 @@ void RemoteLinuxRunConfiguration::init() connect(pro, SIGNAL(proFileUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)), this, SLOT(proFileUpdate(Qt4ProjectManager::Qt4ProFileNode*,bool,bool))); connect(this, SIGNAL(debuggersChanged()), SLOT(updateEnabledState())); - connect(m_d->remoteMounts, SIGNAL(rowsInserted(QModelIndex, int, int)), this, - SLOT(handleRemoteMountsChanged())); - connect(m_d->remoteMounts, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, - SLOT(handleRemoteMountsChanged())); - connect(m_d->remoteMounts, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, - SLOT(handleRemoteMountsChanged())); - connect(m_d->remoteMounts, SIGNAL(modelReset()), SLOT(handleRemoteMountsChanged())); connect(target(), SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)), SLOT(updateEnabledState())); } @@ -183,10 +166,6 @@ bool RemoteLinuxRunConfiguration::isEnabled() const m_d->disabledReason = tr("Don't know what to run."); return false; } - if (!hasEnoughFreePorts(ProjectExplorer::Constants::RUNMODE)) { - m_d->disabledReason = tr("Not enough free ports on the device."); - return false; - } m_d->disabledReason.clear(); return true; } @@ -198,7 +177,7 @@ QString RemoteLinuxRunConfiguration::disabledReason() const QWidget *RemoteLinuxRunConfiguration::createConfigurationWidget() { - return new MaemoRunConfigurationWidget(this); + return new RemoteLinuxRunConfigurationWidget(this); } Utils::OutputFormatter *RemoteLinuxRunConfiguration::createOutputFormatter() const @@ -228,7 +207,6 @@ QVariantMap RemoteLinuxRunConfiguration::toMap() const map.insert(BaseEnvironmentBaseKey, m_d->baseEnvironmentType); map.insert(UserEnvironmentChangesKey, Utils::EnvironmentItem::toStringList(m_d->userEnvironmentChanges)); - map.unite(m_d->remoteMounts->toMap()); return map; } @@ -245,7 +223,6 @@ bool RemoteLinuxRunConfiguration::fromMap(const QVariantMap &map) .toStringList()); m_d->baseEnvironmentType = static_cast (map.value(BaseEnvironmentBaseKey, SystemBaseEnvironment).toInt()); - m_d->remoteMounts->fromMap(map); m_d->validParse = qt4Target()->qt4Project()->validParse(m_d->proFilePath); m_d->parseInProgress = qt4Target()->qt4Project()->parseInProgress(m_d->proFilePath); @@ -279,11 +256,6 @@ Qt4MaemoDeployConfiguration *RemoteLinuxRunConfiguration::deployConfig() const return qobject_cast(target()->activeDeployConfiguration()); } -MaemoRemoteMountsModel *RemoteLinuxRunConfiguration::remoteMounts() const -{ - return m_d->remoteMounts; -} - AbstractLinuxDeviceDeployStep *RemoteLinuxRunConfiguration::deployStep() const { return MaemoGlobal::earlierBuildStep(deployConfig(), 0); @@ -296,12 +268,8 @@ QString RemoteLinuxRunConfiguration::arguments() const QString RemoteLinuxRunConfiguration::commandPrefix() const { - if (!deviceConfig()) - return QString(); - - return QString::fromLocal8Bit("%1 %2") - .arg(MaemoGlobal::remoteCommandPrefix(deviceConfig()->osType())) - .arg(MaemoGlobal::remoteEnvironment(userEnvironmentChanges())); + return QString::fromLocal8Bit("%1; DISPLAY=:0.0 %2") + .arg(MaemoGlobal::remoteSourceProfilesCommand(), userEnvironmentChangesAsString()); } QString RemoteLinuxRunConfiguration::localExecutableFilePath() const @@ -321,11 +289,10 @@ QString RemoteLinuxRunConfiguration::remoteExecutableFilePath() const PortList RemoteLinuxRunConfiguration::freePorts() const { - const Qt4BuildConfiguration * const bc = activeQt4BuildConfiguration(); - const AbstractLinuxDeviceDeployStep * const step = deployStep(); - return bc && step - ? MaemoGlobal::freePorts(deployStep()->helper().deviceConfig(), bc->qtVersion()) - : PortList(); + const LinuxDeviceConfiguration::ConstPtr &devConf = deviceConfig(); + if (!devConf) + return PortList(); + return devConf->freePorts(); } void RemoteLinuxRunConfiguration::setArguments(const QString &args) @@ -335,10 +302,6 @@ void RemoteLinuxRunConfiguration::setArguments(const QString &args) RemoteLinuxRunConfiguration::DebuggingType RemoteLinuxRunConfiguration::debuggingType() const { - const AbstractQt4MaemoTarget * const maemoTarget - = qobject_cast(target()); - if (!maemoTarget || !maemoTarget->allowsQmlDebugging()) - return DebugCppOnly; if (useCppDebugger()) { if (useQmlDebugger()) return DebugCppAndQml; @@ -359,21 +322,6 @@ int RemoteLinuxRunConfiguration::portsUsedByDebuggers() const } } -bool RemoteLinuxRunConfiguration::hasEnoughFreePorts(const QString &mode) const -{ - const int freePortCount = freePorts().count(); - const AbstractQt4MaemoTarget * const maemoTarget - = qobject_cast(target()); - const bool remoteMountsAllowed = maemoTarget && maemoTarget->allowsRemoteMounts(); - const int mountDirCount = remoteMountsAllowed - ? remoteMounts()->validMountSpecificationCount() : 0; - if (mode == Debugger::Constants::DEBUGMODE) - return freePortCount >= mountDirCount + portsUsedByDebuggers(); - if (mode == ProjectExplorer::Constants::RUNMODE) - return freePortCount >= mountDirCount; - return false; -} - void RemoteLinuxRunConfiguration::updateDeviceConfigurations() { emit deviceConfigurationChanged(target()); @@ -412,12 +360,6 @@ void RemoteLinuxRunConfiguration::handleDeployablesUpdated() updateEnabledState(); } -void RemoteLinuxRunConfiguration::handleRemoteMountsChanged() -{ - emit remoteMountsChanged(); - updateEnabledState(); -} - QString RemoteLinuxRunConfiguration::baseEnvironmentText() const { if (m_d->baseEnvironmentType == CleanBaseEnvironment) @@ -458,6 +400,15 @@ QList RemoteLinuxRunConfiguration::userEnvironmentChange return m_d->userEnvironmentChanges; } +QString RemoteLinuxRunConfiguration::userEnvironmentChangesAsString() const +{ + QString env; + QString placeHolder = QLatin1String("%1=%2 "); + foreach (const Utils::EnvironmentItem &item, userEnvironmentChanges()) + env.append(placeHolder.arg(item.name, item.value)); + return env.mid(0, env.size() - 1); +} + void RemoteLinuxRunConfiguration::setUserEnvironmentChanges( const QList &diff) { @@ -485,4 +436,11 @@ QString RemoteLinuxRunConfiguration::proFilePath() const return m_d->proFilePath; } +void RemoteLinuxRunConfiguration::setDisabledReason(const QString &reason) const +{ + m_d->disabledReason = reason; +} + +const QString RemoteLinuxRunConfiguration::Id = QLatin1String("RemoteLinuxRunConfiguration"); + } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.h b/src/plugins/remotelinux/remotelinuxrunconfiguration.h index 41c2d84765f..eaac5bfe840 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfiguration.h +++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.h @@ -30,8 +30,8 @@ ** **************************************************************************/ -#ifndef MAEMORUNCONFIGURATION_H -#define MAEMORUNCONFIGURATION_H +#ifndef REMOTELINUXRUNCONFIGURATION_H +#define REMOTELINUXRUNCONFIGURATION_H #include "linuxdeviceconfiguration.h" #include "maemoconstants.h" @@ -55,22 +55,21 @@ class Qt4ProFileNode; } // namespace Qt4ProjectManager namespace RemoteLinux { +class RemoteLinuxRunConfigurationWidget; + namespace Internal { class AbstractLinuxDeviceDeployStep; class MaemoDeviceConfigListModel; -class MaemoRemoteMountsModel; -class MaemoRunConfigurationFactory; -class MaemoRunConfigurationWidget; -class MaemoToolChain; class Qt4MaemoDeployConfiguration; class RemoteLinuxRunConfigurationPrivate; +class RemoteLinuxRunConfigurationFactory; } // namespace Internal class REMOTELINUX_EXPORT RemoteLinuxRunConfiguration : public ProjectExplorer::RunConfiguration { Q_OBJECT - friend class Internal::MaemoRunConfigurationFactory; - friend class Internal::MaemoRunConfigurationWidget; + friend class Internal::RemoteLinuxRunConfigurationFactory; + friend class RemoteLinuxRunConfigurationWidget; public: enum BaseEnvironmentType { @@ -80,7 +79,7 @@ public: enum DebuggingType { DebugCppOnly, DebugQmlOnly, DebugCppAndQml }; - RemoteLinuxRunConfiguration(Qt4ProjectManager::Qt4BaseTarget *parent, + RemoteLinuxRunConfiguration(Qt4ProjectManager::Qt4BaseTarget *parent, const QString &id, const QString &proFilePath); virtual ~RemoteLinuxRunConfiguration(); @@ -92,16 +91,15 @@ public: Qt4ProjectManager::Qt4BuildConfiguration *activeQt4BuildConfiguration() const; Internal::Qt4MaemoDeployConfiguration *deployConfig() const; - Internal::MaemoRemoteMountsModel *remoteMounts() const; + + virtual QString commandPrefix() const; + virtual PortList freePorts() const; + virtual DebuggingType debuggingType() const; QString localExecutableFilePath() const; QString remoteExecutableFilePath() const; QString arguments() const; - QString commandPrefix() const; QSharedPointer deviceConfig() const; - PortList freePorts() const; - DebuggingType debuggingType() const; - QString gdbCmd() const; virtual QVariantMap toMap() const; @@ -114,10 +112,11 @@ public: Utils::Environment systemEnvironment() const; int portsUsedByDebuggers() const; - bool hasEnoughFreePorts(const QString &mode) const; QString proFilePath() const; + static const QString Id; + signals: void deviceConfigurationChanged(ProjectExplorer::Target *target); void deploySpecsChanged(); @@ -125,25 +124,25 @@ signals: void baseEnvironmentChanged(); void systemEnvironmentChanged(); void userEnvironmentChangesChanged(const QList &diff); - void remoteMountsChanged(); protected: RemoteLinuxRunConfiguration(Qt4ProjectManager::Qt4BaseTarget *parent, RemoteLinuxRunConfiguration *source); virtual bool fromMap(const QVariantMap &map); QString defaultDisplayName(); + void setDisabledReason(const QString &reason) const; + QString userEnvironmentChangesAsString() const; + Internal::AbstractLinuxDeviceDeployStep *deployStep() const; + Q_SLOT void updateEnabledState() { emit isEnabledChanged(isEnabled()); } private slots: void proFileUpdate(Qt4ProjectManager::Qt4ProFileNode *pro, bool success, bool parseInProgress); void updateDeviceConfigurations(); void handleDeployConfigChanged(); void handleDeployablesUpdated(); - void handleRemoteMountsChanged(); - void updateEnabledState() { emit isEnabledChanged(isEnabled()); } private: void init(); - Internal::AbstractLinuxDeviceDeployStep *deployStep() const; void setArguments(const QString &args); void setBaseEnvironmentType(BaseEnvironmentType env); @@ -155,4 +154,4 @@ private: } // namespace RemoteLinux -#endif // MAEMORUNCONFIGURATION_H +#endif // REMOTELINUXRUNCONFIGURATION_H diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp new file mode 100644 index 00000000000..02d99f353f9 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp @@ -0,0 +1,135 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "remotelinuxrunconfigurationfactory.h" + +#include "maemoglobal.h" +#include "remotelinuxrunconfiguration.h" + +#include +#include +#include + +#include +#include +#include + +using namespace ProjectExplorer; +using namespace Qt4ProjectManager; + +namespace RemoteLinux { +namespace Internal { + +namespace { +QString pathFromId(const QString &id) +{ + if (!id.startsWith(RemoteLinuxRunConfiguration::Id)) + return QString(); + return id.mid(RemoteLinuxRunConfiguration::Id.size()); +} + +} // namespace + +RemoteLinuxRunConfigurationFactory::RemoteLinuxRunConfigurationFactory(QObject *parent) + : IRunConfigurationFactory(parent) +{ +} + +RemoteLinuxRunConfigurationFactory::~RemoteLinuxRunConfigurationFactory() +{ +} + +bool RemoteLinuxRunConfigurationFactory::canCreate(Target *parent, + const QString &id) const +{ + if (!id.startsWith(RemoteLinuxRunConfiguration::Id)) + return false; + return qobject_cast(parent)->qt4Project() + ->hasApplicationProFile(pathFromId(id)); +} + +bool RemoteLinuxRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const +{ + Q_UNUSED(parent); + return ProjectExplorer::idFromMap(map).startsWith(RemoteLinuxRunConfiguration::Id); +} + +bool RemoteLinuxRunConfigurationFactory::canClone(Target *parent, RunConfiguration *source) const +{ + return canCreate(parent, source->id()); +} + +QStringList RemoteLinuxRunConfigurationFactory::availableCreationIds(Target *parent) const +{ + if (Qt4BaseTarget *t = qobject_cast(parent)) { + if (t && MaemoGlobal::hasLinuxQt(t)) { + return t->qt4Project()->applicationProFilePathes(RemoteLinuxRunConfiguration::Id); + } + } + return QStringList(); +} + +QString RemoteLinuxRunConfigurationFactory::displayNameForId(const QString &id) const +{ + return QFileInfo(pathFromId(id)).completeBaseName() + + QLatin1String(" (on remote generic Linux device)"); +} + +RunConfiguration *RemoteLinuxRunConfigurationFactory::create(Target *parent, const QString &id) +{ + QTC_ASSERT(canCreate(parent, id), return 0); + return new RemoteLinuxRunConfiguration(qobject_cast(parent), id, + pathFromId(id)); +} + +RunConfiguration *RemoteLinuxRunConfigurationFactory::restore(Target *parent, + const QVariantMap &map) +{ + QTC_ASSERT(canRestore(parent, map), return 0); + RemoteLinuxRunConfiguration *rc = new RemoteLinuxRunConfiguration(qobject_cast(parent), + RemoteLinuxRunConfiguration::Id, QString()); + if (rc->fromMap(map)) + return rc; + + delete rc; + return 0; +} + +RunConfiguration *RemoteLinuxRunConfigurationFactory::clone(Target *parent, + RunConfiguration *source) +{ + QTC_ASSERT(canClone(parent, source), return 0); + RemoteLinuxRunConfiguration *old = static_cast(source); + return new RemoteLinuxRunConfiguration(static_cast(parent), old); +} + +} // namespace Internal +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.h b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.h new file mode 100644 index 00000000000..94e87971150 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.h @@ -0,0 +1,66 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#ifndef REMOTELINUXRUNCONFIGURATIONFACTORY_H +#define REMOTELINUXRUNCONFIGURATIONFACTORY_H + +#include + +namespace RemoteLinux { +namespace Internal { + +class RemoteLinuxRunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory +{ + Q_OBJECT + +public: + explicit RemoteLinuxRunConfigurationFactory(QObject *parent = 0); + ~RemoteLinuxRunConfigurationFactory(); + + QString displayNameForId(const QString &id) const; + QStringList availableCreationIds(ProjectExplorer::Target *parent) const; + + bool canCreate(ProjectExplorer::Target *parent, const QString &id) const; + ProjectExplorer::RunConfiguration *create(ProjectExplorer::Target *parent, const QString &id); + + bool canRestore(ProjectExplorer::Target *parent, const QVariantMap &map) const; + ProjectExplorer::RunConfiguration *restore(ProjectExplorer::Target *parent, + const QVariantMap &map); + + bool canClone(ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration *source) const; + ProjectExplorer::RunConfiguration *clone(ProjectExplorer::Target *parent, + ProjectExplorer::RunConfiguration *source); +}; + +} // namespace Internal +} // namespace RemoteLinux + +#endif // REMOTELINUXRUNCONFIGURATIONFACTORY_H diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp new file mode 100644 index 00000000000..52632de5751 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp @@ -0,0 +1,345 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "remotelinuxrunconfigurationwidget.h" + +#include "maemodeployables.h" +#include "maemodeviceenvreader.h" +#include "maemoglobal.h" +#include "remotelinuxrunconfiguration.h" +#include "maemosettingspages.h" +#include "qt4maemodeployconfiguration.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Qt4ProjectManager; + +namespace RemoteLinux { +namespace { +const QString FetchEnvButtonText + = QCoreApplication::translate("RemoteLinux::RemoteLinuxRunConfigurationWidget", + "Fetch Device Environment"); +} // anonymous namespace + +using namespace Internal; + +RemoteLinuxRunConfigurationWidget::RemoteLinuxRunConfigurationWidget(RemoteLinuxRunConfiguration *runConfiguration, + QWidget *parent) + : QWidget(parent), + m_runConfiguration(runConfiguration), + m_ignoreChange(false), + m_deviceEnvReader(new MaemoDeviceEnvReader(this, runConfiguration)) +{ + QVBoxLayout *topLayout = new QVBoxLayout(this); + topLayout->setMargin(0); + addDisabledLabel(topLayout); + topWidget = new QWidget; + topLayout->addWidget(topWidget); + QVBoxLayout *mainLayout = new QVBoxLayout(topWidget); + mainLayout->setMargin(0); + addGenericWidgets(mainLayout); + addEnvironmentWidgets(mainLayout); + connect(m_runConfiguration, + SIGNAL(deviceConfigurationChanged(ProjectExplorer::Target*)), + this, SLOT(handleCurrentDeviceConfigChanged())); + handleCurrentDeviceConfigChanged(); + + connect(m_runConfiguration, SIGNAL(isEnabledChanged(bool)), + this, SLOT(runConfigurationEnabledChange(bool))); + runConfigurationEnabledChange(m_runConfiguration->isEnabled()); +} + +void RemoteLinuxRunConfigurationWidget::addDisabledLabel(QVBoxLayout *topLayout) +{ + QHBoxLayout *hl = new QHBoxLayout; + hl->addStretch(); + m_disabledIcon = new QLabel(this); + m_disabledIcon->setPixmap(QPixmap(QString::fromUtf8(":/projectexplorer/images/compile_warning.png"))); + hl->addWidget(m_disabledIcon); + m_disabledReason = new QLabel(this); + m_disabledReason->setVisible(false); + hl->addWidget(m_disabledReason); + hl->addStretch(); + topLayout->addLayout(hl); +} + +void RemoteLinuxRunConfigurationWidget::suppressQmlDebuggingOptions() +{ + m_debuggingLanguagesLabel->hide(); + m_debugCppOnlyButton->hide(); + m_debugQmlOnlyButton->hide(); + m_debugCppAndQmlButton->hide(); +} + +void RemoteLinuxRunConfigurationWidget::runConfigurationEnabledChange(bool enabled) +{ topWidget->setEnabled(enabled); + m_disabledIcon->setVisible(!enabled); + m_disabledReason->setVisible(!enabled); + m_disabledReason->setText(m_runConfiguration->disabledReason()); +} + +void RemoteLinuxRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayout) +{ + QFormLayout *formLayout = new QFormLayout; + mainLayout->addLayout(formLayout); + formLayout->setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter); + + QWidget *devConfWidget = new QWidget; + QHBoxLayout *devConfLayout = new QHBoxLayout(devConfWidget); + m_devConfLabel = new QLabel; + devConfLayout->setMargin(0); + devConfLayout->addWidget(m_devConfLabel); + QLabel *addDevConfLabel= new QLabel(tr("Manage device configurations") + .arg(QLatin1String("deviceconfig"))); + addDevConfLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + devConfLayout->addWidget(addDevConfLabel); + + QLabel *debuggerConfLabel = new QLabel(tr("Set Debugger") + .arg(QLatin1String("debugger"))); + debuggerConfLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + devConfLayout->addWidget(debuggerConfLabel); + + formLayout->addRow(new QLabel(tr("Device configuration:")), devConfWidget); + m_localExecutableLabel + = new QLabel(m_runConfiguration->localExecutableFilePath()); + formLayout->addRow(tr("Executable on host:"), m_localExecutableLabel); + m_remoteExecutableLabel = new QLabel; + formLayout->addRow(tr("Executable on device:"), m_remoteExecutableLabel); + m_argsLineEdit = new QLineEdit(m_runConfiguration->arguments()); + formLayout->addRow(tr("Arguments:"), m_argsLineEdit); + + QHBoxLayout * const debugButtonsLayout = new QHBoxLayout; + m_debugCppOnlyButton = new QRadioButton(tr("C++ only")); + m_debugQmlOnlyButton = new QRadioButton(tr("QML only")); + m_debugCppAndQmlButton = new QRadioButton(tr("C++ and QML")); + m_debuggingLanguagesLabel = new QLabel(tr("Debugging type:")); + QButtonGroup * const buttonGroup = new QButtonGroup; + buttonGroup->addButton(m_debugCppOnlyButton); + buttonGroup->addButton(m_debugQmlOnlyButton); + buttonGroup->addButton(m_debugCppAndQmlButton); + debugButtonsLayout->addWidget(m_debugCppOnlyButton); + debugButtonsLayout->addWidget(m_debugQmlOnlyButton); + debugButtonsLayout->addWidget(m_debugCppAndQmlButton); + debugButtonsLayout->addStretch(1); + formLayout->addRow(m_debuggingLanguagesLabel, debugButtonsLayout); + if (m_runConfiguration->useCppDebugger()) { + if (m_runConfiguration->useQmlDebugger()) + m_debugCppAndQmlButton->setChecked(true); + else + m_debugCppOnlyButton->setChecked(true); + } else { + m_debugQmlOnlyButton->setChecked(true); + } + + connect(addDevConfLabel, SIGNAL(linkActivated(QString)), this, + SLOT(showDeviceConfigurationsDialog(QString))); + connect(debuggerConfLabel, SIGNAL(linkActivated(QString)), this, + SLOT(showDeviceConfigurationsDialog(QString))); + connect(m_argsLineEdit, SIGNAL(textEdited(QString)), this, + SLOT(argumentsEdited(QString))); + connect(m_debugCppOnlyButton, SIGNAL(toggled(bool)), this, + SLOT(handleDebuggingTypeChanged())); + connect(m_debugQmlOnlyButton, SIGNAL(toggled(bool)), this, + SLOT(handleDebuggingTypeChanged())); + connect(m_debugCppAndQmlButton, SIGNAL(toggled(bool)), this, + SLOT(handleDebuggingTypeChanged())); + connect(m_runConfiguration, SIGNAL(targetInformationChanged()), this, + SLOT(updateTargetInformation())); + connect(m_runConfiguration, SIGNAL(deploySpecsChanged()), SLOT(handleDeploySpecsChanged())); + handleDeploySpecsChanged(); +} + +void RemoteLinuxRunConfigurationWidget::addEnvironmentWidgets(QVBoxLayout *mainLayout) +{ + QWidget *baseEnvironmentWidget = new QWidget; + QHBoxLayout *baseEnvironmentLayout = new QHBoxLayout(baseEnvironmentWidget); + baseEnvironmentLayout->setMargin(0); + QLabel *label = new QLabel(tr("Base environment for this run configuration:"), this); + baseEnvironmentLayout->addWidget(label); + m_baseEnvironmentComboBox = new QComboBox(this); + m_baseEnvironmentComboBox->addItems(QStringList() << tr("Clean Environment") + << tr("System Environment")); + m_baseEnvironmentComboBox->setCurrentIndex(m_runConfiguration->baseEnvironmentType()); + baseEnvironmentLayout->addWidget(m_baseEnvironmentComboBox); + + m_fetchEnv = new QPushButton(FetchEnvButtonText); + baseEnvironmentLayout->addWidget(m_fetchEnv); + baseEnvironmentLayout->addStretch(10); + + m_environmentWidget = new ProjectExplorer::EnvironmentWidget(this, baseEnvironmentWidget); + m_environmentWidget->setBaseEnvironment(m_deviceEnvReader->deviceEnvironment()); + m_environmentWidget->setBaseEnvironmentText(m_runConfiguration->baseEnvironmentText()); + m_environmentWidget->setUserChanges(m_runConfiguration->userEnvironmentChanges()); + mainLayout->addWidget(m_environmentWidget); + + connect(m_environmentWidget, SIGNAL(userChangesChanged()), this, + SLOT(userChangesEdited())); + connect(m_baseEnvironmentComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(baseEnvironmentSelected(int))); + connect(m_runConfiguration, SIGNAL(baseEnvironmentChanged()), + this, SLOT(baseEnvironmentChanged())); + connect(m_runConfiguration, SIGNAL(systemEnvironmentChanged()), + this, SLOT(systemEnvironmentChanged())); + connect(m_runConfiguration, + SIGNAL(userEnvironmentChangesChanged(QList)), + this, SLOT(userEnvironmentChangesChanged(QList))); + connect(m_fetchEnv, SIGNAL(clicked()), this, SLOT(fetchEnvironment())); + connect(m_deviceEnvReader, SIGNAL(finished()), this, SLOT(fetchEnvironmentFinished())); + connect(m_deviceEnvReader, SIGNAL(error(QString)), this, + SLOT(fetchEnvironmentError(QString))); +} + +void RemoteLinuxRunConfigurationWidget::argumentsEdited(const QString &text) +{ + m_runConfiguration->setArguments(text); +} + +void RemoteLinuxRunConfigurationWidget::updateTargetInformation() +{ + m_localExecutableLabel + ->setText(QDir::toNativeSeparators(m_runConfiguration->localExecutableFilePath())); +} + +void RemoteLinuxRunConfigurationWidget::handleDeploySpecsChanged() +{ + m_remoteExecutableLabel->setText(m_runConfiguration->remoteExecutableFilePath()); +} + +void RemoteLinuxRunConfigurationWidget::showDeviceConfigurationsDialog(const QString &link) +{ + if (link == QLatin1String("deviceconfig")) { + Core::ICore::instance()->showOptionsDialog(MaemoDeviceConfigurationsSettingsPage::Category, + MaemoDeviceConfigurationsSettingsPage::Id); + } else if (link == QLatin1String("debugger")) { + Core::ICore::instance()->showOptionsDialog(QLatin1String("O.Debugger"), + QLatin1String("M.Gdb")); + } +} + +void RemoteLinuxRunConfigurationWidget::handleCurrentDeviceConfigChanged() +{ + m_devConfLabel->setText(MaemoGlobal::deviceConfigurationName(m_runConfiguration->deviceConfig())); +} + +void RemoteLinuxRunConfigurationWidget::fetchEnvironment() +{ + disconnect(m_fetchEnv, SIGNAL(clicked()), this, SLOT(fetchEnvironment())); + connect(m_fetchEnv, SIGNAL(clicked()), this, SLOT(stopFetchEnvironment())); + m_fetchEnv->setText(tr("Cancel Fetch Operation")); + m_deviceEnvReader->start(); +} + +void RemoteLinuxRunConfigurationWidget::stopFetchEnvironment() +{ + m_deviceEnvReader->stop(); + fetchEnvironmentFinished(); +} + +void RemoteLinuxRunConfigurationWidget::fetchEnvironmentFinished() +{ + disconnect(m_fetchEnv, SIGNAL(clicked()), this, + SLOT(stopFetchEnvironment())); + connect(m_fetchEnv, SIGNAL(clicked()), this, SLOT(fetchEnvironment())); + m_fetchEnv->setText(FetchEnvButtonText); + m_runConfiguration->setSystemEnvironment(m_deviceEnvReader->deviceEnvironment()); +} + +void RemoteLinuxRunConfigurationWidget::fetchEnvironmentError(const QString &error) +{ + QMessageBox::warning(this, tr("Device error"), + tr("Fetching environment failed: %1").arg(error)); +} + +void RemoteLinuxRunConfigurationWidget::userChangesEdited() +{ + m_ignoreChange = true; + m_runConfiguration->setUserEnvironmentChanges(m_environmentWidget->userChanges()); + m_ignoreChange = false; +} + +void RemoteLinuxRunConfigurationWidget::baseEnvironmentSelected(int index) +{ + m_ignoreChange = true; + m_runConfiguration->setBaseEnvironmentType(RemoteLinuxRunConfiguration::BaseEnvironmentType(index)); + + m_environmentWidget->setBaseEnvironment(m_runConfiguration->baseEnvironment()); + m_environmentWidget->setBaseEnvironmentText(m_runConfiguration->baseEnvironmentText()); + m_ignoreChange = false; +} + +void RemoteLinuxRunConfigurationWidget::baseEnvironmentChanged() +{ + if (m_ignoreChange) + return; + + m_baseEnvironmentComboBox->setCurrentIndex(m_runConfiguration->baseEnvironmentType()); + m_environmentWidget->setBaseEnvironment(m_runConfiguration->baseEnvironment()); + m_environmentWidget->setBaseEnvironmentText(m_runConfiguration->baseEnvironmentText()); +} + +void RemoteLinuxRunConfigurationWidget::systemEnvironmentChanged() +{ + m_environmentWidget->setBaseEnvironment(m_runConfiguration->systemEnvironment()); +} + +void RemoteLinuxRunConfigurationWidget::userEnvironmentChangesChanged(const QList &userChanges) +{ + if (m_ignoreChange) + return; + m_environmentWidget->setUserChanges(userChanges); +} + +void RemoteLinuxRunConfigurationWidget::handleDebuggingTypeChanged() +{ + m_runConfiguration->setUseCppDebugger(m_debugCppOnlyButton->isChecked() + || m_debugCppAndQmlButton->isChecked()); + m_runConfiguration->setUseQmlDebugger(m_debugQmlOnlyButton->isChecked() + || m_debugCppAndQmlButton->isChecked()); +} + +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h new file mode 100644 index 00000000000..6840a226400 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h @@ -0,0 +1,111 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#ifndef REMOTELINUXRUNCONFIGURATIONWIDGET_H +#define REMOTELINUXRUNCONFIGURATIONWIDGET_H + +#include "remotelinux_export.h" + +#include + +QT_BEGIN_NAMESPACE +class QComboBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QRadioButton; +class QVBoxLayout; +QT_END_NAMESPACE + +namespace ProjectExplorer { class EnvironmentWidget; } +namespace Qt4ProjectManager { class Qt4BuildConfiguration; } +namespace Utils { class EnvironmentItem; } + +namespace RemoteLinux { +class RemoteLinuxRunConfiguration; + +namespace Internal { class MaemoDeviceEnvReader; } + +class REMOTELINUX_EXPORT RemoteLinuxRunConfigurationWidget : public QWidget +{ + Q_OBJECT +public: + explicit RemoteLinuxRunConfigurationWidget(RemoteLinuxRunConfiguration *runConfiguration, + QWidget *parent = 0); + + void addDisabledLabel(QVBoxLayout *topLayout); + void suppressQmlDebuggingOptions(); + Q_SLOT void runConfigurationEnabledChange(bool enabled); + +private slots: + void argumentsEdited(const QString &args); + void showDeviceConfigurationsDialog(const QString &link); + void updateTargetInformation(); + void handleCurrentDeviceConfigChanged(); + void fetchEnvironment(); + void fetchEnvironmentFinished(); + void fetchEnvironmentError(const QString &error); + void stopFetchEnvironment(); + void userChangesEdited(); + void baseEnvironmentSelected(int index); + void baseEnvironmentChanged(); + void systemEnvironmentChanged(); + void userEnvironmentChangesChanged(const QList &userChanges); + void handleDebuggingTypeChanged(); + void handleDeploySpecsChanged(); + +private: + void addGenericWidgets(QVBoxLayout *mainLayout); + void addEnvironmentWidgets(QVBoxLayout *mainLayout); + + RemoteLinuxRunConfiguration *m_runConfiguration; + QWidget *topWidget; + QLabel *m_disabledIcon; + QLabel *m_disabledReason; + QLineEdit *m_argsLineEdit; + QLabel *m_localExecutableLabel; + QLabel *m_remoteExecutableLabel; + QLabel *m_devConfLabel; + QLabel *m_debuggingLanguagesLabel; + QRadioButton *m_debugCppOnlyButton; + QRadioButton *m_debugQmlOnlyButton; + QRadioButton *m_debugCppAndQmlButton; + + bool m_ignoreChange; + QPushButton *m_fetchEnv; + QComboBox *m_baseEnvironmentComboBox; + Internal::MaemoDeviceEnvReader *m_deviceEnvReader; + ProjectExplorer::EnvironmentWidget *m_environmentWidget; +}; + +} // namespace RemoteLinux + +#endif // REMOTELINUXRUNCONFIGURATIONWIDGET_H diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.cpp b/src/plugins/remotelinux/remotelinuxruncontrol.cpp new file mode 100644 index 00000000000..0b9ed277e23 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxruncontrol.cpp @@ -0,0 +1,164 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "remotelinuxruncontrol.h" + +#include "maemoglobal.h" +#include "remotelinuxapplicationrunner.h" +#include "remotelinuxrunconfiguration.h" + +#include +#include + +#include + +using namespace ProjectExplorer; + +namespace RemoteLinux { + +using ProjectExplorer::RunConfiguration; + +AbstractRemoteLinuxRunControl::AbstractRemoteLinuxRunControl(RunConfiguration *rc) + : RunControl(rc, ProjectExplorer::Constants::RUNMODE) + , m_running(false) +{ +} + +AbstractRemoteLinuxRunControl::~AbstractRemoteLinuxRunControl() +{ +} + +void AbstractRemoteLinuxRunControl::start() +{ + m_running = true; + emit started(); + disconnect(runner(), 0, this, 0); + connect(runner(), SIGNAL(error(QString)), SLOT(handleSshError(QString))); + connect(runner(), SIGNAL(readyForExecution()), SLOT(startExecution())); + connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)), + SLOT(handleRemoteErrorOutput(QByteArray))); + connect(runner(), SIGNAL(remoteOutput(QByteArray)), + SLOT(handleRemoteOutput(QByteArray))); + connect(runner(), SIGNAL(remoteProcessStarted()), + SLOT(handleRemoteProcessStarted())); + connect(runner(), SIGNAL(remoteProcessFinished(qint64)), + SLOT(handleRemoteProcessFinished(qint64))); + connect(runner(), SIGNAL(reportProgress(QString)), + SLOT(handleProgressReport(QString))); + runner()->start(); +} + +RunControl::StopResult AbstractRemoteLinuxRunControl::stop() +{ + runner()->stop(); + return StoppedSynchronously; +} + +void AbstractRemoteLinuxRunControl::handleSshError(const QString &error) +{ + handleError(error); + setFinished(); +} + +void AbstractRemoteLinuxRunControl::startExecution() +{ + appendMessage(tr("Starting remote process ...\n"), Utils::NormalMessageFormat); + runner()->startExecution(QString::fromLocal8Bit("%1 %2 %3") + .arg(runner()->commandPrefix()) + .arg(runner()->remoteExecutable()) + .arg(runner()->arguments()).toUtf8()); +} + +void AbstractRemoteLinuxRunControl::handleRemoteProcessFinished(qint64 exitCode) +{ + if (exitCode != RemoteLinuxApplicationRunner::InvalidExitCode) { + appendMessage(tr("Finished running remote process. Exit code was %1.\n") + .arg(exitCode), Utils::NormalMessageFormat); + } + setFinished(); +} + +void AbstractRemoteLinuxRunControl::handleRemoteOutput(const QByteArray &output) +{ + appendMessage(QString::fromUtf8(output), Utils::StdOutFormatSameLine); +} + +void AbstractRemoteLinuxRunControl::handleRemoteErrorOutput(const QByteArray &output) +{ + appendMessage(QString::fromUtf8(output), Utils::StdErrFormatSameLine); +} + +void AbstractRemoteLinuxRunControl::handleProgressReport(const QString &progressString) +{ + appendMessage(progressString + QLatin1Char('\n'), Utils::NormalMessageFormat); +} + +bool AbstractRemoteLinuxRunControl::isRunning() const +{ + return m_running; +} + +QIcon AbstractRemoteLinuxRunControl::icon() const +{ + return QIcon(ProjectExplorer::Constants::ICON_RUN_SMALL); +} + +void AbstractRemoteLinuxRunControl::handleError(const QString &errString) +{ + stop(); + appendMessage(errString, Utils::ErrorMessageFormat); + QMessageBox::critical(0, tr("Remote Execution Failure"), errString); +} + +void AbstractRemoteLinuxRunControl::setFinished() +{ + disconnect(runner(), 0, this, 0); + m_running = false; + emit finished(); +} + + +RemoteLinuxRunControl::RemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig) + : AbstractRemoteLinuxRunControl(runConfig), + m_runner(new RemoteLinuxApplicationRunner(this, qobject_cast(runConfig))) +{ +} + +RemoteLinuxRunControl::~RemoteLinuxRunControl() +{ +} + +RemoteLinuxApplicationRunner *RemoteLinuxRunControl::runner() const +{ + return m_runner; +} + +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.h b/src/plugins/remotelinux/remotelinuxruncontrol.h new file mode 100644 index 00000000000..b2e3628f078 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxruncontrol.h @@ -0,0 +1,90 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef REMOTELINUXRUNCONTROL_H +#define REMOTELINUXRUNCONTROL_H + +#include "remotelinux_export.h" + +#include + +#include + +namespace RemoteLinux { +class RemoteLinuxApplicationRunner; + +class REMOTELINUX_EXPORT AbstractRemoteLinuxRunControl : public ProjectExplorer::RunControl +{ + Q_OBJECT +public: + explicit AbstractRemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig); + virtual ~AbstractRemoteLinuxRunControl(); + + virtual void start(); + virtual StopResult stop(); + virtual bool isRunning() const; + virtual QIcon icon() const; + +private slots: + void startExecution(); + void handleSshError(const QString &error); + void handleRemoteProcessStarted() {} + void handleRemoteProcessFinished(qint64 exitCode); + void handleRemoteOutput(const QByteArray &output); + void handleRemoteErrorOutput(const QByteArray &output); + void handleProgressReport(const QString &progressString); + +private: + virtual RemoteLinuxApplicationRunner *runner() const=0; + + void setFinished(); + void handleError(const QString &errString); + + bool m_running; +}; + + +class REMOTELINUX_EXPORT RemoteLinuxRunControl : public AbstractRemoteLinuxRunControl +{ + Q_OBJECT + +public: + explicit RemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig); + virtual ~RemoteLinuxRunControl(); +private: + virtual RemoteLinuxApplicationRunner *runner() const; + + RemoteLinuxApplicationRunner * const m_runner; +}; + +} // namespace RemoteLinux + +#endif // REMOTELINUXRUNCONTROL_H diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp new file mode 100644 index 00000000000..5ac435d4046 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp @@ -0,0 +1,108 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "remotelinuxruncontrolfactory.h" + +#include "remotelinuxdebugsupport.h" +#include "remotelinuxrunconfiguration.h" +#include "remotelinuxruncontrol.h" + +#include +#include +#include +#include + +using namespace Debugger; +using namespace ProjectExplorer; + +namespace RemoteLinux { +namespace Internal { + +RemoteLinuxRunControlFactory::RemoteLinuxRunControlFactory(QObject *parent) + : IRunControlFactory(parent) +{ +} + +RemoteLinuxRunControlFactory::~RemoteLinuxRunControlFactory() +{ +} + +bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, + const QString &mode) const +{ + if (mode != QLatin1String(ProjectExplorer::Constants::RUNMODE) + && mode != QLatin1String(Debugger::Constants::DEBUGMODE)) + return false; + + if (!runConfiguration->isEnabled() + || !runConfiguration->id().startsWith(RemoteLinuxRunConfiguration::Id)) { + return false; + } + + const RemoteLinuxRunConfiguration * const remoteRunConfig + = qobject_cast(runConfiguration); + if (mode == QLatin1String(Debugger::Constants::DEBUGMODE)) + return remoteRunConfig->portsUsedByDebuggers() <= remoteRunConfig->freePorts().count(); + return true; +} + +RunControl* RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, + const QString &mode) +{ + Q_ASSERT(canRun(runConfig, mode)); + + RemoteLinuxRunConfiguration *rc = qobject_cast(runConfig); + Q_ASSERT(rc); + if (mode == ProjectExplorer::Constants::RUNMODE) + return new RemoteLinuxRunControl(rc); + + const DebuggerStartParameters params + = AbstractRemoteLinuxDebugSupport::startParameters(rc); + DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc); + RemoteLinuxDebugSupport *debugSupport = + new RemoteLinuxDebugSupport(rc, runControl->engine()); + connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished())); + return runControl; +} + +QString RemoteLinuxRunControlFactory::displayName() const +{ + return tr("Run on remote Linux device"); +} + +RunConfigWidget *RemoteLinuxRunControlFactory::createConfigurationWidget(RunConfiguration *config) +{ + Q_UNUSED(config) + return 0; +} + +} // namespace Internal +} // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.h b/src/plugins/remotelinux/remotelinuxruncontrolfactory.h new file mode 100644 index 00000000000..f9dfe4f6aaf --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.h @@ -0,0 +1,57 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#ifndef REMOTELINUXRUNCONTROLFACTORY_H +#define REMOTELINUXRUNCONTROLFACTORY_H + +#include + +namespace RemoteLinux { +namespace Internal { + +class RemoteLinuxRunControlFactory : public ProjectExplorer::IRunControlFactory +{ + Q_OBJECT +public: + explicit RemoteLinuxRunControlFactory(QObject *parent = 0); + ~RemoteLinuxRunControlFactory(); + + QString displayName() const; + ProjectExplorer::RunConfigWidget *createConfigurationWidget(ProjectExplorer::RunConfiguration *runConfiguration); + + bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, const QString &mode) const; + ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, + const QString &mode); +}; + +} // namespace Internal +} // namespace RemoteLinux + +#endif // REMOTELINUXRUNCONTROLFACTORY_H