RemoteLinux: More untangling of generic and Maemo-specific stuff.

- Make key deployment a device type dependent action.
- Split up monolithic device configuration wizard.
- Split up run configurations, run controls and the associated
  factories.

Change-Id: Ib2ef9d405e6b7eaae89fc27c56e3c327829a88f7
Reviewed-on: http://codereview.qt.nokia.com/486
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
This commit is contained in:
Christian Kandeler
2011-06-16 17:03:43 +02:00
parent dfa7995b17
commit f74e167563
50 changed files with 3651 additions and 1385 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 <QtGui/QLabel>
#include <QtGui/QVBoxLayout>
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"

View File

@@ -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

View File

@@ -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

View File

@@ -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 <utils/ssh/sshconnection.h>
#include <QtGui/QWizardPage>
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

View File

@@ -0,0 +1,210 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GenericLinuxDeviceConfigurationWizardSetupPage</class>
<widget class="QWizardPage" name="GenericLinuxDeviceConfigurationWizardSetupPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>542</width>
<height>201</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>The name to identify this configuration:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="nameLineEdit"/>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="hostNameLabel">
<property name="text">
<string>The device's host name or IP address:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="hostNameLineEdit"/>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="userNameLabel">
<property name="text">
<string>User name:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="userNameLineEdit"/>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>153</width>
<height>21</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Authentication type:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QRadioButton" name="passwordButton">
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="keyButton">
<property name="text">
<string>Key</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Password:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="passwordLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Private key:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="Utils::PathChooser" name="privateKeyPathChooser"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
<container>1</container>
<slots>
<signal>editingFinished()</signal>
<signal>browsingFinished()</signal>
</slots>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -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;
};

View File

@@ -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()))

View File

@@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
<width>276</width>
<height>324</height>
<width>414</width>
<height>331</height>
</rect>
</property>
<property name="windowTitle">
<string>Publishing Wizard Selection</string>
<string>Device Configuration Wizard Selection</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@@ -22,7 +22,14 @@
</widget>
</item>
<item>
<widget class="QListWidget" name="listWidget"/>
<widget class="QListWidget" name="listWidget">
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -31,259 +31,22 @@
#include "maemodebugsupport.h"
#include "maemodeployables.h"
#include "maemoglobal.h"
#include "maemosshrunner.h"
#include "maemousedportsgatherer.h"
#include "qt4maemotarget.h"
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggerrunner.h>
#include <debugger/debuggerengine.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/toolchain.h>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#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<State>() << Inactive << Debugging);
showMessage(QString::fromUtf8(output), AppOutput);
}
void MaemoDebugSupport::handleRemoteErrorOutput(const QByteArray &output)
{
ASSERT_STATE(QList<State>() << 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

View File

@@ -32,65 +32,24 @@
#ifndef MAEMODEBUGSUPPORT_H
#define MAEMODEBUGSUPPORT_H
#include "remotelinuxrunconfiguration.h"
#include <QtCore/QObject>
#include <QtCore/QPointer>
#include <QtCore/QSharedPointer>
namespace Debugger {
class DebuggerEngine;
}
namespace ProjectExplorer { class RunControl; }
#include <remotelinux/remotelinuxdebugsupport.h>
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<Debugger::DebuggerEngine> m_engine;
const QPointer<RemoteLinuxRunConfiguration> m_runConfig;
const QSharedPointer<const LinuxDeviceConfiguration> 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

View File

@@ -36,7 +36,6 @@
#include "linuxdeviceconfigurations.h"
#include "linuxdevicefactoryselectiondialog.h"
#include "maemoglobal.h"
#include "maemokeydeployer.h"
#include "maemosshconfigdialog.h"
#include <coreplugin/icore.h>
@@ -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<ILinuxDeviceConfigurationWizard> 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();

View File

@@ -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<LinuxDeviceConfigurations> m_devConfigs;
NameValidator * const m_nameValidator;
MaemoKeyDeployer *const m_keyDeployer;
bool m_saveSettingsRequested;
QList<QPushButton *> m_additionalActionButtons;
QSignalMapper * const m_additionalActionsMapper;

View File

@@ -387,6 +387,19 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="defaultDeviceButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>Set As Default</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="generateKeyButton">
<property name="enabled">
@@ -403,35 +416,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deployKeyButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>This will enable you to log into the device without a password.</string>
</property>
<property name="text">
<string>&amp;Deploy Public Key...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="defaultDeviceButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>Set As Default</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
@@ -582,22 +566,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>deployKeyButton</sender>
<signal>clicked()</signal>
<receiver>MaemoDeviceConfigurationsSettingsWidget</receiver>
<slot>deployKey()</slot>
<hints>
<hint type="sourcelabel">
<x>697</x>
<y>163</y>
</hint>
<hint type="destinationlabel">
<x>510</x>
<y>351</y>
</hint>
</hints>
</connection>
<connection>
<sender>keyButton</sender>
<signal>toggled(bool)</signal>

View File

@@ -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<Ui::MaemoDeviceConfigWizardStartPage> 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();

View File

@@ -57,13 +57,6 @@
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="genericLinuxButton">
<property name="text">
<string>Generic Linux</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">

View File

@@ -190,15 +190,6 @@ QString MaemoGlobal::remoteSourceProfilesCommand()
return QString::fromAscii(remoteCall);
}
QString MaemoGlobal::remoteEnvironment(const QList<Utils::EnvironmentItem> &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)
{

View File

@@ -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<Utils::EnvironmentItem> &list);
static QString remoteSourceProfilesCommand();
static QString failedToConnectToServerMessage(const QSharedPointer<Utils::SshConnection> &connection,
const QSharedPointer<const LinuxDeviceConfiguration> &deviceConfig);

View File

@@ -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 <debugger/debuggerconstants.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
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<AbstractQt4MaemoTarget *>(target());
Q_ASSERT(maemoTarget);
return maemoTarget;
}
const QString MaemoRunConfiguration::Id = QLatin1String(MAEMO_RC_ID);
} // namespace Internal
} // namespace RemoteLinux

View File

@@ -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

View File

@@ -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 <coreplugin/coreconstants.h>
@@ -45,6 +41,7 @@
#include <projectexplorer/environmentwidget.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4target.h>
#include <remotelinux/remotelinuxrunconfigurationwidget.h>
#include <utils/detailswidget.h>
#include <QtGui/QButtonGroup>
@@ -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<AbstractQt4MaemoTarget *>(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("<a href=\"%1\">Manage device configurations</a>")
.arg(QLatin1String("deviceconfig")));
addDevConfLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
devConfLayout->addWidget(addDevConfLabel);
QLabel *debuggerConfLabel = new QLabel(tr("<a href=\"%1\">Set Debugger</a>")
.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<Utils::EnvironmentItem>)),
this, SLOT(userEnvironmentChangesChanged(QList<Utils::EnvironmentItem>)));
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<Utils::EnvironmentItem> &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;

View File

@@ -35,96 +35,47 @@
#include <QtGui/QWidget>
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<Utils::EnvironmentItem> &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

View File

@@ -32,98 +32,28 @@
#include "maemoruncontrol.h"
#include "maemoglobal.h"
#include "remotelinuxrunconfiguration.h"
#include "maemorunconfiguration.h"
#include "maemosshrunner.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/qtcassert.h>
#include <QtGui/QMessageBox>
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<RemoteLinuxRunConfiguration *>(rc)))
, m_running(false)
: AbstractRemoteLinuxRunControl(rc)
, m_runner(new MaemoSshRunner(this, qobject_cast<MaemoRunConfiguration *>(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

View File

@@ -32,45 +32,30 @@
#ifndef MAEMORUNCONTROL_H
#define MAEMORUNCONTROL_H
#include <projectexplorer/runconfiguration.h>
#include <QtCore/QString>
#include <remotelinux/remotelinuxruncontrol.h>
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

View File

@@ -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 <projectexplorer/projectexplorerconstants.h>
#include <debugger/debuggerconstants.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerrunner.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <qt4projectmanager/qt4project.h>
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<Qt4BaseTarget *>(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<Qt4BaseTarget *>(parent)) {
if (t && MaemoGlobal::hasLinuxQt(t)) {
return t->qt4Project()->
applicationProFilePathes(QLatin1String(MAEMO_RC_ID_PREFIX));
}
}
if (AbstractQt4MaemoTarget *t = qobject_cast<AbstractQt4MaemoTarget *>(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<Qt4BaseTarget *>(parent),
return new MaemoRunConfiguration(qobject_cast<AbstractQt4MaemoTarget *>(parent),
pathFromId(id));
}
@@ -125,8 +120,8 @@ RunConfiguration *MaemoRunConfigurationFactory::restore(Target *parent,
{
if (!canRestore(parent, map))
return 0;
RemoteLinuxRunConfiguration *rc
= new RemoteLinuxRunConfiguration(qobject_cast<Qt4BaseTarget *>(parent), QString());
MaemoRunConfiguration *rc
= new MaemoRunConfiguration(qobject_cast<AbstractQt4MaemoTarget *>(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<RemoteLinuxRunConfiguration *>(source);
return new RemoteLinuxRunConfiguration(static_cast<Qt4BaseTarget *>(parent), old);
MaemoRunConfiguration *old = static_cast<MaemoRunConfiguration *>(source);
return new MaemoRunConfiguration(static_cast<AbstractQt4MaemoTarget *>(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<RemoteLinuxRunConfiguration *>(runConfiguration);
const MaemoRunConfiguration * const maemoRunConfig
= qobject_cast<MaemoRunConfiguration *>(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<RemoteLinuxRunConfiguration *>(runConfig);
MaemoRunConfiguration *rc = qobject_cast<MaemoRunConfiguration *>(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

View File

@@ -36,17 +36,8 @@
#include "maemoremotemounter.h"
#include "maemoremotemountsmodel.h"
#include "remotelinuxrunconfiguration.h"
#include "maemousedportsgatherer.h"
#include <utils/ssh/sshconnection.h>
#include <utils/ssh/sshconnectionmanager.h>
#include <utils/ssh/sshremoteprocess.h>
#include <QtCore/QFileInfo>
#include <limits>
#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<State>() << 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<State>() << 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<State>() << 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<State>() << 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<State>() << PreRunCleaning << PreMountUnmounting
<< PostRunCleaning << StopRequested);
ASSERT_STATE(QList<MountState>() << 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<State>() << 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<State>() << PreRunCleaning << PostRunCleaning
<< PreMountUnmounting << Mounting << StopRequested << Inactive);
ASSERT_STATE(QList<MountState>() << 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<State>() << 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<State>() << PreRunCleaning << PreMountUnmounting
<< PostRunCleaning << StopRequested);
ASSERT_STATE(QList<MountState>() << 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<State>() << GatheringPorts << StopRequested);
if (m_state == StopRequested) {
setState(Inactive);
} else {
mount();
}
}
const qint64 MaemoSshRunner::InvalidExitCode
= std::numeric_limits<qint64>::min();
} // namespace Internal
} // namespace RemoteLinux

View File

@@ -32,99 +32,45 @@
#ifndef MAEMOSSHRUNNER_H
#define MAEMOSSHRUNNER_H
#include "linuxdeviceconfiguration.h"
#include "remotelinuxapplicationrunner.h"
#include "maemomountspecification.h"
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QStringList>
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<Utils::SshConnection> 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<const LinuxDeviceConfiguration> 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<const LinuxDeviceConfiguration> m_devConfig;
const QString m_remoteExecutable;
const QString m_appArguments;
const QString m_commandPrefix;
const PortList m_initialFreePorts;
QList<MaemoMountSpecification> m_mountSpecs;
QSharedPointer<Utils::SshConnection> m_connection;
QSharedPointer<Utils::SshRemoteProcess> m_runner;
QSharedPointer<Utils::SshRemoteProcess> m_cleaner;
QStringList m_procsToKill;
PortList m_freePorts;
int m_exitStatus;
State m_state;
MountState m_mountState;
};
} // namespace Internal

View File

@@ -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 <QtGui/QFileDialog>
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("<font color=\"%1\">%2</font>").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

View File

@@ -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 <QtCore/QSharedPointer>
#include <QtGui/QProgressDialog>
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<const LinuxDeviceConfiguration> &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

View File

@@ -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<RemoteLinuxRunConfiguration *>(rc))
if (MaemoRunConfiguration *qt4rc = qobject_cast<MaemoRunConfiguration *>(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<ProjectExplorer::RunConfiguration *> AbstractQt4MaemoTarget::runConfigurat
{
QList<ProjectExplorer::RunConfiguration *> result;
foreach (ProjectExplorer::RunConfiguration *rc, runConfigurations())
if (RemoteLinuxRunConfiguration *mrc = qobject_cast<RemoteLinuxRunConfiguration *>(rc))
if (MaemoRunConfiguration *mrc = qobject_cast<MaemoRunConfiguration *>(rc))
if (mrc->proFilePath() == n->path())
result << rc;
return result;

View File

@@ -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

View File

@@ -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 <utils/qtcassert.h>
#include <utils/ssh/sshconnection.h>
#include <utils/ssh/sshconnectionmanager.h>
#include <utils/ssh/sshremoteprocess.h>
#include <QtCore/QFileInfo>
#include <limits>
#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<State>() << 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<State>() << 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<State>() << 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<qint64>::min();
} // namespace RemoteLinux

View File

@@ -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 <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QStringList>
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<Utils::SshConnection> 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<const LinuxDeviceConfiguration> 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<const LinuxDeviceConfiguration> m_devConfig;
const QString m_remoteExecutable;
const QString m_appArguments;
const QString m_commandPrefix;
const PortList m_initialFreePorts;
QSharedPointer<Utils::SshConnection> m_connection;
QSharedPointer<Utils::SshRemoteProcess> m_runner;
QSharedPointer<Utils::SshRemoteProcess> m_cleaner;
QStringList m_procsToKill;
PortList m_freePorts;
int m_exitStatus;
bool m_stopRequested;
State m_state;
};
} // namespace RemoteLinux
#endif // REMOTELINUXAPPLICATIONRUNNER_H

View File

@@ -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 <debugger/debuggerengine.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/toolchain.h>
#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<State>() << Inactive << Debugging);
showMessage(QString::fromUtf8(output), AppOutput);
}
void AbstractRemoteLinuxDebugSupport::handleRemoteErrorOutput(const QByteArray &output)
{
ASSERT_STATE(QList<State>() << 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

View File

@@ -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 <debugger/debuggerstartparameters.h>
#include <QtCore/QObject>
#include <QtCore/QPointer>
#include <QtCore/QSharedPointer>
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<Debugger::DebuggerEngine> m_engine;
const QPointer<RemoteLinuxRunConfiguration> m_runConfig;
const QSharedPointer<const LinuxDeviceConfiguration> 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

View File

@@ -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 <QtCore/QtPlugin>
@@ -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>("MaemoDeployable");

View File

@@ -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 <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <debugger/debuggerconstants.h>
#include "remotelinuxrunconfigurationwidget.h"
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/session.h>
#include <qtsupport/qtoutputformatter.h>
@@ -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<BaseEnvironmentType> (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<Qt4MaemoDeployConfiguration *>(target()->activeDeployConfiguration());
}
MaemoRemoteMountsModel *RemoteLinuxRunConfiguration::remoteMounts() const
{
return m_d->remoteMounts;
}
AbstractLinuxDeviceDeployStep *RemoteLinuxRunConfiguration::deployStep() const
{
return MaemoGlobal::earlierBuildStep<AbstractLinuxDeviceDeployStep>(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<AbstractQt4MaemoTarget *>(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<AbstractQt4MaemoTarget *>(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<Utils::EnvironmentItem> 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<Utils::EnvironmentItem> &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

View File

@@ -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<const LinuxDeviceConfiguration> 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<Utils::EnvironmentItem> &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

View File

@@ -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 <qt4projectmanager/qt4project.h>
#include <qt4projectmanager/qt4target.h>
#include <utils/qtcassert.h>
#include <QtCore/QFileInfo>
#include <QtCore/QString>
#include <QtCore/QStringList>
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<Qt4BaseTarget *>(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<Qt4BaseTarget *>(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<Qt4BaseTarget *>(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<Qt4BaseTarget *>(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<RemoteLinuxRunConfiguration *>(source);
return new RemoteLinuxRunConfiguration(static_cast<Qt4BaseTarget *>(parent), old);
}
} // namespace Internal
} // namespace RemoteLinux

View File

@@ -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 <projectexplorer/runconfiguration.h>
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

View File

@@ -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 <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <projectexplorer/environmentwidget.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4target.h>
#include <utils/detailswidget.h>
#include <QtGui/QButtonGroup>
#include <QtCore/QCoreApplication>
#include <QtGui/QComboBox>
#include <QtGui/QFormLayout>
#include <QtGui/QGroupBox>
#include <QtGui/QHBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>
#include <QtGui/QRadioButton>
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("<a href=\"%1\">Manage device configurations</a>")
.arg(QLatin1String("deviceconfig")));
addDevConfLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
devConfLayout->addWidget(addDevConfLabel);
QLabel *debuggerConfLabel = new QLabel(tr("<a href=\"%1\">Set Debugger</a>")
.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<Utils::EnvironmentItem>)),
this, SLOT(userEnvironmentChangesChanged(QList<Utils::EnvironmentItem>)));
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<Utils::EnvironmentItem> &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

View File

@@ -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 <QtGui/QWidget>
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<Utils::EnvironmentItem> &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

View File

@@ -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 <projectexplorer/projectexplorerconstants.h>
#include <utils/qtcassert.h>
#include <QtGui/QMessageBox>
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<RemoteLinuxRunConfiguration *>(runConfig)))
{
}
RemoteLinuxRunControl::~RemoteLinuxRunControl()
{
}
RemoteLinuxApplicationRunner *RemoteLinuxRunControl::runner() const
{
return m_runner;
}
} // namespace RemoteLinux

View File

@@ -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 <projectexplorer/runconfiguration.h>
#include <QtCore/QString>
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

View File

@@ -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 <debugger/debuggerconstants.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerrunner.h>
#include <projectexplorer/projectexplorerconstants.h>
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<RemoteLinuxRunConfiguration *>(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<RemoteLinuxRunConfiguration *>(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

View File

@@ -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 <projectexplorer/runconfiguration.h>
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