Start making the Maemo support more generic.

This includes:
    - decoupling deploy configurations from targets (Reviewed-by: dt)
    - adding a "Generic Linux" device type
    - splitting up the Maemo deployment step into small pieces that
      can be combined in different ways (and much more easily maintained)
    - adding a new version handler for pro.user files
      (Reviewed-by: Tobias Hunger)

Also:
  - Add and use an SSH manager class for easier connection sharing.
  - Make the SSH connection parameters a fixed attribute of the connection.
This commit is contained in:
Christian Kandeler
2011-03-09 12:07:35 +01:00
parent 9be947bd1b
commit 439b45618e
91 changed files with 5535 additions and 1550 deletions

View File

@@ -110,13 +110,14 @@ QTCREATOR_UTILS_EXPORT bool operator!=(const SshConnectionParameters &p1, const
// TODO: Mechanism for checking the host key. First connection to host: save, later: compare
SshConnection::Ptr SshConnection::create()
SshConnection::Ptr SshConnection::create(const SshConnectionParameters &serverInfo)
{
doStaticInitializationsIfNecessary();
return Ptr(new SshConnection);
return Ptr(new SshConnection(serverInfo));
}
SshConnection::SshConnection() : d(new Internal::SshConnectionPrivate(this))
SshConnection::SshConnection(const SshConnectionParameters &serverInfo)
: d(new Internal::SshConnectionPrivate(this, serverInfo))
{
connect(d, SIGNAL(connected()), this, SIGNAL(connected()),
Qt::QueuedConnection);
@@ -128,9 +129,9 @@ SshConnection::SshConnection() : d(new Internal::SshConnectionPrivate(this))
SIGNAL(error(Utils::SshError)), Qt::QueuedConnection);
}
void SshConnection::connectToHost(const SshConnectionParameters &serverInfo)
void SshConnection::connectToHost()
{
d->connectToHost(serverInfo);
d->connectToHost();
}
void SshConnection::disconnectFromHost()
@@ -188,14 +189,17 @@ QSharedPointer<SftpChannel> SshConnection::createSftpChannel()
namespace Internal {
SshConnectionPrivate::SshConnectionPrivate(SshConnection *conn)
SshConnectionPrivate::SshConnectionPrivate(SshConnection *conn,
const SshConnectionParameters &serverInfo)
: m_socket(new QTcpSocket(this)), m_state(SocketUnconnected),
m_sendFacility(m_socket),
m_channelManager(new SshChannelManager(m_sendFacility, this)),
m_connParams(SshConnectionParameters::DefaultProxy),
m_error(SshNoError), m_ignoreNextPacket(false), m_conn(conn)
m_connParams(serverInfo), m_error(SshNoError), m_ignoreNextPacket(false),
m_conn(conn)
{
setupPacketHandlers();
m_socket->setProxy(m_connParams.proxyType == SshConnectionParameters::DefaultProxy
? QNetworkProxy::DefaultProxy : QNetworkProxy::NoProxy);
m_timeoutTimer.setSingleShot(true);
m_keepAliveTimer.setSingleShot(true);
m_keepAliveTimer.setInterval(10000);
@@ -581,7 +585,7 @@ void SshConnectionPrivate::sendKeepAlivePacket()
m_timeoutTimer.start(5000);
}
void SshConnectionPrivate::connectToHost(const SshConnectionParameters &serverInfo)
void SshConnectionPrivate::connectToHost()
{
m_incomingData.clear();
m_incomingPacket.reset();
@@ -596,12 +600,9 @@ void SshConnectionPrivate::connectToHost(const SshConnectionParameters &serverIn
connect(m_socket, SIGNAL(disconnected()), this,
SLOT(handleSocketDisconnected()));
connect(&m_timeoutTimer, SIGNAL(timeout()), this, SLOT(handleTimeout()));
this->m_connParams = serverInfo;
m_state = SocketConnecting;
m_timeoutTimer.start(m_connParams.timeout * 1000);
m_socket->setProxy(m_connParams.proxyType == SshConnectionParameters::DefaultProxy
? QNetworkProxy::DefaultProxy : QNetworkProxy::NoProxy);
m_socket->connectToHost(serverInfo.host, serverInfo.port);
m_socket->connectToHost(m_connParams.host, m_connParams.port);
}
void SshConnectionPrivate::closeConnection(SshErrorCode sshError,

View File

@@ -78,9 +78,9 @@ public:
enum State { Unconnected, Connecting, Connected };
typedef QSharedPointer<SshConnection> Ptr;
static Ptr create();
static Ptr create(const SshConnectionParameters &serverInfo);
void connectToHost(const SshConnectionParameters &serverInfo);
void connectToHost();
void disconnectFromHost();
State state() const;
SshError errorState() const;
@@ -98,11 +98,11 @@ signals:
void error(Utils::SshError);
private:
SshConnection();
SshConnection(const SshConnectionParameters &serverInfo);
Internal::SshConnectionPrivate *d;
};
} // namespace Internal
} // namespace Utils
#endif // SSHCONNECTION_H

View File

@@ -78,10 +78,11 @@ class SshConnectionPrivate : public QObject
Q_OBJECT
friend class Utils::SshConnection;
public:
SshConnectionPrivate(SshConnection *conn);
SshConnectionPrivate(SshConnection *conn,
const SshConnectionParameters &serverInfo);
~SshConnectionPrivate();
void connectToHost(const SshConnectionParameters &serverInfo);
void connectToHost();
void closeConnection(SshErrorCode sshError, SshError userError,
const QByteArray &serverErrorString, const QString &userErrorString);
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
@@ -150,7 +151,7 @@ private:
SshIncomingPacket m_incomingPacket;
SshSendFacility m_sendFacility;
SshChannelManager * const m_channelManager;
SshConnectionParameters m_connParams;
const SshConnectionParameters m_connParams;
QByteArray m_incomingData;
SshError m_error;
QString m_errorString;

View File

@@ -0,0 +1,196 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "sshconnectionmanager.h"
#include "sshconnection.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QList>
#include <QtCore/QMutex>
#include <QtCore/QMutexLocker>
#include <QtCore/QObject>
#include <QtCore/QThread>
#include <QtCore/QTimer>
namespace Utils {
namespace Internal {
struct ConnectionInfo
{
typedef QSharedPointer<ConnectionInfo> Ptr;
static ConnectionInfo::Ptr create(const SshConnection::Ptr &conn)
{
return Ptr(new ConnectionInfo(conn));
}
SshConnection::Ptr connection;
int refCount;
bool isConnecting;
private:
ConnectionInfo(const SshConnection::Ptr &conn)
: connection(conn), refCount(1), isConnecting(false) {}
};
class SshConnectionManagerPrivate : public QObject
{
Q_OBJECT
public:
static QMutex instanceMutex;
static SshConnectionManager &instance()
{
static SshConnectionManager manager;
return manager;
}
SshConnectionManagerPrivate()
{
moveToThread(QCoreApplication::instance()->thread());
connect(&m_cleanupTimer, SIGNAL(timeout()), SLOT(cleanup()));
m_cleanupTimer.start(5*60*1000);
}
ConnectionInfo::Ptr findConnection(const SshConnection::Ptr &connection)
{
foreach (const ConnectionInfo::Ptr &connInfo, m_connections) {
if (connInfo->connection == connection)
return connInfo;
}
return ConnectionInfo::Ptr();
}
QSharedPointer<SshConnection> acquireConnection(const SshConnectionParameters &sshParams)
{
QMutexLocker locker(&m_listMutex);
foreach (const ConnectionInfo::Ptr &connInfo, m_connections) {
const SshConnection::Ptr connection = connInfo->connection;
bool connectionUsable = false;
if (connection->state() == SshConnection::Connected
&& connection->connectionParameters() == sshParams) {
if (connInfo->refCount == 0) {
if (connection->thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "switchToCallerThread",
Qt::BlockingQueuedConnection,
Q_ARG(SshConnection *, connection.data()),
Q_ARG(QObject *, QThread::currentThread()));
}
connectionUsable = true;
} else if (connection->thread() == QThread::currentThread()) {
connectionUsable = true;
}
if (connectionUsable) {
++connInfo->refCount;
return connection;
}
}
}
ConnectionInfo::Ptr connInfo
= ConnectionInfo::create(SshConnection::create(sshParams));
m_connections << connInfo;
return connInfo->connection;
}
void releaseConnection(const SshConnection::Ptr &connection)
{
QMutexLocker locker(&m_listMutex);
ConnectionInfo::Ptr connInfo = findConnection(connection);
Q_ASSERT_X(connInfo, Q_FUNC_INFO, "Fatal: Unowned SSH Connection released.");
if (--connInfo->refCount == 0) {
connection->moveToThread(QCoreApplication::instance()->thread());
if (connection->state() != SshConnection::Connected)
m_connections.removeOne(connInfo);
}
}
private:
Q_INVOKABLE void switchToCallerThread(SshConnection *connection, QObject *threadObj)
{
connection->moveToThread(qobject_cast<QThread *>(threadObj));
}
Q_SLOT void cleanup()
{
QMutexLocker locker(&m_listMutex);
foreach (const ConnectionInfo::Ptr &connInfo, m_connections) {
if (connInfo->refCount == 0 &&
connInfo->connection->state() != SshConnection::Connected) {
m_connections.removeOne(connInfo);
}
}
}
// We expect the number of concurrently open connections to be small.
// If that turns out to not be the case, we can still use a data
// structure with faster access.
QList<ConnectionInfo::Ptr> m_connections;
QMutex m_listMutex;
QTimer m_cleanupTimer;
};
QMutex SshConnectionManagerPrivate::instanceMutex;
} // namespace Internal
SshConnectionManager &SshConnectionManager::instance()
{
QMutexLocker locker(&Internal::SshConnectionManagerPrivate::instanceMutex);
return Internal::SshConnectionManagerPrivate::instance();
}
SshConnectionManager::SshConnectionManager()
: d(new Internal::SshConnectionManagerPrivate)
{
}
SshConnectionManager::~SshConnectionManager()
{
}
SshConnection::Ptr SshConnectionManager::acquireConnection(const SshConnectionParameters &sshParams)
{
return d->acquireConnection(sshParams);
}
void SshConnectionManager::releaseConnection(const SshConnection::Ptr &connection)
{
d->releaseConnection(connection);
}
} // namespace Utils
#include "sshconnectionmanager.moc"

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 (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef SSHCONNECTIONMANAGER_H
#define SSHCONNECTIONMANAGER_H
#include <utils/utils_global.h>
#include <QtCore/QScopedPointer>
#include <QtCore/QSharedPointer>
namespace Utils {
class SshConnection;
class SshConnectionParameters;
namespace Internal { class SshConnectionManagerPrivate; }
class QTCREATOR_UTILS_EXPORT SshConnectionManager
{
friend class Internal::SshConnectionManagerPrivate;
public:
static SshConnectionManager &instance();
QSharedPointer<SshConnection> acquireConnection(const SshConnectionParameters &sshParams);
void releaseConnection(const QSharedPointer<SshConnection> &connection);
private:
explicit SshConnectionManager();
virtual ~SshConnectionManager();
SshConnectionManager(const SshConnectionManager &);
SshConnectionManager &operator=(const SshConnectionManager &);
const QScopedPointer<Internal::SshConnectionManagerPrivate> d;
};
} // namespace Utils
#endif // SSHCONNECTIONMANAGER_H

View File

@@ -33,6 +33,8 @@
#include "sshremoteprocessrunner.h"
#include "sshconnectionmanager.h"
#define ASSERT_STATE(states) assertState(states, Q_FUNC_INFO)
/*!
@@ -51,6 +53,7 @@ public:
QObject *parent);
SshRemoteProcessRunnerPrivate(const SshConnection::Ptr &connection,
QObject *parent);
~SshRemoteProcessRunnerPrivate();
void run(const QByteArray &command);
QByteArray command() const { return m_command; }
@@ -79,29 +82,34 @@ private:
void assertState(State allowedState, const char *func);
State m_state;
bool m_needsRelease;
QByteArray m_command;
const SshConnectionParameters m_params;
};
SshRemoteProcessRunnerPrivate::SshRemoteProcessRunnerPrivate(const SshConnectionParameters &params,
QObject *parent)
: QObject(parent),
m_connection(SshConnection::create()),
m_connection(SshConnectionManager::instance().acquireConnection(params)),
m_state(Inactive),
m_params(params)
m_needsRelease(true)
{
}
SshRemoteProcessRunnerPrivate::SshRemoteProcessRunnerPrivate(const SshConnection::Ptr &connection,
QObject *parent)
: QObject(parent),
m_connection(connection),
m_state(Inactive),
m_params(connection->connectionParameters())
: QObject(parent),
m_connection(connection),
m_state(Inactive),
m_needsRelease(false)
{
}
SshRemoteProcessRunnerPrivate::~SshRemoteProcessRunnerPrivate()
{
setState(Inactive);
}
void SshRemoteProcessRunnerPrivate::run(const QByteArray &command)
{
ASSERT_STATE(Inactive);
@@ -117,7 +125,7 @@ void SshRemoteProcessRunnerPrivate::run(const QByteArray &command)
} else {
connect(m_connection.data(), SIGNAL(connected()),
SLOT(handleConnected()));
m_connection->connectToHost(m_params);
m_connection->connectToHost();
}
}
@@ -182,6 +190,8 @@ void SshRemoteProcessRunnerPrivate::setState(State state)
if (m_process)
disconnect(m_process.data(), 0, this, 0);
disconnect(m_connection.data(), 0, this, 0);
if (m_needsRelease)
SshConnectionManager::instance().releaseConnection(m_connection);
}
}
}

View File

@@ -76,7 +76,8 @@ SOURCES += $$PWD/environment.cpp \
$$PWD/ssh/sftpincomingpacket.cpp \
$$PWD/ssh/sftpdefs.cpp \
$$PWD/ssh/sftpchannel.cpp \
$$PWD/ssh/sshremoteprocessrunner.cpp
$$PWD/ssh/sshremoteprocessrunner.cpp \
$$PWD/ssh/sshconnectionmanager.cpp
win32 {
SOURCES += $$PWD/abstractprocess_win.cpp \
@@ -169,6 +170,7 @@ HEADERS += $$PWD/environment.h \
$$PWD/ssh/sftpchannel.h \
$$PWD/ssh/sftpchannel_p.h \
$$PWD/ssh/sshremoteprocessrunner.h \
$$PWD/ssh/sshconnectionmanager.h \
$$PWD/settingsutils.h
FORMS += $$PWD/filewizardpage.ui \

View File

@@ -65,8 +65,7 @@ QString displayNameForId(const QString &id) {
CMakeTarget::CMakeTarget(CMakeProject *parent) :
ProjectExplorer::Target(parent, QLatin1String(DEFAULT_CMAKE_TARGET_ID)),
m_buildConfigurationFactory(new CMakeBuildConfigurationFactory(this)),
m_deployConfigurationFactory(new ProjectExplorer::DeployConfigurationFactory(this))
m_buildConfigurationFactory(new CMakeBuildConfigurationFactory(this))
{
setDefaultDisplayName(displayNameForId(id()));
setIcon(qApp->style()->standardIcon(QStyle::SP_ComputerIcon));
@@ -102,11 +101,6 @@ CMakeBuildConfigurationFactory *CMakeTarget::buildConfigurationFactory() const
return m_buildConfigurationFactory;
}
ProjectExplorer::DeployConfigurationFactory *CMakeTarget::deployConfigurationFactory() const
{
return m_deployConfigurationFactory;
}
QString CMakeTarget::defaultBuildDirectory() const
{
return cmakeProject()->defaultBuildDirectory();
@@ -228,7 +222,7 @@ CMakeTarget *CMakeTargetFactory::create(ProjectExplorer::Project *parent, const
t->addBuildConfiguration(bc);
t->addDeployConfiguration(t->deployConfigurationFactory()->create(t, ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
t->addDeployConfiguration(t->createDeployConfiguration(ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
t->updateRunConfigurations();

View File

@@ -64,7 +64,6 @@ public:
CMakeBuildConfiguration *activeBuildConfiguration() const;
CMakeBuildConfigurationFactory *buildConfigurationFactory() const;
ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
QString defaultBuildDirectory() const;
@@ -76,7 +75,6 @@ private slots:
private:
CMakeBuildConfigurationFactory *m_buildConfigurationFactory;
ProjectExplorer::DeployConfigurationFactory *m_deployConfigurationFactory;
};
class CMakeTargetFactory : public ProjectExplorer::ITargetFactory

View File

@@ -37,12 +37,13 @@
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/ssh/sshconnectionmanager.h>
#include <QtCore/QFileInfo>
#include <ctype.h>
using namespace Core;
using namespace Utils;
namespace Debugger {
namespace Internal {
@@ -91,11 +92,15 @@ void RemoteGdbProcess::realStart(const QString &cmd, const QStringList &args,
m_gdbOutput.clear();
m_errorOutput.clear();
m_inputToSend.clear();
m_conn = Utils::SshConnection::create();
connect(m_conn.data(), SIGNAL(connected()), this, SLOT(handleConnected()));
m_conn = SshConnectionManager::instance().acquireConnection(m_connParams);
connect(m_conn.data(), SIGNAL(error(Utils::SshError)), this,
SLOT(handleConnectionError()));
m_conn->connectToHost(m_connParams);
if (m_conn->state() == SshConnection::Connected) {
handleConnected();
} else {
connect(m_conn.data(), SIGNAL(connected()), this, SLOT(handleConnected()));
m_conn->connectToHost();
}
}
void RemoteGdbProcess::handleConnected()
@@ -386,7 +391,8 @@ void RemoteGdbProcess::setState(State newState)
m_fifoCreator = Utils::SshRemoteProcess::Ptr();
}
disconnect(m_conn.data(), 0, this, 0);
m_conn->disconnectFromHost();
SshConnectionManager::instance().releaseConnection(m_conn);
m_conn.clear();
}
}

View File

@@ -58,8 +58,7 @@ using namespace GenericProjectManager::Internal;
GenericTarget::GenericTarget(GenericProject *parent) :
ProjectExplorer::Target(parent, QLatin1String(GENERIC_DESKTOP_TARGET_ID)),
m_buildConfigurationFactory(new GenericBuildConfigurationFactory(this)),
m_deployConfigurationFactory(new ProjectExplorer::DeployConfigurationFactory(this))
m_buildConfigurationFactory(new GenericBuildConfigurationFactory(this))
{
setDefaultDisplayName(QApplication::translate("GenericProjectManager::GenericTarget",
GENERIC_DESKTOP_TARGET_DISPLAY_NAME));
@@ -85,11 +84,6 @@ GenericBuildConfigurationFactory *GenericTarget::buildConfigurationFactory() con
return m_buildConfigurationFactory;
}
ProjectExplorer::DeployConfigurationFactory *GenericTarget::deployConfigurationFactory() const
{
return m_deployConfigurationFactory;
}
GenericBuildConfiguration *GenericTarget::activeBuildConfiguration() const
{
return static_cast<GenericBuildConfiguration *>(Target::activeBuildConfiguration());
@@ -165,7 +159,7 @@ GenericTarget *GenericTargetFactory::create(ProjectExplorer::Project *parent, co
t->addBuildConfiguration(bc);
t->addDeployConfiguration(t->deployConfigurationFactory()->create(t, ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
t->addDeployConfiguration(t->createDeployConfiguration(ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
// Add a runconfiguration. The CustomExecutableRC one will query the user
// for its settings, so it is a good choice here.

View File

@@ -70,7 +70,6 @@ public:
GenericProject *genericProject() const;
GenericBuildConfigurationFactory *buildConfigurationFactory() const;
ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
GenericBuildConfiguration *activeBuildConfiguration() const;
protected:
@@ -78,7 +77,6 @@ protected:
private:
GenericBuildConfigurationFactory *m_buildConfigurationFactory;
ProjectExplorer::DeployConfigurationFactory *m_deployConfigurationFactory;
};
class GenericTargetFactory : public ProjectExplorer::ITargetFactory

View File

@@ -850,6 +850,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
addAutoReleasedObject(new ProjectTreeWidgetFactory);
addAutoReleasedObject(new FolderNavigationWidgetFactory);
addAutoReleasedObject(new DeployConfigurationFactory);
if (QSettings *s = core->settings()) {
const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").toStringList();

View File

@@ -319,10 +319,9 @@ void RunSettingsWidget::currentDeployConfigurationChanged(int index)
void RunSettingsWidget::aboutToShowDeployMenu()
{
m_addDeployMenu->clear();
DeployConfigurationFactory *factory = m_target->deployConfigurationFactory();
QStringList ids = factory->availableCreationIds(m_target);
QStringList ids = m_target->availableDeployConfigurationIds();
foreach (const QString &id, ids) {
QAction *action = m_addDeployMenu->addAction(factory->displayNameForId(id));;
QAction *action = m_addDeployMenu->addAction(m_target->displayNameForDeployConfigurationId(id));
action->setData(QVariant(id));
connect(action, SIGNAL(triggered()),
this, SLOT(addDeployConfiguration()));
@@ -335,7 +334,7 @@ void RunSettingsWidget::addDeployConfiguration()
if (!act)
return;
QString id = act->data().toString();
DeployConfiguration *newDc = m_target->deployConfigurationFactory()->create(m_target, id);
DeployConfiguration *newDc = m_target->createDeployConfiguration(id);
if (!newDc)
return;
m_target->addDeployConfiguration(newDc);

View File

@@ -41,6 +41,7 @@
#include "toolchainmanager.h"
#include <limits>
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <QtGui/QIcon>
@@ -69,6 +70,9 @@ namespace ProjectExplorer {
class TargetPrivate {
public:
TargetPrivate();
QList<DeployConfigurationFactory *> deployFactories() const;
bool m_isEnabled;
QIcon m_icon;
QIcon m_overlayIcon;
@@ -90,6 +94,11 @@ TargetPrivate::TargetPrivate() :
{
}
QList<DeployConfigurationFactory *> TargetPrivate::deployFactories() const
{
return ExtensionSystem::PluginManager::instance()->getObjects<DeployConfigurationFactory>();
}
Target::Target(Project *project, const QString &id) :
ProjectConfiguration(project, id), d(new TargetPrivate)
@@ -199,7 +208,7 @@ void Target::addDeployConfiguration(DeployConfiguration *dc)
QTC_ASSERT(dc && !d->m_deployConfigurations.contains(dc), return);
Q_ASSERT(dc->target() == this);
if (!deployConfigurationFactory())
if (d->deployFactories().isEmpty())
return;
// Check that we don't have a configuration with the same displayName
@@ -260,6 +269,32 @@ void Target::setActiveDeployConfiguration(DeployConfiguration *dc)
}
}
QStringList Target::availableDeployConfigurationIds()
{
QStringList ids;
foreach (const DeployConfigurationFactory * const factory, d->deployFactories())
ids << factory->availableCreationIds(this);
return ids;
}
QString Target::displayNameForDeployConfigurationId(const QString &id)
{
foreach (const DeployConfigurationFactory * const factory, d->deployFactories()) {
if (factory->availableCreationIds(this).contains(id))
return factory->displayNameForId(id);
}
return QString();
}
DeployConfiguration *Target::createDeployConfiguration(const QString &id)
{
foreach (DeployConfigurationFactory * const factory, d->deployFactories()) {
if (factory->canCreate(this, id))
return factory->create(this, id);
}
return 0;
}
QList<RunConfiguration *> Target::runConfigurations() const
{
return d->m_runConfigurations;
@@ -451,15 +486,20 @@ bool Target::fromMap(const QVariantMap &map)
if (!map.contains(key))
return false;
DeployConfiguration *dc = 0;
if (deployConfigurationFactory())
dc = deployConfigurationFactory()->restore(this, map.value(key).toMap());
foreach (DeployConfigurationFactory * const factory, d->deployFactories()) {
QVariantMap valueMap = map.value(key).toMap();
if (factory->canRestore(this, valueMap)) {
dc = factory->restore(this, valueMap);
break;
}
}
if (!dc)
continue;
addDeployConfiguration(dc);
if (i == activeConfiguration)
setActiveDeployConfiguration(dc);
}
if (deployConfigurations().isEmpty() && deployConfigurationFactory())
if (deployConfigurations().isEmpty() && d->deployFactories().isEmpty())
return false;
int rcCount(map.value(QLatin1String(RC_COUNT_KEY), 0).toInt(&ok));

View File

@@ -85,7 +85,9 @@ public:
virtual DeployConfiguration *activeDeployConfiguration() const;
void setActiveDeployConfiguration(DeployConfiguration *configuration);
virtual DeployConfigurationFactory *deployConfigurationFactory() const = 0;
QStringList availableDeployConfigurationIds();
QString displayNameForDeployConfigurationId(const QString &id);
DeployConfiguration *createDeployConfiguration(const QString &id);
// Running
QList<RunConfiguration *> runConfigurations() const;

View File

@@ -245,6 +245,24 @@ public:
QVariantMap update(Project *project, const QVariantMap &map);
};
// Version 9 reflects the refactoring of the Maemo deploy step.
class Version9Handler : public UserFileVersionHandler
{
public:
int userFileVersion() const
{
return 9;
}
QString displayUserFileVersion() const
{
return QLatin1String("2.3pre1");
}
QVariantMap update(Project *project, const QVariantMap &map);
};
} // namespace
//
@@ -372,6 +390,7 @@ UserFileAccessor::UserFileAccessor() :
addVersionHandler(new Version6Handler);
addVersionHandler(new Version7Handler);
addVersionHandler(new Version8Handler);
addVersionHandler(new Version9Handler);
}
UserFileAccessor::~UserFileAccessor()
@@ -1866,3 +1885,52 @@ QVariantMap Version8Handler::update(Project *, const QVariantMap &map)
const char * const *p4 = varExpandedKeys;
return processHandlerNodes(buildHandlerNodes(&p4), rmap3, version8VarNodeHandler);
}
QVariantMap Version9Handler::update(Project *project, const QVariantMap &map)
{
Q_UNUSED(project);
QVariantMap result;
QMapIterator<QString, QVariant> globalIt(map);
while (globalIt.hasNext()) {
globalIt.next();
const QString &globalKey = globalIt.key();
// check for target info
if (!globalKey.startsWith(QLatin1String("ProjectExplorer.Project.Target."))) {
result.insert(globalKey, globalIt.value());
continue;
}
const QVariantMap &origTargetMap = globalIt.value().toMap();
const QString targetIdKey
= QLatin1String("ProjectExplorer.ProjectConfiguration.Id");
// check for maemo device target
if (origTargetMap.value(targetIdKey)
!= QLatin1String("Qt4ProjectManager.Target.MaemoDeviceTarget")
&& origTargetMap.value(targetIdKey)
!= QLatin1String("Qt4ProjectManager.Target.HarmattanDeviceTarget")
&& origTargetMap.value(targetIdKey)
!= QLatin1String("Qt4ProjectManager.Target.MeegoDeviceTarget"))
{
result.insert(globalKey, origTargetMap);
continue;
}
QVariantMap newTargetMap;
QMapIterator<QString, QVariant> targetIt(origTargetMap);
while (targetIt.hasNext()) {
targetIt.next();
if (!targetIt.key().startsWith(QLatin1String("ProjectExplorer.Target.DeployConfiguration."))) {
newTargetMap.insert(targetIt.key(), targetIt.value());
continue;
}
QVariantMap deployConfMap = targetIt.value().toMap();
deployConfMap.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"),
QLatin1String("2.2MaemoDeployConfig"));
newTargetMap.insert(targetIt.key(), deployConfMap);
}
result.insert(globalKey, newTargetMap);
}
return result;
}

View File

@@ -72,11 +72,6 @@ ProjectExplorer::IBuildConfigurationFactory *QmlProjectTarget::buildConfiguratio
return 0;
}
ProjectExplorer::DeployConfigurationFactory *QmlProjectTarget::deployConfigurationFactory() const
{
return 0;
}
bool QmlProjectTarget::fromMap(const QVariantMap &map)
{
if (!Target::fromMap(map))

View File

@@ -61,7 +61,6 @@ public:
QmlProject *qmlProject() const;
ProjectExplorer::IBuildConfigurationFactory *buildConfigurationFactory() const;
ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
protected:
bool fromMap(const QVariantMap &map);

View File

@@ -44,8 +44,7 @@ using namespace Qt4ProjectManager::Internal;
Qt4DesktopTarget::Qt4DesktopTarget(Qt4Project *parent, const QString &id) :
Qt4BaseTarget(parent, id),
m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this)),
m_deployConfigurationFactory(new ProjectExplorer::DeployConfigurationFactory(this))
m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this))
{
setDisplayName(defaultDisplayName());
setIcon(qApp->style()->standardIcon(QStyle::SP_ComputerIcon));
@@ -65,11 +64,6 @@ Qt4BuildConfigurationFactory *Qt4DesktopTarget::buildConfigurationFactory() cons
return m_buildConfigurationFactory;
}
ProjectExplorer::DeployConfigurationFactory *Qt4DesktopTarget::deployConfigurationFactory() const
{
return m_deployConfigurationFactory;
}
void Qt4DesktopTarget::createApplicationProFiles()
{
removeUnconfiguredCustomExectutableRunConfigurations();

View File

@@ -51,7 +51,6 @@ public:
virtual ~Qt4DesktopTarget();
Internal::Qt4BuildConfigurationFactory *buildConfigurationFactory() const;
ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
void createApplicationProFiles();
QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n);
@@ -60,7 +59,6 @@ public:
private:
Internal::Qt4BuildConfigurationFactory *m_buildConfigurationFactory;
ProjectExplorer::DeployConfigurationFactory *m_deployConfigurationFactory;
};
} // namespace Internal

View File

@@ -197,7 +197,7 @@ ProjectExplorer::Target *Qt4DesktopTargetFactory::create(ProjectExplorer::Projec
info.version, info.buildConfig,
info.additionalArguments, info.directory);
t->addDeployConfiguration(t->deployConfigurationFactory()->create(t, ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
t->addDeployConfiguration(t->createDeployConfiguration(ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
t->createApplicationProFiles();

View File

@@ -49,8 +49,7 @@ using namespace Qt4ProjectManager::Internal;
Qt4SimulatorTarget::Qt4SimulatorTarget(Qt4Project *parent, const QString &id) :
Qt4BaseTarget(parent, id),
m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this)),
m_deployConfigurationFactory(new ProjectExplorer::DeployConfigurationFactory(this))
m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this))
{
setDisplayName(defaultDisplayName());
setIcon(QIcon(":/projectexplorer/images/SymbianEmulator.png"));
@@ -70,11 +69,6 @@ Qt4BuildConfigurationFactory *Qt4SimulatorTarget::buildConfigurationFactory() co
return m_buildConfigurationFactory;
}
ProjectExplorer::DeployConfigurationFactory *Qt4SimulatorTarget::deployConfigurationFactory() const
{
return m_deployConfigurationFactory;
}
void Qt4SimulatorTarget::createApplicationProFiles()
{
removeUnconfiguredCustomExectutableRunConfigurations();

View File

@@ -51,7 +51,6 @@ public:
virtual ~Qt4SimulatorTarget();
Internal::Qt4BuildConfigurationFactory *buildConfigurationFactory() const;
ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
void createApplicationProFiles();
QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n);
@@ -60,7 +59,6 @@ public:
private:
Internal::Qt4BuildConfigurationFactory *m_buildConfigurationFactory;
ProjectExplorer::DeployConfigurationFactory *m_deployConfigurationFactory;
};
} // namespace Internal

View File

@@ -182,7 +182,7 @@ ProjectExplorer::Target *Qt4SimulatorTargetFactory::create(ProjectExplorer::Proj
t->addQt4BuildConfiguration(msgBuildConfigurationName(info), info.version, info.buildConfig,
info.additionalArguments, info.directory);
t->addDeployConfiguration(t->deployConfigurationFactory()->create(t, ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
t->addDeployConfiguration(t->createDeployConfiguration(ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
t->createApplicationProFiles();

View File

@@ -0,0 +1,462 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "abstractmaemodeploystep.h"
#include "maemoconstants.h"
#include "maemodeploystepwidget.h"
#include "maemoglobal.h"
#include "maemopackagecreationstep.h"
#include "maemopertargetdeviceconfigurationlistmodel.h"
#include "maemoqemumanager.h"
#include "qt4maemodeployconfiguration.h"
#include <utils/ssh/sshconnection.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4projectmanagerconstants.h>
#include <utils/ssh/sshconnectionmanager.h>
#include <QtCore/QEventLoop>
#include <QtCore/QFileInfo>
#include <QtCore/QTimer>
#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(BaseState, state, m_baseState)
using namespace Core;
using namespace Utils;
using namespace ProjectExplorer;
namespace Qt4ProjectManager {
namespace Internal {
namespace {
class MaemoDeployEventHandler : public QObject
{
Q_OBJECT
public:
MaemoDeployEventHandler(AbstractMaemoDeployStep *deployStep,
QFutureInterface<bool> &future);
private slots:
void handleDeployingDone();
void handleDeployingFailed();
void checkForCanceled();
private:
AbstractMaemoDeployStep * const m_deployStep;
const QFutureInterface<bool> m_future;
QEventLoop * const m_eventLoop;
bool m_error;
};
} // anonymous namespace
AbstractMaemoDeployStep::AbstractMaemoDeployStep(BuildStepList *parent,
const QString &id) : BuildStep(parent, id)
{
baseCtor();
}
AbstractMaemoDeployStep::AbstractMaemoDeployStep(BuildStepList *parent,
AbstractMaemoDeployStep *other)
: BuildStep(parent, other), m_lastDeployed(other->m_lastDeployed)
{
baseCtor();
}
AbstractMaemoDeployStep::~AbstractMaemoDeployStep() { }
void AbstractMaemoDeployStep::baseCtor()
{
m_baseState = BaseInactive;
m_deviceConfig = maemoDeployConfig()->deviceConfigModel()->defaultDeviceConfig();
connect(maemoDeployConfig()->deviceConfigModel(), SIGNAL(updated()),
SLOT(handleDeviceConfigurationsUpdated()));
}
void AbstractMaemoDeployStep::run(QFutureInterface<bool> &fi)
{
// Move to GUI thread.
QTimer::singleShot(0, this, SLOT(start()));
MaemoDeployEventHandler eventHandler(this, fi);
}
BuildStepConfigWidget *AbstractMaemoDeployStep::createConfigWidget()
{
return new MaemoDeployStepWidget(this);
}
QVariantMap AbstractMaemoDeployStep::toMap() const
{
QVariantMap map(BuildStep::toMap());
addDeployTimesToMap(map);
map.insert(DeviceIdKey,
MaemoDeviceConfigurations::instance()->internalId(m_deviceConfig));
return map;
}
void AbstractMaemoDeployStep::addDeployTimesToMap(QVariantMap &map) const
{
QVariantList hostList;
QVariantList fileList;
QVariantList remotePathList;
QVariantList timeList;
typedef QHash<DeployablePerHost, QDateTime>::ConstIterator DepIt;
for (DepIt it = m_lastDeployed.begin(); it != m_lastDeployed.end(); ++it) {
fileList << it.key().first.localFilePath;
remotePathList << it.key().first.remoteDir;
hostList << it.key().second;
timeList << it.value();
}
map.insert(LastDeployedHostsKey, hostList);
map.insert(LastDeployedFilesKey, fileList);
map.insert(LastDeployedRemotePathsKey, remotePathList);
map.insert(LastDeployedTimesKey, timeList);
}
bool AbstractMaemoDeployStep::fromMap(const QVariantMap &map)
{
if (!BuildStep::fromMap(map))
return false;
getDeployTimesFromMap(map);
setDeviceConfig(map.value(DeviceIdKey, MaemoDeviceConfig::InvalidId).toULongLong());
return true;
}
void AbstractMaemoDeployStep::getDeployTimesFromMap(const QVariantMap &map)
{
const QVariantList &hostList = map.value(LastDeployedHostsKey).toList();
const QVariantList &fileList = map.value(LastDeployedFilesKey).toList();
const QVariantList &remotePathList
= map.value(LastDeployedRemotePathsKey).toList();
const QVariantList &timeList = map.value(LastDeployedTimesKey).toList();
const int elemCount
= qMin(qMin(hostList.size(), fileList.size()),
qMin(remotePathList.size(), timeList.size()));
for (int i = 0; i < elemCount; ++i) {
const MaemoDeployable d(fileList.at(i).toString(),
remotePathList.at(i).toString());
m_lastDeployed.insert(DeployablePerHost(d, hostList.at(i).toString()),
timeList.at(i).toDateTime());
}
}
const AbstractMaemoPackageCreationStep *AbstractMaemoDeployStep::packagingStep() const
{
return MaemoGlobal::earlierBuildStep<AbstractMaemoPackageCreationStep>(maemoDeployConfig(), this);
}
void AbstractMaemoDeployStep::raiseError(const QString &errorString)
{
emit addTask(Task(Task::Error, errorString, QString(), -1,
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
m_hasError = true;
emit error();
}
void AbstractMaemoDeployStep::writeOutput(const QString &text, OutputFormat format)
{
emit addOutput(text, format);
}
void AbstractMaemoDeployStep::stop()
{
if (m_baseState == StopRequested || m_baseState == BaseInactive)
return;
writeOutput(tr("Operation canceled by user, cleaning up..."));
const BaseState oldState = m_baseState;
setBaseState(StopRequested);
switch (oldState) {
case Connecting:
m_connection->disconnectFromHost();
setDeploymentFinished();
break;
case Deploying:
stopInternal();
break;
default:
qFatal("Missing switch case in %s.", Q_FUNC_INFO);
}
}
bool AbstractMaemoDeployStep::currentlyNeedsDeployment(const QString &host,
const MaemoDeployable &deployable) const
{
const QDateTime &lastDeployed
= m_lastDeployed.value(DeployablePerHost(deployable, host));
return !lastDeployed.isValid()
|| QFileInfo(deployable.localFilePath).lastModified() > lastDeployed;
}
void AbstractMaemoDeployStep::setDeployed(const QString &host,
const MaemoDeployable &deployable)
{
m_lastDeployed.insert(DeployablePerHost(deployable, host),
QDateTime::currentDateTime());
}
void AbstractMaemoDeployStep::handleDeviceConfigurationsUpdated()
{
setDeviceConfig(MaemoDeviceConfigurations::instance()->internalId(m_deviceConfig));
}
void AbstractMaemoDeployStep::setDeviceConfig(MaemoDeviceConfig::Id internalId)
{
m_deviceConfig = maemoDeployConfig()->deviceConfigModel()->find(internalId);
emit deviceConfigChanged();
}
void AbstractMaemoDeployStep::setDeviceConfig(int i)
{
m_deviceConfig = maemoDeployConfig()->deviceConfigModel()->deviceAt(i);
emit deviceConfigChanged();
}
bool AbstractMaemoDeployStep::isDeploymentPossible(QString &whyNot) const
{
if (!m_deviceConfig) {
whyNot = tr("No valid device set.");
return false;
}
return isDeploymentPossibleInternal(whyNot);
}
void AbstractMaemoDeployStep::start()
{
if (m_baseState != BaseInactive) {
raiseError(tr("Cannot deploy: Still cleaning up from last time."));
emit done();
return;
}
m_cachedDeviceConfig = m_deviceConfig;
QString message;
if (!isDeploymentPossible(message)) {
raiseError(tr("Cannot deploy: %1").arg(message));
emit done();
return;
}
m_hasError = false;
if (isDeploymentNeeded(m_cachedDeviceConfig->sshParameters().host)) {
if (m_cachedDeviceConfig->type() == MaemoDeviceConfig::Emulator
&& !MaemoQemuManager::instance().qemuIsRunning()) {
MaemoQemuManager::instance().startRuntime();
raiseError(tr("Cannot deploy: Qemu was not running. "
"It has now been started up for you, but it will take "
"a bit of time until it is ready."));
emit done();
return;
}
connectToDevice();
} else {
writeOutput(tr("All files up to date, no installation necessary."));
emit done();
}
}
void AbstractMaemoDeployStep::handleConnectionFailure()
{
if (m_baseState == BaseInactive)
return;
const QString errorMsg = m_baseState == Connecting
? MaemoGlobal::failedToConnectToServerMessage(m_connection, m_cachedDeviceConfig)
: tr("Connection error: %1").arg(m_connection->errorString());
raiseError(errorMsg);
setDeploymentFinished();
}
void AbstractMaemoDeployStep::connectToDevice()
{
ASSERT_STATE(QList<BaseState>() << BaseInactive);
setBaseState(Connecting);
m_connection = SshConnectionManager::instance().acquireConnection(m_cachedDeviceConfig->sshParameters());
connect(m_connection.data(), SIGNAL(error(Utils::SshError)), this,
SLOT(handleConnectionFailure()));
if (m_connection->state() == SshConnection::Connected) {
handleConnected();
} else {
connect(m_connection.data(), SIGNAL(connected()), this,
SLOT(handleConnected()));
writeOutput(tr("Connecting to device..."));
m_connection->connectToHost();
}
}
void AbstractMaemoDeployStep::handleConnected()
{
ASSERT_STATE(QList<BaseState>() << Connecting << StopRequested);
if (m_baseState == Connecting) {
setBaseState(Deploying);
startInternal();
}
}
void AbstractMaemoDeployStep::handleProgressReport(const QString &progressMsg)
{
ASSERT_STATE(QList<BaseState>() << Deploying << StopRequested << BaseInactive);
switch (m_baseState) {
case Deploying:
case StopRequested:
writeOutput(progressMsg);
break;
case BaseInactive:
default:
break;
}
}
void AbstractMaemoDeployStep::setDeploymentFinished()
{
if (m_hasError)
writeOutput(tr("Deployment failed."), ErrorMessageOutput);
else
writeOutput(tr("Deployment finished."));
setBaseState(BaseInactive);
}
void AbstractMaemoDeployStep::setBaseState(BaseState newState)
{
if (newState == m_baseState)
return;
m_baseState = newState;
if (m_baseState == BaseInactive) {
disconnect(m_connection.data(), 0, this, 0);
SshConnectionManager::instance().releaseConnection(m_connection);
emit done();
}
}
void AbstractMaemoDeployStep::handleRemoteStdout(const QString &output)
{
ASSERT_STATE(QList<BaseState>() << Deploying << StopRequested);
switch (m_baseState) {
case Deploying:
case StopRequested:
writeOutput(output, NormalOutput);
break;
default:
break;
}
}
void AbstractMaemoDeployStep::handleRemoteStderr(const QString &output)
{
ASSERT_STATE(QList<BaseState>() << Deploying << StopRequested);
switch (m_baseState) {
case Deploying:
case StopRequested:
writeOutput(output, ErrorOutput);
break;
default:
break;
}
}
MaemoPortList AbstractMaemoDeployStep::freePorts() const
{
const Qt4BuildConfiguration * const qt4bc = qt4BuildConfiguration();
const MaemoDeviceConfig::ConstPtr &devConf
= m_cachedDeviceConfig ? m_cachedDeviceConfig : m_deviceConfig;
if (!devConf)
return MaemoPortList();
if (devConf->type() == MaemoDeviceConfig::Emulator && qt4bc) {
MaemoQemuRuntime rt;
const int id = qt4bc->qtVersion()->uniqueId();
if (MaemoQemuManager::instance().runtimeForQtVersion(id, &rt))
return rt.m_freePorts;
}
return devConf->freePorts();
}
const Qt4BuildConfiguration *AbstractMaemoDeployStep::qt4BuildConfiguration() const
{
return static_cast<Qt4BuildConfiguration *>(buildConfiguration());
}
Qt4MaemoDeployConfiguration *AbstractMaemoDeployStep::maemoDeployConfig() const
{
return qobject_cast<Qt4MaemoDeployConfiguration *>(deployConfiguration());
}
MaemoDeployEventHandler::MaemoDeployEventHandler(AbstractMaemoDeployStep *deployStep,
QFutureInterface<bool> &future)
: m_deployStep(deployStep), m_future(future), m_eventLoop(new QEventLoop),
m_error(false)
{
connect(m_deployStep, SIGNAL(done()), this, SLOT(handleDeployingDone()));
connect(m_deployStep, SIGNAL(error()), this, SLOT(handleDeployingFailed()));
QTimer cancelChecker;
connect(&cancelChecker, SIGNAL(timeout()), this, SLOT(checkForCanceled()));
cancelChecker.start(500);
future.reportResult(m_eventLoop->exec() == 0);
}
void MaemoDeployEventHandler::handleDeployingDone()
{
m_eventLoop->exit(m_error ? 1 : 0);
}
void MaemoDeployEventHandler::handleDeployingFailed()
{
m_error = true;
}
void MaemoDeployEventHandler::checkForCanceled()
{
if (!m_error && m_future.isCanceled()) {
QMetaObject::invokeMethod(m_deployStep, "stop");
m_error = true;
handleDeployingDone();
}
}
} // namespace Internal
} // namespace Qt4ProjectManager
#include "abstractmaemodeploystep.moc"

View File

@@ -0,0 +1,139 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef ABSTRACTMAEMODEPLOYSTEP_H
#define ABSTRACTMAEMODEPLOYSTEP_H
#include "maemodeployable.h"
#include "maemodeployables.h"
#include "maemodeviceconfigurations.h"
#include <projectexplorer/buildstep.h>
#include <QtCore/QHash>
#include <QtCore/QList>
#include <QtCore/QPair>
#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
class QEventLoop;
QT_END_NAMESPACE
namespace Utils { class SshConnection; }
namespace Qt4ProjectManager {
class Qt4BuildConfiguration;
namespace Internal {
class AbstractMaemoPackageCreationStep;
class MaemoDeviceConfig;
class Qt4MaemoDeployConfiguration;
class AbstractMaemoDeployStep : public ProjectExplorer::BuildStep
{
Q_OBJECT
public:
virtual ~AbstractMaemoDeployStep();
QSharedPointer<const MaemoDeviceConfig> deviceConfig() const { return m_deviceConfig; }
void setDeviceConfig(int i);
bool currentlyNeedsDeployment(const QString &host,
const MaemoDeployable &deployable) const;
void setDeployed(const QString &host, const MaemoDeployable &deployable);
MaemoPortList freePorts() const;
Qt4MaemoDeployConfiguration *maemoDeployConfig() const;
bool isDeploymentPossible(QString &whyNot) const;
Q_INVOKABLE void stop();
signals:
void done();
void error();
void deviceConfigChanged();
protected:
AbstractMaemoDeployStep(ProjectExplorer::BuildStepList *bc,
const QString &id);
AbstractMaemoDeployStep(ProjectExplorer::BuildStepList *bc,
AbstractMaemoDeployStep *other);
enum BaseState { BaseInactive, StopRequested, Connecting, Deploying };
BaseState baseState() const { return m_baseState; }
void raiseError(const QString &error);
void writeOutput(const QString &text, OutputFormat = MessageOutput);
void setDeploymentFinished();
const AbstractMaemoPackageCreationStep *packagingStep() const;
QString deployMountPoint() const;
const Qt4BuildConfiguration *qt4BuildConfiguration() const;
QSharedPointer<Utils::SshConnection> connection() const { return m_connection; }
private slots:
void start();
void handleConnected();
void handleConnectionFailure();
void handleProgressReport(const QString &progressMsg);
void handleRemoteStdout(const QString &output);
void handleRemoteStderr(const QString &output);
void handleDeviceConfigurationsUpdated();
private:
virtual bool init() { return true; }
virtual void run(QFutureInterface<bool> &fi);
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
virtual QVariantMap toMap() const;
virtual bool fromMap(const QVariantMap &map);
virtual bool isDeploymentPossibleInternal(QString &whynot) const=0;
virtual bool isDeploymentNeeded(const QString &hostName) const=0;
virtual void startInternal()=0;
virtual void stopInternal()=0;
void baseCtor();
void addDeployTimesToMap(QVariantMap &map) const;
void getDeployTimesFromMap(const QVariantMap &map);
void connectToDevice();
void setBaseState(BaseState newState);
void setDeviceConfig(MaemoDeviceConfig::Id internalId);
QSharedPointer<Utils::SshConnection> m_connection;
typedef QPair<MaemoDeployable, QString> DeployablePerHost;
QHash<DeployablePerHost, QDateTime> m_lastDeployed;
QSharedPointer<const MaemoDeviceConfig> m_deviceConfig;
QSharedPointer<const MaemoDeviceConfig> m_cachedDeviceConfig;
BaseState m_baseState;
bool m_hasError;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // ABSTRACTMAEMODEPLOYSTEP_H

View File

@@ -86,7 +86,12 @@ void MaemoConfigTestDialog::startConfigTest()
: tr("Testing configuration...");
m_ui->testResultEdit->setPlainText(testingText);
m_closeButton->setText(tr("Stop Test"));
m_testProcessRunner = SshRemoteProcessRunner::create(m_config->sshParameters());
// We need to explicitly create the connection here, because the other
// constructor uses a managed connection, i.e. it might re-use an
// existing one, which we explicitly don't want here.
m_testProcessRunner = SshRemoteProcessRunner::create(SshConnection::create(m_config->sshParameters()));
connect(m_testProcessRunner.data(), SIGNAL(connectionError(Utils::SshError)),
this, SLOT(handleConnectionError()));
connect(m_testProcessRunner.data(), SIGNAL(processClosed(int)), this,
@@ -95,12 +100,15 @@ void MaemoConfigTestDialog::startConfigTest()
SIGNAL(processOutputAvailable(QByteArray)), this,
SLOT(processSshOutput(QByteArray)));
const QLatin1String sysInfoCmd("uname -rsm");
const bool osUsesRpm = MaemoGlobal::packagingSystem(m_config->osVersion()) == MaemoGlobal::Rpm;
const QLatin1String qtInfoCmd(osUsesRpm
? "rpm -qa 'libqt*' --queryformat '%{NAME} %{VERSION}\\n'"
: "dpkg-query -W -f '${Package} ${Version} ${Status}\n' 'libqt*' "
"|grep ' installed$'");
QString command(sysInfoCmd + " && " + qtInfoCmd);
QString command = sysInfoCmd;
if (m_config->osVersion() != MaemoGlobal::GenericLinux) {
const bool osUsesRpm = MaemoGlobal::packagingSystem(m_config->osVersion()) == MaemoGlobal::Rpm;
const QLatin1String qtInfoCmd(osUsesRpm
? "rpm -qa 'libqt*' --queryformat '%{NAME} %{VERSION}\\n'"
: "dpkg-query -W -f '${Package} ${Version} ${Status}\n' 'libqt*' "
"|grep ' installed$'");
command += QLatin1String(" && ") + qtInfoCmd;
}
m_testProcessRunner->run(command.toUtf8());
}
@@ -137,7 +145,7 @@ void MaemoConfigTestDialog::handleGeneralTestResult(int exitStatus)
|| m_testProcessRunner->process()->exitCode() != 0) {
m_ui->testResultEdit->setPlainText(tr("Remote process failed: %1")
.arg(m_testProcessRunner->process()->errorString()));
} else {
} else {
const QString &output = parseTestOutput();
if (!m_qtVersionOk) {
m_ui->errorLabel->setText(tr("Qt version mismatch! "
@@ -146,6 +154,11 @@ void MaemoConfigTestDialog::handleGeneralTestResult(int exitStatus)
m_ui->testResultEdit->setPlainText(output);
}
if (m_config->osVersion() == MaemoGlobal::GenericLinux) {
testPorts();
return;
}
m_currentTest = MadDeveloperTest;
disconnect(m_testProcessRunner.data(),
SIGNAL(processOutputAvailable(QByteArray)), this,
@@ -164,11 +177,7 @@ void MaemoConfigTestDialog::handleMadDeveloperTestResult(int exitStatus)
+ QLatin1String("<br>") + tr("Mad Developer is not installed.<br>"
"You will not be able to deploy to this device."));
}
if (m_config->freePorts().hasMore())
m_portsGatherer->start(m_testProcessRunner->connection(),
m_config->freePorts());
else
finish();
testPorts();
}
void MaemoConfigTestDialog::handlePortListFailure(const QString &errMsg)
@@ -193,6 +202,15 @@ void MaemoConfigTestDialog::handlePortListReady()
finish();
}
void MaemoConfigTestDialog::testPorts()
{
if (m_config->freePorts().hasMore())
m_portsGatherer->start(m_testProcessRunner->connection(),
m_config->freePorts());
else
finish();
}
void MaemoConfigTestDialog::finish()
{
if (m_ui->errorLabel->text().isEmpty()) {
@@ -235,6 +253,11 @@ QString MaemoConfigTestDialog::parseTestOutput()
output = tr("Hardware architecture: %1\n").arg(unamePattern.cap(2));
output.append(tr("Kernel version: %1\n").arg(unamePattern.cap(1)));
if (m_config->osVersion() == MaemoGlobal::GenericLinux) {
m_qtVersionOk = true;
return output;
}
const bool osUsesRpm = MaemoGlobal::packagingSystem(m_config->osVersion()) == MaemoGlobal::Rpm;
const QRegExp packagePattern(QLatin1String(osUsesRpm
? "(libqt\\S+) ((\\d+)\\.(\\d+)\\.(\\d+))"

View File

@@ -77,6 +77,7 @@ private:
QString parseTestOutput();
void handleGeneralTestResult(int exitStatus);
void handleMadDeveloperTestResult(int exitStatus);
void testPorts();
void finish();
Ui_MaemoConfigTestDialog *m_ui;

View File

@@ -57,7 +57,6 @@ static const QLatin1String LastDeployedHostsKey(PREFIX ".LastDeployedHosts");
static const QLatin1String LastDeployedFilesKey(PREFIX ".LastDeployedFiles");
static const QLatin1String LastDeployedRemotePathsKey(PREFIX ".LastDeployedRemotePaths");
static const QLatin1String LastDeployedTimesKey(PREFIX ".LastDeployedTimes");
static const QLatin1String DeployToSysrootKey(PREFIX ".DeployToSysroot");
static const QLatin1String ProFileKey(PREFIX ".ProFile");
static const QLatin1String ExportedLocalDirsKey(PREFIX ".ExportedLocalDirs");
static const QLatin1String RemoteMountPointsKey(PREFIX ".RemoteMountPoints");

View File

@@ -34,8 +34,8 @@
#include "maemodebugsupport.h"
#include "abstractmaemodeploystep.h"
#include "maemodeployables.h"
#include "maemodeploystep.h"
#include "maemoglobal.h"
#include "maemosshrunner.h"
#include "maemousedportsgatherer.h"

View File

@@ -42,6 +42,8 @@ namespace Internal {
struct MaemoDeployable
{
MaemoDeployable() {}
MaemoDeployable(const QString &localFilePath, const QString &remoteDir)
: localFilePath(localFilePath), remoteDir(remoteDir) {}

View File

@@ -42,20 +42,20 @@
#include "maemodeployables.h"
#include "maemoprofilesupdatedialog.h"
#include "qt4maemotarget.h"
#include <profileevaluator.h>
#include <projectexplorer/buildstep.h>
#include <qt4projectmanager/qt4projectmanagerconstants.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4project.h>
#include <qt4projectmanager/qt4target.h>
#include <QtCore/QTimer>
namespace Qt4ProjectManager {
namespace Internal {
MaemoDeployables::MaemoDeployables(const AbstractQt4MaemoTarget *target)
MaemoDeployables::MaemoDeployables(const Qt4BaseTarget *target)
: m_target(target), m_updateTimer(new QTimer(this))
{
QTimer::singleShot(0, this, SLOT(init()));

View File

@@ -53,16 +53,16 @@ QT_FORWARD_DECLARE_CLASS(QTimer)
namespace Qt4ProjectManager {
class Qt4BuildConfiguration;
class Qt4BaseTarget;
namespace Internal {
class Qt4ProFileNode;
class AbstractQt4MaemoTarget;
class MaemoDeployables : public QAbstractListModel
{
Q_OBJECT
public:
MaemoDeployables(const AbstractQt4MaemoTarget *target);
MaemoDeployables(const Qt4BaseTarget *target);
~MaemoDeployables();
void setUnmodified();
bool isModified() const;
@@ -84,7 +84,7 @@ private:
QList<MaemoDeployableListModel *> m_listModels;
UpdateSettingsMap m_updateSettings;
const AbstractQt4MaemoTarget * const m_target;
const Qt4BaseTarget * const m_target;
QTimer *const m_updateTimer;
};

View File

@@ -0,0 +1,384 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "maemodeploybymountstep.h"
#include "maemodeploymentmounter.h"
#include "maemoglobal.h"
#include "maemopackagecreationstep.h"
#include "maemopackageinstaller.h"
#include "maemoremotecopyfacility.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include <utils/ssh/sshconnection.h>
#include <QtCore/QFileInfo>
#define ASSERT_BASE_STATE(state) ASSERT_STATE_GENERIC(BaseState, state, baseState())
#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(ExtendedState, state, m_extendedState)
using namespace ProjectExplorer;
namespace Qt4ProjectManager {
namespace Internal {
AbstractMaemoDeployByMountStep::AbstractMaemoDeployByMountStep(BuildStepList *parent,
const QString &id)
: AbstractMaemoDeployStep(parent, id)
{
ctor();
}
AbstractMaemoDeployByMountStep::AbstractMaemoDeployByMountStep(BuildStepList *parent,
AbstractMaemoDeployByMountStep *other)
: AbstractMaemoDeployStep(parent, other)
{
ctor();
}
void AbstractMaemoDeployByMountStep::ctor()
{
m_extendedState= Inactive;
m_mounter = new MaemoDeploymentMounter(this);
connect(m_mounter, SIGNAL(setupDone()), this, SLOT(handleMounted()));
connect(m_mounter, SIGNAL(tearDownDone()), this, SLOT(handleUnmounted()));
connect(m_mounter, SIGNAL(error(QString)), this,
SLOT(handleMountError(QString)));
connect(m_mounter, SIGNAL(reportProgress(QString)), this,
SLOT(handleProgressReport(QString)));
connect(m_mounter, SIGNAL(debugOutput(QString)), this,
SLOT(handleMountDebugOutput(QString)));
}
void AbstractMaemoDeployByMountStep::stopInternal()
{
ASSERT_STATE(QList<ExtendedState>() << Mounting << Installing
<< Unmounting);
switch (m_extendedState) {
case Installing:
cancelInstallation();
unmount();
break;
case Mounting:
case Unmounting:
break; // Nothing to do here.
case Inactive:
setDeploymentFinished();
break;
default:
qFatal("Missing switch case in %s.", Q_FUNC_INFO);
}
}
void AbstractMaemoDeployByMountStep::startInternal()
{
Q_ASSERT(m_extendedState == Inactive);
mount();
}
void AbstractMaemoDeployByMountStep::handleMounted()
{
ASSERT_BASE_STATE(QList<BaseState>() << Deploying << StopRequested);
ASSERT_STATE(Mounting);
if (baseState() == StopRequested) {
unmount();
return;
}
writeOutput(tr("Installing package to device..."));
m_extendedState = Installing;
deploy();
}
void AbstractMaemoDeployByMountStep::handleUnmounted()
{
ASSERT_BASE_STATE(QList<BaseState>() << Deploying << StopRequested);
ASSERT_STATE(Unmounting);
setFinished();
}
void AbstractMaemoDeployByMountStep::handleMountError(const QString &errorMsg)
{
ASSERT_BASE_STATE(QList<BaseState>() << Deploying << StopRequested);
ASSERT_STATE(QList<ExtendedState>() << Mounting << Unmounting);
raiseError(errorMsg);
setFinished();
}
void AbstractMaemoDeployByMountStep::handleMountDebugOutput(const QString &output)
{
ASSERT_BASE_STATE(QList<BaseState>() << Deploying << StopRequested);
if (m_extendedState != Inactive)
writeOutput(output, ErrorOutput);
}
void AbstractMaemoDeployByMountStep::mount()
{
m_extendedState = Mounting;
m_mounter->setupMounts(connection(), mountSpecifications(), freePorts(),
qt4BuildConfiguration());
}
QString AbstractMaemoDeployByMountStep::deployMountPoint() const
{
return MaemoGlobal::homeDirOnDevice(connection()->connectionParameters().userName)
+ QLatin1String("/deployMountPoint_") + target()->project()->displayName();
}
void AbstractMaemoDeployByMountStep::handleInstallationFinished(const QString &errorMsg)
{
ASSERT_BASE_STATE(QList<BaseState>() << Deploying << StopRequested);
if (baseState() == StopRequested) {
unmount();
return;
}
if (m_extendedState != Installing)
return;
if (errorMsg.isEmpty())
handleInstallationSuccess();
else
raiseError(errorMsg);
unmount();
}
void AbstractMaemoDeployByMountStep::unmount()
{
m_extendedState = Unmounting;
m_mounter->tearDownMounts();
}
void AbstractMaemoDeployByMountStep::setFinished()
{
m_extendedState = Inactive;
setDeploymentFinished();
}
MaemoMountAndInstallDeployStep::MaemoMountAndInstallDeployStep(BuildStepList *bc)
: AbstractMaemoDeployByMountStep(bc, Id)
{
ctor();
}
MaemoMountAndInstallDeployStep::MaemoMountAndInstallDeployStep(BuildStepList *bc,
MaemoMountAndInstallDeployStep *other)
: AbstractMaemoDeployByMountStep(bc, other)
{
ctor();
}
void MaemoMountAndInstallDeployStep::ctor()
{
//: MaemoMountAndInstallDeployStep default display name
setDefaultDisplayName(DisplayName);
if (qobject_cast<AbstractDebBasedQt4MaemoTarget *>(target()))
m_installer = new MaemoDebianPackageInstaller(this);
else
m_installer = new MaemoRpmPackageInstaller(this);
connect(m_installer, SIGNAL(stdout(QString)),
SLOT(handleRemoteStdout(QString)));
connect(m_installer, SIGNAL(stderr(QString)),
SLOT(handleRemoteStderr(QString)));
connect(m_installer, SIGNAL(finished(QString)),
SLOT(handleInstallationFinished(QString)));
}
bool MaemoMountAndInstallDeployStep::isDeploymentPossibleInternal(QString &whyNot) const
{
if (!packagingStep()) {
whyNot = tr("No packaging step found.");
return false;
}
return true;
}
bool MaemoMountAndInstallDeployStep::isDeploymentNeeded(const QString &hostName) const
{
const AbstractMaemoPackageCreationStep * const pStep = packagingStep();
Q_ASSERT(pStep);
const MaemoDeployable d(pStep->packageFilePath(), QString());
return currentlyNeedsDeployment(hostName, d);
}
QList<MaemoMountSpecification> MaemoMountAndInstallDeployStep::mountSpecifications() const
{
const QString localDir
= QFileInfo(packagingStep()->packageFilePath()).absolutePath();
return QList<MaemoMountSpecification>()
<< MaemoMountSpecification(localDir, deployMountPoint());
}
void MaemoMountAndInstallDeployStep::deploy()
{
const QString remoteFilePath = deployMountPoint() + QLatin1Char('/')
+ QFileInfo(packagingStep()->packageFilePath()).fileName();
m_installer->installPackage(connection(), remoteFilePath, false);
}
void MaemoMountAndInstallDeployStep::cancelInstallation()
{
m_installer->cancelInstallation();
}
void MaemoMountAndInstallDeployStep::handleInstallationSuccess()
{
setDeployed(connection()->connectionParameters().host,
MaemoDeployable(packagingStep()->packageFilePath(), QString()));
writeOutput(tr("Package installed."));
}
const QString MaemoMountAndInstallDeployStep::Id("MaemoMountAndInstallDeployStep");
const QString MaemoMountAndInstallDeployStep::DisplayName
= tr("Deploy package via UTFS mount");
MaemoMountAndCopyDeployStep::MaemoMountAndCopyDeployStep(BuildStepList *bc)
: AbstractMaemoDeployByMountStep(bc, Id)
{
ctor();
}
MaemoMountAndCopyDeployStep::MaemoMountAndCopyDeployStep(BuildStepList *bc,
MaemoMountAndCopyDeployStep *other)
: AbstractMaemoDeployByMountStep(bc, other)
{
ctor();
}
void MaemoMountAndCopyDeployStep::ctor()
{
//: MaemoMountAndCopyDeployStep default display name
setDefaultDisplayName(DisplayName);
m_copyFacility = new MaemoRemoteCopyFacility(this);
connect(m_copyFacility, SIGNAL(stdout(QString)),
SLOT(handleRemoteStdout(QString)));
connect(m_copyFacility, SIGNAL(stderr(QString)),
SLOT(handleRemoteStderr(QString)));
connect(m_copyFacility, SIGNAL(progress(QString)),
SLOT(handleProgressReport(QString)));
connect(m_copyFacility, SIGNAL(fileCopied(MaemoDeployable)),
SLOT(handleFileCopied(MaemoDeployable)));
connect(m_copyFacility, SIGNAL(finished(QString)),
SLOT(handleInstallationFinished(QString)));
}
bool MaemoMountAndCopyDeployStep::isDeploymentPossibleInternal(QString &) const
{
return true;
}
bool MaemoMountAndCopyDeployStep::isDeploymentNeeded(const QString &hostName) const
{
m_filesToCopy.clear();
const QSharedPointer<MaemoDeployables> deployables
= maemoDeployConfig()->deployables();
const int deployableCount = deployables->deployableCount();
for (int i = 0; i < deployableCount; ++i) {
const MaemoDeployable &d = deployables->deployableAt(i);
if (currentlyNeedsDeployment(hostName, d))
m_filesToCopy << d;
}
return !m_filesToCopy.isEmpty();
}
QList<MaemoMountSpecification> MaemoMountAndCopyDeployStep::mountSpecifications() const
{
QList<MaemoMountSpecification> mountSpecs;
#ifdef Q_OS_WIN
bool drivesToMount[26];
qFill(drivesToMount, drivesToMount + sizeof drivesToMount / sizeof drivesToMount[0], false);
for (int i = 0; i < m_filesToCopy.count(); ++i) {
const QString localDir
= QFileInfo(m_filesToCopy.at(i).localFilePath).canonicalPath();
const char driveLetter = localDir.at(0).toLower().toLatin1();
if (driveLetter < 'a' || driveLetter > 'z') {
qWarning("Weird: drive letter is '%c'.", driveLetter);
continue;
}
const int index = driveLetter - 'a';
if (drivesToMount[index])
continue;
const QString mountPoint = deployMountPoint() + QLatin1Char('/')
+ QLatin1Char(driveLetter);
const MaemoMountSpecification mountSpec(localDir.left(3), mountPoint);
mountSpecs << mountSpec;
drivesToMount[index] = true;
}
#else
mountSpecs << MaemoMountSpecification(QLatin1String("/"),
deployMountPoint());
#endif
return mountSpecs;
}
void MaemoMountAndCopyDeployStep::deploy()
{
m_copyFacility->copyFiles(connection(), m_filesToCopy, deployMountPoint());
}
void MaemoMountAndCopyDeployStep::handleFileCopied(const MaemoDeployable &deployable)
{
setDeployed(connection()->connectionParameters().host, deployable);
}
void MaemoMountAndCopyDeployStep::cancelInstallation()
{
m_copyFacility->cancel();
}
void MaemoMountAndCopyDeployStep::handleInstallationSuccess()
{
writeOutput(tr("All files copied."));
}
const QString MaemoMountAndCopyDeployStep::Id("MaemoMountAndCopyDeployStep");
const QString MaemoMountAndCopyDeployStep::DisplayName
= tr("Deploy files via UTFS mount");
} // namespace Internal
} // namespace Qt4ProjectManager

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 (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef MAEMODEPLOYBYMOUNTSTEP_H
#define MAEMODEPLOYBYMOUNTSTEP_H
#include "abstractmaemodeploystep.h"
#include "maemodeployable.h"
#include "maemomountspecification.h"
namespace Qt4ProjectManager {
namespace Internal {
class AbstractMaemoPackageInstaller;
class MaemoDeploymentMounter;
class MaemoRemoteCopyFacility;
class AbstractMaemoDeployByMountStep : public AbstractMaemoDeployStep
{
Q_OBJECT
public:
private slots:
void handleMounted();
void handleUnmounted();
void handleMountError(const QString &errorMsg);
void handleMountDebugOutput(const QString &output);
void handleInstallationFinished(const QString &errorMsg);
protected:
AbstractMaemoDeployByMountStep(ProjectExplorer::BuildStepList *bc,
const QString &id);
AbstractMaemoDeployByMountStep(ProjectExplorer::BuildStepList *bc,
AbstractMaemoDeployByMountStep *other);
QString deployMountPoint() const;
private:
enum ExtendedState { Inactive, Mounting, Installing, Unmounting };
virtual void startInternal();
virtual void stopInternal();
virtual QList<MaemoMountSpecification> mountSpecifications() const=0;
virtual void deploy()=0;
virtual void cancelInstallation()=0;
virtual void handleInstallationSuccess()=0;
void ctor();
void mount();
void unmount();
void setFinished();
MaemoDeploymentMounter *m_mounter;
ExtendedState m_extendedState;
};
class MaemoMountAndInstallDeployStep : public AbstractMaemoDeployByMountStep
{
Q_OBJECT
public:
MaemoMountAndInstallDeployStep(ProjectExplorer::BuildStepList *bc);
MaemoMountAndInstallDeployStep(ProjectExplorer::BuildStepList *bc,
MaemoMountAndInstallDeployStep *other);
static const QString Id;
static const QString DisplayName;
private:
virtual bool isDeploymentPossibleInternal(QString &whynot) const;
virtual bool isDeploymentNeeded(const QString &hostName) const;
virtual QList<MaemoMountSpecification> mountSpecifications() const;
virtual void deploy();
virtual void cancelInstallation();
virtual void handleInstallationSuccess();
void ctor();
AbstractMaemoPackageInstaller *m_installer;
};
class MaemoMountAndCopyDeployStep : public AbstractMaemoDeployByMountStep
{
Q_OBJECT
public:
MaemoMountAndCopyDeployStep(ProjectExplorer::BuildStepList *bc);
MaemoMountAndCopyDeployStep(ProjectExplorer::BuildStepList *bc,
MaemoMountAndCopyDeployStep *other);
static const QString Id;
static const QString DisplayName;
private:
virtual bool isDeploymentPossibleInternal(QString &whynot) const;
virtual bool isDeploymentNeeded(const QString &hostName) const;
virtual QList<MaemoMountSpecification> mountSpecifications() const;
virtual void deploy();
virtual void cancelInstallation();
virtual void handleInstallationSuccess();
void ctor();
Q_SLOT void handleFileCopied(const MaemoDeployable &deployable);
MaemoRemoteCopyFacility *m_copyFacility;
mutable QList<MaemoDeployable> m_filesToCopy;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // MAEMODEPLOYBYMOUNTSTEP_H

View File

@@ -0,0 +1,174 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "maemodeployconfigurationwidget.h"
#include "ui_maemodeployconfigurationwidget.h"
#include "maemodeployablelistmodel.h"
#include "maemodeployables.h"
#include "qt4maemodeployconfiguration.h"
#include <utils/qtcassert.h>
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include <QtGui/QPixmap>
using namespace ProjectExplorer;
namespace Qt4ProjectManager {
namespace Internal {
MaemoDeployConfigurationWidget::MaemoDeployConfigurationWidget(QWidget *parent)
: DeployConfigurationWidget(parent),
ui(new Ui::MaemoDeployConfigurationWidget)
{
ui->setupUi(this);
}
MaemoDeployConfigurationWidget::~MaemoDeployConfigurationWidget()
{
delete ui;
}
void MaemoDeployConfigurationWidget::init(DeployConfiguration *dc)
{
m_deployConfig = qobject_cast<Qt4MaemoDeployConfiguration *>(dc);
Q_ASSERT(m_deployConfig);
ui->modelComboBox->setModel(m_deployConfig->deployables().data());
connect(m_deployConfig->deployables().data(), SIGNAL(modelAboutToBeReset()),
SLOT(handleModelListToBeReset()));
// Queued connection because of race condition with combo box's reaction
// to modelReset().
connect(m_deployConfig->deployables().data(), SIGNAL(modelReset()),
SLOT(handleModelListReset()), Qt::QueuedConnection);
connect(ui->modelComboBox, SIGNAL(currentIndexChanged(int)),
SLOT(setModel(int)));
connect(ui->addDesktopFileButton, SIGNAL(clicked()),
SLOT(addDesktopFile()));
connect(ui->addIconButton, SIGNAL(clicked()), SLOT(addIcon()));
handleModelListReset();
}
void MaemoDeployConfigurationWidget::handleModelListToBeReset()
{
ui->tableView->reset(); // Otherwise we'll crash if the user is currently editing.
ui->tableView->setModel(0);
ui->addDesktopFileButton->setEnabled(false);
ui->addIconButton->setEnabled(false);
}
void MaemoDeployConfigurationWidget::handleModelListReset()
{
QTC_ASSERT(m_deployConfig->deployables()->modelCount() == ui->modelComboBox->count(), return);
if (m_deployConfig->deployables()->modelCount() > 0) {
if (ui->modelComboBox->currentIndex() == -1)
ui->modelComboBox->setCurrentIndex(0);
else
setModel(ui->modelComboBox->currentIndex());
}
}
void MaemoDeployConfigurationWidget::setModel(int row)
{
bool canAddDesktopFile = false;
bool canAddIconFile = false;
if (row != -1) {
MaemoDeployableListModel * const model
= m_deployConfig->deployables()->modelAt(row);
ui->tableView->setModel(model);
ui->tableView->resizeRowsToContents();
canAddDesktopFile = model->canAddDesktopFile();
canAddIconFile = model->canAddIcon();
}
ui->addDesktopFileButton->setEnabled(canAddDesktopFile);
ui->addIconButton->setEnabled(canAddIconFile);
}
void MaemoDeployConfigurationWidget::addDesktopFile()
{
const int modelRow = ui->modelComboBox->currentIndex();
if (modelRow == -1)
return;
MaemoDeployableListModel *const model
= m_deployConfig->deployables()->modelAt(modelRow);
QString error;
if (!model->addDesktopFile(error)) {
QMessageBox::warning(this, tr("Could not create desktop file"),
tr("Error creating desktop file: %1").arg(error));
}
ui->addDesktopFileButton->setEnabled(model->canAddDesktopFile());
ui->tableView->resizeRowsToContents();
}
void MaemoDeployConfigurationWidget::addIcon()
{
const int modelRow = ui->modelComboBox->currentIndex();
if (modelRow == -1)
return;
MaemoDeployableListModel *const model
= m_deployConfig->deployables()->modelAt(modelRow);
const QString origFilePath = QFileDialog::getOpenFileName(this,
tr("Choose Icon (will be scaled to 64x64 pixels, if necessary)"),
model->projectDir(), QLatin1String("(*.png)"));
if (origFilePath.isEmpty())
return;
QPixmap pixmap(origFilePath);
if (pixmap.isNull()) {
QMessageBox::critical(this, tr("Invalid Icon"),
tr("Unable to read image"));
return;
}
const QSize iconSize(64, 64);
if (pixmap.size() != iconSize)
pixmap = pixmap.scaled(iconSize);
const QString newFileName = model->projectName() + QLatin1Char('.')
+ QFileInfo(origFilePath).suffix();
const QString newFilePath = model->projectDir() + QLatin1Char('/')
+ newFileName;
if (!pixmap.save(newFilePath)) {
QMessageBox::critical(this, tr("Failed to Save Icon"),
tr("Could not save icon to '%1'.").arg(newFilePath));
return;
}
QString error;
if (!model->addIcon(newFileName, error)) {
QMessageBox::critical(this, tr("Could Not Add Icon"),
tr("Error adding icon: %1").arg(error));
}
ui->addIconButton->setEnabled(model->canAddIcon());
ui->tableView->resizeRowsToContents();
}
} // namespace Internal
} // namespace Qt4ProjectManager

View File

@@ -0,0 +1,68 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef MAEMODEPLOYCONFIGURATIONWIDGET_H
#define MAEMODEPLOYCONFIGURATIONWIDGET_H
#include <projectexplorer/deployconfiguration.h>
QT_BEGIN_NAMESPACE
namespace Ui {
class MaemoDeployConfigurationWidget;
}
QT_END_NAMESPACE
namespace Qt4ProjectManager {
namespace Internal {
class Qt4MaemoDeployConfiguration;
class MaemoDeployConfigurationWidget : public ProjectExplorer::DeployConfigurationWidget
{
Q_OBJECT
public:
explicit MaemoDeployConfigurationWidget(QWidget *parent = 0);
~MaemoDeployConfigurationWidget();
void init(ProjectExplorer::DeployConfiguration *dc);
private:
Q_SLOT void handleModelListToBeReset();
Q_SLOT void handleModelListReset();
Q_SLOT void setModel(int row);
Q_SLOT void addDesktopFile();
Q_SLOT void addIcon();
Ui::MaemoDeployConfigurationWidget *ui;
Qt4MaemoDeployConfiguration * m_deployConfig;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // MAEMODEPLOYCONFIGURATIONWIDGET_H

View File

@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MaemoDeployConfigurationWidget</class>
<widget class="QWidget" name="MaemoDeployConfigurationWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>584</width>
<height>315</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="installLabel">
<property name="toolTip">
<string>These show the INSTALLS settings from the project file(s).</string>
</property>
<property name="text">
<string>&lt;b&gt;Files to install for subproject:&lt;/b&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="modelComboBox">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<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>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QTableView" name="tableView">
<property name="minimumSize">
<size>
<width>0</width>
<height>150</height>
</size>
</property>
<property name="toolTip">
<string>Edit the project file to add or remove entries.</string>
</property>
<property name="textElideMode">
<enum>Qt::ElideMiddle</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>400</number>
</attribute>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>100</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="addDesktopFileButton">
<property name="text">
<string>Add Desktop File</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addIconButton">
<property name="text">
<string>Add Launcher Icon ...</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,204 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "maemodeploymentmounter.h"
#include "maemoglobal.h"
#include "maemoremotemounter.h"
#include "maemousedportsgatherer.h"
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <utils/ssh/sshconnection.h>
#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(State, state, m_state)
using namespace Utils;
namespace Qt4ProjectManager {
namespace Internal {
MaemoDeploymentMounter::MaemoDeploymentMounter(QObject *parent)
: QObject(parent),
m_state(Inactive),
m_mounter(new MaemoRemoteMounter(this)),
m_portsGatherer(new MaemoUsedPortsGatherer(this))
{
connect(m_mounter, SIGNAL(error(QString)), SLOT(handleMountError(QString)));
connect(m_mounter, SIGNAL(mounted()), SLOT(handleMounted()));
connect(m_mounter, SIGNAL(unmounted()), SLOT(handleUnmounted()));
connect(m_mounter, SIGNAL(reportProgress(QString)),
SIGNAL(reportProgress(QString)));
connect(m_mounter, SIGNAL(debugOutput(QString)),
SIGNAL(debugOutput(QString)));
connect(m_portsGatherer, SIGNAL(error(QString)),
SLOT(handlePortsGathererError(QString)));
connect(m_portsGatherer, SIGNAL(portListReady()),
SLOT(handlePortListReady()));
}
void MaemoDeploymentMounter::setupMounts(const SshConnection::Ptr &connection,
const QList<MaemoMountSpecification> &mountSpecs,
const MaemoPortList &freePorts, const Qt4BuildConfiguration *bc)
{
ASSERT_STATE(Inactive);
m_freePorts = freePorts;
m_mountSpecs = mountSpecs;
m_connection = connection;
m_mounter->setConnection(m_connection);
m_buildConfig = bc;
connect(m_connection.data(), SIGNAL(error(Utils::SshError)),
SLOT(handleConnectionError()));
setState(UnmountingOldDirs);
unmount();
}
void MaemoDeploymentMounter::tearDownMounts()
{
ASSERT_STATE(Mounted);
setState(UnmountingCurrentMounts);
unmount();
}
void MaemoDeploymentMounter::setupMounter()
{
ASSERT_STATE(UnmountingOldDirs);
setState(UnmountingCurrentDirs);
m_mounter->resetMountSpecifications();
m_mounter->setBuildConfiguration(m_buildConfig);
foreach (const MaemoMountSpecification &mountSpec, m_mountSpecs)
m_mounter->addMountSpecification(mountSpec, true);
unmount();
}
void MaemoDeploymentMounter::unmount()
{
ASSERT_STATE(QList<State>() << UnmountingOldDirs << UnmountingCurrentDirs
<< UnmountingCurrentMounts);
if (m_mounter->hasValidMountSpecifications())
m_mounter->unmount();
else
handleUnmounted();
}
void MaemoDeploymentMounter::handleMounted()
{
ASSERT_STATE(QList<State>() << Mounting << Inactive);
if (m_state == Inactive)
return;
setState(Mounted);
emit setupDone();
}
void MaemoDeploymentMounter::handleUnmounted()
{
ASSERT_STATE(QList<State>() << UnmountingOldDirs << UnmountingCurrentDirs
<< UnmountingCurrentMounts << Inactive);
switch (m_state) {
case UnmountingOldDirs:
setupMounter();
break;
case UnmountingCurrentDirs:
setState(GatheringPorts);
m_portsGatherer->start(m_connection, m_freePorts);
break;
case UnmountingCurrentMounts:
setState(Inactive);
emit tearDownDone();
break;
case Inactive:
default:
break;
}
}
void MaemoDeploymentMounter::handlePortsGathererError(const QString &errorMsg)
{
ASSERT_STATE(QList<State>() << GatheringPorts << Inactive);
if (m_state == Inactive)
return;
setState(Inactive);
m_mounter->resetMountSpecifications();
emit error(errorMsg);
}
void MaemoDeploymentMounter::handlePortListReady()
{
ASSERT_STATE(QList<State>() << GatheringPorts << Inactive);
if (m_state == Inactive)
return;
setState(Mounting);
m_mounter->mount(&m_freePorts, m_portsGatherer);
}
void MaemoDeploymentMounter::handleMountError(const QString &errorMsg)
{
ASSERT_STATE(QList<State>() << UnmountingOldDirs << UnmountingCurrentDirs
<< UnmountingCurrentMounts << Mounting << Mounted << Inactive);
if (m_state == Inactive)
return;
setState(Inactive);
emit error(errorMsg);
}
void MaemoDeploymentMounter::handleConnectionError()
{
if (m_state == Inactive)
return;
setState(Inactive);
emit error(tr("Connection failed: %1").arg(m_connection->errorString()));
}
void MaemoDeploymentMounter::setState(State newState)
{
if (m_state == newState)
return;
if (newState == Inactive && m_connection) {
disconnect(m_connection.data(), 0, this, 0);
m_connection.clear();
}
m_state = newState;
}
} // namespace Internal
} // namespace Qt4ProjectManager

View File

@@ -0,0 +1,100 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef MAEMODEPLOYMENTMOUNTER_H
#define MAEMODEPLOYMENTMOUNTER_H
#include "maemodeviceconfigurations.h"
#include "maemomountspecification.h"
#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
namespace Utils { class SshConnection; }
namespace Qt4ProjectManager {
class Qt4BuildConfiguration;
namespace Internal {
class MaemoRemoteMounter;
class MaemoUsedPortsGatherer;
class MaemoDeploymentMounter : public QObject
{
Q_OBJECT
public:
explicit MaemoDeploymentMounter(QObject *parent = 0);
// Connection must be in connected state.
void setupMounts(const QSharedPointer<Utils::SshConnection> &connection,
const QList<MaemoMountSpecification> &mountSpecs,
const MaemoPortList &freePorts, const Qt4BuildConfiguration *bc);
void tearDownMounts();
signals:
void debugOutput(const QString &output);
void setupDone();
void tearDownDone();
void error(const QString &error);
void reportProgress(const QString &message);
private slots:
void handleMounted();
void handleUnmounted();
void handleMountError(const QString &errorMsg);
void handlePortsGathererError(const QString &errorMsg);
void handlePortListReady();
void handleConnectionError();
private:
enum State {
Inactive, UnmountingOldDirs, UnmountingCurrentDirs, GatheringPorts,
Mounting, Mounted, UnmountingCurrentMounts
};
void unmount();
void setupMounter();
void setState(State newState);
State m_state;
QSharedPointer<Utils::SshConnection> m_connection;
MaemoRemoteMounter * const m_mounter;
MaemoUsedPortsGatherer * const m_portsGatherer;
MaemoPortList m_freePorts;
QList<MaemoMountSpecification> m_mountSpecs;
const Qt4BuildConfiguration *m_buildConfig;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // MAEMODEPLOYMENTMOUNTER_H

View File

@@ -34,18 +34,20 @@
#include "maemodeploystep.h"
#include "maemoconstants.h"
#include "maemodeploymentmounter.h"
#include "maemodeploystepwidget.h"
#include "maemoglobal.h"
#include "maemopackagecreationstep.h"
#include "maemopackageinstaller.h"
#include "maemopackageuploader.h"
#include "maemopertargetdeviceconfigurationlistmodel.h"
#include "maemoqemumanager.h"
#include "maemoremotemounter.h"
#include "maemoremotecopyfacility.h"
#include "maemorunconfiguration.h"
#include "maemotoolchain.h"
#include "maemousedportsgatherer.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include <utils/ssh/sftpchannel.h>
#include <utils/ssh/sshconnection.h>
#include <utils/ssh/sshremoteprocess.h>
@@ -57,6 +59,8 @@
#include <qt4projectmanager/qt4projectmanagerconstants.h>
#include <qt4projectmanager/qt4target.h>
#include <utils/ssh/sshconnectionmanager.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QEventLoop>
@@ -71,7 +75,6 @@ using namespace ProjectExplorer;
namespace Qt4ProjectManager {
namespace Internal {
namespace { const int DefaultMountPort = 1050; }
const QLatin1String MaemoDeployStep::Id("Qt4ProjectManager.MaemoDeployStep");
@@ -100,45 +103,49 @@ void MaemoDeployStep::ctor()
else if (target()->id() == QLatin1String(Constants::MEEGO_DEVICE_TARGET_ID))
setDefaultDisplayName(tr("Deploy to Meego device"));
// A MaemoDeployables object is only dependent on the active build
// configuration and therefore can (and should) be shared among all
// deploy steps.
const QList<DeployConfiguration *> &deployConfigs
= target()->deployConfigurations();
if (deployConfigs.isEmpty()) {
const AbstractQt4MaemoTarget * const qt4Target = qobject_cast<AbstractQt4MaemoTarget *>(target());
Q_ASSERT(qt4Target);
m_deployables = QSharedPointer<MaemoDeployables>(new MaemoDeployables(qt4Target));
} else {
const MaemoDeployStep *const other
= MaemoGlobal::buildStep<MaemoDeployStep>(deployConfigs.first());
m_deployables = other->deployables();
}
m_state = Inactive;
m_deviceConfig = maemotarget()->deviceConfigurationsModel()->defaultDeviceConfig();
m_needsInstall = false;
m_sysrootInstaller = new QProcess(this);
connect(m_sysrootInstaller, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(handleSysrootInstallerFinished()));
connect(m_sysrootInstaller, SIGNAL(readyReadStandardOutput()), this,
SLOT(handleSysrootInstallerOutput()));
connect(m_sysrootInstaller, SIGNAL(readyReadStandardError()), this,
SLOT(handleSysrootInstallerErrorOutput()));
m_mounter = new MaemoRemoteMounter(this);
connect(m_mounter, SIGNAL(mounted()), this, SLOT(handleMounted()));
connect(m_mounter, SIGNAL(unmounted()), this, SLOT(handleUnmounted()));
m_mounter = new MaemoDeploymentMounter(this);
connect(m_mounter, SIGNAL(setupDone()), this, SLOT(handleMounted()));
connect(m_mounter, SIGNAL(tearDownDone()), this, SLOT(handleUnmounted()));
connect(m_mounter, SIGNAL(error(QString)), this,
SLOT(handleMountError(QString)));
connect(m_mounter, SIGNAL(reportProgress(QString)), this,
SLOT(handleProgressReport(QString)));
connect(m_mounter, SIGNAL(debugOutput(QString)), this,
SLOT(handleMountDebugOutput(QString)));
m_portsGatherer = new MaemoUsedPortsGatherer(this);
connect(m_portsGatherer, SIGNAL(error(QString)), this,
SLOT(handlePortsGathererError(QString)));
connect(m_portsGatherer, SIGNAL(portListReady()), this,
SLOT(handlePortListReady()));
m_uploader = new MaemoPackageUploader(this);
connect(m_uploader, SIGNAL(progress(QString)),
SLOT(handleProgressReport(QString)));
connect(m_uploader, SIGNAL(uploadFinished(QString)),
SLOT(handleUploadFinished(QString)));
if (qobject_cast<AbstractDebBasedQt4MaemoTarget *>(target()))
m_installer = new MaemoDebianPackageInstaller(this);
else
m_installer = new MaemoRpmPackageInstaller(this);
connect(m_installer, SIGNAL(stdout(QString)),
SLOT(handleRemoteStdout(QString)));
connect(m_installer, SIGNAL(stderr(QString)),
SLOT(handleRemoteStderr(QString)));
connect(m_installer, SIGNAL(finished(QString)),
SLOT(handleInstallationFinished(QString)));
m_copyFacility = new MaemoRemoteCopyFacility(this);
connect(m_copyFacility, SIGNAL(stdout(QString)),
SLOT(handleRemoteStdout(QString)));
connect(m_copyFacility, SIGNAL(stderr(QString)),
SLOT(handleRemoteStderr(QString)));
connect(m_copyFacility, SIGNAL(progress(QString)),
SLOT(handleProgressReport(QString)));
connect(m_copyFacility, SIGNAL(fileCopied(MaemoDeployable)),
SLOT(handleFileCopied(MaemoDeployable)));
connect(m_copyFacility, SIGNAL(finished(QString)),
SLOT(handleCopyingFinished(QString)));
connect(maemotarget()->deviceConfigurationsModel(), SIGNAL(updated()),
SLOT(handleDeviceConfigurationsUpdated()));
}
@@ -150,7 +157,7 @@ bool MaemoDeployStep::init()
void MaemoDeployStep::run(QFutureInterface<bool> &fi)
{
// Move to GUI thread for connection sharing with run control.
// Move to GUI thread.
QTimer::singleShot(0, this, SLOT(start()));
MaemoDeployEventHandler eventHandler(this, fi);
@@ -165,7 +172,6 @@ QVariantMap MaemoDeployStep::toMap() const
{
QVariantMap map(BuildStep::toMap());
addDeployTimesToMap(map);
map.insert(DeployToSysrootKey, m_deployToSysroot);
map.insert(DeviceIdKey,
MaemoDeviceConfigurations::instance()->internalId(m_deviceConfig));
return map;
@@ -196,7 +202,6 @@ bool MaemoDeployStep::fromMap(const QVariantMap &map)
return false;
getDeployTimesFromMap(map);
setDeviceConfig(map.value(DeviceIdKey, MaemoDeviceConfig::InvalidId).toULongLong());
m_deployToSysroot = map.value(DeployToSysrootKey, true).toBool();
return true;
}
@@ -218,13 +223,9 @@ void MaemoDeployStep::getDeployTimesFromMap(const QVariantMap &map)
}
}
const MaemoPackageCreationStep *MaemoDeployStep::packagingStep() const
const AbstractMaemoPackageCreationStep *MaemoDeployStep::packagingStep() const
{
const MaemoPackageCreationStep * const step
= MaemoGlobal::buildStep<MaemoPackageCreationStep>(target()->activeDeployConfiguration());
Q_ASSERT_X(step, Q_FUNC_INFO,
"Impossible: Maemo build configuration without packaging step.");
return step;
return MaemoGlobal::earlierBuildStep<AbstractMaemoPackageCreationStep>(maemoDeployConfig());
}
void MaemoDeployStep::raiseError(const QString &errorString)
@@ -248,39 +249,27 @@ void MaemoDeployStep::stop()
const State oldState = m_state;
setState(StopRequested);
switch (oldState) {
case InstallingToSysroot:
if (m_needsInstall)
m_sysrootInstaller->terminate();
break;
case Connecting:
m_connection->disconnectFromHost();
setState(Inactive);
break;
case InstallingToDevice:
case CopyingFile: {
const QByteArray programToKill = oldState == CopyingFile
? " cp " : "dpkg";
const QByteArray killCommand
= MaemoGlobal::remoteSudo().toUtf8() + " pkill -f ";
const QByteArray cmdLine = killCommand + programToKill + "; sleep 1; "
+ killCommand + "-9 " + programToKill;
SshRemoteProcess::Ptr killProc
= m_connection->createRemoteProcess(cmdLine);
killProc->start();
case Installing:
m_installer->cancelInstallation();
setState(Inactive);
break;
case Copying:
m_copyFacility->cancel();
setState(Inactive);
break;
}
case Uploading:
m_uploader->closeChannel();
m_uploader->cancelUpload();
setState(Inactive);
break;
case UnmountingOldDirs:
case UnmountingCurrentDirs:
case UnmountingCurrentMounts:
case GatheringPorts:
case Mounting:
case InitializingSftp:
case Unmounting:
break; // Nothing to do here.
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Missing switch case.");
qFatal("Missing switch case in %s.", Q_FUNC_INFO);
}
}
@@ -337,21 +326,21 @@ void MaemoDeployStep::start()
return;
}
Q_ASSERT(!m_currentDeviceDeployAction);
Q_ASSERT(!m_needsInstall);
Q_ASSERT(m_filesToCopy.isEmpty());
m_installerStderr.clear();
m_hasError = false;
const MaemoPackageCreationStep * const pStep = packagingStep();
const AbstractMaemoPackageCreationStep * const pStep = packagingStep();
const QString hostName = m_cachedDeviceConfig->sshParameters().host;
if (pStep->isPackagingEnabled()) {
if (pStep) {
const MaemoDeployable d(pStep->packageFilePath(), QString());
if (currentlyNeedsDeployment(hostName, d))
m_needsInstall = true;
} else {
const int deployableCount = m_deployables->deployableCount();
const QSharedPointer<MaemoDeployables> deployables
= maemoDeployConfig()->deployables();
const int deployableCount = deployables->deployableCount();
for (int i = 0; i < deployableCount; ++i) {
const MaemoDeployable &d = m_deployables->deployableAt(i);
const MaemoDeployable &d = deployables->deployableAt(i);
if (currentlyNeedsDeployment(hostName, d))
m_filesToCopy << d;
}
@@ -370,10 +359,7 @@ void MaemoDeployStep::start()
return;
}
if (m_deployToSysroot)
installToSysroot();
else
connectToDevice();
connectToDevice();
} else {
writeOutput(tr("All files up to date, no installation necessary."));
emit done();
@@ -392,78 +378,23 @@ void MaemoDeployStep::handleConnectionFailure()
setState(Inactive);
}
void MaemoDeployStep::handleSftpChannelInitialized()
{
ASSERT_STATE(QList<State>() << InitializingSftp << StopRequested);
switch (m_state) {
case InitializingSftp: {
const QString filePath = packagingStep()->packageFilePath();
const QString filePathNative = QDir::toNativeSeparators(filePath);
const QString fileName = QFileInfo(filePath).fileName();
const QString remoteFilePath = uploadDir() + QLatin1Char('/') + fileName;
const SftpJobId job = m_uploader->uploadFile(filePath,
remoteFilePath, SftpOverwriteExisting);
if (job == SftpInvalidJob) {
raiseError(tr("Upload failed: Could not open file '%1'")
.arg(filePathNative));
setState(Inactive);
} else {
setState(Uploading);
writeOutput(tr("Started uploading file '%1'.").arg(filePathNative));
}
break;
}
case StopRequested:
setState(Inactive);
break;
default:
break;
}
}
void MaemoDeployStep::handleSftpChannelInitializationFailed(const QString &error)
{
ASSERT_STATE(QList<State>() << InitializingSftp << StopRequested);
switch (m_state) {
case InitializingSftp:
case StopRequested:
raiseError(tr("Could not set up SFTP connection: %1").arg(error));
setState(Inactive);
break;
default:
break;
}
}
void MaemoDeployStep::handleSftpJobFinished(Utils::SftpJobId,
const QString &error)
void MaemoDeployStep::handleUploadFinished(const QString &errorMsg)
{
ASSERT_STATE(QList<State>() << Uploading << StopRequested);
if (m_state == StopRequested)
return;
const QString filePathNative
= QDir::toNativeSeparators(packagingStep()->packageFilePath());
if (!error.isEmpty()) {
raiseError(tr("Failed to upload file %1: %2")
.arg(filePathNative, error));
if (m_state == Uploading)
setState(Inactive);
} else if (m_state == Uploading) {
writeOutput(tr("Successfully uploaded file '%1'.")
.arg(filePathNative));
const QString remoteFilePath
= uploadDir() + QLatin1Char('/') + QFileInfo(filePathNative).fileName();
if (!errorMsg.isEmpty()) {
raiseError(errorMsg);
setState(Inactive);
} else {
writeOutput(tr("Successfully uploaded package file."));
const QString remoteFilePath = uploadDir() + QLatin1Char('/')
+ QFileInfo(packagingStep()->packageFilePath()).fileName();
runPackageInstaller(remoteFilePath);
}
}
void MaemoDeployStep::handleSftpChannelClosed()
{
ASSERT_STATE(StopRequested);
setState(Inactive);
}
void MaemoDeployStep::handleMounted()
{
ASSERT_STATE(QList<State>() << Mounting << StopRequested << Inactive);
@@ -475,12 +406,13 @@ void MaemoDeployStep::handleMounted()
+ QFileInfo(packagingStep()->packageFilePath()).fileName();
runPackageInstaller(remoteFilePath);
} else {
setState(CopyingFile);
copyNextFileToDevice();
setState(Copying);
m_copyFacility->copyFiles(m_connection, m_filesToCopy,
deployMountPoint());
}
break;
case StopRequested:
unmount();
m_mounter->tearDownMounts();
break;
case Inactive:
default:
@@ -490,30 +422,14 @@ void MaemoDeployStep::handleMounted()
void MaemoDeployStep::handleUnmounted()
{
ASSERT_STATE(QList<State>() << UnmountingOldDirs << UnmountingCurrentDirs
<< UnmountingCurrentMounts << StopRequested << Inactive);
ASSERT_STATE(QList<State>() << Unmounting << StopRequested << Inactive);
switch (m_state) {
case StopRequested:
m_mounter->resetMountSpecifications();
setState(Inactive);
break;
case UnmountingOldDirs:
if (maemotarget()->allowsRemoteMounts())
setupMount();
else
prepareSftpConnection();
break;
case UnmountingCurrentDirs:
setState(GatheringPorts);
m_portsGatherer->start(m_connection, freePorts());
break;
case UnmountingCurrentMounts:
if (m_hasError)
writeOutput(tr("Deployment failed."), ErrorMessageOutput);
else
writeOutput(tr("Deployment finished."));
setState(Inactive);
case Unmounting:
setDeploymentFinished();
break;
case Inactive:
default:
@@ -523,14 +439,12 @@ void MaemoDeployStep::handleUnmounted()
void MaemoDeployStep::handleMountError(const QString &errorMsg)
{
ASSERT_STATE(QList<State>() << UnmountingOldDirs << UnmountingCurrentDirs
<< UnmountingCurrentMounts << Mounting << StopRequested << Inactive);
ASSERT_STATE(QList<State>() << Mounting << Unmounting << StopRequested
<< Inactive);
switch (m_state) {
case UnmountingOldDirs:
case UnmountingCurrentDirs:
case UnmountingCurrentMounts:
case Mounting:
case Unmounting:
case StopRequested:
raiseError(errorMsg);
setState(Inactive);
@@ -543,14 +457,12 @@ void MaemoDeployStep::handleMountError(const QString &errorMsg)
void MaemoDeployStep::handleMountDebugOutput(const QString &output)
{
ASSERT_STATE(QList<State>() << UnmountingOldDirs << UnmountingCurrentDirs
<< UnmountingCurrentMounts << Mounting << StopRequested << Inactive);
ASSERT_STATE(QList<State>() << Mounting << Unmounting << StopRequested
<< Inactive);
switch (m_state) {
case UnmountingOldDirs:
case UnmountingCurrentDirs:
case UnmountingCurrentMounts:
case Mounting:
case Unmounting:
case StopRequested:
writeOutput(output, ErrorOutput);
break;
@@ -560,19 +472,17 @@ void MaemoDeployStep::handleMountDebugOutput(const QString &output)
}
}
void MaemoDeployStep::setupMount()
void MaemoDeployStep::mount()
{
ASSERT_STATE(UnmountingOldDirs);
setState(UnmountingCurrentDirs);
ASSERT_STATE(Connecting);
setState(Mounting);
Q_ASSERT(m_needsInstall || !m_filesToCopy.isEmpty());
m_mounter->resetMountSpecifications();
m_mounter->setBuildConfiguration(qt4BuildConfiguration());
QList<MaemoMountSpecification> mountSpecs;
if (m_needsInstall) {
const QString localDir
= QFileInfo(packagingStep()->packageFilePath()).absolutePath();
const MaemoMountSpecification mountSpec(localDir, deployMountPoint());
m_mounter->addMountSpecification(mountSpec, true);
mountSpecs << MaemoMountSpecification(localDir, deployMountPoint());
} else {
#ifdef Q_OS_WIN
bool drivesToMount[26];
@@ -594,106 +504,36 @@ void MaemoDeployStep::setupMount()
+ QLatin1Char(driveLetter);
const MaemoMountSpecification mountSpec(localDir.left(3),
mountPoint);
m_mounter->addMountSpecification(mountSpec, true);
mountSpecs << mountSpec;
drivesToMount[index] = true;
}
#else
m_mounter->addMountSpecification(MaemoMountSpecification(QLatin1String("/"),
deployMountPoint()), true);
mountSpecs << MaemoMountSpecification(QLatin1String("/"),
deployMountPoint());
#endif
}
unmount();
m_mounter->setupMounts(m_connection, mountSpecs, freePorts(),
qt4BuildConfiguration());
}
void MaemoDeployStep::prepareSftpConnection()
void MaemoDeployStep::upload()
{
setState(InitializingSftp);
m_uploader = m_connection->createSftpChannel();
connect(m_uploader.data(), SIGNAL(initialized()), this,
SLOT(handleSftpChannelInitialized()));
connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this,
SLOT(handleSftpChannelInitializationFailed(QString)));
connect(m_uploader.data(), SIGNAL(finished(Utils::SftpJobId, QString)),
this, SLOT(handleSftpJobFinished(Utils::SftpJobId, QString)));
connect(m_uploader.data(), SIGNAL(closed()), this,
SLOT(handleSftpChannelClosed()));
m_uploader->initialize();
}
void MaemoDeployStep::installToSysroot()
{
ASSERT_STATE(Inactive);
setState(InstallingToSysroot);
if (m_needsInstall) {
writeOutput(tr("Installing package to sysroot ..."));
const QtVersion * const qtVersion = qt4BuildConfiguration()->qtVersion();
const QString command = QLatin1String(
packagingStep()->debBasedMaemoTarget() ? "xdpkg" : "xrpm");
QStringList args = QStringList() << command << QLatin1String("-i");
if (packagingStep()->debBasedMaemoTarget())
args << QLatin1String("--no-force-downgrade");
args << packagingStep()->packageFilePath();
MaemoGlobal::callMadAdmin(*m_sysrootInstaller, args, qtVersion, true);
if (!m_sysrootInstaller->waitForStarted()) {
writeOutput(tr("Installation to sysroot failed, continuing anyway."),
ErrorMessageOutput);
connectToDevice();
}
} else {
writeOutput(tr("Copying files to sysroot ..."));
Q_ASSERT(!m_filesToCopy.isEmpty());
QDir sysRootDir(toolChain()->sysroot());
foreach (const MaemoDeployable &d, m_filesToCopy) {
const QLatin1Char sep('/');
const QString targetFilePath = toolChain()->sysroot() + sep
+ d.remoteDir + sep + QFileInfo(d.localFilePath).fileName();
sysRootDir.mkpath(d.remoteDir.mid(1));
QFile::remove(targetFilePath);
if (!QFile::copy(d.localFilePath, targetFilePath)) {
writeOutput(tr("Sysroot installation failed: "
"Could not copy '%1' to '%2'. Continuing anyway.")
.arg(QDir::toNativeSeparators(d.localFilePath),
QDir::toNativeSeparators(targetFilePath)),
ErrorMessageOutput);
}
QCoreApplication::processEvents();
if (m_state == StopRequested) {
setState(Inactive);
return;
}
}
connectToDevice();
}
}
void MaemoDeployStep::handleSysrootInstallerFinished()
{
ASSERT_STATE(QList<State>() << InstallingToSysroot << StopRequested);
if (m_state == StopRequested) {
setState(Inactive);
return;
}
if (m_sysrootInstaller->error() != QProcess::UnknownError
|| m_sysrootInstaller->exitCode() != 0) {
writeOutput(tr("Installation to sysroot failed, continuing anyway."),
ErrorMessageOutput);
}
connectToDevice();
writeOutput(tr(""));
setState(Uploading);
const QString localFilePath = packagingStep()->packageFilePath();
const QString fileName = QFileInfo(localFilePath).fileName();
const QString remoteFilePath = uploadDir() + QLatin1Char('/') + fileName;
m_uploader->uploadPackage(m_connection, localFilePath, remoteFilePath);
}
void MaemoDeployStep::connectToDevice()
{
ASSERT_STATE(QList<State>() << Inactive << InstallingToSysroot);
ASSERT_STATE(QList<State>() << Inactive);
setState(Connecting);
const bool canReUse = m_connection
&& m_connection->state() == SshConnection::Connected
m_connection = SshConnectionManager::instance().acquireConnection(m_cachedDeviceConfig->sshParameters());
const bool canReUse = m_connection->state() == SshConnection::Connected
&& m_connection->connectionParameters() == m_cachedDeviceConfig->sshParameters();
if (!canReUse)
m_connection = SshConnection::create();
connect(m_connection.data(), SIGNAL(connected()), this,
SLOT(handleConnected()));
connect(m_connection.data(), SIGNAL(error(Utils::SshError)), this,
@@ -702,7 +542,7 @@ void MaemoDeployStep::connectToDevice()
handleConnected();
} else {
writeOutput(tr("Connecting to device..."));
m_connection->connectToHost(m_cachedDeviceConfig->sshParameters());
m_connection->connectToHost();
}
}
@@ -710,51 +550,34 @@ void MaemoDeployStep::handleConnected()
{
ASSERT_STATE(QList<State>() << Connecting << StopRequested);
if (m_state == Connecting)
unmountOldDirs();
}
void MaemoDeployStep::unmountOldDirs()
{
setState(UnmountingOldDirs);
m_mounter->setConnection(m_connection);
unmount();
if (m_state == Connecting) {
if (maemotarget()->allowsRemoteMounts())
mount();
else
upload();
}
}
void MaemoDeployStep::runPackageInstaller(const QString &packageFilePath)
{
ASSERT_STATE(QList<State>() << Mounting << Uploading);
const bool removeAfterInstall = m_state == Uploading;
setState(InstallingToDevice);
setState(Installing);
writeOutput(tr("Installing package to device..."));
const QByteArray installCommand = packagingStep()->debBasedMaemoTarget()
? "dpkg -i --no-force-downgrade" : "rpm -Uhv";
QByteArray cmd = MaemoGlobal::remoteSudo().toUtf8() + ' '
+ installCommand + ' ' + packageFilePath.toUtf8();
if (removeAfterInstall)
cmd += " && (rm " + packageFilePath.toUtf8() + " || :)";
m_deviceInstaller = m_connection->createRemoteProcess(cmd);
connect(m_deviceInstaller.data(), SIGNAL(closed(int)), this,
SLOT(handleInstallationFinished(int)));
connect(m_deviceInstaller.data(), SIGNAL(outputAvailable(QByteArray)),
this, SLOT(handleDeviceInstallerOutput(QByteArray)));
connect(m_deviceInstaller.data(),
SIGNAL(errorOutputAvailable(QByteArray)), this,
SLOT(handleDeviceInstallerErrorOutput(QByteArray)));
m_deviceInstaller->start();
m_installer->installPackage(m_connection, packageFilePath,
m_state == Uploading);
}
void MaemoDeployStep::handleProgressReport(const QString &progressMsg)
{
ASSERT_STATE(QList<State>() << UnmountingOldDirs << UnmountingCurrentDirs
<< UnmountingCurrentMounts << Mounting << StopRequested << Inactive);
ASSERT_STATE(QList<State>() << Mounting << Unmounting << Uploading
<< Copying << StopRequested << Inactive);
switch (m_state) {
case UnmountingOldDirs:
case UnmountingCurrentDirs:
case UnmountingCurrentMounts:
case Mounting:
case Unmounting:
case Uploading:
case Copying:
case StopRequested:
writeOutput(progressMsg);
break;
@@ -764,68 +587,26 @@ void MaemoDeployStep::handleProgressReport(const QString &progressMsg)
}
}
void MaemoDeployStep::copyNextFileToDevice()
void MaemoDeployStep::handleFileCopied(const MaemoDeployable &deployable)
{
ASSERT_STATE(CopyingFile);
Q_ASSERT(!m_filesToCopy.isEmpty());
Q_ASSERT(!m_currentDeviceDeployAction);
const MaemoDeployable d = m_filesToCopy.takeFirst();
QString sourceFilePath = deployMountPoint();
#ifdef Q_OS_WIN
const QString localFilePath = QDir::fromNativeSeparators(d.localFilePath);
sourceFilePath += QLatin1Char('/') + localFilePath.at(0).toLower()
+ localFilePath.mid(2);
#else
sourceFilePath += d.localFilePath;
#endif
QString command = QString::fromLatin1("%1 cp -r %2 %3")
.arg(MaemoGlobal::remoteSudo(), sourceFilePath,
d.remoteDir + QLatin1Char('/'));
SshRemoteProcess::Ptr copyProcess
= m_connection->createRemoteProcess(command.toUtf8());
connect(copyProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)),
this, SLOT(handleDeviceInstallerErrorOutput(QByteArray)));
connect(copyProcess.data(), SIGNAL(closed(int)), this,
SLOT(handleCopyProcessFinished(int)));
m_currentDeviceDeployAction.reset(new DeviceDeployAction(d, copyProcess));
writeOutput(tr("Copying file '%1' to path '%2' on the device...")
.arg(d.localFilePath, d.remoteDir));
copyProcess->start();
setDeployed(m_connection->connectionParameters().host, deployable);
}
void MaemoDeployStep::handleCopyProcessFinished(int exitStatus)
void MaemoDeployStep::handleCopyingFinished(const QString &errorMsg)
{
ASSERT_STATE(QList<State>() << CopyingFile << StopRequested << Inactive);
ASSERT_STATE(QList<State>() << Copying << StopRequested << Inactive);
switch (m_state) {
case CopyingFile: {
Q_ASSERT(m_currentDeviceDeployAction);
const QString localFilePath
= m_currentDeviceDeployAction->first.localFilePath;
if (exitStatus != SshRemoteProcess::ExitedNormally
|| m_currentDeviceDeployAction->second->exitCode() != 0) {
raiseError(tr("Copying file '%1' failed.").arg(localFilePath));
m_currentDeviceDeployAction.reset(0);
setState(UnmountingCurrentMounts);
unmount();
} else {
writeOutput(tr("Successfully copied file '%1'.").arg(localFilePath));
setDeployed(m_connection->connectionParameters().host,
m_currentDeviceDeployAction->first);
m_currentDeviceDeployAction.reset(0);
if (m_filesToCopy.isEmpty()) {
writeOutput(tr("All files copied."));
setState(UnmountingCurrentMounts);
unmount();
} else {
copyNextFileToDevice();
}
}
case Copying:
if (!errorMsg.isEmpty())
raiseError(errorMsg);
else
writeOutput(tr("All files copied."));
setState(Unmounting);
m_mounter->tearDownMounts();
break;
}
case StopRequested:
unmount();
m_mounter->tearDownMounts();
break;
case Inactive:
default:
@@ -836,7 +617,7 @@ void MaemoDeployStep::handleCopyProcessFinished(int exitStatus)
QString MaemoDeployStep::deployMountPoint() const
{
return MaemoGlobal::homeDirOnDevice(m_cachedDeviceConfig->sshParameters().userName)
+ QLatin1String("/deployMountPoint_") + packagingStep()->projectName();
+ QLatin1String("/deployMountPoint_") + target()->project()->displayName();
}
const MaemoToolChain *MaemoDeployStep::toolChain() const
@@ -849,60 +630,34 @@ const AbstractQt4MaemoTarget *MaemoDeployStep::maemotarget() const
return static_cast<AbstractQt4MaemoTarget *>(qt4BuildConfiguration()->target());
}
void MaemoDeployStep::handleSysrootInstallerOutput()
void MaemoDeployStep::handleInstallationFinished(const QString &errorMsg)
{
ASSERT_STATE(QList<State>() << InstallingToSysroot << StopRequested);
ASSERT_STATE(QList<State>() << Installing << StopRequested << Inactive);
switch (m_state) {
case InstallingToSysroot:
case StopRequested:
writeOutput(QString::fromLocal8Bit(m_sysrootInstaller->readAllStandardOutput()),
NormalOutput);
break;
default:
break;
}
}
void MaemoDeployStep::handleSysrootInstallerErrorOutput()
{
ASSERT_STATE(QList<State>() << InstallingToSysroot << StopRequested);
switch (m_state) {
case InstallingToSysroot:
case StopRequested:
writeOutput(QString::fromLocal8Bit(m_sysrootInstaller->readAllStandardError()),
BuildStep::ErrorOutput);
break;
default:
break;
}
}
void MaemoDeployStep::handleInstallationFinished(int exitStatus)
{
ASSERT_STATE(QList<State>() << InstallingToDevice << StopRequested
<< Inactive);
switch (m_state) {
case InstallingToDevice:
if (exitStatus != SshRemoteProcess::ExitedNormally
|| m_deviceInstaller->exitCode() != 0) {
raiseError(tr("Installing package failed."));
} else if (m_installerStderr.contains("Will not downgrade")) {
raiseError(tr("Installation failed: "
"You tried to downgrade a package, which is not allowed."));
} else {
case Installing:
if (errorMsg.isEmpty()) {
m_needsInstall = false;
setDeployed(m_connection->connectionParameters().host,
MaemoDeployable(packagingStep()->packageFilePath(), QString()));
writeOutput(tr("Package installed."));
} else {
raiseError(errorMsg);
}
if (maemotarget()->allowsRemoteMounts()) {
setState(Unmounting);
m_mounter->tearDownMounts();
} else {
setDeploymentFinished();
}
setState(UnmountingCurrentMounts);
unmount();
break;
case StopRequested:
unmount();
if (maemotarget()->allowsRemoteMounts()) {
setState(Unmounting);
m_mounter->tearDownMounts();
} else {
setDeploymentFinished();
}
break;
case Inactive:
default:
@@ -910,27 +665,13 @@ void MaemoDeployStep::handleInstallationFinished(int exitStatus)
}
}
void MaemoDeployStep::handlePortsGathererError(const QString &errorMsg)
void MaemoDeployStep::setDeploymentFinished()
{
ASSERT_STATE(QList<State>() << GatheringPorts << StopRequested << Inactive);
if (m_state != Inactive) {
raiseError(errorMsg);
setState(Inactive);
}
}
void MaemoDeployStep::handlePortListReady()
{
ASSERT_STATE(QList<State>() << GatheringPorts << StopRequested);
if (m_state == GatheringPorts) {
setState(Mounting);
m_freePorts = freePorts();
m_mounter->mount(&m_freePorts, m_portsGatherer);
} else {
setState(Inactive);
}
if (m_hasError)
writeOutput(tr("Deployment failed."), ErrorMessageOutput);
else
writeOutput(tr("Deployment finished."));
setState(Inactive);
}
void MaemoDeployStep::setState(State newState)
@@ -941,50 +682,38 @@ void MaemoDeployStep::setState(State newState)
if (m_state == Inactive) {
m_needsInstall = false;
m_filesToCopy.clear();
m_currentDeviceDeployAction.reset(0);
if (m_connection)
if (m_connection) {
disconnect(m_connection.data(), 0, this, 0);
if (m_uploader) {
disconnect(m_uploader.data(), 0, this, 0);
m_uploader->closeChannel();
SshConnectionManager::instance().releaseConnection(m_connection);
}
if (m_deviceInstaller)
disconnect(m_deviceInstaller.data(), 0, this, 0);
emit done();
}
}
void MaemoDeployStep::unmount()
void MaemoDeployStep::handleRemoteStdout(const QString &output)
{
if (m_mounter->hasValidMountSpecifications())
m_mounter->unmount();
else
handleUnmounted();
}
void MaemoDeployStep::handleDeviceInstallerOutput(const QByteArray &output)
{
ASSERT_STATE(QList<State>() << InstallingToDevice << StopRequested);
ASSERT_STATE(QList<State>() << Installing << Copying << StopRequested);
switch (m_state) {
case InstallingToDevice:
case Installing:
case Copying:
case StopRequested:
writeOutput(QString::fromUtf8(output), NormalOutput);
writeOutput(output, NormalOutput);
break;
default:
break;
}
}
void MaemoDeployStep::handleDeviceInstallerErrorOutput(const QByteArray &output)
void MaemoDeployStep::handleRemoteStderr(const QString &output)
{
ASSERT_STATE(QList<State>() << InstallingToDevice << StopRequested);
ASSERT_STATE(QList<State>() << Installing << Copying << StopRequested);
switch (m_state) {
case InstallingToDevice:
case Installing:
case Copying:
case StopRequested:
m_installerStderr += output;
writeOutput(QString::fromUtf8(output), ErrorOutput);
writeOutput(output, ErrorOutput);
break;
default:
break;
@@ -1012,6 +741,10 @@ const Qt4BuildConfiguration *MaemoDeployStep::qt4BuildConfiguration() const
return static_cast<Qt4BuildConfiguration *>(buildConfiguration());
}
Qt4MaemoDeployConfiguration *MaemoDeployStep::maemoDeployConfig() const
{
return qobject_cast<Qt4MaemoDeployConfiguration *>(deployConfiguration());
}
MaemoDeployEventHandler::MaemoDeployEventHandler(MaemoDeployStep *deployStep,
QFutureInterface<bool> &future)

View File

@@ -37,9 +37,7 @@
#include "maemodeployable.h"
#include "maemodeployables.h"
#include "maemodeviceconfigurations.h"
#include "maemomountspecification.h"
#include <utils/ssh/sftpdefs.h>
#include <projectexplorer/buildstep.h>
#include <QtCore/QHash>
@@ -50,24 +48,23 @@
QT_BEGIN_NAMESPACE
class QEventLoop;
class QProcess;
class QTimer;
QT_END_NAMESPACE
namespace Utils {
class SftpChannel;
class SshConnection;
class SshRemoteProcess;
}
namespace Qt4ProjectManager {
class Qt4BuildConfiguration;
namespace Internal {
class MaemoRemoteMounter;
class AbstractMaemoPackageCreationStep;
class AbstractMaemoPackageInstaller;
class MaemoDeploymentMounter;
class MaemoDeviceConfig;
class MaemoPackageCreationStep;
class MaemoPackageUploader;
class MaemoRemoteCopyFacility;
class MaemoToolChain;
class MaemoUsedPortsGatherer;
class Qt4MaemoDeployConfiguration;
class MaemoDeployStep : public ProjectExplorer::BuildStep
{
@@ -83,12 +80,8 @@ public:
bool currentlyNeedsDeployment(const QString &host,
const MaemoDeployable &deployable) const;
void setDeployed(const QString &host, const MaemoDeployable &deployable);
QSharedPointer<MaemoDeployables> deployables() const { return m_deployables; }
QSharedPointer<Utils::SshConnection> sshConnection() const { return m_connection; }
MaemoPortList freePorts() const;
bool isDeployToSysrootEnabled() const { return m_deployToSysroot; }
void setDeployToSysrootEnabled(bool deploy) { m_deployToSysroot = deploy; }
Qt4MaemoDeployConfiguration *maemoDeployConfig() const;
Q_INVOKABLE void stop();
@@ -106,27 +99,18 @@ private slots:
void handleMountError(const QString &errorMsg);
void handleMountDebugOutput(const QString &output);
void handleProgressReport(const QString &progressMsg);
void handleCopyProcessFinished(int exitStatus);
void handleSysrootInstallerFinished();
void handleSysrootInstallerOutput();
void handleSysrootInstallerErrorOutput();
void handleSftpChannelInitialized();
void handleSftpChannelInitializationFailed(const QString &error);
void handleSftpJobFinished(Utils::SftpJobId job, const QString &error);
void handleSftpChannelClosed();
void handleInstallationFinished(int exitStatus);
void handleDeviceInstallerOutput(const QByteArray &output);
void handleDeviceInstallerErrorOutput(const QByteArray &output);
void handlePortsGathererError(const QString &errorMsg);
void handlePortListReady();
void handleUploadFinished(const QString &errorMsg);
void handleInstallationFinished(const QString &errorMsg);
void handleFileCopied(const MaemoDeployable &deployable);
void handleCopyingFinished(const QString &errorMsg);
void handleRemoteStdout(const QString &output);
void handleRemoteStderr(const QString &output);
void handleDeviceConfigurationsUpdated();
private:
enum State {
Inactive, StopRequested, InstallingToSysroot, Connecting,
UnmountingOldDirs, UnmountingCurrentDirs, GatheringPorts, Mounting,
InstallingToDevice, UnmountingCurrentMounts, CopyingFile,
InitializingSftp, Uploading
Inactive, StopRequested, Connecting, Uploading, Mounting, Installing,
Copying, Unmounting
};
MaemoDeployStep(ProjectExplorer::BuildStepList *bc,
@@ -134,7 +118,6 @@ private:
virtual bool init();
virtual void run(QFutureInterface<bool> &fi);
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
virtual bool immutable() const { return true; }
virtual QVariantMap toMap() const;
virtual bool fromMap(const QVariantMap &map);
@@ -143,43 +126,33 @@ private:
void writeOutput(const QString &text, OutputFormat = MessageOutput);
void addDeployTimesToMap(QVariantMap &map) const;
void getDeployTimesFromMap(const QVariantMap &map);
const MaemoPackageCreationStep *packagingStep() const;
const AbstractMaemoPackageCreationStep *packagingStep() const;
QString deployMountPoint() const;
const MaemoToolChain *toolChain() const;
void copyNextFileToDevice();
void installToSysroot();
QString uploadDir() const;
void connectToDevice();
void unmountOldDirs();
void setupMount();
void prepareSftpConnection();
void upload();
void runPackageInstaller(const QString &packageFilePath);
void mount();
void setDeploymentFinished();
void setState(State newState);
void unmount();
void setDeviceConfig(MaemoDeviceConfig::Id internalId);
const Qt4BuildConfiguration *qt4BuildConfiguration() const;
static const QLatin1String Id;
QSharedPointer<MaemoDeployables> m_deployables;
QSharedPointer<Utils::SshConnection> m_connection;
QProcess *m_sysrootInstaller;
typedef QPair<MaemoDeployable, QSharedPointer<Utils::SshRemoteProcess> > DeviceDeployAction;
QScopedPointer<DeviceDeployAction> m_currentDeviceDeployAction;
QList<MaemoDeployable> m_filesToCopy;
MaemoRemoteMounter *m_mounter;
bool m_deployToSysroot;
QSharedPointer<Utils::SftpChannel> m_uploader;
QSharedPointer<Utils::SshRemoteProcess> m_deviceInstaller;
MaemoDeploymentMounter *m_mounter;
MaemoPackageUploader *m_uploader;
AbstractMaemoPackageInstaller *m_installer;
MaemoRemoteCopyFacility *m_copyFacility;
bool m_needsInstall;
typedef QPair<MaemoDeployable, QString> DeployablePerHost;
QHash<DeployablePerHost, QDateTime> m_lastDeployed;
QSharedPointer<const MaemoDeviceConfig> m_deviceConfig;
QSharedPointer<const MaemoDeviceConfig> m_cachedDeviceConfig;
MaemoUsedPortsGatherer *m_portsGatherer;
MaemoPortList m_freePorts;
QByteArray m_installerStderr;
State m_state;
bool m_hasError;
};

View File

@@ -33,8 +33,12 @@
#include "maemodeploystepfactory.h"
#include "maemodeploystep.h"
#include "maemodeploybymountstep.h"
#include "maemoglobal.h"
#include "maemoinstalltosysrootstep.h"
#include "maemouploadandinstalldeploystep.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildsteplist.h>
@@ -48,6 +52,9 @@ using namespace ProjectExplorer;
namespace Qt4ProjectManager {
namespace Internal {
namespace {
const QString OldMaemoDeployStepId(QLatin1String("Qt4ProjectManager.MaemoDeployStep"));
} // anonymous namespace
MaemoDeployStepFactory::MaemoDeployStepFactory(QObject *parent)
: IBuildStepFactory(parent)
@@ -56,44 +63,81 @@ MaemoDeployStepFactory::MaemoDeployStepFactory(QObject *parent)
QStringList MaemoDeployStepFactory::availableCreationIds(BuildStepList *parent) const
{
if (parent->id() == QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)
&& MaemoGlobal::isMaemoTargetId(parent->target()->id())
&& !parent->contains(MaemoDeployStep::Id))
return QStringList() << MaemoDeployStep::Id;
return QStringList();
if (!qobject_cast<Qt4MaemoDeployConfiguration *>(parent->parent()))
return QStringList();
QStringList ids;
if (qobject_cast<Qt4BaseTarget *>(parent->target()))
ids << MaemoUploadAndInstallDeployStep::Id;
if (qobject_cast<AbstractQt4MaemoTarget *>(parent->target()))
ids << MaemoCopyToSysrootStep::Id;
if (qobject_cast<AbstractDebBasedQt4MaemoTarget *>(parent->target()))
ids << MaemoInstallDebianPackageToSysrootStep::Id;
else if (qobject_cast<AbstractRpmBasedQt4MaemoTarget *>(parent->target()))
ids << MaemoInstallRpmPackageToSysrootStep::Id;
if (qobject_cast<Qt4Maemo5Target *>(parent->target())) {
ids << MaemoMountAndInstallDeployStep::Id
<< MaemoMountAndCopyDeployStep::Id;
}
return ids;
}
QString MaemoDeployStepFactory::displayNameForId(const QString &id) const
{
if (id == MaemoDeployStep::Id)
return QCoreApplication::translate("Qt4ProjectManager::Internal::MaemoDeployStepFactory",
"Deploy to device");
if (id == MaemoMountAndInstallDeployStep::Id)
return MaemoMountAndInstallDeployStep::DisplayName;
else if (id == MaemoMountAndCopyDeployStep::Id)
return MaemoMountAndCopyDeployStep::DisplayName;
else if (id == MaemoUploadAndInstallDeployStep::Id)
return MaemoUploadAndInstallDeployStep::DisplayName;
else if (id == MaemoInstallDebianPackageToSysrootStep::Id)
return MaemoInstallDebianPackageToSysrootStep::DisplayName;
else if (id == MaemoInstallRpmPackageToSysrootStep::Id)
return MaemoInstallRpmPackageToSysrootStep::DisplayName;
else if (id == MaemoCopyToSysrootStep::Id)
return MaemoCopyToSysrootStep::DisplayName;
return QString();
}
bool MaemoDeployStepFactory::canCreate(BuildStepList *parent, const QString &id) const
{
return parent->id() == QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)
&& id == QLatin1String(MaemoDeployStep::Id)
&& MaemoGlobal::isMaemoTargetId(parent->target()->id())
&& !parent->contains(MaemoDeployStep::Id);
return availableCreationIds(parent).contains(id) && !parent->contains(id);
}
BuildStep *MaemoDeployStepFactory::create(BuildStepList *parent, const QString &id)
{
Q_ASSERT(canCreate(parent, id));
return new MaemoDeployStep(parent);
const Target * const t = parent->target();
if (id == MaemoInstallDebianPackageToSysrootStep::Id) {
return new MaemoInstallDebianPackageToSysrootStep(parent);
} else if (id == MaemoInstallRpmPackageToSysrootStep::Id) {
return new MaemoInstallRpmPackageToSysrootStep(parent);
} else if (id == MaemoCopyToSysrootStep::Id) {
return new MaemoCopyToSysrootStep(parent);
} else if (id == MaemoMountAndInstallDeployStep::Id
|| (id == OldMaemoDeployStepId && qobject_cast< const Qt4Maemo5Target *>(t))) {
return new MaemoMountAndInstallDeployStep(parent);
} else if (id == MaemoMountAndCopyDeployStep::Id) {
return new MaemoMountAndCopyDeployStep(parent);
} else if (id == MaemoUploadAndInstallDeployStep::Id
|| (id == OldMaemoDeployStepId && (qobject_cast<const Qt4HarmattanTarget *>(t)
|| qobject_cast<const Qt4MeegoTarget *>(t)))) {
return new MaemoUploadAndInstallDeployStep(parent);
}
return 0;
}
bool MaemoDeployStepFactory::canRestore(BuildStepList *parent, const QVariantMap &map) const
{
return canCreate(parent, idFromMap(map));
return canCreate(parent, idFromMap(map))
|| idFromMap(map) == OldMaemoDeployStepId;
}
BuildStep *MaemoDeployStepFactory::restore(BuildStepList *parent, const QVariantMap &map)
{
Q_ASSERT(canRestore(parent, map));
MaemoDeployStep * const step = new MaemoDeployStep(parent);
BuildStep * const step = create(parent, idFromMap(map));
if (!step->fromMap(map)) {
delete step;
return 0;
@@ -109,7 +153,26 @@ bool MaemoDeployStepFactory::canClone(BuildStepList *parent, BuildStep *product)
BuildStep *MaemoDeployStepFactory::clone(BuildStepList *parent, BuildStep *product)
{
Q_ASSERT(canClone(parent, product));
return new MaemoDeployStep(parent, static_cast<MaemoDeployStep*>(product));
if (product->id() == MaemoMountAndInstallDeployStep::Id) {
return new MaemoMountAndInstallDeployStep(parent,
qobject_cast<MaemoMountAndInstallDeployStep *>(product));
} else if (product->id() == MaemoMountAndCopyDeployStep::Id) {
return new MaemoMountAndCopyDeployStep(parent,
qobject_cast<MaemoMountAndCopyDeployStep *>(product));
} else if (product->id() == MaemoUploadAndInstallDeployStep::Id) {
return new MaemoUploadAndInstallDeployStep(parent,
qobject_cast<MaemoUploadAndInstallDeployStep*>(product));
} else if (product->id() == MaemoInstallDebianPackageToSysrootStep::Id) {
return new MaemoInstallDebianPackageToSysrootStep(parent,
qobject_cast<MaemoInstallDebianPackageToSysrootStep *>(product));
} else if (product->id() == MaemoInstallRpmPackageToSysrootStep::Id) {
return new MaemoInstallRpmPackageToSysrootStep(parent,
qobject_cast<MaemoInstallRpmPackageToSysrootStep *>(product));
} else if (product->id() == MaemoCopyToSysrootStep::Id) {
return new MaemoCopyToSysrootStep(parent,
qobject_cast<MaemoCopyToSysrootStep *>(product));
}
return 0;
}
} // namespace Internal

View File

@@ -34,15 +34,14 @@
#include "maemodeploystepwidget.h"
#include "ui_maemodeploystepwidget.h"
#include "maemodeploystep.h"
#include "maemodeployablelistmodel.h"
#include "maemodeployables.h"
#include "abstractmaemodeploystep.h"
#include "maemodeviceconfigurations.h"
#include "maemosettingspages.h"
#include "maemoglobal.h"
#include "maemomanager.h"
#include "maemopertargetdeviceconfigurationlistmodel.h"
#include "maemorunconfiguration.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include <coreplugin/icore.h>
@@ -50,35 +49,20 @@
#include <projectexplorer/target.h>
#include <utils/qtcassert.h>
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include <QtGui/QPixmap>
namespace Qt4ProjectManager {
namespace Internal {
MaemoDeployStepWidget::MaemoDeployStepWidget(MaemoDeployStep *step) :
MaemoDeployStepWidget::MaemoDeployStepWidget(AbstractMaemoDeployStep *step) :
ProjectExplorer::BuildStepConfigWidget(),
ui(new Ui::MaemoDeployStepWidget),
m_step(step)
{
ui->setupUi(this);
ui->modelComboBox->setModel(m_step->deployables().data());
connect(m_step->deployables().data(), SIGNAL(modelAboutToBeReset()),
SLOT(handleModelListToBeReset()));
// Queued connection because of race condition with combo box's reaction
// to modelReset().
connect(m_step->deployables().data(), SIGNAL(modelReset()),
SLOT(handleModelListReset()), Qt::QueuedConnection);
connect(ui->modelComboBox, SIGNAL(currentIndexChanged(int)),
SLOT(setModel(int)));
connect(ui->addDesktopFileButton, SIGNAL(clicked()),
SLOT(addDesktopFile()));
connect(ui->addIconButton, SIGNAL(clicked()), SLOT(addIcon()));
handleModelListReset();
ProjectExplorer::BuildStepList * const list
= qobject_cast<ProjectExplorer::BuildStepList *>(step->parent());
connect(list, SIGNAL(stepInserted(int)), SIGNAL(updateSummary()));
connect(list, SIGNAL(stepMoved(int,int)), SIGNAL(updateSummary()));
connect(list, SIGNAL(stepRemoved(int)), SIGNAL(updateSummary()));
}
MaemoDeployStepWidget::~MaemoDeployStepWidget()
@@ -88,14 +72,11 @@ MaemoDeployStepWidget::~MaemoDeployStepWidget()
void MaemoDeployStepWidget::init()
{
ui->deviceConfigComboBox->setModel(m_step->maemotarget()->deviceConfigurationsModel());
ui->deviceConfigComboBox->setModel(m_step->maemoDeployConfig()->deviceConfigModel());
connect(m_step, SIGNAL(deviceConfigChanged()), SLOT(handleDeviceUpdate()));
handleDeviceUpdate();
connect(ui->deviceConfigComboBox, SIGNAL(activated(int)), this,
SLOT(setCurrentDeviceConfig(int)));
ui->deployToSysrootCheckBox->setChecked(m_step->isDeployToSysrootEnabled());
connect(ui->deployToSysrootCheckBox, SIGNAL(toggled(bool)), this,
SLOT(setDeployToSysroot(bool)));
connect(ui->manageDevConfsLabel, SIGNAL(linkActivated(QString)),
SLOT(showDeviceConfigurations()));
}
@@ -105,7 +86,7 @@ void MaemoDeployStepWidget::handleDeviceUpdate()
const MaemoDeviceConfig::ConstPtr &devConf = m_step->deviceConfig();
const MaemoDeviceConfig::Id internalId
= MaemoDeviceConfigurations::instance()->internalId(devConf);
const int newIndex = m_step->maemotarget()->deviceConfigurationsModel()
const int newIndex = m_step->maemoDeployConfig()->deviceConfigModel()
->indexForInternalId(internalId);
ui->deviceConfigComboBox->setCurrentIndex(newIndex);
emit updateSummary();
@@ -113,6 +94,12 @@ void MaemoDeployStepWidget::handleDeviceUpdate()
QString MaemoDeployStepWidget::summaryText() const
{
QString error;
if (!m_step->isDeploymentPossible(error)) {
return QLatin1String("<font color=\"red\">")
+ tr("Cannot deploy: %1").arg(error)
+ QLatin1String("</font>");
}
return tr("<b>Deploy to device</b>: %1")
.arg(MaemoGlobal::deviceConfigurationName(m_step->deviceConfig()));
}
@@ -131,103 +118,6 @@ void MaemoDeployStepWidget::setCurrentDeviceConfig(int index)
updateSummary();
}
void MaemoDeployStepWidget::setDeployToSysroot(bool doDeploy)
{
m_step->setDeployToSysrootEnabled(doDeploy);
}
void MaemoDeployStepWidget::handleModelListToBeReset()
{
ui->tableView->reset(); // Otherwise we'll crash if the user is currently editing.
ui->tableView->setModel(0);
ui->addDesktopFileButton->setEnabled(false);
ui->addIconButton->setEnabled(false);
}
void MaemoDeployStepWidget::handleModelListReset()
{
QTC_ASSERT(m_step->deployables()->modelCount() == ui->modelComboBox->count(), return);
if (m_step->deployables()->modelCount() > 0) {
if (ui->modelComboBox->currentIndex() == -1)
ui->modelComboBox->setCurrentIndex(0);
else
setModel(ui->modelComboBox->currentIndex());
}
}
void MaemoDeployStepWidget::setModel(int row)
{
bool canAddDesktopFile = false;
bool canAddIconFile = false;
if (row != -1) {
MaemoDeployableListModel *const model
= m_step->deployables()->modelAt(row);
ui->tableView->setModel(model);
ui->tableView->resizeRowsToContents();
canAddDesktopFile = model->canAddDesktopFile();
canAddIconFile = model->canAddIcon();
}
ui->addDesktopFileButton->setEnabled(canAddDesktopFile);
ui->addIconButton->setEnabled(canAddIconFile);
}
void MaemoDeployStepWidget::addDesktopFile()
{
const int modelRow = ui->modelComboBox->currentIndex();
if (modelRow == -1)
return;
MaemoDeployableListModel *const model
= m_step->deployables()->modelAt(modelRow);
QString error;
if (!model->addDesktopFile(error)) {
QMessageBox::warning(this, tr("Could not create desktop file"),
tr("Error creating desktop file: %1").arg(error));
}
ui->addDesktopFileButton->setEnabled(model->canAddDesktopFile());
ui->tableView->resizeRowsToContents();
}
void MaemoDeployStepWidget::addIcon()
{
const int modelRow = ui->modelComboBox->currentIndex();
if (modelRow == -1)
return;
MaemoDeployableListModel *const model
= m_step->deployables()->modelAt(modelRow);
const QString origFilePath = QFileDialog::getOpenFileName(this,
tr("Choose Icon (will be scaled to 64x64 pixels, if necessary)"),
model->projectDir(), QLatin1String("(*.png)"));
if (origFilePath.isEmpty())
return;
QPixmap pixmap(origFilePath);
if (pixmap.isNull()) {
QMessageBox::critical(this, tr("Invalid Icon"),
tr("Unable to read image"));
return;
}
const QSize iconSize(64, 64);
if (pixmap.size() != iconSize)
pixmap = pixmap.scaled(iconSize);
const QString newFileName = model->projectName() + QLatin1Char('.')
+ QFileInfo(origFilePath).suffix();
const QString newFilePath = model->projectDir() + QLatin1Char('/')
+ newFileName;
if (!pixmap.save(newFilePath)) {
QMessageBox::critical(this, tr("Failed to Save Icon"),
tr("Could not save icon to '%1'.").arg(newFilePath));
return;
}
QString error;
if (!model->addIcon(newFileName, error)) {
QMessageBox::critical(this, tr("Could Not Add Icon"),
tr("Error adding icon: %1").arg(error));
}
ui->addIconButton->setEnabled(model->canAddIcon());
ui->tableView->resizeRowsToContents();
}
void MaemoDeployStepWidget::showDeviceConfigurations()
{
MaemoDeviceConfigurationsSettingsPage *page

View File

@@ -44,25 +44,19 @@ QT_END_NAMESPACE
namespace Qt4ProjectManager {
namespace Internal {
class MaemoDeployStep;
class AbstractMaemoDeployStep;
class MaemoDeployStepWidget : public ProjectExplorer::BuildStepConfigWidget
{
Q_OBJECT
public:
MaemoDeployStepWidget(MaemoDeployStep *step);
MaemoDeployStepWidget(AbstractMaemoDeployStep *step);
~MaemoDeployStepWidget();
private:
Q_SLOT void handleDeviceUpdate();
Q_SLOT void setCurrentDeviceConfig(int index);
Q_SLOT void setDeployToSysroot(bool doDeloy);
Q_SLOT void setModel(int row);
Q_SLOT void handleModelListToBeReset();
Q_SLOT void handleModelListReset();
Q_SLOT void addDesktopFile();
Q_SLOT void addIcon();
Q_SLOT void showDeviceConfigurations();
virtual void init();
@@ -70,7 +64,7 @@ private:
virtual QString displayName() const;
Ui::MaemoDeployStepWidget *ui;
MaemoDeployStep * const m_step;
AbstractMaemoDeployStep * const m_step;
};
} // namespace Internal

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>662</width>
<height>418</height>
<width>597</width>
<height>74</height>
</rect>
</property>
<property name="windowTitle">
@@ -53,144 +53,17 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="deployToSysrootCheckBox">
<property name="text">
<string>Also deploy to sysroot</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>
<widget class="Line" name="line">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="installLabel">
<property name="toolTip">
<string>These show the INSTALLS settings from the project file(s).</string>
</property>
<property name="text">
<string>&lt;b&gt;Files to install for subproject:&lt;/b&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="modelComboBox">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<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>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QTableView" name="tableView">
<property name="minimumSize">
<size>
<width>0</width>
<height>150</height>
</size>
</property>
<property name="toolTip">
<string>Edit the project file to add or remove entries.</string>
</property>
<property name="textElideMode">
<enum>Qt::ElideMiddle</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>400</number>
</attribute>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>100</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="addDesktopFileButton">
<property name="text">
<string>Add Desktop File</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addIconButton">
<property name="text">
<string>Add Launcher Icon ...</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>

View File

@@ -227,28 +227,58 @@ MaemoDeviceConfig::Ptr MaemoDeviceConfig::create(const ConstPtr &other)
}
MaemoDeviceConfig::Ptr MaemoDeviceConfig::createHardwareConfig(const QString &name,
MaemoGlobal::MaemoVersion osVersion, const QString &hostName,
const QString privateKeyFilePath, Id &nextId)
MaemoGlobal::OsVersion osVersion, const QString &hostName,
const QString &privateKeyFilePath, Id &nextId)
{
Utils::SshConnectionParameters sshParams(Utils::SshConnectionParameters::NoProxy);
sshParams.authenticationType = Utils::SshConnectionParameters::AuthenticationByKey;
sshParams.host = hostName;
sshParams.userName = defaultUser(osVersion);
sshParams.privateKeyFile = privateKeyFilePath;
return Ptr(new MaemoDeviceConfig(name, osVersion, Physical, sshParams, nextId));
}
MaemoDeviceConfig::Ptr MaemoDeviceConfig::createGenericLinuxConfigUsingPassword(const QString &name,
const QString &hostName, const QString &userName, const QString &password,
Id &nextId)
{
Utils::SshConnectionParameters sshParams(Utils::SshConnectionParameters::NoProxy);
sshParams.authenticationType
= Utils::SshConnectionParameters::AuthenticationByPassword;
sshParams.host = hostName;
sshParams.userName = userName;
sshParams.password = password;
return Ptr(new MaemoDeviceConfig(name, MaemoGlobal::GenericLinux, Physical,
sshParams, nextId));
}
MaemoDeviceConfig::Ptr MaemoDeviceConfig::createGenericLinuxConfigUsingKey(const QString &name,
const QString &hostName, const QString &userName, const QString &privateKeyFile,
Id &nextId)
{
Utils::SshConnectionParameters sshParams(Utils::SshConnectionParameters::NoProxy);
sshParams.authenticationType
= Utils::SshConnectionParameters::AuthenticationByKey;
sshParams.host = hostName;
sshParams.userName = userName;
sshParams.privateKeyFile = privateKeyFile;
return Ptr(new MaemoDeviceConfig(name, MaemoGlobal::GenericLinux, Physical,
sshParams, nextId));
}
MaemoDeviceConfig::Ptr MaemoDeviceConfig::createEmulatorConfig(const QString &name,
MaemoGlobal::MaemoVersion osVersion, Id &nextId)
MaemoGlobal::OsVersion osVersion, Id &nextId)
{
Utils::SshConnectionParameters sshParams(Utils::SshConnectionParameters::NoProxy);
sshParams.authenticationType = Utils::SshConnectionParameters::AuthenticationByPassword;
sshParams.host = defaultHost(Emulator);
sshParams.host = defaultHost(Emulator, osVersion);
sshParams.userName = defaultUser(osVersion);
sshParams.password = defaultQemuPassword(osVersion);
return Ptr(new MaemoDeviceConfig(name, osVersion, Emulator, sshParams, nextId));
}
MaemoDeviceConfig::MaemoDeviceConfig(const QString &name,
MaemoGlobal::MaemoVersion osVersion, DeviceType devType,
MaemoGlobal::OsVersion osVersion, DeviceType devType,
const Utils::SshConnectionParameters &sshParams, Id &nextId)
: m_sshParameters(sshParams),
m_name(name),
@@ -259,7 +289,6 @@ MaemoDeviceConfig::MaemoDeviceConfig(const QString &name,
m_internalId(nextId++)
{
m_sshParameters.port = defaultSshPort(m_type);
m_sshParameters.userName = defaultUser(m_osVersion);
m_sshParameters.timeout = DefaultTimeout;
}
@@ -267,7 +296,7 @@ MaemoDeviceConfig::MaemoDeviceConfig(const QSettings &settings,
Id &nextId)
: m_sshParameters(Utils::SshConnectionParameters::NoProxy),
m_name(settings.value(NameKey).toString()),
m_osVersion(static_cast<MaemoGlobal::MaemoVersion>(settings.value(OsVersionKey, MaemoGlobal::Maemo5).toInt())),
m_osVersion(static_cast<MaemoGlobal::OsVersion>(settings.value(OsVersionKey, MaemoGlobal::Maemo5).toInt())),
m_type(static_cast<DeviceType>(settings.value(TypeKey, DefaultDeviceType).toInt())),
m_portsSpec(settings.value(PortsSpecKey, defaultPortsSpec(m_type)).toString()),
m_isDefault(settings.value(IsDefaultKey, false).toBool()),
@@ -275,7 +304,7 @@ MaemoDeviceConfig::MaemoDeviceConfig(const QSettings &settings,
{
if (m_internalId == nextId)
++nextId;
m_sshParameters.host = settings.value(HostKey, defaultHost(m_type)).toString();
m_sshParameters.host = settings.value(HostKey, defaultHost(m_type, m_osVersion)).toString();
m_sshParameters.port = settings.value(SshPortKey, defaultSshPort(m_type)).toInt();
m_sshParameters.userName = settings.value(UserNameKey, defaultUser(m_osVersion)).toString();
m_sshParameters.authenticationType
@@ -314,8 +343,10 @@ QString MaemoDeviceConfig::defaultPortsSpec(DeviceType type) const
return QLatin1String(type == Physical ? "10000-10100" : "13219,14168");
}
QString MaemoDeviceConfig::defaultHost(DeviceType type)
QString MaemoDeviceConfig::defaultHost(DeviceType type, MaemoGlobal::OsVersion osVersion)
{
if (osVersion == MaemoGlobal::GenericLinux)
return QString();
return type == Physical ? DefaultHostNameHW : DefaultHostNameSim;
}
@@ -330,7 +361,7 @@ QString MaemoDeviceConfig::defaultPublicKeyFilePath()
return defaultPrivateKeyFilePath() + QLatin1String(".pub");
}
QString MaemoDeviceConfig::defaultUser(MaemoGlobal::MaemoVersion osVersion)
QString MaemoDeviceConfig::defaultUser(MaemoGlobal::OsVersion osVersion)
{
switch (osVersion) {
case MaemoGlobal::Maemo5:
@@ -338,13 +369,15 @@ QString MaemoDeviceConfig::defaultUser(MaemoGlobal::MaemoVersion osVersion)
return QLatin1String("developer");
case MaemoGlobal::Meego:
return QLatin1String("meego");
case MaemoGlobal::GenericLinux:
return QString();
default:
Q_ASSERT(false);
qFatal("%s: Missing switch case.", Q_FUNC_INFO);
return QString();
}
}
QString MaemoDeviceConfig::defaultQemuPassword(MaemoGlobal::MaemoVersion osVersion)
QString MaemoDeviceConfig::defaultQemuPassword(MaemoGlobal::OsVersion osVersion)
{
switch (osVersion) {
case MaemoGlobal::Maemo5:
@@ -438,16 +471,33 @@ void MaemoDeviceConfigurations::save()
}
void MaemoDeviceConfigurations::addHardwareDeviceConfiguration(const QString &name,
MaemoGlobal::MaemoVersion osVersion, const QString &hostName,
const QString privateKeyFilePath)
MaemoGlobal::OsVersion osVersion, const QString &hostName,
const QString &privateKeyFilePath)
{
const MaemoDeviceConfig::Ptr &devConf = MaemoDeviceConfig::createHardwareConfig(name,
osVersion, hostName, privateKeyFilePath, m_nextId);
addConfiguration(devConf);
}
void MaemoDeviceConfigurations::addGenericLinuxConfigurationUsingPassword(const QString &name,
const QString &hostName, const QString &userName, const QString &password)
{
const MaemoDeviceConfig::Ptr &devConf
= MaemoDeviceConfig::createGenericLinuxConfigUsingPassword(name,
hostName, userName, password, m_nextId);
addConfiguration(devConf);
}
void MaemoDeviceConfigurations::addGenericLinuxConfigurationUsingKey(const QString &name,
const QString &hostName, const QString &userName, const QString &privateKeyFilePath)
{
const MaemoDeviceConfig::Ptr &devConf = MaemoDeviceConfig::createGenericLinuxConfigUsingKey(name,
hostName, userName, privateKeyFilePath, m_nextId);
addConfiguration(devConf);
}
void MaemoDeviceConfigurations::addEmulatorDeviceConfiguration(const QString &name,
MaemoGlobal::MaemoVersion osVersion)
MaemoGlobal::OsVersion osVersion)
{
const MaemoDeviceConfig::Ptr &devConf
= MaemoDeviceConfig::createEmulatorConfig(name, osVersion, m_nextId);
@@ -468,7 +518,7 @@ void MaemoDeviceConfigurations::removeConfiguration(int idx)
Q_ASSERT(idx >= 0 && idx < rowCount());
beginRemoveRows(QModelIndex(), idx, idx);
const bool wasDefault = deviceAt(idx)->m_isDefault;
const MaemoGlobal::MaemoVersion osVersion = deviceAt(idx)->osVersion();
const MaemoGlobal::OsVersion osVersion = deviceAt(idx)->osVersion();
m_devConfigs.removeAt(idx);
endRemoveRows();
if (wasDefault) {
@@ -551,6 +601,7 @@ void MaemoDeviceConfigurations::load()
ensureDefaultExists(MaemoGlobal::Maemo5);
ensureDefaultExists(MaemoGlobal::Maemo6);
ensureDefaultExists(MaemoGlobal::Meego);
ensureDefaultExists(MaemoGlobal::GenericLinux);
}
MaemoDeviceConfig::ConstPtr MaemoDeviceConfigurations::deviceAt(int idx) const
@@ -573,7 +624,7 @@ MaemoDeviceConfig::ConstPtr MaemoDeviceConfigurations::find(MaemoDeviceConfig::I
return index == -1 ? MaemoDeviceConfig::ConstPtr() : deviceAt(index);
}
MaemoDeviceConfig::ConstPtr MaemoDeviceConfigurations::defaultDeviceConfig(const MaemoGlobal::MaemoVersion osVersion) const
MaemoDeviceConfig::ConstPtr MaemoDeviceConfigurations::defaultDeviceConfig(const MaemoGlobal::OsVersion osVersion) const
{
foreach (const MaemoDeviceConfig::ConstPtr &devConf, m_devConfigs) {
if (devConf->m_isDefault && devConf->osVersion() == osVersion)
@@ -596,7 +647,7 @@ MaemoDeviceConfig::Id MaemoDeviceConfigurations::internalId(MaemoDeviceConfig::C
return devConf ? devConf->m_internalId : MaemoDeviceConfig::InvalidId;
}
void MaemoDeviceConfigurations::ensureDefaultExists(MaemoGlobal::MaemoVersion osVersion)
void MaemoDeviceConfigurations::ensureDefaultExists(MaemoGlobal::OsVersion osVersion)
{
if (!defaultDeviceConfig(osVersion)) {
foreach (const MaemoDeviceConfig::Ptr &devConf, m_devConfigs) {
@@ -622,7 +673,7 @@ QVariant MaemoDeviceConfigurations::data(const QModelIndex &index, int role) con
QString name = devConf->name();
if (devConf->m_isDefault) {
name += QLatin1Char(' ') + tr("(default for %1)")
.arg(MaemoGlobal::maemoVersionToString(devConf->osVersion()));
.arg(MaemoGlobal::osVersionToString(devConf->osVersion()));
}
return name;
}

View File

@@ -78,25 +78,25 @@ public:
MaemoPortList freePorts() const;
Utils::SshConnectionParameters sshParameters() const { return m_sshParameters; }
QString name() const { return m_name; }
MaemoGlobal::MaemoVersion osVersion() const { return m_osVersion; }
MaemoGlobal::OsVersion osVersion() const { return m_osVersion; }
DeviceType type() const { return m_type; }
QString portsSpec() const { return m_portsSpec; }
Id internalId() const { return m_internalId; }
bool isDefault() const { return m_isDefault; }
static QString portsRegExpr();
static QString defaultHost(DeviceType type);
static QString defaultHost(DeviceType type, MaemoGlobal::OsVersion osVersion);
static QString defaultPrivateKeyFilePath();
static QString defaultPublicKeyFilePath();
static QString defaultUser(MaemoGlobal::MaemoVersion osVersion);
static QString defaultUser(MaemoGlobal::OsVersion osVersion);
static int defaultSshPort(DeviceType type);
static QString defaultQemuPassword(MaemoGlobal::MaemoVersion osVersion);
static QString defaultQemuPassword(MaemoGlobal::OsVersion osVersion);
static const Id InvalidId;
private:
typedef QSharedPointer<MaemoDeviceConfig> Ptr;
MaemoDeviceConfig(const QString &name, MaemoGlobal::MaemoVersion osVersion,
MaemoDeviceConfig(const QString &name, MaemoGlobal::OsVersion osVersion,
DeviceType type, const Utils::SshConnectionParameters &sshParams,
Id &nextId);
MaemoDeviceConfig(const QSettings &settings, Id &nextId);
@@ -106,10 +106,16 @@ private:
MaemoDeviceConfig &operator=(const MaemoDeviceConfig &);
static Ptr createHardwareConfig(const QString &name,
MaemoGlobal::MaemoVersion osVersion, const QString &hostName,
const QString privateKeyFilePath, Id &nextId);
MaemoGlobal::OsVersion osVersion, const QString &hostName,
const QString &privateKeyFilePath, Id &nextId);
static Ptr createGenericLinuxConfigUsingPassword(const QString &name,
const QString &hostName, const QString &userName,
const QString &password, Id &nextId);
static Ptr createGenericLinuxConfigUsingKey(const QString &name,
const QString &hostName, const QString &userName,
const QString &privateKeyFilePath, Id &nextId);
static Ptr createEmulatorConfig(const QString &name,
MaemoGlobal::MaemoVersion osVersion, Id &nextId);
MaemoGlobal::OsVersion osVersion, Id &nextId);
static Ptr create(const QSettings &settings, Id &nextId);
static Ptr create(const ConstPtr &other);
@@ -118,7 +124,7 @@ private:
Utils::SshConnectionParameters m_sshParameters;
QString m_name;
MaemoGlobal::MaemoVersion m_osVersion;
MaemoGlobal::OsVersion m_osVersion;
DeviceType m_type;
QString m_portsSpec;
bool m_isDefault;
@@ -138,7 +144,7 @@ public:
MaemoDeviceConfig::ConstPtr deviceAt(int index) const;
MaemoDeviceConfig::ConstPtr find(MaemoDeviceConfig::Id id) const;
MaemoDeviceConfig::ConstPtr defaultDeviceConfig(const MaemoGlobal::MaemoVersion osVersion) const;
MaemoDeviceConfig::ConstPtr defaultDeviceConfig(const MaemoGlobal::OsVersion osVersion) const;
bool hasConfig(const QString &name) const;
int indexForInternalId(MaemoDeviceConfig::Id internalId) const;
MaemoDeviceConfig::Id internalId(MaemoDeviceConfig::ConstPtr devConf) const;
@@ -147,10 +153,16 @@ public:
QString defaultSshKeyFilePath() const { return m_defaultSshKeyFilePath; }
void addHardwareDeviceConfiguration(const QString &name,
MaemoGlobal::MaemoVersion osVersion, const QString &hostName,
const QString privateKeyFilePath);
MaemoGlobal::OsVersion osVersion, const QString &hostName,
const QString &privateKeyFilePath);
void addGenericLinuxConfigurationUsingPassword(const QString &name,
const QString &hostName, const QString &userName,
const QString &password);
void addGenericLinuxConfigurationUsingKey(const QString &name,
const QString &hostName, const QString &userName,
const QString &privateKeyFilePath);
void addEmulatorDeviceConfiguration(const QString &name,
MaemoGlobal::MaemoVersion osVersion);
MaemoGlobal::OsVersion osVersion);
void removeConfiguration(int index);
void setConfigurationName(int i, const QString &name);
void setSshParameters(int i, const Utils::SshConnectionParameters &params);
@@ -171,7 +183,7 @@ private:
static void copy(const MaemoDeviceConfigurations *source,
MaemoDeviceConfigurations *target, bool deep);
void addConfiguration(const MaemoDeviceConfig::Ptr &devConfig);
void ensureDefaultExists(MaemoGlobal::MaemoVersion osVersion);
void ensureDefaultExists(MaemoGlobal::OsVersion osVersion);
static MaemoDeviceConfigurations *m_instance;
MaemoDeviceConfig::Id m_nextId;

View File

@@ -196,7 +196,7 @@ void MaemoDeviceConfigurationsSettingsWidget::displayCurrent()
{
const MaemoDeviceConfig::ConstPtr &current = currentConfig();
m_ui->defaultDeviceButton->setEnabled(!current->isDefault());
m_ui->osTypeValueLabel->setText(MaemoGlobal::maemoVersionToString(current->osVersion()));
m_ui->osTypeValueLabel->setText(MaemoGlobal::osVersionToString(current->osVersion()));
const SshConnectionParameters &sshParams = current->sshParameters();
if (current->type() == MaemoDeviceConfig::Physical) {
m_ui->deviceTypeValueLabel->setText(tr("Physical Device"));

View File

@@ -34,6 +34,7 @@
#include "maemodeviceconfigwizard.h"
#include "ui_maemodeviceconfigwizardkeycreationpage.h"
#include "ui_maemodeviceconfigwizardkeydeploymentpage.h"
#include "ui_maemodeviceconfigwizardlogindatapage.h"
#include "ui_maemodeviceconfigwizardpreviouskeysetupcheckpage.h"
#include "ui_maemodeviceconfigwizardreusekeyscheckpage.h"
#include "ui_maemodeviceconfigwizardstartpage.h"
@@ -50,6 +51,8 @@
#include <QtGui/QMessageBox>
#include <QtGui/QWizardPage>
using namespace Utils;
namespace Qt4ProjectManager {
namespace Internal {
namespace {
@@ -58,15 +61,18 @@ struct WizardData
{
QString configName;
QString hostName;
MaemoGlobal::MaemoVersion maemoVersion;
MaemoGlobal::OsVersion osVersion;
SshConnectionParameters::AuthenticationType authType;
MaemoDeviceConfig::DeviceType deviceType;
QString privateKeyFilePath;
QString publicKeyFilePath;
QString userName;
QString password;
};
enum PageId {
StartPageId, PreviousKeySetupCheckPageId, ReuseKeysCheckPageId,
KeyCreationPageId, KeyDeploymentPageId, FinalPageId
StartPageId, LoginDataPageId, PreviousKeySetupCheckPageId,
ReuseKeysCheckPageId, KeyCreationPageId, KeyDeploymentPageId, FinalPageId
};
class MaemoDeviceConfigWizardStartPage : public QWizardPage
@@ -79,20 +85,33 @@ public:
m_ui->setupUi(this);
setTitle(tr("General Information"));
setSubTitle(QLatin1String(" ")); // For Qt bug (background color)
m_ui->fremantleButton->setText(MaemoGlobal::maemoVersionToString(MaemoGlobal::Maemo5));
m_ui->harmattanButton->setText(MaemoGlobal::maemoVersionToString(MaemoGlobal::Maemo6));
m_ui->meegoButton->setText(MaemoGlobal::maemoVersionToString(MaemoGlobal::Meego));
QButtonGroup * const buttonGroup = new QButtonGroup(this);
m_ui->fremantleButton->setText(MaemoGlobal::osVersionToString(MaemoGlobal::Maemo5));
m_ui->harmattanButton->setText(MaemoGlobal::osVersionToString(MaemoGlobal::Maemo6));
m_ui->meegoButton->setText(MaemoGlobal::osVersionToString(MaemoGlobal::Meego));
m_ui->genericLinuxButton->setText(MaemoGlobal::osVersionToString(MaemoGlobal::GenericLinux));
QButtonGroup *buttonGroup = new QButtonGroup(this);
buttonGroup->setExclusive(true);
buttonGroup->addButton(m_ui->hwButton);
buttonGroup->addButton(m_ui->qemuButton);
m_ui->nameLineEdit->setText(QLatin1String("(New Configuration)"));
connect(buttonGroup, SIGNAL(buttonClicked(int)),
SLOT(handleDeviceTypeChanged()));
buttonGroup = new QButtonGroup(this);
buttonGroup->setExclusive(true);
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);
m_ui->hwButton->setChecked(true);
handleDeviceTypeChanged();
m_ui->hostNameLineEdit->setText(MaemoDeviceConfig::defaultHost(deviceType()));
m_ui->hostNameLineEdit->setText(MaemoDeviceConfig::defaultHost(deviceType(),
osVersion()));
connect(m_ui->nameLineEdit, SIGNAL(textChanged(QString)), this,
SIGNAL(completeChanged()));
connect(m_ui->hostNameLineEdit, SIGNAL(textChanged(QString)), this,
@@ -109,15 +128,16 @@ public:
QString hostName() const
{
return deviceType() == MaemoDeviceConfig::Emulator
? MaemoDeviceConfig::defaultHost(MaemoDeviceConfig::Emulator)
? MaemoDeviceConfig::defaultHost(MaemoDeviceConfig::Emulator, osVersion())
: m_ui->hostNameLineEdit->text().trimmed();
}
MaemoGlobal::MaemoVersion maemoVersion() const
MaemoGlobal::OsVersion osVersion() const
{
return m_ui->fremantleButton->isChecked() ? MaemoGlobal::Maemo5
: m_ui->harmattanButton->isChecked() ? MaemoGlobal::Maemo6
: MaemoGlobal::Meego;
: m_ui->meegoButton->isChecked() ? MaemoGlobal::Meego
: MaemoGlobal::GenericLinux;
}
MaemoDeviceConfig::DeviceType deviceType() const
@@ -134,10 +154,82 @@ private slots:
m_ui->hostNameLineEdit->setEnabled(enable);
}
void handleOsTypeChanged()
{
if (osVersion() == MaemoGlobal::GenericLinux) {
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;
};
class MaemoDeviceConfigWizardLoginDataPage : public QWizardPage
{
Q_OBJECT
public:
MaemoDeviceConfigWizardLoginDataPage(QWidget *parent)
: QWizardPage(parent),
m_ui(new Ui::MaemoDeviceConfigWizardLoginDataPage)
{
m_ui->setupUi(this);
setTitle(tr("Login Data"));
m_ui->privateKeyPathChooser->setExpectedKind(PathChooser::File);
setSubTitle(QLatin1String(" ")); // For Qt bug (background color)
connect(m_ui->userNameLineEdit, SIGNAL(textChanged(QString)),
SIGNAL(completeChanged()));
connect(m_ui->privateKeyPathChooser, SIGNAL(validChanged()),
SIGNAL(completeChanged()));
connect(m_ui->passwordButton, SIGNAL(toggled(bool)),
SLOT(handleAuthTypeChanged()));
}
virtual bool isComplete() const
{
return !userName().isEmpty()
&& (authType() == SshConnectionParameters::AuthenticationByPassword
|| m_ui->privateKeyPathChooser->isValid());
}
virtual void initializePage()
{
m_ui->userNameLineEdit->clear();
m_ui->passwordButton->setChecked(true);
m_ui->passwordLineEdit->clear();
m_ui->privateKeyPathChooser->setPath(MaemoDeviceConfig::defaultPrivateKeyFilePath());
handleAuthTypeChanged();
}
SshConnectionParameters::AuthenticationType authType() const
{
return m_ui->passwordButton->isChecked()
? SshConnectionParameters::AuthenticationByPassword
: SshConnectionParameters::AuthenticationByKey;
}
QString userName() const { return m_ui->userNameLineEdit->text().trimmed(); }
QString password() const { return m_ui->passwordLineEdit->text(); }
QString privateKeyFilePath() const { return m_ui->privateKeyPathChooser->path(); }
private:
Q_SLOT void handleAuthTypeChanged()
{
m_ui->passwordLineEdit->setEnabled(authType() == SshConnectionParameters::AuthenticationByPassword);
m_ui->privateKeyPathChooser->setEnabled(authType() == SshConnectionParameters::AuthenticationByKey);
emit completeChanged();
}
const QScopedPointer<Ui::MaemoDeviceConfigWizardLoginDataPage> m_ui;
};
class MaemoDeviceConfigWizardPreviousKeySetupCheckPage : public QWizardPage
{
Q_OBJECT
@@ -147,7 +239,7 @@ public:
m_ui(new Ui::MaemoDeviceConfigWizardCheckPreviousKeySetupPage)
{
m_ui->setupUi(this);
m_ui->privateKeyFilePathChooser->setExpectedKind(Utils::PathChooser::File);
m_ui->privateKeyFilePathChooser->setExpectedKind(PathChooser::File);
setTitle(tr("Device Status Check"));
setSubTitle(QLatin1String(" ")); // For Qt bug (background color)
QButtonGroup * const buttonGroup = new QButtonGroup(this);
@@ -202,8 +294,8 @@ public:
m_ui->setupUi(this);
setTitle(tr("Existing Keys Check"));
setSubTitle(QLatin1String(" ")); // For Qt bug (background color)
m_ui->publicKeyFilePathChooser->setExpectedKind(Utils::PathChooser::File);
m_ui->privateKeyFilePathChooser->setExpectedKind(Utils::PathChooser::File);
m_ui->publicKeyFilePathChooser->setExpectedKind(PathChooser::File);
m_ui->privateKeyFilePathChooser->setExpectedKind(PathChooser::File);
QButtonGroup * const buttonGroup = new QButtonGroup(this);
buttonGroup->setExclusive(true);
buttonGroup->addButton(m_ui->reuseButton);
@@ -309,9 +401,9 @@ private:
m_ui->keyDirPathChooser->setEnabled(false);
m_ui->createKeysButton->setEnabled(false);
m_ui->statusLabel->setText(tr("Creating keys ... "));
Utils::SshKeyGenerator keyGenerator;
if (!keyGenerator.generateKeys(Utils::SshKeyGenerator::Rsa,
Utils::SshKeyGenerator::OpenSsl, 1024)) {
SshKeyGenerator keyGenerator;
if (!keyGenerator.generateKeys(SshKeyGenerator::Rsa,
SshKeyGenerator::OpenSsl, 1024)) {
QMessageBox::critical(this, tr("Cannot Create Keys"),
tr("Key creation failed: %1").arg(keyGenerator.error()));
enableInput();
@@ -406,13 +498,13 @@ private:
m_ui->deviceAddressLineEdit->setEnabled(false);
m_ui->passwordLineEdit->setEnabled(false);
m_ui->deployButton->setEnabled(false);
Utils::SshConnectionParameters sshParams(SshConnectionParameters::NoProxy);
SshConnectionParameters sshParams(SshConnectionParameters::NoProxy);
sshParams.authenticationType = SshConnectionParameters::AuthenticationByPassword;
sshParams.host = hostAddress();
sshParams.port = MaemoDeviceConfig::defaultSshPort(MaemoDeviceConfig::Physical);
sshParams.password = password();
sshParams.timeout = 30;
sshParams.userName = MaemoDeviceConfig::defaultUser(m_wizardData.maemoVersion);
sshParams.userName = MaemoDeviceConfig::defaultUser(m_wizardData.osVersion);
m_ui->statusLabel->setText(tr("Deploying... "));
m_keyDeployer->deployPublicKey(sshParams, m_wizardData.publicKeyFilePath);
}
@@ -496,6 +588,7 @@ struct MaemoDeviceConfigWizardPrivate
QWidget *parent)
: devConfigs(devConfigs),
startPage(parent),
loginDataPage(parent),
previousKeySetupPage(parent),
reuseKeysCheckPage(parent),
keyCreationPage(parent),
@@ -507,6 +600,7 @@ struct MaemoDeviceConfigWizardPrivate
WizardData wizardData;
MaemoDeviceConfigurations * const devConfigs;
MaemoDeviceConfigWizardStartPage startPage;
MaemoDeviceConfigWizardLoginDataPage loginDataPage;
MaemoDeviceConfigWizardPreviousKeySetupCheckPage previousKeySetupPage;
MaemoDeviceConfigWizardReuseKeysCheckPage reuseKeysCheckPage;
MaemoDeviceConfigWizardKeyCreationPage keyCreationPage;
@@ -522,6 +616,7 @@ MaemoDeviceConfigWizard::MaemoDeviceConfigWizard(MaemoDeviceConfigurations *devC
{
setWindowTitle(tr("New Device Configuration Setup"));
setPage(StartPageId, &d->startPage);
setPage(LoginDataPageId, &d->loginDataPage);
setPage(PreviousKeySetupCheckPageId, &d->previousKeySetupPage);
setPage(ReuseKeysCheckPageId, &d->reuseKeysCheckPage);
setPage(KeyCreationPageId, &d->keyCreationPage);
@@ -543,13 +638,23 @@ void MaemoDeviceConfigWizard::createDeviceConfig()
while (d->devConfigs->hasConfig(name));
}
if (d->wizardData.deviceType == MaemoDeviceConfig::Physical) {
if (d->wizardData.osVersion == MaemoGlobal::GenericLinux) {
if (d->wizardData.authType == SshConnectionParameters::AuthenticationByPassword) {
d->devConfigs->addGenericLinuxConfigurationUsingPassword(name,
d->wizardData.hostName, d->wizardData.userName,
d->wizardData.password);
} else {
d->devConfigs->addGenericLinuxConfigurationUsingKey(name,
d->wizardData.hostName, d->wizardData.userName,
d->wizardData.privateKeyFilePath);
}
} else if (d->wizardData.deviceType == MaemoDeviceConfig::Physical) {
d->devConfigs->addHardwareDeviceConfiguration(name,
d->wizardData.maemoVersion, d->wizardData.hostName,
d->wizardData.osVersion, d->wizardData.hostName,
d->wizardData.privateKeyFilePath);
} else {
d->devConfigs->addEmulatorDeviceConfiguration(name,
d->wizardData.maemoVersion);
d->wizardData.osVersion);
}
}
@@ -558,15 +663,25 @@ int MaemoDeviceConfigWizard::nextId() const
switch (currentId()) {
case StartPageId:
d->wizardData.configName = d->startPage.configName();
d->wizardData.maemoVersion = d->startPage.maemoVersion();
d->wizardData.osVersion = d->startPage.osVersion();
d->wizardData.deviceType = d->startPage.deviceType();
d->wizardData.hostName = d->startPage.hostName();
if (d->wizardData.deviceType == MaemoDeviceConfig::Emulator) {
return FinalPageId;
} else if (d->wizardData.osVersion == MaemoGlobal::GenericLinux) {
return LoginDataPageId;
} else {
return PreviousKeySetupCheckPageId;
}
case LoginDataPageId:
d->wizardData.userName = d->loginDataPage.userName();
d->wizardData.authType = d->loginDataPage.authType();
if (d->wizardData.authType == SshConnectionParameters::AuthenticationByPassword)
d->wizardData.password = d->loginDataPage.password();
else
d->wizardData.privateKeyFilePath = d->loginDataPage.privateKeyFilePath();
return FinalPageId;
case PreviousKeySetupCheckPageId:
if (d->previousKeySetupPage.keyBasedLoginWasSetup()) {
d->wizardData.privateKeyFilePath

View File

@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MaemoDeviceConfigWizardLoginDataPage</class>
<widget class="QWizardPage" name="MaemoDeviceConfigWizardLoginDataPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>423</width>
<height>127</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="userNameLabel">
<property name="text">
<string>User name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="userNameLineEdit"/>
</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>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Authentication type:</string>
</property>
</widget>
</item>
<item row="1" 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="radioButton">
<property name="text">
<string>Key</string>
</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="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Password:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="passwordLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<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="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Private key:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="Utils::PathChooser" name="privateKeyPathChooser"/>
</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>
</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

@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>618</width>
<width>727</width>
<height>122</height>
</rect>
</property>
@@ -54,6 +54,13 @@
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="genericLinuxButton">
<property name="text">
<string>Generic Linux</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">

View File

@@ -44,10 +44,12 @@
#include <qt4projectmanager/qtversionmanager.h>
#include <utils/environment.h>
#include <QtGui/QDesktopServices>
#include <QtCore/QDateTime>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QProcess>
#include <QtCore/QString>
#include <QtGui/QDesktopServices>
namespace Qt4ProjectManager {
namespace Internal {
@@ -57,9 +59,23 @@ static const QLatin1String binQmake("/bin/qmake" EXEC_SUFFIX);
bool MaemoGlobal::isMaemoTargetId(const QString &id)
{
return id == QLatin1String(Constants::MAEMO5_DEVICE_TARGET_ID)
|| id == QLatin1String(Constants::HARMATTAN_DEVICE_TARGET_ID)
|| id == QLatin1String(Constants::MEEGO_DEVICE_TARGET_ID);
return isFremantleTargetId(id) || isHarmattanTargetId(id)
|| isMeegoTargetId(id);
}
bool MaemoGlobal::isFremantleTargetId(const QString &id)
{
return id == QLatin1String(Constants::MAEMO5_DEVICE_TARGET_ID);
}
bool MaemoGlobal::isHarmattanTargetId(const QString &id)
{
return id == QLatin1String(Constants::HARMATTAN_DEVICE_TARGET_ID);
}
bool MaemoGlobal::isMeegoTargetId(const QString &id)
{
return id == QLatin1String(Constants::MEEGO_DEVICE_TARGET_ID);
}
bool MaemoGlobal::isValidMaemo5QtVersion(const QtVersion *version)
@@ -78,7 +94,7 @@ bool MaemoGlobal::isValidMeegoQtVersion(const Qt4ProjectManager::QtVersion *vers
}
bool MaemoGlobal::isValidMaemoQtVersion(const QtVersion *qtVersion,
MaemoVersion maemoVersion)
OsVersion maemoVersion)
{
if (version(qtVersion) != maemoVersion)
return false;
@@ -149,7 +165,7 @@ QString MaemoGlobal::failedToConnectToServerMessage(const Utils::SshConnection::
|| connection->errorState() == Utils::SshSocketError) {
errorMsg += tr("\nDid you start Qemu?");
}
} else if (connection->errorState() == Utils::SshTimeoutError) {
} else if (connection->errorState() == Utils::SshTimeoutError) {
errorMsg += tr("\nIs the device connected and set up for network access?");
}
return errorMsg;
@@ -187,7 +203,7 @@ QString MaemoGlobal::madCommand(const QtVersion *qtVersion)
return maddeRoot(qtVersion) + QLatin1String("/bin/mad");
}
MaemoGlobal::MaemoVersion MaemoGlobal::version(const QtVersion *qtVersion)
MaemoGlobal::OsVersion MaemoGlobal::version(const QtVersion *qtVersion)
{
const QString &name = targetName(qtVersion);
if (name.startsWith(QLatin1String("fremantle")))
@@ -196,7 +212,7 @@ MaemoGlobal::MaemoVersion MaemoGlobal::version(const QtVersion *qtVersion)
return Maemo6;
if (name.startsWith(QLatin1String("meego")))
return Meego;
return static_cast<MaemoVersion>(-1);
return static_cast<OsVersion>(-1);
}
QString MaemoGlobal::architecture(const QtVersion *qtVersion)
@@ -244,6 +260,25 @@ bool MaemoGlobal::removeRecursively(const QString &filePath, QString &error)
return true;
}
bool MaemoGlobal::isFileNewerThan(const QString &filePath,
const QDateTime &timeStamp)
{
QFileInfo fileInfo(filePath);
if (!fileInfo.exists() || fileInfo.lastModified() >= timeStamp)
return true;
if (fileInfo.isDir()) {
const QStringList dirContents = QDir(filePath)
.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
foreach (const QString &curFileName, dirContents) {
const QString curFilePath
= filePath + QLatin1Char('/') + curFileName;
if (isFileNewerThan(curFilePath, timeStamp))
return true;
}
}
return false;
}
bool MaemoGlobal::callMad(QProcess &proc, const QStringList &args,
const QtVersion *qtVersion, bool useTarget)
{
@@ -289,20 +324,27 @@ QStringList MaemoGlobal::targetArgs(const QtVersion *qtVersion, bool useTarget)
return args;
}
QString MaemoGlobal::maemoVersionToString(MaemoVersion version)
QString MaemoGlobal::osVersionToString(OsVersion version)
{
switch (version) {
case Maemo5: return QLatin1String("Maemo 5/Fremantle");
case Maemo6: return QLatin1String("Maemo 6/Harmattan");
case Meego: return QLatin1String("Meego");
case GenericLinux: return QLatin1String("Other Linux");
}
Q_ASSERT(false);
return QString();
}
MaemoGlobal::PackagingSystem MaemoGlobal::packagingSystem(MaemoVersion maemoVersion)
MaemoGlobal::PackagingSystem MaemoGlobal::packagingSystem(OsVersion osVersion)
{
return maemoVersion == Meego ? Rpm : Dpkg;
switch (osVersion) {
case Maemo5: case Maemo6: return Dpkg;
case Meego: return Rpm;
case GenericLinux: return Tar;
default: qFatal("%s: Missing case in switch.", Q_FUNC_INFO);
}
return static_cast<PackagingSystem>(-1);
}
MaemoGlobal::FileUpdate::FileUpdate(const QString &fileName)

View File

@@ -36,6 +36,7 @@
#include <utils/environment.h>
#include <projectexplorer/buildstep.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/deployconfiguration.h>
@@ -47,6 +48,7 @@
MaemoGlobal::assertState<State>(expected, actual, Q_FUNC_INFO)
QT_BEGIN_NAMESPACE
class QDateTime;
class QProcess;
class QString;
QT_END_NAMESPACE
@@ -61,8 +63,8 @@ class MaemoGlobal
{
Q_DECLARE_TR_FUNCTIONS(Qt4ProjectManager::Internal::MaemoGlobal)
public:
enum MaemoVersion { Maemo5, Maemo6, Meego };
enum PackagingSystem { Dpkg, Rpm };
enum OsVersion { Maemo5, Maemo6, Meego, GenericLinux };
enum PackagingSystem { Dpkg, Rpm, Tar };
class FileUpdate {
public:
@@ -73,6 +75,9 @@ public:
};
static bool isMaemoTargetId(const QString &id);
static bool isFremantleTargetId(const QString &id);
static bool isHarmattanTargetId(const QString &id);
static bool isMeegoTargetId(const QString &id);
static bool isValidMaemo5QtVersion(const Qt4ProjectManager::QtVersion *version);
static bool isValidHarmattanQtVersion(const Qt4ProjectManager::QtVersion *version);
static bool isValidMeegoQtVersion(const Qt4ProjectManager::QtVersion *version);
@@ -90,7 +95,7 @@ public:
static QString targetRoot(const QtVersion *qtVersion);
static QString targetName(const QtVersion *qtVersion);
static QString madCommand(const QtVersion *qtVersion);
static MaemoVersion version(const QtVersion *qtVersion);
static OsVersion version(const QtVersion *qtVersion);
// TODO: IS this still needed with Qt Version having an Abi?
static QString architecture(const QtVersion *version);
@@ -99,21 +104,23 @@ public:
static bool callMadAdmin(QProcess &proc, const QStringList &args,
const QtVersion *qtVersion, bool useTarget);
static QString maemoVersionToString(MaemoVersion version);
static QString osVersionToString(OsVersion version);
static PackagingSystem packagingSystem(MaemoVersion maemoVersion);
static PackagingSystem packagingSystem(OsVersion osVersion);
static bool removeRecursively(const QString &filePath, QString &error);
template<class T> static T *buildStep(const ProjectExplorer::DeployConfiguration *dc)
static bool isFileNewerThan(const QString &filePath,
const QDateTime &timeStamp);
template<class T> static T *earlierBuildStep(const ProjectExplorer::DeployConfiguration *dc,
const ProjectExplorer::BuildStep *laterBuildStep)
{
if (!dc)
return 0;
ProjectExplorer::BuildStepList *bsl = dc->stepList();
if (!bsl)
return 0;
const ProjectExplorer::BuildStepList * const bsl = dc->stepList();
const QList<ProjectExplorer::BuildStep *> &buildSteps = bsl->steps();
for (int i = buildSteps.count() - 1; i >= 0; --i) {
for (int i = 0; i < buildSteps.count(); ++i) {
if (buildSteps.at(i) == laterBuildStep)
return 0;
if (T * const step = qobject_cast<T *>(buildSteps.at(i)))
return step;
}
@@ -137,7 +144,7 @@ public:
private:
static bool isValidMaemoQtVersion(const Qt4ProjectManager::QtVersion *qtVersion,
MaemoVersion maemoVersion);
OsVersion maemoVersion);
static QString madAdminCommand(const QtVersion *qtVersion);
static bool callMaddeShellScript(QProcess &proc, const QtVersion *qtVersion,
const QString &command, const QStringList &args, bool useTarget);

View File

@@ -0,0 +1,327 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "maemoinstalltosysrootstep.h"
#include "maemodeployables.h"
#include "maemoglobal.h"
#include "maemopackagecreationstep.h"
#include "maemotoolchain.h"
#include "qt4maemodeployconfiguration.h"
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4target.h>
#include <QtCore/QLatin1Char>
#include <QtCore/QProcess>
using namespace ProjectExplorer;
namespace Qt4ProjectManager {
namespace Internal {
class AbstractMaemoInstallPackageToSysrootWidget : public BuildStepConfigWidget
{
Q_OBJECT
public:
AbstractMaemoInstallPackageToSysrootWidget(AbstractMaemoInstallPackageToSysrootStep *step)
: m_step(step) {}
virtual void init()
{
ProjectExplorer::BuildStepList * const list
= qobject_cast<BuildStepList *>(m_step->parent());
connect(list, SIGNAL(stepInserted(int)), SIGNAL(updateSummary()));
connect(list, SIGNAL(stepMoved(int,int)), SIGNAL(updateSummary()));
connect(list, SIGNAL(stepRemoved(int)), SIGNAL(updateSummary()));
}
virtual QString summaryText() const
{
if (!MaemoGlobal::earlierBuildStep<AbstractMaemoPackageCreationStep>(m_step->deployConfiguration(), m_step)) {
return QLatin1String("<font color=\"red\">")
+ tr("Cannot deploy to sysroot: No packaging step found.")
+ QLatin1String("</font>");
}
return QLatin1String("<b>") + displayName() + QLatin1String("</b>");
}
private:
const AbstractMaemoInstallPackageToSysrootStep * const m_step;
};
class MaemoInstallDebianPackageToSysrootWidget : public AbstractMaemoInstallPackageToSysrootWidget
{
Q_OBJECT
public:
MaemoInstallDebianPackageToSysrootWidget(AbstractMaemoInstallPackageToSysrootStep *step)
: AbstractMaemoInstallPackageToSysrootWidget(step) {}
virtual QString displayName() const { return MaemoInstallDebianPackageToSysrootStep::DisplayName; }
};
class MaemoInstallRpmPackageToSysrootWidget : public AbstractMaemoInstallPackageToSysrootWidget
{
Q_OBJECT
public:
MaemoInstallRpmPackageToSysrootWidget(AbstractMaemoInstallPackageToSysrootStep *step)
: AbstractMaemoInstallPackageToSysrootWidget(step) {}
virtual QString displayName() const { return MaemoInstallRpmPackageToSysrootStep::DisplayName; }
};
class MaemoCopyFilesToSysrootWidget : public BuildStepConfigWidget
{
Q_OBJECT
public:
virtual void init() { }
virtual QString summaryText() const {
return QLatin1String("<b>") + displayName() + QLatin1String("</b>"); }
virtual QString displayName() const { return MaemoCopyToSysrootStep::DisplayName; }
};
AbstractMaemoInstallPackageToSysrootStep::AbstractMaemoInstallPackageToSysrootStep(BuildStepList *bsl,
const QString &id)
: BuildStep(bsl, id)
{
}
AbstractMaemoInstallPackageToSysrootStep::AbstractMaemoInstallPackageToSysrootStep(BuildStepList *bsl,
AbstractMaemoInstallPackageToSysrootStep *other)
: BuildStep(bsl, other)
{
}
void AbstractMaemoInstallPackageToSysrootStep::run(QFutureInterface<bool> &fi)
{
const Qt4BuildConfiguration * const bc
= qobject_cast<Qt4BaseTarget *>(target())->activeBuildConfiguration();
if (!bc) {
addOutput(tr("Can't install to sysroot without build configuration."),
ErrorMessageOutput);
fi.reportResult(false);
return;
}
const AbstractMaemoPackageCreationStep * const pStep
= MaemoGlobal::earlierBuildStep<AbstractMaemoPackageCreationStep>(deployConfiguration(), this);
if (!pStep) {
addOutput(tr("Can't install package to sysroot without packaging step."),
ErrorMessageOutput);
fi.reportResult(false);
return;
}
m_installerProcess = new QProcess;
connect(m_installerProcess, SIGNAL(readyReadStandardOutput()),
SLOT(handleInstallerStdout()));
connect(m_installerProcess, SIGNAL(readyReadStandardError()),
SLOT(handleInstallerStderr()));
emit addOutput(tr("Installing package to sysroot ..."), MessageOutput);
const QtVersion * const qtVersion = bc->qtVersion();
const QString packageFilePath = pStep->packageFilePath();
const int packageFileSize = QFileInfo(packageFilePath).size() / (1024*1024);
const QStringList args = madArguments() << packageFilePath;
MaemoGlobal::callMadAdmin(*m_installerProcess, args, qtVersion, true);
if (!m_installerProcess->waitForFinished((2*packageFileSize + 10)*1000)
|| m_installerProcess->exitStatus() != QProcess::NormalExit
|| m_installerProcess->exitCode() != 0) {
emit addOutput(tr("Installation to sysroot failed, continuing anyway."),
ErrorMessageOutput);
if (m_installerProcess->state() != QProcess::NotRunning) {
m_installerProcess->terminate();
m_installerProcess->waitForFinished();
m_installerProcess->kill();
}
fi.reportResult(true);
return;
}
fi.reportResult(true);
m_installerProcess->deleteLater();
m_installerProcess = 0;
}
void AbstractMaemoInstallPackageToSysrootStep::handleInstallerStdout()
{
if (m_installerProcess)
emit addOutput(QString::fromLocal8Bit(m_installerProcess->readAllStandardOutput()), NormalOutput);
}
void AbstractMaemoInstallPackageToSysrootStep::handleInstallerStderr()
{
if (m_installerProcess)
emit addOutput(QString::fromLocal8Bit(m_installerProcess->readAllStandardError()), ErrorOutput);
}
MaemoInstallDebianPackageToSysrootStep::MaemoInstallDebianPackageToSysrootStep(BuildStepList *bsl)
: AbstractMaemoInstallPackageToSysrootStep(bsl, Id)
{
setDisplayName(DisplayName);
}
MaemoInstallDebianPackageToSysrootStep::MaemoInstallDebianPackageToSysrootStep(BuildStepList *bsl,
MaemoInstallDebianPackageToSysrootStep *other)
: AbstractMaemoInstallPackageToSysrootStep(bsl, other)
{
setDisplayName(DisplayName);
}
BuildStepConfigWidget *MaemoInstallDebianPackageToSysrootStep::createConfigWidget()
{
return new MaemoInstallDebianPackageToSysrootWidget(this);
}
QStringList MaemoInstallDebianPackageToSysrootStep::madArguments() const
{
return QStringList() << QLatin1String("xdpkg") << QLatin1String("-i")
<< QLatin1String("--no-force-downgrade");
}
const QString MaemoInstallDebianPackageToSysrootStep::Id
= QLatin1String("MaemoInstallDebianPackageToSysrootStep");
const QString MaemoInstallDebianPackageToSysrootStep::DisplayName
= tr("Install Debian package to sysroot");
MaemoInstallRpmPackageToSysrootStep::MaemoInstallRpmPackageToSysrootStep(BuildStepList *bsl)
: AbstractMaemoInstallPackageToSysrootStep(bsl, Id)
{
setDisplayName(DisplayName);
}
MaemoInstallRpmPackageToSysrootStep::MaemoInstallRpmPackageToSysrootStep(BuildStepList *bsl,
MaemoInstallRpmPackageToSysrootStep *other)
: AbstractMaemoInstallPackageToSysrootStep(bsl, other)
{
setDisplayName(DisplayName);
}
BuildStepConfigWidget *MaemoInstallRpmPackageToSysrootStep::createConfigWidget()
{
return new MaemoInstallRpmPackageToSysrootWidget(this);
}
QStringList MaemoInstallRpmPackageToSysrootStep::madArguments() const
{
return QStringList() << QLatin1String("xrpm") << QLatin1String("-i");
}
const QString MaemoInstallRpmPackageToSysrootStep::Id
= QLatin1String("MaemoInstallRpmPackageToSysrootStep");
const QString MaemoInstallRpmPackageToSysrootStep::DisplayName
= tr("Install RPM package to sysroot");
MaemoCopyToSysrootStep::MaemoCopyToSysrootStep(BuildStepList *bsl)
: BuildStep(bsl, Id)
{
setDisplayName(DisplayName);
}
MaemoCopyToSysrootStep::MaemoCopyToSysrootStep(BuildStepList *bsl,
MaemoCopyToSysrootStep *other)
: BuildStep(bsl, other)
{
setDisplayName(DisplayName);
}
void MaemoCopyToSysrootStep::run(QFutureInterface<bool> &fi)
{
const Qt4BuildConfiguration * const bc
= qobject_cast<Qt4BaseTarget *>(target())->activeBuildConfiguration();
if (!bc) {
addOutput(tr("Can't copy to sysroot without build configuration."),
ErrorMessageOutput);
fi.reportResult(false);
return;
}
const MaemoToolChain * const tc
= dynamic_cast<MaemoToolChain *>(bc->toolChain());
if (!tc) {
addOutput(tr("Can't copy to sysroot without toolchain."),
ErrorMessageOutput);
fi.reportResult(false);
return;
}
emit addOutput(tr("Copying files to sysroot ..."), MessageOutput);
QDir sysRootDir(tc->sysroot());
const QSharedPointer<MaemoDeployables> deployables
= qobject_cast<Qt4MaemoDeployConfiguration *>(deployConfiguration())->deployables();
const QChar sep = QLatin1Char('/');
for (int i = 0; i < deployables->deployableCount(); ++i) {
const MaemoDeployable &deployable = deployables->deployableAt(i);
const QFileInfo localFileInfo(deployable.localFilePath);
const QString targetFilePath = tc->sysroot() + sep
+ deployable.remoteDir + sep + localFileInfo.fileName();
if (QFileInfo(targetFilePath).exists()
&& MaemoGlobal::isFileNewerThan(targetFilePath, localFileInfo.lastModified())) {
continue;
}
sysRootDir.mkpath(deployable.remoteDir.mid(1));
QFile::remove(targetFilePath);
if (!QFile::copy(deployable.localFilePath, targetFilePath)) {
emit addOutput(tr("Sysroot installation failed: "
"Could not copy '%1' to '%2'. Continuing anyway.")
.arg(QDir::toNativeSeparators(deployable.localFilePath),
QDir::toNativeSeparators(targetFilePath)),
ErrorMessageOutput);
}
QCoreApplication::processEvents();
if (fi.isCanceled()) {
fi.reportResult(false);
return;
}
}
fi.reportResult(true);
}
BuildStepConfigWidget *MaemoCopyToSysrootStep::createConfigWidget()
{
return new MaemoCopyFilesToSysrootWidget;
}
const QString MaemoCopyToSysrootStep::Id
= QLatin1String("MaemoCopyToSysrootStep");
const QString MaemoCopyToSysrootStep::DisplayName
= tr("Copy files to sysroot");
} // namespace Internal
} // namespace Qt4ProjectManager
#include "maemoinstalltosysrootstep.moc"

View File

@@ -0,0 +1,120 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef MAEMOINSTALLTOSYSROOTSTEP_H
#define MAEMOINSTALLTOSYSROOTSTEP_H
#include <projectexplorer/buildstep.h>
#include <QtCore/QStringList>
QT_FORWARD_DECLARE_CLASS(QProcess);
namespace Qt4ProjectManager {
namespace Internal {
class AbstractMaemoInstallPackageToSysrootStep : public ProjectExplorer::BuildStep
{
Q_OBJECT
public:
virtual bool init() { return true; }
virtual void run(QFutureInterface<bool> &fi);
protected:
AbstractMaemoInstallPackageToSysrootStep(ProjectExplorer::BuildStepList *bsl,
const QString &id);
AbstractMaemoInstallPackageToSysrootStep(ProjectExplorer::BuildStepList *bsl,
AbstractMaemoInstallPackageToSysrootStep *other);
private slots:
void handleInstallerStdout();
void handleInstallerStderr();
private:
virtual QStringList madArguments() const=0;
QProcess *m_installerProcess;
};
class MaemoInstallDebianPackageToSysrootStep : public AbstractMaemoInstallPackageToSysrootStep
{
Q_OBJECT
public:
explicit MaemoInstallDebianPackageToSysrootStep(ProjectExplorer::BuildStepList *bsl);
MaemoInstallDebianPackageToSysrootStep(ProjectExplorer::BuildStepList *bsl,
MaemoInstallDebianPackageToSysrootStep *other);
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
static const QString Id;
static const QString DisplayName;
private:
virtual QStringList madArguments() const;
};
class MaemoInstallRpmPackageToSysrootStep : public AbstractMaemoInstallPackageToSysrootStep
{
Q_OBJECT
public:
explicit MaemoInstallRpmPackageToSysrootStep(ProjectExplorer::BuildStepList *bsl);
MaemoInstallRpmPackageToSysrootStep(ProjectExplorer::BuildStepList *bsl,
MaemoInstallRpmPackageToSysrootStep *other);
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
static const QString Id;
static const QString DisplayName;
private:
virtual QStringList madArguments() const;
};
class MaemoCopyToSysrootStep : public ProjectExplorer::BuildStep
{
Q_OBJECT
public:
explicit MaemoCopyToSysrootStep(ProjectExplorer::BuildStepList *bsl);
MaemoCopyToSysrootStep(ProjectExplorer::BuildStepList *bsl,
MaemoCopyToSysrootStep *other);
virtual bool init() { return true; }
virtual void run(QFutureInterface<bool> &fi);
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
static const QString Id;
static const QString DisplayName;
private:
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // MAEMOINSTALLTOSYSROOTSTEP_H

View File

@@ -34,6 +34,7 @@
#include "maemomanager.h"
#include "maemoconstants.h"
#include "maemodeployable.h"
#include "maemodeploystepfactory.h"
#include "maemodeviceconfigurations.h"
#include "maemoglobal.h"
@@ -43,6 +44,7 @@
#include "maemorunfactories.h"
#include "maemosettingspages.h"
#include "maemotoolchain.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotargetfactory.h"
#include "qt4projectmanager/qtversionmanager.h"
#include "qt4projectmanager/qt4projectmanagerconstants.h"
@@ -65,6 +67,7 @@ MaemoManager::MaemoManager()
: QObject(0)
, m_runControlFactory(new MaemoRunControlFactory(this))
, m_runConfigurationFactory(new MaemoRunConfigurationFactory(this))
, m_deployConfigurationFactory(new Qt4MaemoDeployConfigurationFactory(this))
, m_packageCreationFactory(new MaemoPackageCreationFactory(this))
, m_deployStepFactory(new MaemoDeployStepFactory(this))
, m_deviceConfigurationsSettingsPage(new MaemoDeviceConfigurationsSettingsPage(this))
@@ -83,12 +86,15 @@ MaemoManager::MaemoManager()
pluginManager->addObject(m_toolChainFactory);
pluginManager->addObject(m_runControlFactory);
pluginManager->addObject(m_runConfigurationFactory);
pluginManager->addObject(m_deployConfigurationFactory);
pluginManager->addObject(m_packageCreationFactory);
pluginManager->addObject(m_deployStepFactory);
pluginManager->addObject(m_deviceConfigurationsSettingsPage);
pluginManager->addObject(m_qemuSettingsPage);
pluginManager->addObject(m_publishingFactoryFremantleFree);
pluginManager->addObject(m_maemoTargetFactory);
qRegisterMetaType<MaemoDeployable>("MaemoDeployable");
}
MaemoManager::~MaemoManager()
@@ -100,6 +106,7 @@ MaemoManager::~MaemoManager()
pluginManager->removeObject(m_deviceConfigurationsSettingsPage);
pluginManager->removeObject(m_deployStepFactory);
pluginManager->removeObject(m_packageCreationFactory);
pluginManager->removeObject(m_deployConfigurationFactory);
pluginManager->removeObject(m_runConfigurationFactory);
pluginManager->removeObject(m_runControlFactory);
pluginManager->removeObject(m_toolChainFactory);

View File

@@ -48,6 +48,7 @@ class MaemoRunConfigurationFactory;
class MaemoDeviceConfigurationsSettingsPage;
class MaemoQemuManager;
class MaemoQemuSettingsPage;
class Qt4MaemoDeployConfigurationFactory;
class Qt4MaemoTargetFactory;
class MaemoToolChainFactory;
@@ -68,6 +69,7 @@ private:
MaemoRunControlFactory *m_runControlFactory;
MaemoRunConfigurationFactory *m_runConfigurationFactory;
Qt4MaemoDeployConfigurationFactory *m_deployConfigurationFactory;
MaemoPackageCreationFactory *m_packageCreationFactory;
MaemoDeployStepFactory *m_deployStepFactory;
MaemoDeviceConfigurationsSettingsPage *m_deviceConfigurationsSettingsPage;

View File

@@ -43,6 +43,8 @@
#include "maemoglobal.h"
#include "maemopackagecreationstep.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildsteplist.h>
@@ -58,6 +60,9 @@ using ProjectExplorer::BuildStep;
namespace Qt4ProjectManager {
namespace Internal {
namespace {
const QString OldCreatePackageId("Qt4ProjectManager.MaemoPackageCreationStep");
} // anonymous namespace
MaemoPackageCreationFactory::MaemoPackageCreationFactory(QObject *parent)
: ProjectExplorer::IBuildStepFactory(parent)
@@ -66,47 +71,79 @@ MaemoPackageCreationFactory::MaemoPackageCreationFactory(QObject *parent)
QStringList MaemoPackageCreationFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const
{
if (parent->id() == QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)
&& MaemoGlobal::isMaemoTargetId(parent->target()->id())
&& !parent->contains(MaemoPackageCreationStep::CreatePackageId))
return QStringList() << MaemoPackageCreationStep::CreatePackageId;
if (!qobject_cast<Qt4MaemoDeployConfiguration *>(parent->parent()))
return QStringList();
if (qobject_cast<AbstractDebBasedQt4MaemoTarget *>(parent->target())
&& !parent->contains(MaemoDebianPackageCreationStep::CreatePackageId)) {
return QStringList() << MaemoDebianPackageCreationStep::CreatePackageId;
} else if (qobject_cast<AbstractRpmBasedQt4MaemoTarget *>(parent->target())
&& !parent->contains(MaemoRpmPackageCreationStep::CreatePackageId)) {
return QStringList() << MaemoRpmPackageCreationStep::CreatePackageId;
} else if (!parent->contains(MaemoTarPackageCreationStep::CreatePackageId)) {
return QStringList() << MaemoTarPackageCreationStep::CreatePackageId;
}
return QStringList();
}
QString MaemoPackageCreationFactory::displayNameForId(const QString &id) const
{
if (id == MaemoPackageCreationStep::CreatePackageId)
if (id == MaemoDebianPackageCreationStep::CreatePackageId) {
return QCoreApplication::translate("Qt4ProjectManager::Internal::MaemoPackageCreationFactory",
"Create Debian Package");
"Create Debian Package");
} else if (id == MaemoRpmPackageCreationStep::CreatePackageId) {
return QCoreApplication::translate("Qt4ProjectManager::Internal::MaemoPackageCreationFactory",
"Create RPM Package");
} else if (id == MaemoTarPackageCreationStep::CreatePackageId) {
return QCoreApplication::translate("Qt4ProjectManager::Internal::MaemoPackageCreationFactory",
"Create tarball");
}
return QString();
}
bool MaemoPackageCreationFactory::canCreate(ProjectExplorer::BuildStepList *parent, const QString &id) const
{
return parent->id() == QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)
&& id == QLatin1String(MaemoPackageCreationStep::CreatePackageId)
&& MaemoGlobal::isMaemoTargetId(parent->target()->id())
&& !parent->contains(MaemoPackageCreationStep::CreatePackageId);
return availableCreationIds(parent).contains(id);
}
BuildStep *MaemoPackageCreationFactory::create(ProjectExplorer::BuildStepList *parent, const QString &id)
{
Q_ASSERT(canCreate(parent, id));
return new MaemoPackageCreationStep(parent);
if (id == MaemoDebianPackageCreationStep::CreatePackageId)
return new MaemoDebianPackageCreationStep(parent);
else if (id == MaemoRpmPackageCreationStep::CreatePackageId)
return new MaemoRpmPackageCreationStep(parent);
else if (id == MaemoTarPackageCreationStep::CreatePackageId)
return new MaemoTarPackageCreationStep(parent);
return 0;
}
bool MaemoPackageCreationFactory::canRestore(ProjectExplorer::BuildStepList *parent,
const QVariantMap &map) const
{
return canCreate(parent, ProjectExplorer::idFromMap(map));
const QString id = ProjectExplorer::idFromMap(map);
return canCreate(parent, id) || id == OldCreatePackageId;
}
BuildStep *MaemoPackageCreationFactory::restore(ProjectExplorer::BuildStepList *parent,
const QVariantMap &map)
{
Q_ASSERT(canRestore(parent, map));
MaemoPackageCreationStep * const step
= new MaemoPackageCreationStep(parent);
BuildStep * step = 0;
const QString id = ProjectExplorer::idFromMap(map);
if (id == MaemoDebianPackageCreationStep::CreatePackageId
|| (id == OldCreatePackageId
&& qobject_cast<AbstractDebBasedQt4MaemoTarget *>(parent->target()))) {
step = new MaemoDebianPackageCreationStep(parent);
} else if (id == MaemoRpmPackageCreationStep::CreatePackageId
|| (id == OldCreatePackageId
&& qobject_cast<AbstractRpmBasedQt4MaemoTarget *>(parent->target()))) {
step = new MaemoRpmPackageCreationStep(parent);
} else if (id == MaemoTarPackageCreationStep::CreatePackageId) {
step = new MaemoTarPackageCreationStep(parent);
}
Q_ASSERT(step);
if (!step->fromMap(map)) {
delete step;
return 0;
@@ -124,7 +161,20 @@ BuildStep *MaemoPackageCreationFactory::clone(ProjectExplorer::BuildStepList *pa
ProjectExplorer::BuildStep *product)
{
Q_ASSERT(canClone(parent, product));
return new MaemoPackageCreationStep(parent, static_cast<MaemoPackageCreationStep *>(product));
MaemoDebianPackageCreationStep * const debianStep
= qobject_cast<MaemoDebianPackageCreationStep *>(product);
if (debianStep) {
return new MaemoDebianPackageCreationStep(parent, debianStep);
} else {
MaemoRpmPackageCreationStep * const rpmStep
= qobject_cast<MaemoRpmPackageCreationStep *>(product);
if (rpmStep) {
return new MaemoRpmPackageCreationStep(parent, rpmStep);
} else {
return new MaemoTarPackageCreationStep(parent,
qobject_cast<MaemoTarPackageCreationStep *>(product));
}
}
}
} // namespace Internal

View File

@@ -43,9 +43,9 @@
#include "maemoconstants.h"
#include "maemodeployables.h"
#include "maemodeploystep.h"
#include "maemoglobal.h"
#include "maemopackagecreationwidget.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include <projectexplorer/buildsteplist.h>
@@ -62,7 +62,6 @@
#include <QtGui/QWidget>
namespace {
const QLatin1String PackagingEnabledKey("Packaging Enabled");
const QLatin1String MagicFileName(".qtcreator");
}
@@ -74,31 +73,27 @@ using ProjectExplorer::Task;
namespace Qt4ProjectManager {
namespace Internal {
const QLatin1String MaemoPackageCreationStep::DefaultVersionNumber("0.0.1");
const QLatin1String AbstractMaemoPackageCreationStep::DefaultVersionNumber("0.0.1");
MaemoPackageCreationStep::MaemoPackageCreationStep(BuildStepList *bsl)
: ProjectExplorer::BuildStep(bsl, CreatePackageId),
m_packagingEnabled(true)
AbstractMaemoPackageCreationStep::AbstractMaemoPackageCreationStep(BuildStepList *bsl,
const QString &id)
: ProjectExplorer::BuildStep(bsl, id)
{
ctor();
}
MaemoPackageCreationStep::MaemoPackageCreationStep(BuildStepList *bsl,
MaemoPackageCreationStep *other)
: BuildStep(bsl, other),
m_packagingEnabled(other->m_packagingEnabled)
AbstractMaemoPackageCreationStep::AbstractMaemoPackageCreationStep(BuildStepList *bsl,
AbstractMaemoPackageCreationStep *other) : BuildStep(bsl, other)
{
ctor();
}
MaemoPackageCreationStep::~MaemoPackageCreationStep()
AbstractMaemoPackageCreationStep::~AbstractMaemoPackageCreationStep()
{
}
void MaemoPackageCreationStep::ctor()
void AbstractMaemoPackageCreationStep::ctor()
{
setDefaultDisplayName(tr("Packaging for Maemo"));
m_lastBuildConfig = qt4BuildConfiguration();
connect(target(),
SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
@@ -106,144 +101,278 @@ void MaemoPackageCreationStep::ctor()
handleBuildConfigChanged();
}
bool MaemoPackageCreationStep::init()
bool AbstractMaemoPackageCreationStep::init()
{
return true;
}
QVariantMap MaemoPackageCreationStep::toMap() const
void AbstractMaemoPackageCreationStep::run(QFutureInterface<bool> &fi)
{
QVariantMap map(ProjectExplorer::BuildStep::toMap());
map.insert(PackagingEnabledKey, m_packagingEnabled);
return map;
}
if (!packagingNeeded()) {
emit addOutput(tr("Package up to date."), MessageOutput);
fi.reportResult(true);
return;
}
bool MaemoPackageCreationStep::fromMap(const QVariantMap &map)
{
m_packagingEnabled = map.value(PackagingEnabledKey, true).toBool();
return ProjectExplorer::BuildStep::fromMap(map);
}
void MaemoPackageCreationStep::run(QFutureInterface<bool> &fi)
{
bool success;
if (m_packagingEnabled) {
// TODO: Make the build process asynchronous; i.e. no waitFor()-functions etc.
QProcess * const buildProc = new QProcess;
connect(buildProc, SIGNAL(readyReadStandardOutput()), this,
SLOT(handleBuildOutput()));
connect(buildProc, SIGNAL(readyReadStandardError()), this,
SLOT(handleBuildOutput()));
success = createPackage(buildProc);
disconnect(buildProc, 0, this, 0);
buildProc->deleteLater();
} else {
success = true;
// TODO: Make the build process asynchronous; i.e. no waitFor()-functions etc.
QProcess * const buildProc = new QProcess;
connect(buildProc, SIGNAL(readyReadStandardOutput()), this,
SLOT(handleBuildOutput()));
connect(buildProc, SIGNAL(readyReadStandardError()), this,
SLOT(handleBuildOutput()));
emit addOutput(tr("Creating package file ..."), MessageOutput);
const bool success = createPackage(buildProc);
disconnect(buildProc, 0, this, 0);
buildProc->deleteLater();
if (success) {
emit addOutput(tr("Package created."), BuildStep::MessageOutput);
deployConfig()->deployables()->setUnmodified();
}
fi.reportResult(success);
}
BuildStepConfigWidget *MaemoPackageCreationStep::createConfigWidget()
BuildStepConfigWidget *AbstractMaemoPackageCreationStep::createConfigWidget()
{
return new MaemoPackageCreationWidget(this);
}
bool MaemoPackageCreationStep::createPackage(QProcess *buildProc)
void AbstractMaemoPackageCreationStep::handleBuildOutput()
{
if (!packagingNeeded()) {
emit addOutput(tr("Package up to date."), MessageOutput);
QProcess * const buildProc = qobject_cast<QProcess *>(sender());
if (!buildProc)
return;
const QByteArray &stdOut = buildProc->readAllStandardOutput();
if (!stdOut.isEmpty())
emit addOutput(QString::fromLocal8Bit(stdOut), BuildStep::NormalOutput);
const QByteArray &errorOut = buildProc->readAllStandardError();
if (!errorOut.isEmpty()) {
emit addOutput(QString::fromLocal8Bit(errorOut), BuildStep::ErrorOutput);
}
}
void AbstractMaemoPackageCreationStep::handleBuildConfigChanged()
{
if (m_lastBuildConfig)
disconnect(m_lastBuildConfig, 0, this, 0);
m_lastBuildConfig = qt4BuildConfiguration();
connect(m_lastBuildConfig, SIGNAL(qtVersionChanged()), this,
SIGNAL(qtVersionChanged()));
connect(m_lastBuildConfig, SIGNAL(buildDirectoryChanged()), this,
SIGNAL(packageFilePathChanged()));
emit qtVersionChanged();
emit packageFilePathChanged();
}
const Qt4BuildConfiguration *AbstractMaemoPackageCreationStep::qt4BuildConfiguration() const
{
return static_cast<Qt4BuildConfiguration *>(buildConfiguration());
}
AbstractQt4MaemoTarget *AbstractMaemoPackageCreationStep::maemoTarget() const
{
return qobject_cast<AbstractQt4MaemoTarget *>(buildConfiguration()->target());
}
AbstractDebBasedQt4MaemoTarget *AbstractMaemoPackageCreationStep::debBasedMaemoTarget() const
{
return qobject_cast<AbstractDebBasedQt4MaemoTarget*>(buildConfiguration()->target());
}
AbstractRpmBasedQt4MaemoTarget *AbstractMaemoPackageCreationStep::rpmBasedMaemoTarget() const
{
return qobject_cast<AbstractRpmBasedQt4MaemoTarget*>(buildConfiguration()->target());
}
Qt4MaemoDeployConfiguration *AbstractMaemoPackageCreationStep::deployConfig() const
{
return qobject_cast<Qt4MaemoDeployConfiguration *>(parent()->parent());
}
QString AbstractMaemoPackageCreationStep::buildDirectory() const
{
return qt4BuildConfiguration()->buildDirectory();
}
QString AbstractMaemoPackageCreationStep::projectName() const
{
return qt4BuildConfiguration()->qt4Target()->qt4Project()
->rootProjectNode()->displayName().toLower();
}
bool AbstractMaemoPackageCreationStep::packagingNeeded() const
{
const QSharedPointer<MaemoDeployables> &deployables
= deployConfig()->deployables();
QFileInfo packageInfo(packageFilePath());
if (!packageInfo.exists() || deployables->isModified())
return true;
const int deployableCount = deployables->deployableCount();
for (int i = 0; i < deployableCount; ++i) {
if (MaemoGlobal::isFileNewerThan(deployables->deployableAt(i).localFilePath,
packageInfo.lastModified()))
return true;
}
emit addOutput(tr("Creating package file ..."), MessageOutput);
checkProjectName();
preparePackagingProcess(buildProc, qt4BuildConfiguration(),
buildDirectory());
return isMetaDataNewerThan(packageInfo.lastModified());
}
QString AbstractMaemoPackageCreationStep::packageFilePath() const
{
QString error;
const QString &version = versionString(&error);
if (version.isEmpty())
return QString();
QFileInfo fi(maemoTarget()->packageFileName());
const QString baseName = replaceDots(fi.completeBaseName());
return buildDirectory() + QLatin1Char('/') + baseName
+ QLatin1Char('.') + fi.suffix();
}
QString AbstractMaemoPackageCreationStep::versionString(QString *error) const
{
return maemoTarget()->projectVersion(error);
}
bool AbstractMaemoPackageCreationStep::setVersionString(const QString &version,
QString *error)
{
const bool success = maemoTarget()->setProjectVersion(version, error);
if (success)
emit packageFilePathChanged();
return success;
}
QString AbstractMaemoPackageCreationStep::nativePath(const QFile &file)
{
return QDir::toNativeSeparators(QFileInfo(file).filePath());
}
void AbstractMaemoPackageCreationStep::raiseError(const QString &shortMsg,
const QString &detailedMsg)
{
emit addOutput(detailedMsg.isNull() ? shortMsg : detailedMsg, BuildStep::ErrorOutput);
emit addTask(Task(Task::Error, shortMsg, QString(), -1,
TASK_CATEGORY_BUILDSYSTEM));
}
bool AbstractMaemoPackageCreationStep::callPackagingCommand(QProcess *proc,
const QStringList &arguments)
{
preparePackagingProcess(proc, qt4BuildConfiguration(), buildDirectory());
const QtVersion * const qtVersion = qt4BuildConfiguration()->qtVersion();
const QString madCommand = MaemoGlobal::madCommand(qtVersion);
const QString cmdLine = madCommand + QLatin1Char(' ')
+ arguments.join(QLatin1String(" "));
emit addOutput(tr("Package Creation: Running command '%1'.").arg(cmdLine),
BuildStep::MessageOutput);
MaemoGlobal::callMad(*proc, arguments, qtVersion, true);
if (!proc->waitForStarted()) {
raiseError(tr("Packaging failed."),
tr("Packaging error: Could not start command '%1'. Reason: %2")
.arg(cmdLine, proc->errorString()));
return false;
}
proc->waitForFinished(-1);
if (proc->error() != QProcess::UnknownError || proc->exitCode() != 0) {
QString mainMessage = tr("Packaging Error: Command '%1' failed.")
.arg(cmdLine);
if (proc->error() != QProcess::UnknownError)
mainMessage += tr(" Reason: %1").arg(proc->errorString());
else
mainMessage += tr("Exit code: %1").arg(proc->exitCode());
raiseError(mainMessage);
return false;
}
return true;
}
void AbstractMaemoPackageCreationStep::preparePackagingProcess(QProcess *proc,
const Qt4BuildConfiguration *bc, const QString &workingDir)
{
Utils::Environment env = bc->environment();
if (bc->qmakeBuildConfiguration() & QtVersion::DebugBuild) {
env.appendOrSet(QLatin1String("DEB_BUILD_OPTIONS"),
QLatin1String("nostrip"), QLatin1String(" "));
}
proc->setEnvironment(env.toStringList());
proc->setWorkingDirectory(workingDir);
}
QString AbstractMaemoPackageCreationStep::replaceDots(const QString &name)
{
QString adaptedName = name;
return adaptedName.replace(QLatin1Char('.'), QLatin1Char('_'));
}
MaemoDebianPackageCreationStep::MaemoDebianPackageCreationStep(BuildStepList *bsl)
: AbstractMaemoPackageCreationStep(bsl, CreatePackageId)
{
ctor();
}
const QString MaemoDebianPackageCreationStep::CreatePackageId
= QLatin1String("MaemoDebianPackageCreationStep");
MaemoDebianPackageCreationStep::MaemoDebianPackageCreationStep(BuildStepList *buildConfig,
MaemoDebianPackageCreationStep *other)
: AbstractMaemoPackageCreationStep(buildConfig, other)
{
ctor();
}
void MaemoDebianPackageCreationStep::ctor()
{
setDefaultDisplayName(tr("Create Debian Package"));
}
bool MaemoDebianPackageCreationStep::createPackage(QProcess *buildProc)
{
checkProjectName();
const QString projectDir
= buildConfiguration()->target()->project()->projectDirectory();
const bool inSourceBuild
= QFileInfo(buildDirectory()) == QFileInfo(projectDir);
if (debBasedMaemoTarget() && !copyDebianFiles(inSourceBuild))
if (!copyDebianFiles(inSourceBuild))
return false;
const QtVersion * const qtVersion = qt4BuildConfiguration()->qtVersion();
const QString madCommand = MaemoGlobal::madCommand(qtVersion);
QStringList args;
if (debBasedMaemoTarget()) {
args << QLatin1String("dpkg-buildpackage") << QLatin1String("-nc")
<< QLatin1String("-uc") << QLatin1String("-us");
} else {
args << QLatin1String("rrpmbuild") << QLatin1String("-bb")
<< rpmBasedMaemoTarget()->specFilePath();
}
const QString cmdLine = madCommand + QLatin1Char(' ')
+ args.join(QLatin1String(" "));
emit addOutput(tr("Package Creation: Running command '%1'.").arg(cmdLine),
BuildStep::MessageOutput);
MaemoGlobal::callMad(*buildProc, args, qtVersion, true);
if (!buildProc->waitForStarted()) {
raiseError(tr("Packaging failed."),
tr("Packaging error: Could not start command '%1'. Reason: %2")
.arg(cmdLine, buildProc->errorString()));
const QStringList args = QStringList() << QLatin1String("dpkg-buildpackage")
<< QLatin1String("-nc") << QLatin1String("-uc") << QLatin1String("-us");
if (!callPackagingCommand(buildProc, args))
return false;
}
buildProc->waitForFinished(-1);
if (buildProc->error() != QProcess::UnknownError
|| buildProc->exitCode() != 0) {
QString mainMessage = tr("Packaging Error: Command '%1' failed.")
.arg(cmdLine);
if (buildProc->error() != QProcess::UnknownError)
mainMessage += tr(" Reason: %1").arg(buildProc->errorString());
else
mainMessage += tr("Exit code: %1").arg(buildProc->exitCode());
raiseError(mainMessage);
return false;
}
QFile::remove(packageFilePath());
if (debBasedMaemoTarget()) {
// Workaround for non-working dh_builddeb --destdir=.
if (!QDir(buildDirectory()).isRoot()) {
const AbstractQt4MaemoTarget * const target = maemoTarget();
QString error;
const QString pkgFileName = target->packageFileName();
if (!error.isEmpty())
raiseError(tr("Packaging failed."), "Failed to get package name.");
const QString changesSourceFileName = QFileInfo(pkgFileName).completeBaseName()
// Workaround for non-working dh_builddeb --destdir=.
if (!QDir(buildDirectory()).isRoot()) {
const AbstractQt4MaemoTarget * const target = maemoTarget();
QString error;
const QString pkgFileName = target->packageFileName();
if (!error.isEmpty())
raiseError(tr("Packaging failed."), "Failed to get package name.");
const QString changesSourceFileName = QFileInfo(pkgFileName).completeBaseName()
+ QLatin1String(".changes");
const QString changesTargetFileName = replaceDots(QFileInfo(pkgFileName).completeBaseName())
const QString changesTargetFileName = replaceDots(QFileInfo(pkgFileName).completeBaseName())
+ QLatin1String(".changes");
const QString packageSourceDir = buildDirectory() + QLatin1String("/../");
const QString packageSourceFilePath
const QString packageSourceDir = buildDirectory() + QLatin1String("/../");
const QString packageSourceFilePath
= packageSourceDir + pkgFileName;
const QString changesSourceFilePath
const QString changesSourceFilePath
= packageSourceDir + changesSourceFileName;
const QString changesTargetFilePath
const QString changesTargetFilePath
= buildDirectory() + QLatin1Char('/') + changesTargetFileName;
QFile::remove(changesTargetFilePath);
if (!QFile::rename(packageSourceFilePath, packageFilePath())
|| !QFile::rename(changesSourceFilePath, changesTargetFilePath)) {
raiseError(tr("Packaging failed."),
tr("Could not move package files from %1 to %2.")
.arg(packageSourceDir, buildDirectory()));
return false;
}
}
} else {
const QString packageSourceFilePath = rpmBuildDir(qt4BuildConfiguration())
+ QLatin1Char('/') + rpmBasedMaemoTarget()->packageFileName();
if (!QFile::rename(packageSourceFilePath, packageFilePath())) {
QFile::remove(changesTargetFilePath);
if (!QFile::rename(packageSourceFilePath, packageFilePath())
|| !QFile::rename(changesSourceFilePath, changesTargetFilePath)) {
raiseError(tr("Packaging failed."),
tr("Could not move package file from %1 to %2.")
.arg(packageSourceFilePath, packageFilePath()));
tr("Could not move package files from %1 to %2.")
.arg(packageSourceDir, buildDirectory()));
return false;
}
}
emit addOutput(tr("Package created."), BuildStep::MessageOutput);
deployStep()->deployables()->setUnmodified();
if (inSourceBuild && debBasedMaemoTarget()) {
if (inSourceBuild) {
buildProc->start(packagingCommand(qt4BuildConfiguration(),
QLatin1String("dh_clean")));
buildProc->waitForFinished();
@@ -252,7 +381,35 @@ bool MaemoPackageCreationStep::createPackage(QProcess *buildProc)
return true;
}
bool MaemoPackageCreationStep::copyDebianFiles(bool inSourceBuild)
bool MaemoDebianPackageCreationStep::isMetaDataNewerThan(const QDateTime &packageDate) const
{
const QString debianPath = debBasedMaemoTarget()->debianDirPath();
if (packageDate <= QFileInfo(debianPath).lastModified())
return true;
const QStringList debianFiles = debBasedMaemoTarget()->debianFiles();
foreach (const QString &debianFile, debianFiles) {
const QString absFilePath
= debianPath + QLatin1Char('/') + debianFile;
if (packageDate <= QFileInfo(absFilePath).lastModified())
return true;
}
return false;
}
void MaemoDebianPackageCreationStep::checkProjectName()
{
const QRegExp legalName(QLatin1String("[0-9-+a-z\\.]+"));
if (!legalName.exactMatch(buildConfiguration()->target()->project()->displayName())) {
emit addTask(Task(Task::Warning,
tr("Your project name contains characters not allowed in "
"Debian packages.\nThey must only use lower-case letters, "
"numbers, '-', '+' and '.'.\n""We will try to work around that, "
"but you may experience problems."),
QString(), -1, TASK_CATEGORY_BUILDSYSTEM));
}
}
bool MaemoDebianPackageCreationStep::copyDebianFiles(bool inSourceBuild)
{
const QString debianDirPath = buildDirectory() + QLatin1String("/debian");
const QString magicFilePath
@@ -308,185 +465,7 @@ bool MaemoPackageCreationStep::copyDebianFiles(bool inSourceBuild)
return true;
}
void MaemoPackageCreationStep::handleBuildOutput()
{
QProcess * const buildProc = qobject_cast<QProcess *>(sender());
if (!buildProc)
return;
const QByteArray &stdOut = buildProc->readAllStandardOutput();
if (!stdOut.isEmpty())
emit addOutput(QString::fromLocal8Bit(stdOut), BuildStep::NormalOutput);
const QByteArray &errorOut = buildProc->readAllStandardError();
if (!errorOut.isEmpty()) {
emit addOutput(QString::fromLocal8Bit(errorOut), BuildStep::ErrorOutput);
}
}
void MaemoPackageCreationStep::handleBuildConfigChanged()
{
if (m_lastBuildConfig)
disconnect(m_lastBuildConfig, 0, this, 0);
m_lastBuildConfig = qt4BuildConfiguration();
connect(m_lastBuildConfig, SIGNAL(qtVersionChanged()), this,
SIGNAL(qtVersionChanged()));
connect(m_lastBuildConfig, SIGNAL(buildDirectoryChanged()), this,
SIGNAL(packageFilePathChanged()));
emit qtVersionChanged();
emit packageFilePathChanged();
}
const Qt4BuildConfiguration *MaemoPackageCreationStep::qt4BuildConfiguration() const
{
return static_cast<Qt4BuildConfiguration *>(buildConfiguration());
}
AbstractQt4MaemoTarget *MaemoPackageCreationStep::maemoTarget() const
{
return qobject_cast<AbstractQt4MaemoTarget *>(buildConfiguration()->target());
}
AbstractDebBasedQt4MaemoTarget *MaemoPackageCreationStep::debBasedMaemoTarget() const
{
return qobject_cast<AbstractDebBasedQt4MaemoTarget*>(buildConfiguration()->target());
}
AbstractRpmBasedQt4MaemoTarget *MaemoPackageCreationStep::rpmBasedMaemoTarget() const
{
return qobject_cast<AbstractRpmBasedQt4MaemoTarget*>(buildConfiguration()->target());
}
QString MaemoPackageCreationStep::buildDirectory() const
{
return qt4BuildConfiguration()->buildDirectory();
}
QString MaemoPackageCreationStep::projectName() const
{
return qt4BuildConfiguration()->qt4Target()->qt4Project()
->rootProjectNode()->displayName().toLower();
}
MaemoDeployStep *MaemoPackageCreationStep::deployStep() const
{
MaemoDeployStep * const deployStep
= MaemoGlobal::buildStep<MaemoDeployStep>(target()->activeDeployConfiguration());
Q_ASSERT(deployStep &&
"Fatal error: Maemo build configuration without deploy step.");
return deployStep;
}
bool MaemoPackageCreationStep::packagingNeeded() const
{
const QSharedPointer<MaemoDeployables> &deployables
= deployStep()->deployables();
QFileInfo packageInfo(packageFilePath());
if (!packageInfo.exists() || deployables->isModified())
return true;
const int deployableCount = deployables->deployableCount();
for (int i = 0; i < deployableCount; ++i) {
if (isFileNewerThan(deployables->deployableAt(i).localFilePath,
packageInfo.lastModified()))
return true;
}
if (debBasedMaemoTarget()) {
const QString debianPath = debBasedMaemoTarget()->debianDirPath();
if (packageInfo.lastModified() <= QFileInfo(debianPath).lastModified())
return true;
const QStringList debianFiles = debBasedMaemoTarget()->debianFiles();
foreach (const QString &debianFile, debianFiles) {
const QString absFilePath
= debianPath + QLatin1Char('/') + debianFile;
if (packageInfo.lastModified() <= QFileInfo(absFilePath).lastModified())
return true;
}
} else {
const QDateTime specFileChangeDate
= QFileInfo(rpmBasedMaemoTarget()->specFilePath()).lastModified();
if (packageInfo.lastModified() <= specFileChangeDate)
return true;
}
return false;
}
bool MaemoPackageCreationStep::isFileNewerThan(const QString &filePath,
const QDateTime &timeStamp) const
{
QFileInfo fileInfo(filePath);
if (!fileInfo.exists() || fileInfo.lastModified() >= timeStamp)
return true;
if (fileInfo.isDir()) {
const QStringList dirContents = QDir(filePath)
.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
foreach (const QString &curFileName, dirContents) {
const QString curFilePath
= filePath + QLatin1Char('/') + curFileName;
if (isFileNewerThan(curFilePath, timeStamp))
return true;
}
}
return false;
}
QString MaemoPackageCreationStep::packageFilePath() const
{
QString error;
const QString &version = versionString(&error);
if (version.isEmpty())
return QString();
QFileInfo fi(maemoTarget()->packageFileName());
const QString baseName = replaceDots(fi.completeBaseName());
return buildDirectory() + QLatin1Char('/') + baseName
+ QLatin1Char('.') + fi.suffix();
}
bool MaemoPackageCreationStep::isPackagingEnabled() const
{
return m_packagingEnabled || !maemoTarget()->allowsPackagingDisabling();
}
QString MaemoPackageCreationStep::versionString(QString *error) const
{
return maemoTarget()->projectVersion(error);
}
bool MaemoPackageCreationStep::setVersionString(const QString &version,
QString *error)
{
const bool success = maemoTarget()->setProjectVersion(version, error);
if (success)
emit packageFilePathChanged();
return success;
}
QString MaemoPackageCreationStep::nativePath(const QFile &file)
{
return QDir::toNativeSeparators(QFileInfo(file).filePath());
}
void MaemoPackageCreationStep::raiseError(const QString &shortMsg,
const QString &detailedMsg)
{
emit addOutput(detailedMsg.isNull() ? shortMsg : detailedMsg, BuildStep::ErrorOutput);
emit addTask(Task(Task::Error, shortMsg, QString(), -1,
TASK_CATEGORY_BUILDSYSTEM));
}
void MaemoPackageCreationStep::preparePackagingProcess(QProcess *proc,
const Qt4BuildConfiguration *bc, const QString &workingDir)
{
Utils::Environment env = bc->environment();
if (bc->qmakeBuildConfiguration() & QtVersion::DebugBuild) {
env.appendOrSet(QLatin1String("DEB_BUILD_OPTIONS"),
QLatin1String("nostrip"), QLatin1String(" "));
}
proc->setEnvironment(env.toStringList());
proc->setWorkingDirectory(workingDir);
}
QString MaemoPackageCreationStep::packagingCommand(const Qt4BuildConfiguration *bc,
QString MaemoDebianPackageCreationStep::packagingCommand(const Qt4BuildConfiguration *bc,
const QString &commandName)
{
QString perl;
@@ -497,21 +476,7 @@ QString MaemoPackageCreationStep::packagingCommand(const Qt4BuildConfiguration *
return perl + maddeRoot % QLatin1String("/madbin/") % commandName;
}
void MaemoPackageCreationStep::checkProjectName()
{
if (debBasedMaemoTarget()) {
const QRegExp legalName(QLatin1String("[0-9-+a-z\\.]+"));
if (!legalName.exactMatch(buildConfiguration()->target()->project()->displayName())) {
emit addTask(Task(Task::Warning,
tr("Your project name contains characters not allowed in Debian packages.\n"
"They must only use lower-case letters, numbers, '-', '+' and '.'.\n"
"We will try to work around that, but you may experience problems."),
QString(), -1, TASK_CATEGORY_BUILDSYSTEM));
}
}
}
void MaemoPackageCreationStep::ensureShlibdeps(QByteArray &rulesContent)
void MaemoDebianPackageCreationStep::ensureShlibdeps(QByteArray &rulesContent)
{
QString contentAsString = QString::fromLocal8Bit(rulesContent);
const QString whiteSpace(QLatin1String("[ \\t]*"));
@@ -523,7 +488,7 @@ void MaemoPackageCreationStep::ensureShlibdeps(QByteArray &rulesContent)
rulesContent = contentAsString.toLocal8Bit();
}
void MaemoPackageCreationStep::adaptRulesFile(const QString &rulesFilePath)
void MaemoDebianPackageCreationStep::adaptRulesFile(const QString &rulesFilePath)
{
QFile rulesFile(rulesFilePath);
rulesFile.setPermissions(rulesFile.permissions() | QFile::ExeUser);
@@ -542,7 +507,7 @@ void MaemoPackageCreationStep::adaptRulesFile(const QString &rulesFilePath)
+ QLatin1Char('/') + projectName()
+ QLatin1String("/usr/share/applications/");
const Qt4BuildConfiguration * const bc = qt4BuildConfiguration();
const MaemoGlobal::MaemoVersion version
const MaemoGlobal::OsVersion version
= MaemoGlobal::version(bc->qtVersion());
if (version == MaemoGlobal::Maemo5)
desktopFileDir += QLatin1String("hildon/");
@@ -551,9 +516,9 @@ void MaemoPackageCreationStep::adaptRulesFile(const QString &rulesFilePath)
desktopFileDir.prepend(QLatin1Char('/'));
#endif
int insertPos = makeInstallEol + 1;
for (int i = 0; i < deployStep()->deployables()->modelCount(); ++i) {
for (int i = 0; i < deployConfig()->deployables()->modelCount(); ++i) {
const MaemoDeployableListModel * const model
= deployStep()->deployables()->modelAt(i);
= deployConfig()->deployables()->modelAt(i);
if (!model->hasDesktopFile())
continue;
if (version == MaemoGlobal::Maemo6) {
@@ -582,7 +547,7 @@ void MaemoPackageCreationStep::adaptRulesFile(const QString &rulesFilePath)
rulesFile.write(content);
}
void MaemoPackageCreationStep::addWorkaroundForHarmattanBug(QByteArray &rulesFileContent,
void MaemoDebianPackageCreationStep::addWorkaroundForHarmattanBug(QByteArray &rulesFileContent,
int &insertPos, const MaemoDeployableListModel *model,
const QString &desktopFileDir)
{
@@ -597,7 +562,7 @@ void MaemoPackageCreationStep::addWorkaroundForHarmattanBug(QByteArray &rulesFil
lineBefore, lineAfter);
}
void MaemoPackageCreationStep::addSedCmdToRulesFile(QByteArray &rulesFileContent,
void MaemoDebianPackageCreationStep::addSedCmdToRulesFile(QByteArray &rulesFileContent,
int &insertPos, const QString &desktopFilePath, const QByteArray &oldString,
const QByteArray &newString)
{
@@ -613,18 +578,133 @@ void MaemoPackageCreationStep::addSedCmdToRulesFile(QByteArray &rulesFileContent
insertPos += mvCmd.length();
}
QString MaemoPackageCreationStep::replaceDots(const QString &name)
MaemoRpmPackageCreationStep::MaemoRpmPackageCreationStep(BuildStepList *bsl)
: AbstractMaemoPackageCreationStep(bsl, CreatePackageId)
{
QString adaptedName = name;
return adaptedName.replace(QLatin1Char('.'), QLatin1Char('_'));
ctor();
}
QString MaemoPackageCreationStep::rpmBuildDir(const Qt4BuildConfiguration *bc)
MaemoRpmPackageCreationStep::MaemoRpmPackageCreationStep(BuildStepList *buildConfig,
MaemoRpmPackageCreationStep *other)
: AbstractMaemoPackageCreationStep(buildConfig, other)
{
ctor();
}
void MaemoRpmPackageCreationStep::ctor()
{
setDefaultDisplayName(tr("Create RPM Package"));
}
bool MaemoRpmPackageCreationStep::createPackage(QProcess *buildProc)
{
const QStringList args = QStringList() << QLatin1String("rrpmbuild")
<< QLatin1String("-bb") << rpmBasedMaemoTarget()->specFilePath();
if (!callPackagingCommand(buildProc, args))
return false;
QFile::remove(packageFilePath());
const QString packageSourceFilePath = rpmBuildDir(qt4BuildConfiguration())
+ QLatin1Char('/') + rpmBasedMaemoTarget()->packageFileName();
if (!QFile::rename(packageSourceFilePath, packageFilePath())) {
raiseError(tr("Packaging failed."),
tr("Could not move package file from %1 to %2.")
.arg(packageSourceFilePath, packageFilePath()));
return false;
}
return true;
}
bool MaemoRpmPackageCreationStep::isMetaDataNewerThan(const QDateTime &packageDate) const
{
const QDateTime specFileChangeDate
= QFileInfo(rpmBasedMaemoTarget()->specFilePath()).lastModified();
return packageDate <= specFileChangeDate;
}
QString MaemoRpmPackageCreationStep::rpmBuildDir(const Qt4BuildConfiguration *bc)
{
return bc->buildDirectory() + QLatin1String("/rrpmbuild");
}
const QLatin1String MaemoPackageCreationStep::CreatePackageId("Qt4ProjectManager.MaemoPackageCreationStep");
const QString MaemoRpmPackageCreationStep::CreatePackageId
= QLatin1String("MaemoRpmPackageCreationStep");
class PROJECTEXPLORER_EXPORT CreateTarStepWidget : public BuildStepConfigWidget
{
Q_OBJECT
public:
CreateTarStepWidget(MaemoTarPackageCreationStep *step) : m_step(step) {}
virtual void init()
{
connect(m_step, SIGNAL(packageFilePathChanged()),
SIGNAL(updateSummary()));
}
virtual QString summaryText() const
{
return QLatin1String("<b>") + tr("Create tarball:")
+ QLatin1String("</b> ") + m_step->packageFilePath();
}
virtual QString displayName() const { return QString(); }
private:
const MaemoTarPackageCreationStep * const m_step;
};
MaemoTarPackageCreationStep::MaemoTarPackageCreationStep(BuildStepList *bsl)
: AbstractMaemoPackageCreationStep(bsl, CreatePackageId)
{
ctor();
}
MaemoTarPackageCreationStep::MaemoTarPackageCreationStep(BuildStepList *buildConfig,
MaemoTarPackageCreationStep *other)
: AbstractMaemoPackageCreationStep(buildConfig, other)
{
ctor();
}
void MaemoTarPackageCreationStep::ctor()
{
setDefaultDisplayName(tr("Create tar ball"));
}
bool MaemoTarPackageCreationStep::createPackage(QProcess *buildProc)
{
Q_UNUSED(buildProc);
// TODO: Copy files one by one into tar file.
return true;
}
bool MaemoTarPackageCreationStep::isMetaDataNewerThan(const QDateTime &packageDate) const
{
Q_UNUSED(packageDate);
return false;
}
QString MaemoTarPackageCreationStep::packageFilePath() const
{
return buildDirectory() + QLatin1Char('/') + projectName()
+ QLatin1String(".tar");
}
BuildStepConfigWidget *MaemoTarPackageCreationStep::createConfigWidget()
{
return new CreateTarStepWidget(this);
}
const QString MaemoTarPackageCreationStep::CreatePackageId
= QLatin1String("MaemoTarPackageCreationStep");
} // namespace Internal
} // namespace Qt4ProjectManager
#include "maemopackagecreationstep.moc"

View File

@@ -54,38 +54,32 @@ namespace Qt4ProjectManager {
class Qt4BuildConfiguration;
namespace Internal {
class MaemoDeployStep;
class MaemoDeployableListModel;
class AbstractQt4MaemoTarget;
class AbstractDebBasedQt4MaemoTarget;
class AbstractRpmBasedQt4MaemoTarget;
class Qt4MaemoDeployConfiguration;
class MaemoPackageCreationStep : public ProjectExplorer::BuildStep
class AbstractMaemoPackageCreationStep : public ProjectExplorer::BuildStep
{
Q_OBJECT
friend class MaemoPackageCreationFactory;
public:
MaemoPackageCreationStep(ProjectExplorer::BuildStepList *bsl);
~MaemoPackageCreationStep();
virtual ~AbstractMaemoPackageCreationStep();
QString packageFilePath() const;
bool isPackagingEnabled() const;
void setPackagingEnabled(bool enabled) { m_packagingEnabled = enabled; }
virtual QString packageFilePath() const;
QString versionString(QString *error) const;
bool setVersionString(const QString &version, QString *error);
static void preparePackagingProcess(QProcess *proc,
const Qt4BuildConfiguration *bc, const QString &workingDir);
static QString packagingCommand(const Qt4BuildConfiguration *bc,
const QString &commandName);
static void ensureShlibdeps(QByteArray &rulesContent);
QString projectName() const;
const Qt4BuildConfiguration *qt4BuildConfiguration() const;
AbstractQt4MaemoTarget *maemoTarget() const;
AbstractDebBasedQt4MaemoTarget *debBasedMaemoTarget() const;
AbstractRpmBasedQt4MaemoTarget *rpmBasedMaemoTarget() const;
Qt4MaemoDeployConfiguration *deployConfig() const;
static const QLatin1String DefaultVersionNumber;
@@ -93,47 +87,109 @@ signals:
void packageFilePathChanged();
void qtVersionChanged();
protected:
AbstractMaemoPackageCreationStep(ProjectExplorer::BuildStepList *bsl,
const QString &id);
AbstractMaemoPackageCreationStep(ProjectExplorer::BuildStepList *buildConfig,
AbstractMaemoPackageCreationStep *other);
void raiseError(const QString &shortMsg,
const QString &detailedMsg = QString());
bool callPackagingCommand(QProcess *proc, const QStringList &arguments);
static QString replaceDots(const QString &name);
QString buildDirectory() const;
private slots:
void handleBuildOutput();
void handleBuildConfigChanged();
private:
MaemoPackageCreationStep(ProjectExplorer::BuildStepList *buildConfig,
MaemoPackageCreationStep *other);
void ctor();
virtual bool init();
virtual void run(QFutureInterface<bool> &fi);
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
virtual bool immutable() const { return true; }
virtual QVariantMap toMap() const;
virtual bool fromMap(const QVariantMap &map);
bool createPackage(QProcess *buildProc);
bool copyDebianFiles(bool inSourceBuild);
virtual bool createPackage(QProcess *buildProc)=0;
virtual bool isMetaDataNewerThan(const QDateTime &packageDate) const=0;
static QString nativePath(const QFile &file);
bool packagingNeeded() const;
bool isFileNewerThan(const QString &filePath,
const QDateTime &timeStamp) const;
void raiseError(const QString &shortMsg,
const QString &detailedMsg = QString());
QString buildDirectory() const;
MaemoDeployStep * deployStep() const;
void checkProjectName();
void adaptRulesFile(const QString &rulesFilePath);
void addWorkaroundForHarmattanBug(QByteArray &rulesFileContent,
int &insertPos, const MaemoDeployableListModel *model,
const QString &desktopFileDir);
const Qt4BuildConfiguration *m_lastBuildConfig;
};
class MaemoDebianPackageCreationStep : public AbstractMaemoPackageCreationStep
{
Q_OBJECT
friend class MaemoPackageCreationFactory;
public:
MaemoDebianPackageCreationStep(ProjectExplorer::BuildStepList *bsl);
static void ensureShlibdeps(QByteArray &rulesContent);
private:
MaemoDebianPackageCreationStep(ProjectExplorer::BuildStepList *buildConfig,
MaemoDebianPackageCreationStep *other);
virtual bool createPackage(QProcess *buildProc);
virtual bool isMetaDataNewerThan(const QDateTime &packageDate) const;
void ctor();
static QString packagingCommand(const Qt4BuildConfiguration *bc,
const QString &commandName);
bool copyDebianFiles(bool inSourceBuild);
void addSedCmdToRulesFile(QByteArray &rulesFileContent, int &insertPos,
const QString &desktopFilePath, const QByteArray &oldString,
const QByteArray &newString);
static QString replaceDots(const QString &name);
void addWorkaroundForHarmattanBug(QByteArray &rulesFileContent,
int &insertPos, const MaemoDeployableListModel *model,
const QString &desktopFileDir);
void checkProjectName();
void adaptRulesFile(const QString &rulesFilePath);
static const QString CreatePackageId;
};
class MaemoRpmPackageCreationStep : public AbstractMaemoPackageCreationStep
{
Q_OBJECT
friend class MaemoPackageCreationFactory;
public:
MaemoRpmPackageCreationStep(ProjectExplorer::BuildStepList *bsl);
private:
virtual bool createPackage(QProcess *buildProc);
virtual bool isMetaDataNewerThan(const QDateTime &packageDate) const;
MaemoRpmPackageCreationStep(ProjectExplorer::BuildStepList *buildConfig,
MaemoRpmPackageCreationStep *other);
void ctor();
static QString rpmBuildDir(const Qt4BuildConfiguration *bc);
static const QLatin1String CreatePackageId;
static const QString CreatePackageId;
};
bool m_packagingEnabled;
const Qt4BuildConfiguration *m_lastBuildConfig;
class MaemoTarPackageCreationStep : public AbstractMaemoPackageCreationStep
{
Q_OBJECT
friend class MaemoPackageCreationFactory;
public:
MaemoTarPackageCreationStep(ProjectExplorer::BuildStepList *bsl);
virtual QString packageFilePath() const;
private:
virtual bool createPackage(QProcess *buildProc);
virtual bool isMetaDataNewerThan(const QDateTime &packageDate) const;
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
MaemoTarPackageCreationStep(ProjectExplorer::BuildStepList *buildConfig,
MaemoTarPackageCreationStep *other);
void ctor();
static const QString CreatePackageId;
};
} // namespace Internal

View File

@@ -62,13 +62,13 @@ using namespace ProjectExplorer;
namespace Qt4ProjectManager {
namespace Internal {
MaemoPackageCreationWidget::MaemoPackageCreationWidget(MaemoPackageCreationStep *step)
// TODO: Split up into dedicated widgets for Debian and RPM steps.
MaemoPackageCreationWidget::MaemoPackageCreationWidget(AbstractMaemoPackageCreationStep *step)
: ProjectExplorer::BuildStepConfigWidget(),
m_step(step),
m_ui(new Ui::MaemoPackageCreationWidget)
{
m_ui->setupUi(this);
m_ui->skipCheckBox->setChecked(!m_step->isPackagingEnabled());
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QTimer::singleShot(0, this, SLOT(initGui()));
}
@@ -84,12 +84,6 @@ void MaemoPackageCreationWidget::init()
void MaemoPackageCreationWidget::initGui()
{
// The "remove" stuff below is fragile; be careful when editing the UI file.
m_ui->skipCheckBox->setChecked(!m_step->isPackagingEnabled());
if (!m_step->maemoTarget()->allowsPackagingDisabling()) {
m_ui->skipCheckBox->hide();
m_ui->formLayout->removeItem(m_ui->formLayout->itemAt(0, QFormLayout::FieldRole));
}
m_ui->shortDescriptionLineEdit->setMaxLength(60);
updateVersionInfo();
versionInfoChanged();
@@ -115,12 +109,14 @@ void MaemoPackageCreationWidget::initGui()
m_ui->editDebianFileLabel->hide();
m_ui->debianFilesComboBox->hide();
m_ui->editDebianFileButton->hide();
// This is fragile; be careful when editing the UI file.
m_ui->formLayout->removeItem(m_ui->formLayout->itemAt(4, QFormLayout::LabelRole));
m_ui->formLayout->removeItem(m_ui->formLayout->itemAt(4, QFormLayout::FieldRole));
m_ui->formLayout->removeItem(m_ui->formLayout->itemAt(5, QFormLayout::LabelRole));
m_ui->formLayout->removeItem(m_ui->formLayout->itemAt(5, QFormLayout::FieldRole));
m_ui->formLayout->removeItem(m_ui->formLayout->itemAt(6, QFormLayout::LabelRole));
m_ui->formLayout->removeItem(m_ui->formLayout->itemAt(6, QFormLayout::FieldRole));
m_ui->formLayout->removeItem(m_ui->formLayout->itemAt(7, QFormLayout::LabelRole));
m_ui->formLayout->removeItem(m_ui->formLayout->itemAt(7, QFormLayout::FieldRole));
handleSpecFileUpdate();
connect(m_step->rpmBasedMaemoTarget(), SIGNAL(specFileChanged()),
SLOT(handleSpecFileUpdate()));
@@ -152,7 +148,7 @@ void MaemoPackageCreationWidget::updateVersionInfo()
QString versionString = m_step->versionString(&error);
if (versionString.isEmpty()) {
QMessageBox::critical(this, tr("No Version Available."), error);
versionString = MaemoPackageCreationStep::DefaultVersionNumber;
versionString = AbstractMaemoPackageCreationStep::DefaultVersionNumber;
}
const QStringList list = versionString.split(QLatin1Char('.'),
QString::SkipEmptyParts);
@@ -248,11 +244,8 @@ void MaemoPackageCreationWidget::setShortDescription()
QString MaemoPackageCreationWidget::summaryText() const
{
const QString constantString = tr("<b>Create Package:</b> ");
const QString dynamicString = m_step->isPackagingEnabled()
? QDir::toNativeSeparators(m_step->packageFilePath())
: tr("(Packaging disabled)");
return constantString + dynamicString;
return tr("<b>Create Package:</b> ")
+ QDir::toNativeSeparators(m_step->packageFilePath());
}
QString MaemoPackageCreationWidget::displayName() const
@@ -260,22 +253,6 @@ QString MaemoPackageCreationWidget::displayName() const
return m_step->displayName();
}
void MaemoPackageCreationWidget::handleSkipButtonToggled(bool checked)
{
m_ui->major->setEnabled(!checked);
m_ui->minor->setEnabled(!checked);
m_ui->patch->setEnabled(!checked);
m_ui->debianFilesComboBox->setEnabled(!checked);
m_ui->editDebianFileButton->setEnabled(!checked);
m_ui->editSpecFileButton->setEnabled(!checked);
m_ui->packageManagerIconButton->setEnabled(!checked);
m_ui->packageNameLineEdit->setEnabled(!checked);
m_ui->packageManagerNameLineEdit->setEnabled(!checked);
m_ui->shortDescriptionLineEdit->setEnabled(!checked);
m_step->setPackagingEnabled(!checked);
emit updateSummary();
}
void MaemoPackageCreationWidget::versionInfoChanged()
{
QString error;

View File

@@ -50,13 +50,13 @@ QT_END_NAMESPACE
namespace Qt4ProjectManager {
namespace Internal {
class MaemoPackageCreationStep;
class AbstractMaemoPackageCreationStep;
class MaemoPackageCreationWidget : public ProjectExplorer::BuildStepConfigWidget
{
Q_OBJECT
public:
MaemoPackageCreationWidget(MaemoPackageCreationStep *step);
MaemoPackageCreationWidget(AbstractMaemoPackageCreationStep *step);
~MaemoPackageCreationWidget();
virtual void init();
@@ -64,7 +64,6 @@ public:
virtual QString displayName() const;
private slots:
void handleSkipButtonToggled(bool checked);
void editDebianFile();
void editSpecFile();
void versionInfoChanged();
@@ -85,7 +84,7 @@ private:
void updateShortDescription();
void editFile(const QString &filePath);
MaemoPackageCreationStep * const m_step;
AbstractMaemoPackageCreationStep * const m_step;
Ui::MaemoPackageCreationWidget * const m_ui;
};

View File

@@ -17,45 +17,22 @@
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="skipCheckBox">
<property name="toolTip">
<string>Check this if you want the files below to be deployed directly.</string>
</property>
<property name="text">
<string>Skip packaging step</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<item row="0" column="0">
<widget class="QLabel" name="packageNameLabel">
<property name="text">
<string>Package name:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="0" column="1">
<widget class="QLineEdit" name="packageNameLineEdit"/>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -74,7 +51,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
@@ -169,35 +146,35 @@
</item>
</layout>
</item>
<item row="4" column="0">
<item row="3" column="0">
<widget class="QLabel" name="shortDescriptionLabel">
<property name="text">
<string>Short package description:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="shortDescriptionLineEdit"/>
</item>
</layout>
</item>
<item row="5" column="0">
<item row="4" column="0">
<widget class="QLabel" name="packageManagerNameLabel">
<property name="text">
<string>Name to be displayed in Package Manager:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="packageManagerNameLineEdit"/>
</item>
</layout>
</item>
<item row="6" column="0">
<item row="5" column="0">
<widget class="QLabel" name="packageManagerIconLabel">
<property name="minimumSize">
<size>
@@ -210,7 +187,7 @@
</property>
</widget>
</item>
<item row="6" column="1">
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QToolButton" name="packageManagerIconButton">
@@ -249,14 +226,14 @@
</item>
</layout>
</item>
<item row="7" column="0">
<item row="6" column="0">
<widget class="QLabel" name="editDebianFileLabel">
<property name="text">
<string>Adapt Debian file:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="debianFilesComboBox"/>
@@ -283,7 +260,7 @@
</item>
</layout>
</item>
<item row="8" column="1">
<item row="7" column="1">
<widget class="QPushButton" name="editSpecFileButton">
<property name="text">
<string>Edit spec file</string>
@@ -296,22 +273,6 @@
</widget>
<resources/>
<connections>
<connection>
<sender>skipCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>MaemoPackageCreationWidget</receiver>
<slot>handleSkipButtonToggled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>129</x>
<y>18</y>
</hint>
<hint type="destinationlabel">
<x>240</x>
<y>31</y>
</hint>
</hints>
</connection>
<connection>
<sender>major</sender>
<signal>valueChanged(int)</signal>

View File

@@ -0,0 +1,205 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "maemopackageinstaller.h"
#include "maemoglobal.h"
#include <utils/ssh/sshconnection.h>
#include <utils/ssh/sshremoteprocessrunner.h>
using namespace Utils;
namespace Qt4ProjectManager {
namespace Internal {
AbstractMaemoPackageInstaller::AbstractMaemoPackageInstaller(QObject *parent)
: QObject(parent), m_isRunning(false)
{
}
AbstractMaemoPackageInstaller::~AbstractMaemoPackageInstaller() {}
void AbstractMaemoPackageInstaller::installPackage(const SshConnection::Ptr &connection,
const QString &packageFilePath, bool removePackageFile)
{
Q_ASSERT(connection && connection->state() == SshConnection::Connected);
Q_ASSERT(!m_isRunning);
prepareInstallation();
m_installer = SshRemoteProcessRunner::create(connection);
connect(m_installer.data(), SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError()));
connect(m_installer.data(), SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleInstallerOutput(QByteArray)));
connect(m_installer.data(), SIGNAL(processErrorOutputAvailable(QByteArray)),
SLOT(handleInstallerErrorOutput(QByteArray)));
connect(m_installer.data(), SIGNAL(processClosed(int)),
SLOT(handleInstallationFinished(int)));
const QString space = QLatin1String(" ");
QString cmdLine = MaemoGlobal::remoteSudo() + space + installCommand()
+ space + installCommandArguments().join(space) + space
+ packageFilePath;
if (removePackageFile) {
cmdLine += QLatin1String(" && (rm ") + packageFilePath
+ QLatin1String(" || :)");
}
m_installer->run(cmdLine.toUtf8());
m_isRunning = true;
}
void AbstractMaemoPackageInstaller::cancelInstallation()
{
Q_ASSERT(m_isRunning);
const SshRemoteProcessRunner::Ptr killProcess
= SshRemoteProcessRunner::create(m_installer->connection());
killProcess->run("pkill " + installCommand().toUtf8());
setFinished();
}
void AbstractMaemoPackageInstaller::handleConnectionError()
{
if (!m_isRunning)
return;
emit finished(tr("Connection failure: %1")
.arg(m_installer->connection()->errorString()));
setFinished();
}
void AbstractMaemoPackageInstaller::handleInstallationFinished(int exitStatus)
{
if (!m_isRunning)
return;
if (exitStatus != SshRemoteProcess::ExitedNormally
|| m_installer->process()->exitCode() != 0) {
emit finished(tr("Installing package failed."));
} else if (!errorString().isEmpty()) {
emit finished(errorString());
} else {
emit finished();
}
setFinished();
}
void AbstractMaemoPackageInstaller::handleInstallerOutput(const QByteArray &output)
{
emit stdout(QString::fromUtf8(output));
}
void AbstractMaemoPackageInstaller::handleInstallerErrorOutput(const QByteArray &output)
{
emit stderr(QString::fromUtf8(output));
}
void AbstractMaemoPackageInstaller::setFinished()
{
disconnect(m_installer.data(), 0, this, 0);
m_installer.clear();
m_isRunning = false;
}
MaemoDebianPackageInstaller::MaemoDebianPackageInstaller(QObject *parent)
: AbstractMaemoPackageInstaller(parent)
{
connect(this, SIGNAL(stderr(QString)),
SLOT(handleInstallerErrorOutput(QString)));
}
void MaemoDebianPackageInstaller::prepareInstallation()
{
m_installerStderr.clear();
}
QString MaemoDebianPackageInstaller::installCommand() const
{
return QLatin1String("dpkg");
}
QStringList MaemoDebianPackageInstaller::installCommandArguments() const
{
return QStringList() << QLatin1String("-i")
<< QLatin1String("--no-force-downgrade");
}
void MaemoDebianPackageInstaller::handleInstallerErrorOutput(const QString &output)
{
m_installerStderr += output;
}
QString MaemoDebianPackageInstaller::errorString() const
{
if (m_installerStderr.contains(QLatin1String("Will not downgrade"))) {
return tr("Installation failed: "
"You tried to downgrade a package, which is not allowed.");
} else {
return QString();
}
}
MaemoRpmPackageInstaller::MaemoRpmPackageInstaller(QObject *parent)
: AbstractMaemoPackageInstaller(parent)
{
}
QString MaemoRpmPackageInstaller::installCommand() const
{
return QLatin1String("rpm");
}
QStringList MaemoRpmPackageInstaller::installCommandArguments() const
{
return QStringList() << QLatin1String("-Uhv");
}
MaemoTarPackageInstaller::MaemoTarPackageInstaller(QObject *parent)
: AbstractMaemoPackageInstaller(parent)
{
}
QString MaemoTarPackageInstaller::installCommand() const
{
return QLatin1String("tar");
}
QStringList MaemoTarPackageInstaller::installCommandArguments() const
{
return QStringList() << QLatin1String("xvf");
}
} // namespace Internal
} // namespace Qt4ProjectManager

View File

@@ -0,0 +1,131 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef ABSTRACTMAEMOPACKAGEINSTALLER_H
#define ABSTRACTMAEMOPACKAGEINSTALLER_H
namespace Utils {
class SshConnection;
class SshRemoteProcessRunner;
}
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QString>
#include <QtCore/QStringList>
namespace Qt4ProjectManager {
namespace Internal {
class AbstractMaemoPackageInstaller : public QObject
{
Q_OBJECT
public:
~AbstractMaemoPackageInstaller();
void installPackage(const QSharedPointer<Utils::SshConnection> &connection,
const QString &packageFilePath, bool removePackageFile);
void cancelInstallation();
signals:
void stdout(const QString &output);
void stderr(const QString &output);
void finished(const QString &errorMsg = QString());
protected:
explicit AbstractMaemoPackageInstaller(QObject *parent = 0);
bool isRunning() const { return m_isRunning; }
private slots:
void handleConnectionError();
void handleInstallationFinished(int exitStatus);
void handleInstallerOutput(const QByteArray &output);
void handleInstallerErrorOutput(const QByteArray &output);
private:
virtual void prepareInstallation() {}
virtual QString installCommand() const=0;
virtual QStringList installCommandArguments() const=0;
virtual QString errorString() const { return QString(); }
void setFinished();
bool m_isRunning;
QSharedPointer<Utils::SshRemoteProcessRunner> m_installer;
};
class MaemoDebianPackageInstaller: public AbstractMaemoPackageInstaller
{
Q_OBJECT
public:
MaemoDebianPackageInstaller(QObject *parent);
private slots:
virtual void prepareInstallation();
virtual QString installCommand() const;
virtual QStringList installCommandArguments() const;
virtual QString errorString() const;
void handleInstallerErrorOutput(const QString &output);
private:
QString m_installerStderr;
};
class MaemoRpmPackageInstaller : public AbstractMaemoPackageInstaller
{
Q_OBJECT
public:
MaemoRpmPackageInstaller(QObject *parent);
private:
virtual QString installCommand() const;
virtual QStringList installCommandArguments() const;
};
class MaemoTarPackageInstaller : public AbstractMaemoPackageInstaller
{
Q_OBJECT
public:
MaemoTarPackageInstaller(QObject *parent);
private:
virtual QString installCommand() const;
virtual QStringList installCommandArguments() const;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // ABSTRACTMAEMOPACKAGEINSTALLER_H

View File

@@ -0,0 +1,159 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "maemopackageuploader.h"
#include "maemoglobal.h"
#include <utils/ssh/sftpchannel.h>
#include <utils/ssh/sshconnection.h>
#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(State, state, m_state)
using namespace Utils;
namespace Qt4ProjectManager {
namespace Internal {
MaemoPackageUploader::MaemoPackageUploader(QObject *parent) :
QObject(parent), m_state(Inactive)
{
}
MaemoPackageUploader::~MaemoPackageUploader()
{
}
void MaemoPackageUploader::uploadPackage(const SshConnection::Ptr &connection,
const QString &localFilePath, const QString &remoteFilePath)
{
ASSERT_STATE(Inactive);
setState(InitializingSftp);
emit progress(tr("Preparing SFTP connection..."));
m_localFilePath = localFilePath;
m_remoteFilePath = remoteFilePath;
m_connection = connection;
connect(m_connection.data(), SIGNAL(error(Utils::SshError)),
SLOT(handleConnectionFailure()));
m_uploader = m_connection->createSftpChannel();
connect(m_uploader.data(), SIGNAL(initialized()), this,
SLOT(handleSftpChannelInitialized()));
connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this,
SLOT(handleSftpChannelInitializationFailed(QString)));
connect(m_uploader.data(), SIGNAL(finished(Utils::SftpJobId, QString)),
this, SLOT(handleSftpJobFinished(Utils::SftpJobId, QString)));
m_uploader->initialize();
}
void MaemoPackageUploader::cancelUpload()
{
ASSERT_STATE(QList<State>() << InitializingSftp << Uploading);
cleanup();
}
void MaemoPackageUploader::handleConnectionFailure()
{
if (m_state == Inactive)
return;
const QString errorMsg = m_connection->errorString();
setState(Inactive);
emit uploadFinished(tr("Connection failed: %1").arg(errorMsg));
}
void MaemoPackageUploader::handleSftpChannelInitializationFailed(const QString &errorMsg)
{
ASSERT_STATE(QList<State>() << InitializingSftp << Inactive);
if (m_state == Inactive)
return;
setState(Inactive);
emit uploadFinished(tr("SFTP error: %1").arg(errorMsg));
}
void MaemoPackageUploader::handleSftpChannelInitialized()
{
ASSERT_STATE(QList<State>() << InitializingSftp << Inactive);
if (m_state == Inactive)
return;
const SftpJobId job = m_uploader->uploadFile(m_localFilePath,
m_remoteFilePath, SftpOverwriteExisting);
if (job == SftpInvalidJob) {
setState(Inactive);
emit uploadFinished(tr("Package upload failed: Could not open file."));
} else {
emit progress("Starting upload...");
setState(Uploading);
}
}
void MaemoPackageUploader::handleSftpJobFinished(SftpJobId, const QString &errorMsg)
{
ASSERT_STATE(QList<State>() << Uploading << Inactive);
if (m_state == Inactive)
return;
if (!errorMsg.isEmpty())
emit uploadFinished(tr("Failed to upload package: %2").arg(errorMsg));
else
emit uploadFinished();
cleanup();
}
void MaemoPackageUploader::cleanup()
{
m_uploader->closeChannel();
setState(Inactive);
}
void MaemoPackageUploader::setState(State newState)
{
if (m_state == newState)
return;
if (newState == Inactive) {
if (m_uploader) {
disconnect(m_uploader.data(), 0, this, 0);
m_uploader.clear();
}
if (m_connection) {
disconnect(m_connection.data(), 0, this, 0);
m_connection.clear();
}
}
m_state = newState;
}
} // namespace Internal
} // namespace Qt4ProjectManager

View File

@@ -0,0 +1,88 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef MAEMOPACKAGEUPLOADER_H
#define MAEMOPACKAGEUPLOADER_H
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QString>
#include <utils/ssh/sftpdefs.h>
namespace Utils {
class SftpChannel;
class SshConnection;
}
namespace Qt4ProjectManager {
namespace Internal {
class MaemoPackageUploader : public QObject
{
Q_OBJECT
public:
explicit MaemoPackageUploader(QObject *parent = 0);
~MaemoPackageUploader();
// Connection has to be established already.
void uploadPackage(const QSharedPointer<Utils::SshConnection> &connection,
const QString &localFilePath, const QString &remoteFilePath);
void cancelUpload();
signals:
void progress(const QString &message);
void uploadFinished(const QString &errorMsg = QString());
private slots:
void handleConnectionFailure();
void handleSftpChannelInitialized();
void handleSftpChannelInitializationFailed(const QString &error);
void handleSftpJobFinished(Utils::SftpJobId job, const QString &error);
private:
enum State { InitializingSftp, Uploading, Inactive };
void cleanup();
void setState(State newState);
State m_state;
QSharedPointer<Utils::SshConnection> m_connection;
QSharedPointer<Utils::SftpChannel> m_uploader;
QString m_localFilePath;
QString m_remoteFilePath;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // MAEMOPACKAGEUPLOADER_H

View File

@@ -39,17 +39,17 @@ using namespace ProjectExplorer;
namespace Qt4ProjectManager {
namespace Internal {
MaemoPerTargetDeviceConfigurationListModel::MaemoPerTargetDeviceConfigurationListModel(Target *target)
: QAbstractListModel(target)
MaemoPerTargetDeviceConfigurationListModel::MaemoPerTargetDeviceConfigurationListModel(QObject *parent,
const Target *target) : QAbstractListModel(parent)
{
if (qobject_cast<Qt4Maemo5Target *>(target))
if (qobject_cast<const Qt4Maemo5Target *>(target))
m_targetOsVersion = MaemoGlobal::Maemo5;
else if (qobject_cast<Qt4HarmattanTarget *>(target))
else if (qobject_cast<const Qt4HarmattanTarget *>(target))
m_targetOsVersion = MaemoGlobal::Maemo6;
else if (qobject_cast<Qt4MeegoTarget *>(target))
else if (qobject_cast<const Qt4MeegoTarget *>(target))
m_targetOsVersion = MaemoGlobal::Meego;
else
Q_ASSERT(false);
m_targetOsVersion = MaemoGlobal::GenericLinux;
const MaemoDeviceConfigurations * const devConfs
= MaemoDeviceConfigurations::instance();
connect(devConfs, SIGNAL(modelReset()), this, SIGNAL(modelReset()));
@@ -64,6 +64,8 @@ int MaemoPerTargetDeviceConfigurationListModel::rowCount(const QModelIndex &pare
const MaemoDeviceConfigurations * const devConfs
= MaemoDeviceConfigurations::instance();
const int devConfsCount = devConfs->rowCount();
if (m_targetOsVersion == MaemoGlobal::GenericLinux)
return devConfsCount;
for (int i = 0; i < devConfsCount; ++i) {
if (devConfs->deviceAt(i)->osVersion() == m_targetOsVersion)
++count;
@@ -79,7 +81,7 @@ QVariant MaemoPerTargetDeviceConfigurationListModel::data(const QModelIndex &ind
const MaemoDeviceConfig::ConstPtr &devConf = deviceAt(index.row());
Q_ASSERT(devConf);
QString displayedName = devConf->name();
if (devConf->isDefault())
if (devConf->isDefault() && devConf->osVersion() == m_targetOsVersion)
displayedName += QLatin1Char(' ') + tr("(default)");
return displayedName;
}
@@ -89,6 +91,8 @@ MaemoDeviceConfig::ConstPtr MaemoPerTargetDeviceConfigurationListModel::deviceAt
int currentRow = -1;
const MaemoDeviceConfigurations * const devConfs
= MaemoDeviceConfigurations::instance();
if (m_targetOsVersion == MaemoGlobal::GenericLinux)
return devConfs->deviceAt(idx);
const int devConfsCount = devConfs->rowCount();
for (int i = 0; i < devConfsCount; ++i) {
if (devConfs->deviceAt(i)->osVersion() == m_targetOsVersion) {
@@ -109,7 +113,8 @@ MaemoDeviceConfig::ConstPtr MaemoPerTargetDeviceConfigurationListModel::find(Mae
{
const MaemoDeviceConfig::ConstPtr &devConf
= MaemoDeviceConfigurations::instance()->find(id);
return devConf && devConf->osVersion() == m_targetOsVersion
return devConf && (devConf->osVersion() == m_targetOsVersion
|| m_targetOsVersion == MaemoGlobal::GenericLinux)
? devConf : defaultDeviceConfig();
}

View File

@@ -48,7 +48,8 @@ class MaemoPerTargetDeviceConfigurationListModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit MaemoPerTargetDeviceConfigurationListModel(ProjectExplorer::Target *target);
explicit MaemoPerTargetDeviceConfigurationListModel(QObject *parent, const
ProjectExplorer::Target *target);
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index,
@@ -63,7 +64,7 @@ signals:
void updated();
private:
MaemoGlobal::MaemoVersion m_targetOsVersion;
MaemoGlobal::OsVersion m_targetOsVersion;
};
} // namespace Internal

View File

@@ -33,10 +33,10 @@
#include "maemopublisherfremantlefree.h"
#include "maemodeployablelistmodel.h"
#include "maemodeploystep.h"
#include "maemoglobal.h"
#include "maemopackagecreationstep.h"
#include "maemopublishingfileselectiondialog.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include <coreplugin/ifile.h>
@@ -156,7 +156,7 @@ void MaemoPublisherFremantleFree::createPackage()
}
emit progressReport(tr("Cleaning up temporary directory ..."));
MaemoPackageCreationStep::preparePackagingProcess(m_process,
AbstractMaemoPackageCreationStep::preparePackagingProcess(m_process,
m_buildConfig, m_tmpProjectDir);
setState(RunningQmake);
ProjectExplorer::AbstractProcessStep * const qmakeStep
@@ -223,7 +223,7 @@ bool MaemoPublisherFremantleFree::copyRecursively(const QString &srcFilePath,
rulesContents.replace("$(MAKE) clean", "# $(MAKE) clean");
rulesContents.replace("# Add here commands to configure the package.",
"qmake " + QFileInfo(m_project->file()->fileName()).fileName().toLocal8Bit());
MaemoPackageCreationStep::ensureShlibdeps(rulesContents);
MaemoDebianPackageCreationStep::ensureShlibdeps(rulesContents);
rulesFile.resize(0);
rulesFile.write(rulesContents);
}
@@ -520,12 +520,12 @@ void MaemoPublisherFremantleFree::finishWithFailure(const QString &progressMsg,
bool MaemoPublisherFremantleFree::updateDesktopFiles(QString *error) const
{
bool success = true;
MaemoDeployStep * const deployStep
= MaemoGlobal::buildStep<MaemoDeployStep>(m_buildConfig->target()
->activeDeployConfiguration());
for (int i = 0; i < deployStep->deployables()->modelCount(); ++i) {
const MaemoDeployableListModel * const model
= deployStep->deployables()->modelAt(i);
const Qt4MaemoDeployConfiguration * const deployConfig
= qobject_cast<Qt4MaemoDeployConfiguration *>(m_buildConfig->target()->activeDeployConfiguration());
const QSharedPointer<MaemoDeployables> deployables
= deployConfig->deployables();
for (int i = 0; i < deployables->modelCount(); ++i) {
const MaemoDeployableListModel * const model = deployables->modelAt(i);
QString desktopFilePath = model->localDesktopFilePath();
if (desktopFilePath.isEmpty())
continue;

View File

@@ -0,0 +1,155 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "maemoremotecopyfacility.h"
#include "maemoglobal.h"
#include <utils/ssh/sshconnection.h>
#include <utils/ssh/sshremoteprocessrunner.h>
using namespace Utils;
namespace Qt4ProjectManager {
namespace Internal {
MaemoRemoteCopyFacility::MaemoRemoteCopyFacility(QObject *parent) :
QObject(parent), m_isCopying(false)
{
}
MaemoRemoteCopyFacility::~MaemoRemoteCopyFacility() {}
void MaemoRemoteCopyFacility::copyFiles(const SshConnection::Ptr &connection,
const QList<MaemoDeployable> &deployables, const QString &mountPoint)
{
Q_ASSERT(connection->state() == SshConnection::Connected);
Q_ASSERT(!m_isCopying);
m_deployables = deployables;
m_mountPoint = mountPoint;
m_copyRunner = SshRemoteProcessRunner::create(connection);
connect(m_copyRunner.data(), SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError()));
connect(m_copyRunner.data(), SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleRemoteStdout(QByteArray)));
connect(m_copyRunner.data(),
SIGNAL(processErrorOutputAvailable(QByteArray)),
SLOT(handleRemoteStderr(QByteArray)));
connect(m_copyRunner.data(), SIGNAL(processClosed(int)),
SLOT(handleCopyFinished(int)));
m_isCopying = true;
copyNextFile();
}
void MaemoRemoteCopyFacility::cancel()
{
Q_ASSERT(m_isCopying);
SshRemoteProcessRunner::Ptr killProcess
= SshRemoteProcessRunner::create(m_copyRunner->connection());
killProcess->run("pkill cp");
setFinished();
}
void MaemoRemoteCopyFacility::handleConnectionError()
{
const QString errMsg = m_copyRunner->connection()->errorString();
setFinished();
emit finished(tr("Connection failed: %1").arg(errMsg));
}
void MaemoRemoteCopyFacility::handleRemoteStdout(const QByteArray &output)
{
emit stdout(QString::fromUtf8(output));
}
void MaemoRemoteCopyFacility::handleRemoteStderr(const QByteArray &output)
{
emit stderr(QString::fromUtf8(output));
}
void MaemoRemoteCopyFacility::handleCopyFinished(int exitStatus)
{
if (!m_isCopying)
return;
if (exitStatus != SshRemoteProcess::ExitedNormally
|| m_copyRunner->process()->exitCode() != 0) {
setFinished();
emit finished(tr("Error: Copy command failed."));
} else {
emit fileCopied(m_deployables.takeFirst());
copyNextFile();
}
}
void MaemoRemoteCopyFacility::copyNextFile()
{
Q_ASSERT(m_isCopying);
if (m_deployables.isEmpty()) {
setFinished();
emit finished();
return;
}
const MaemoDeployable &d = m_deployables.first();
QString sourceFilePath = m_mountPoint;
#ifdef Q_OS_WIN
const QString localFilePath = QDir::fromNativeSeparators(d.localFilePath);
sourceFilePath += QLatin1Char('/') + localFilePath.at(0).toLower()
+ localFilePath.mid(2);
#else
sourceFilePath += d.localFilePath;
#endif
QString command = QString::fromLatin1("%1 cp -r %2 %3")
.arg(MaemoGlobal::remoteSudo(), sourceFilePath,
d.remoteDir + QLatin1Char('/'));
emit progress(tr("Copying file '%1' to directory '%2' on the device...")
.arg(d.localFilePath, d.remoteDir));
m_copyRunner->run(command.toUtf8());
}
void MaemoRemoteCopyFacility::setFinished()
{
disconnect(m_copyRunner.data(), 0, this, 0);
m_copyRunner.clear();
m_deployables.clear();
m_isCopying = false;
}
} // namespace Internal
} // namespace Qt4ProjectManager

View File

@@ -0,0 +1,88 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef MAEMOREMOTECOPYFACILITY_H
#define MAEMOREMOTECOPYFACILITY_H
#include "maemodeployable.h"
#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QString>
namespace Utils {
class SshConnection;
class SshRemoteProcessRunner;
}
namespace Qt4ProjectManager {
namespace Internal {
class MaemoRemoteCopyFacility : public QObject
{
Q_OBJECT
public:
explicit MaemoRemoteCopyFacility(QObject *parent = 0);
~MaemoRemoteCopyFacility();
void copyFiles(const QSharedPointer<Utils::SshConnection> &connection,
const QList<MaemoDeployable> &deployables, const QString &mountPoint);
void cancel();
signals:
void stdout(const QString &output);
void stderr(const QString &output);
void progress(const QString &message);
void fileCopied(const MaemoDeployable &deployable);
void finished(const QString &errorMsg = QString());
private slots:
void handleConnectionError();
void handleCopyFinished(int exitStatus);
void handleRemoteStdout(const QByteArray &output);
void handleRemoteStderr(const QByteArray &output);
private:
void copyNextFile();
void setFinished();
QSharedPointer<Utils::SshRemoteProcessRunner> m_copyRunner;
QList<MaemoDeployable> m_deployables;
QString m_mountPoint;
bool m_isCopying;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // MAEMOREMOTECOPYFACILITY_H

View File

@@ -33,13 +33,14 @@
#include "maemorunconfiguration.h"
#include "abstractmaemodeploystep.h"
#include "maemodeployables.h"
#include "maemodeploystep.h"
#include "maemoglobal.h"
#include "maemoqemumanager.h"
#include "maemoremotemountsmodel.h"
#include "maemorunconfigurationwidget.h"
#include "maemotoolchain.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include "qtoutputformatter.h"
@@ -213,7 +214,7 @@ QString MaemoRunConfiguration::defaultDisplayName()
MaemoDeviceConfig::ConstPtr MaemoRunConfiguration::deviceConfig() const
{
const MaemoDeployStep * const step = deployStep();
const AbstractMaemoDeployStep * const step = deployStep();
return step ? step->deviceConfig() : MaemoDeviceConfig::ConstPtr();
}
@@ -231,9 +232,14 @@ const QString MaemoRunConfiguration::gdbCmd() const
return QDir::toNativeSeparators(targetRoot() + QLatin1String("/bin/gdb"));
}
MaemoDeployStep *MaemoRunConfiguration::deployStep() const
Qt4MaemoDeployConfiguration *MaemoRunConfiguration::deployConfig() const
{
return MaemoGlobal::buildStep<MaemoDeployStep>(target()->activeDeployConfiguration());
return qobject_cast<Qt4MaemoDeployConfiguration *>(target()->activeDeployConfiguration());
}
AbstractMaemoDeployStep *MaemoRunConfiguration::deployStep() const
{
return MaemoGlobal::earlierBuildStep<AbstractMaemoDeployStep>(deployConfig(), 0);
}
const QString MaemoRunConfiguration::sysRoot() const
@@ -299,10 +305,7 @@ QString MaemoRunConfiguration::localExecutableFilePath() const
QString MaemoRunConfiguration::remoteExecutableFilePath() const
{
const MaemoDeployStep * const step = deployStep();
return step
? step->deployables()->remoteExecutableFilePath(localExecutableFilePath())
: QString();
return deployConfig()->deployables()->remoteExecutableFilePath(localExecutableFilePath());
}
MaemoPortList MaemoRunConfiguration::freePorts() const
@@ -356,8 +359,8 @@ void MaemoRunConfiguration::handleDeployConfigChanged()
DeployConfiguration * const activeDeployConf
= target()->activeDeployConfiguration();
for (int i = 0; i < deployConfigs.count(); ++i) {
MaemoDeployStep * const step
= MaemoGlobal::buildStep<MaemoDeployStep>(deployConfigs.at(i));
AbstractMaemoDeployStep * const step
= MaemoGlobal::earlierBuildStep<AbstractMaemoDeployStep>(deployConfigs.at(i), 0);
if (!step)
continue;
if (deployConfigs.at(i) == activeDeployConf) {

View File

@@ -56,14 +56,15 @@ class Qt4BaseTarget;
namespace Internal {
class Qt4ProFileNode;
class AbstractQt4MaemoTarget;
class AbstractQt4MaemoTarget;
class AbstractMaemoDeployStep;
class MaemoDeviceConfigListModel;
class MaemoDeployStep;
class MaemoManager;
class MaemoRemoteMountsModel;
class MaemoRunConfigurationFactory;
class MaemoToolChain;
class Qt4MaemoDeployConfiguration;
class MaemoRunConfiguration : public ProjectExplorer::RunConfiguration
{
@@ -88,7 +89,8 @@ public:
AbstractQt4MaemoTarget *maemoTarget() const;
Qt4BuildConfiguration *activeQt4BuildConfiguration() const;
MaemoDeployStep *deployStep() const;
Qt4MaemoDeployConfiguration *deployConfig() const;
AbstractMaemoDeployStep *deployStep() const;
MaemoRemoteMountsModel *remoteMounts() const { return m_remoteMounts; }
const MaemoToolChain *toolchain() const;

View File

@@ -35,13 +35,13 @@
#include "maemorunconfigurationwidget.h"
#include "maemodeployables.h"
#include "maemodeploystep.h"
#include "maemodeviceenvreader.h"
#include "maemomanager.h"
#include "maemoglobal.h"
#include "maemoremotemountsmodel.h"
#include "maemorunconfiguration.h"
#include "maemosettingspages.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include <coreplugin/coreconstants.h>
@@ -313,11 +313,8 @@ void MaemoRunConfigurationWidget::handleActiveDeployConfigurationChanged()
{
if (m_deployablesConnected)
return;
MaemoDeployStep * const deployStep = m_runConfiguration->deployStep();
if (!deployStep)
return;
connect(deployStep->deployables().data(), SIGNAL(modelReset()),
SLOT(handleDeploySpecsChanged()));
connect(m_runConfiguration->deployConfig()->deployables().data(),
SIGNAL(modelReset()), SLOT(handleDeploySpecsChanged()));
handleDeploySpecsChanged();
m_deployablesConnected = true;
disconnect(m_runConfiguration->target(),

View File

@@ -34,7 +34,6 @@
#include "maemoruncontrol.h"
#include "maemodeploystep.h"
#include "maemoglobal.h"
#include "maemorunconfiguration.h"
#include "maemosshrunner.h"
@@ -44,7 +43,6 @@
#include <QtGui/QMessageBox>
using namespace Core;
using namespace ProjectExplorer;
namespace Qt4ProjectManager {

View File

@@ -34,7 +34,6 @@
#include "maemosshrunner.h"
#include "maemodeploystep.h"
#include "maemoglobal.h"
#include "maemoqemumanager.h"
#include "maemoremotemounter.h"
@@ -43,6 +42,7 @@
#include "maemousedportsgatherer.h"
#include <utils/ssh/sshconnection.h>
#include <utils/ssh/sshconnectionmanager.h>
#include <utils/ssh/sshremoteprocess.h>
#include <QtCore/QFileInfo>
@@ -69,7 +69,7 @@ MaemoSshRunner::MaemoSshRunner(QObject *parent,
m_mountSpecs(runConfig->remoteMounts()->mountSpecs()),
m_state(Inactive)
{
m_connection = runConfig->deployStep()->sshConnection();
m_connection = SshConnectionManager::instance().acquireConnection(m_devConfig->sshParameters());
m_mounter->setBuildConfiguration(runConfig->activeQt4BuildConfiguration());
if (debugging && runConfig->useRemoteGdb()) {
m_mountSpecs << MaemoMountSpecification(runConfig->localDirToMountForRemoteGdb(),
@@ -118,20 +118,15 @@ void MaemoSshRunner::start()
setState(Connecting);
m_exitStatus = -1;
m_freePorts = m_initialFreePorts;
if (m_connection)
disconnect(m_connection.data(), 0, this, 0);
const bool reUse = isConnectionUsable();
if (!reUse)
m_connection = SshConnection::create();
connect(m_connection.data(), SIGNAL(connected()), this,
SLOT(handleConnected()));
connect(m_connection.data(), SIGNAL(error(Utils::SshError)), this,
SLOT(handleConnectionFailure()));
if (reUse) {
if (isConnectionUsable()) {
handleConnected();
} else {
emit reportProgress(tr("Connecting to device..."));
m_connection->connectToHost(m_devConfig->sshParameters());
m_connection->connectToHost();
}
}
@@ -319,6 +314,7 @@ void MaemoSshRunner::setState(State newState)
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)

View File

@@ -0,0 +1,203 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "maemouploadandinstalldeploystep.h"
#include "maemoglobal.h"
#include "maemopackagecreationstep.h"
#include "maemopackageinstaller.h"
#include "maemopackageuploader.h"
#include "qt4maemotarget.h"
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <QtCore/QFileInfo>
#define ASSERT_BASE_STATE(state) ASSERT_STATE_GENERIC(BaseState, state, baseState())
#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(ExtendedState, state, m_extendedState)
using namespace ProjectExplorer;
using namespace Utils;
namespace Qt4ProjectManager {
namespace Internal {
MaemoUploadAndInstallDeployStep::MaemoUploadAndInstallDeployStep(BuildStepList *parent)
: AbstractMaemoDeployStep(parent, Id)
{
ctor();
}
MaemoUploadAndInstallDeployStep::MaemoUploadAndInstallDeployStep(BuildStepList *parent,
MaemoUploadAndInstallDeployStep *other)
: AbstractMaemoDeployStep(parent, other)
{
ctor();
}
void MaemoUploadAndInstallDeployStep::ctor()
{
setDefaultDisplayName(DisplayName);
m_extendedState = Inactive;
m_uploader = new MaemoPackageUploader(this);
connect(m_uploader, SIGNAL(progress(QString)),
SLOT(handleProgressReport(QString)));
connect(m_uploader, SIGNAL(uploadFinished(QString)),
SLOT(handleUploadFinished(QString)));
if (qobject_cast<AbstractDebBasedQt4MaemoTarget *>(target()))
m_installer = new MaemoDebianPackageInstaller(this);
else if (qobject_cast<AbstractRpmBasedQt4MaemoTarget *>(target()))
m_installer = new MaemoRpmPackageInstaller(this);
else
m_installer = new MaemoTarPackageInstaller(this);
connect(m_installer, SIGNAL(stdout(QString)),
SLOT(handleRemoteStdout(QString)));
connect(m_installer, SIGNAL(stderr(QString)),
SLOT(handleRemoteStderr(QString)));
connect(m_installer, SIGNAL(finished(QString)),
SLOT(handleInstallationFinished(QString)));
}
bool MaemoUploadAndInstallDeployStep::isDeploymentPossibleInternal(QString &whyNot) const
{
if (!packagingStep()) {
whyNot = tr("No packaging step found.");
return false;
}
return true;
}
bool MaemoUploadAndInstallDeployStep::isDeploymentNeeded(const QString &hostName) const
{
const AbstractMaemoPackageCreationStep * const pStep = packagingStep();
Q_ASSERT(pStep);
const MaemoDeployable d(pStep->packageFilePath(), QString());
return currentlyNeedsDeployment(hostName, d);
}
void MaemoUploadAndInstallDeployStep::startInternal()
{
Q_ASSERT(m_extendedState == Inactive);
upload();
}
void MaemoUploadAndInstallDeployStep::stopInternal()
{
ASSERT_BASE_STATE(StopRequested);
ASSERT_STATE(QList<ExtendedState>() << Uploading << Installing);
switch (m_extendedState) {
case Uploading:
m_uploader->cancelUpload();
break;
case Installing:
m_installer->cancelInstallation();
break;
case Inactive:
break;
default:
qFatal("Missing switch case in %s.", Q_FUNC_INFO);
}
setFinished();
}
void MaemoUploadAndInstallDeployStep::upload()
{
m_extendedState = Uploading;
const QString localFilePath = packagingStep()->packageFilePath();
const QString fileName = QFileInfo(localFilePath).fileName();
const QString remoteFilePath = uploadDir() + QLatin1Char('/') + fileName;
m_uploader->uploadPackage(connection(), localFilePath, remoteFilePath);
}
void MaemoUploadAndInstallDeployStep::handleUploadFinished(const QString &errorMsg)
{
ASSERT_BASE_STATE(QList<BaseState>() << Deploying << StopRequested);
ASSERT_STATE(QList<ExtendedState>() << Uploading << Inactive);
if (m_extendedState == Inactive)
return;
if (!errorMsg.isEmpty()) {
raiseError(errorMsg);
setFinished();
} else {
writeOutput(tr("Successfully uploaded package file."));
const QString remoteFilePath = uploadDir() + QLatin1Char('/')
+ QFileInfo(packagingStep()->packageFilePath()).fileName();
m_extendedState = Installing;
writeOutput(tr("Installing package to device..."));
m_installer->installPackage(connection(), remoteFilePath, true);
}
}
void MaemoUploadAndInstallDeployStep::handleInstallationFinished(const QString &errorMsg)
{
ASSERT_BASE_STATE(QList<BaseState>() << Deploying << StopRequested);
ASSERT_STATE(QList<ExtendedState>() << Installing << Inactive);
if (m_extendedState == Inactive)
return;
if (errorMsg.isEmpty()) {
setDeployed(connection()->connectionParameters().host,
MaemoDeployable(packagingStep()->packageFilePath(), QString()));
writeOutput(tr("Package installed."));
} else {
raiseError(errorMsg);
}
setFinished();
}
void MaemoUploadAndInstallDeployStep::setFinished()
{
m_extendedState = Inactive;
setDeploymentFinished();
}
QString MaemoUploadAndInstallDeployStep::uploadDir() const
{
return MaemoGlobal::homeDirOnDevice(connection()->connectionParameters().userName);
}
const QString MaemoUploadAndInstallDeployStep::Id("MaemoUploadAndInstallDeployStep");
const QString MaemoUploadAndInstallDeployStep::DisplayName
= tr("Deploy package via SFTP upload");
} // namespace Internal
} // namespace Qt4ProjectManager

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 (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef MAEMODEPLOYSTEP_H
#define MAEMODEPLOYSTEP_H
#include "abstractmaemodeploystep.h"
namespace Qt4ProjectManager {
namespace Internal {
class AbstractMaemoPackageInstaller;
class MaemoPackageUploader;
class MaemoUploadAndInstallDeployStep : public AbstractMaemoDeployStep
{
Q_OBJECT
public:
MaemoUploadAndInstallDeployStep(ProjectExplorer::BuildStepList *bc);
MaemoUploadAndInstallDeployStep(ProjectExplorer::BuildStepList *bc,
MaemoUploadAndInstallDeployStep *other);
static const QString Id;
static const QString DisplayName;
private slots:
void handleUploadFinished(const QString &errorMsg);
void handleInstallationFinished(const QString &errorMsg);
private:
enum ExtendedState { Inactive, Uploading, Installing };
virtual bool isDeploymentPossibleInternal(QString &whynot) const;
virtual bool isDeploymentNeeded(const QString &hostName) const;
virtual void startInternal();
virtual void stopInternal();
void ctor();
void upload();
void setFinished();
QString uploadDir() const;
MaemoPackageUploader *m_uploader;
AbstractMaemoPackageInstaller *m_installer;
ExtendedState m_extendedState;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // MAEMODEPLOYSTEP_H

View File

@@ -18,7 +18,6 @@ HEADERS += \
$$PWD/maemoqemumanager.h \
$$PWD/maemodeployables.h \
$$PWD/maemodeployable.h \
$$PWD/maemodeploystep.h \
$$PWD/maemodeploystepwidget.h \
$$PWD/maemodeploystepfactory.h \
$$PWD/maemoglobal.h \
@@ -49,7 +48,16 @@ HEADERS += \
$$PWD/qt4maemodeployconfiguration.h \
$$PWD/maemodeviceconfigwizard.h \
$$PWD/maemokeydeployer.h \
$$PWD/maemopertargetdeviceconfigurationlistmodel.h
$$PWD/maemopertargetdeviceconfigurationlistmodel.h \
$$PWD/maemodeployconfigurationwidget.h \
$$PWD/maemoinstalltosysrootstep.h \
$$PWD/maemodeploymentmounter.h \
$$PWD/maemopackageuploader.h \
$$PWD/maemopackageinstaller.h \
$$PWD/maemoremotecopyfacility.h \
$$PWD/abstractmaemodeploystep.h \
$$PWD/maemodeploybymountstep.h \
$$PWD/maemouploadandinstalldeploystep.h
SOURCES += \
$$PWD/maemoconfigtestdialog.cpp \
@@ -69,7 +77,6 @@ SOURCES += \
$$PWD/maemodeployablelistmodel.cpp \
$$PWD/maemoqemumanager.cpp \
$$PWD/maemodeployables.cpp \
$$PWD/maemodeploystep.cpp \
$$PWD/maemodeploystepwidget.cpp \
$$PWD/maemodeploystepfactory.cpp \
$$PWD/maemoglobal.cpp \
@@ -99,7 +106,16 @@ SOURCES += \
$$PWD/qt4maemodeployconfiguration.cpp \
$$PWD/maemodeviceconfigwizard.cpp \
$$PWD/maemokeydeployer.cpp \
$$PWD/maemopertargetdeviceconfigurationlistmodel.cpp
$$PWD/maemopertargetdeviceconfigurationlistmodel.cpp \
$$PWD/maemodeployconfigurationwidget.cpp \
$$PWD/maemoinstalltosysrootstep.cpp \
$$PWD/maemodeploymentmounter.cpp \
$$PWD/maemopackageuploader.cpp \
$$PWD/maemopackageinstaller.cpp \
$$PWD/maemoremotecopyfacility.cpp \
$$PWD/abstractmaemodeploystep.cpp \
$$PWD/maemodeploybymountstep.cpp \
$$PWD/maemouploadandinstalldeploystep.cpp
FORMS += \
$$PWD/maemoconfigtestdialog.ui \
@@ -118,6 +134,8 @@ FORMS += \
$$PWD/maemodeviceconfigwizardpreviouskeysetupcheckpage.ui \
$$PWD/maemodeviceconfigwizardreusekeyscheckpage.ui \
$$PWD/maemodeviceconfigwizardkeycreationpage.ui \
$$PWD/maemodeviceconfigwizardkeydeploymentpage.ui
$$PWD/maemodeviceconfigwizardkeydeploymentpage.ui \
$$PWD/maemodeployconfigurationwidget.ui \
$$PWD/maemodeviceconfigwizardlogindatapage.ui
RESOURCES += $$PWD/qt-maemo.qrc

View File

@@ -31,36 +31,191 @@
**
**************************************************************************/
#include "maemodeploystep.h"
#include "maemopackagecreationstep.h"
#include "qt4maemodeployconfiguration.h"
#include "maemodeploybymountstep.h"
#include "maemodeployconfigurationwidget.h"
#include "maemodeployables.h"
#include "maemoinstalltosysrootstep.h"
#include "maemopertargetdeviceconfigurationlistmodel.h"
#include "maemopackagecreationstep.h"
#include "maemouploadandinstalldeploystep.h"
#include "qt4maemotarget.h"
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/target.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <qt4projectmanager/qt4projectmanagerconstants.h>
#include <qt4projectmanager/qt4target.h>
using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;
using namespace ProjectExplorer;
Qt4MaemoDeployConfigurationFactory::Qt4MaemoDeployConfigurationFactory(QObject *parent) :
ProjectExplorer::DeployConfigurationFactory(parent)
namespace Qt4ProjectManager {
namespace Internal {
namespace {
const QString OldDeployConfigId = QLatin1String("2.2MaemoDeployConfig");
} // namespace
Qt4MaemoDeployConfiguration::Qt4MaemoDeployConfiguration(Target *target,
const QString &id) : DeployConfiguration(target, id)
{
// A MaemoDeployables object is only dependent on the active build
// configuration and therefore can (and should) be shared among all
// deploy steps. The per-target device configurations model is
// similarly only dependent on the target.
const QList<DeployConfiguration *> &deployConfigs
= this->target()->deployConfigurations();
foreach (const DeployConfiguration * const dc, deployConfigs) {
const Qt4MaemoDeployConfiguration * const mdc
= qobject_cast<const Qt4MaemoDeployConfiguration *>(dc);
if (mdc) {
m_deployables = mdc->deployables();
m_devConfModel = mdc->m_devConfModel;
break;
}
}
if (!m_deployables) {
m_deployables = QSharedPointer<MaemoDeployables>(new MaemoDeployables(qobject_cast<Qt4BaseTarget *>(target)));
m_devConfModel = new MaemoPerTargetDeviceConfigurationListModel(this, target);
}
}
Qt4MaemoDeployConfiguration::Qt4MaemoDeployConfiguration(ProjectExplorer::Target *target,
DeployConfiguration *source) : DeployConfiguration(target, source)
{
m_deployables = qobject_cast<Qt4MaemoDeployConfiguration *>(source)->deployables();
}
Qt4MaemoDeployConfiguration::~Qt4MaemoDeployConfiguration() {}
DeployConfigurationWidget *Qt4MaemoDeployConfiguration::configurationWidget() const
{
return new MaemoDeployConfigurationWidget;
}
const QString Qt4MaemoDeployConfiguration::FremantleWithPackagingId
= QLatin1String("DeployToFremantleWithPackaging");
const QString Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId
= QLatin1String("DeployToFremantleWithoutPackaging");
const QString Qt4MaemoDeployConfiguration::HarmattanId
= QLatin1String("DeployToHarmattan");
const QString Qt4MaemoDeployConfiguration::MeegoId
= QLatin1String("DeployToMeego");
const QString Qt4MaemoDeployConfiguration::GenericLinuxId
= QLatin1String("DeployToGenericLinux");
Qt4MaemoDeployConfigurationFactory::Qt4MaemoDeployConfigurationFactory(QObject *parent)
: DeployConfigurationFactory(parent)
{ }
ProjectExplorer::DeployConfiguration *Qt4MaemoDeployConfigurationFactory::create(ProjectExplorer::Target *parent, const QString &id)
QStringList Qt4MaemoDeployConfigurationFactory::availableCreationIds(Target *parent) const
{
ProjectExplorer::DeployConfiguration *dc = ProjectExplorer::DeployConfigurationFactory::create(parent, id);
QStringList ids;
if (qobject_cast<Qt4Maemo5Target *>(parent)) {
ids << Qt4MaemoDeployConfiguration::FremantleWithPackagingId
<< Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId;
} else if (qobject_cast<Qt4HarmattanTarget *>(parent)) {
ids << Qt4MaemoDeployConfiguration::HarmattanId;
} else if (qobject_cast<Qt4MeegoTarget *>(parent)) {
ids << Qt4MaemoDeployConfiguration::MeegoId;
} /*else if (qobject_cast<Qt4BaseTarget *>(parent)) { // TODO: Check for Linux
ids << Qt4MaemoDeployConfiguration::GenericLinuxId;
}*/
if (!dc)
return 0;
if (parent->id() == QLatin1String(Constants::MAEMO5_DEVICE_TARGET_ID))
dc->setDefaultDisplayName(tr("Deploy to Maemo5 device"));
if (parent->id() == QLatin1String(Constants::HARMATTAN_DEVICE_TARGET_ID))
dc->setDefaultDisplayName(tr("Deploy to Harmattan device"));
if (parent->id() == QLatin1String(Constants::MEEGO_DEVICE_TARGET_ID))
dc->setDefaultDisplayName(tr("Deploy to Meego device"));
dc->stepList()->insertStep(0, new MaemoPackageCreationStep(dc->stepList()));
dc->stepList()->insertStep(1, new MaemoDeployStep(dc->stepList()));
return ids;
}
QString Qt4MaemoDeployConfigurationFactory::displayNameForId(const QString &id) const
{
if (id == Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId)
return tr("Copy files to Maemo5 device");
else if (id == Qt4MaemoDeployConfiguration::FremantleWithPackagingId)
return tr("Build Debian package and install to Maemo5 device");
else if (id == Qt4MaemoDeployConfiguration::HarmattanId)
return tr("Build Debian package and install to Harmattan device");
else if (id == Qt4MaemoDeployConfiguration::MeegoId)
return tr("Build RPM package and install to Meego device");
else if (id == Qt4MaemoDeployConfiguration::GenericLinuxId)
return tr("Build tarball and install to Linux host");
return QString();
}
bool Qt4MaemoDeployConfigurationFactory::canCreate(Target *parent,
const QString &id) const
{
return availableCreationIds(parent).contains(id);
}
DeployConfiguration *Qt4MaemoDeployConfigurationFactory::create(Target *parent,
const QString &id)
{
Q_ASSERT(canCreate(parent, id));
DeployConfiguration * const dc
= new Qt4MaemoDeployConfiguration(parent, id);
dc->setDefaultDisplayName(displayNameForId(id));
if (id == Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId) {
dc->stepList()->insertStep(0, new MaemoCopyToSysrootStep(dc->stepList()));
dc->stepList()->insertStep(1, new MaemoMountAndCopyDeployStep(dc->stepList()));
} else if (id == Qt4MaemoDeployConfiguration::FremantleWithPackagingId) {
dc->stepList()->insertStep(0, new MaemoDebianPackageCreationStep(dc->stepList()));
dc->stepList()->insertStep(1, new MaemoInstallDebianPackageToSysrootStep(dc->stepList()));
dc->stepList()->insertStep(2, new MaemoMountAndInstallDeployStep(dc->stepList()));
} else if (id == Qt4MaemoDeployConfiguration::HarmattanId) {
dc->stepList()->insertStep(0, new MaemoDebianPackageCreationStep(dc->stepList()));
dc->stepList()->insertStep(1, new MaemoInstallDebianPackageToSysrootStep(dc->stepList()));
dc->stepList()->insertStep(2, new MaemoUploadAndInstallDeployStep(dc->stepList()));
} else if (id == Qt4MaemoDeployConfiguration::MeegoId) {
dc->stepList()->insertStep(0, new MaemoRpmPackageCreationStep(dc->stepList()));
dc->stepList()->insertStep(1, new MaemoInstallRpmPackageToSysrootStep(dc->stepList()));
dc->stepList()->insertStep(2, new MaemoUploadAndInstallDeployStep(dc->stepList()));
} else if (id == Qt4MaemoDeployConfiguration::GenericLinuxId) {
dc->stepList()->insertStep(0, new MaemoTarPackageCreationStep(dc->stepList()));
dc->stepList()->insertStep(1, new MaemoUploadAndInstallDeployStep(dc->stepList()));
}
return dc;
}
bool Qt4MaemoDeployConfigurationFactory::canRestore(Target *parent,
const QVariantMap &map) const
{
return canCreate(parent, idFromMap(map))
|| (idFromMap(map) == OldDeployConfigId
&& qobject_cast<AbstractQt4MaemoTarget *>(parent));
}
DeployConfiguration *Qt4MaemoDeployConfigurationFactory::restore(Target *parent,
const QVariantMap &map)
{
if (!canRestore(parent, map))
return 0;
QString id = idFromMap(map);
if (id == OldDeployConfigId) {
if (qobject_cast<Qt4Maemo5Target *>(parent))
id = Qt4MaemoDeployConfiguration::FremantleWithPackagingId;
else if (qobject_cast<Qt4HarmattanTarget *>(parent))
id = Qt4MaemoDeployConfiguration::HarmattanId;
else if (qobject_cast<Qt4MeegoTarget *>(parent))
id = Qt4MaemoDeployConfiguration::MeegoId;
}
Qt4MaemoDeployConfiguration * const dc
= new Qt4MaemoDeployConfiguration(parent, id);
if (!dc->fromMap(map)) {
delete dc;
return 0;
}
return dc;
}
DeployConfiguration *Qt4MaemoDeployConfigurationFactory::clone(Target *parent,
DeployConfiguration *product)
{
if (!canClone(parent, product))
return 0;
return new Qt4MaemoDeployConfiguration(parent, product);
}
} // namespace Internal
} // namespace Qt4ProjectManager

View File

@@ -34,12 +34,46 @@
#ifndef QT4PROJECTMANAGER_QT4DEPLOYCONFIGURATION_H
#define QT4PROJECTMANAGER_QT4DEPLOYCONFIGURATION_H
#include"maemodeployables.h"
#include <projectexplorer/deployconfiguration.h>
#include <QtCore/QSharedPointer>
namespace Qt4ProjectManager {
namespace Internal {
class MaemoPerTargetDeviceConfigurationListModel;
class Qt4MaemoDeployConfiguration : public ProjectExplorer::DeployConfiguration
{
Q_OBJECT
public:
virtual ~Qt4MaemoDeployConfiguration();
virtual ProjectExplorer::DeployConfigurationWidget *configurationWidget() const;
QSharedPointer<MaemoDeployables> deployables() const { return m_deployables; }
MaemoPerTargetDeviceConfigurationListModel *deviceConfigModel() const { return m_devConfModel; }
static const QString FremantleWithPackagingId;
static const QString FremantleWithoutPackagingId;
static const QString HarmattanId;
static const QString MeegoId;
static const QString GenericLinuxId;
private:
friend class Qt4MaemoDeployConfigurationFactory;
Qt4MaemoDeployConfiguration(ProjectExplorer::Target *target,
const QString &id);
Qt4MaemoDeployConfiguration(ProjectExplorer::Target *target,
ProjectExplorer::DeployConfiguration *source);
QSharedPointer<MaemoDeployables> m_deployables;
MaemoPerTargetDeviceConfigurationListModel *m_devConfModel;
};
class Target;
class Qt4MaemoDeployConfigurationFactory : public ProjectExplorer::DeployConfigurationFactory
{
@@ -48,7 +82,16 @@ class Qt4MaemoDeployConfigurationFactory : public ProjectExplorer::DeployConfigu
public:
explicit Qt4MaemoDeployConfigurationFactory(QObject *parent = 0);
ProjectExplorer::DeployConfiguration *create(ProjectExplorer::Target *parent, const QString &id);
virtual QStringList availableCreationIds(ProjectExplorer::Target *parent) const;
virtual QString displayNameForId(const QString &id) const;
virtual bool canCreate(ProjectExplorer::Target *parent, const QString &id) const;
virtual ProjectExplorer::DeployConfiguration *create(ProjectExplorer::Target *parent, const QString &id);
virtual bool canRestore(ProjectExplorer::Target *parent,
const QVariantMap &map) const;
virtual ProjectExplorer::DeployConfiguration *restore(ProjectExplorer::Target *parent,
const QVariantMap &map);
virtual ProjectExplorer::DeployConfiguration *clone(ProjectExplorer::Target *parent,
ProjectExplorer::DeployConfiguration *product);
};
} // namespace Internal

View File

@@ -35,7 +35,6 @@
#include "maemoglobal.h"
#include "maemopackagecreationstep.h"
#include "maemopertargetdeviceconfigurationlistmodel.h"
#include "maemorunconfiguration.h"
#include "maemotoolchain.h"
#include "qt4maemodeployconfiguration.h"
@@ -110,8 +109,7 @@ bool adaptTagValue(QByteArray &document, const QByteArray &fieldName,
AbstractQt4MaemoTarget::AbstractQt4MaemoTarget(Qt4Project *parent, const QString &id) :
Qt4BaseTarget(parent, id),
m_filesWatcher(new QFileSystemWatcher(this)),
m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this)),
m_deployConfigurationFactory(new Qt4MaemoDeployConfigurationFactory(this))
m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this))
{
setIcon(QIcon(":/projectexplorer/images/MaemoDevice.png"));
connect(parent, SIGNAL(addedTarget(ProjectExplorer::Target*)),
@@ -164,11 +162,6 @@ Qt4BuildConfigurationFactory *AbstractQt4MaemoTarget::buildConfigurationFactory(
return m_buildConfigurationFactory;
}
ProjectExplorer::DeployConfigurationFactory *AbstractQt4MaemoTarget::deployConfigurationFactory() const
{
return m_deployConfigurationFactory;
}
QString AbstractQt4MaemoTarget::defaultBuildDirectory() const
{
//TODO why?
@@ -370,12 +363,6 @@ bool AbstractQt4MaemoTarget::initPackagingSettingsFromOtherTarget()
return initAdditionalPackagingSettingsFromOtherTarget();
}
void AbstractQt4MaemoTarget::initDeviceConfigurationsModel()
{
m_deviceConfigurationsListModel
= new MaemoPerTargetDeviceConfigurationListModel(this);
}
void AbstractQt4MaemoTarget::raiseError(const QString &reason)
{
QMessageBox::critical(0, tr("Error creating Maemo templates"), reason);
@@ -713,7 +700,7 @@ AbstractQt4MaemoTarget::ActionStatus AbstractDebBasedQt4MaemoTarget::createSpeci
QProcess dh_makeProc;
QString error;
const Qt4BuildConfiguration * const bc = activeBuildConfiguration();
MaemoPackageCreationStep::preparePackagingProcess(&dh_makeProc, bc,
AbstractMaemoPackageCreationStep::preparePackagingProcess(&dh_makeProc, bc,
projectDir.path() + QLatin1Char('/') + PackagingDirName);
const QString dhMakeDebianDir = projectDir.path() + QLatin1Char('/')
+ PackagingDirName + QLatin1String("/debian");
@@ -721,7 +708,7 @@ AbstractQt4MaemoTarget::ActionStatus AbstractDebBasedQt4MaemoTarget::createSpeci
const QStringList dh_makeArgs = QStringList() << QLatin1String("dh_make")
<< QLatin1String("-s") << QLatin1String("-n") << QLatin1String("-p")
<< (defaultPackageFileName() + QLatin1Char('_')
+ MaemoPackageCreationStep::DefaultVersionNumber);
+ AbstractMaemoPackageCreationStep::DefaultVersionNumber);
if (!MaemoGlobal::callMad(dh_makeProc, dh_makeArgs, activeBuildConfiguration()->qtVersion(), true)
|| !dh_makeProc.waitForStarted()) {
raiseError(tr("Unable to create Debian templates: dh_make failed (%1)")
@@ -1054,7 +1041,6 @@ Qt4Maemo5Target::Qt4Maemo5Target(Qt4Project *parent, const QString &id)
: AbstractDebBasedQt4MaemoTarget(parent, id)
{
setDisplayName(defaultDisplayName());
initDeviceConfigurationsModel();
}
Qt4Maemo5Target::~Qt4Maemo5Target() {}
@@ -1084,7 +1070,6 @@ Qt4HarmattanTarget::Qt4HarmattanTarget(Qt4Project *parent, const QString &id)
: AbstractDebBasedQt4MaemoTarget(parent, id)
{
setDisplayName(defaultDisplayName());
initDeviceConfigurationsModel();
}
Qt4HarmattanTarget::~Qt4HarmattanTarget() {}
@@ -1116,7 +1101,6 @@ Qt4MeegoTarget::Qt4MeegoTarget(Qt4Project *parent, const QString &id)
: AbstractRpmBasedQt4MaemoTarget(parent, id)
{
setDisplayName(defaultDisplayName());
initDeviceConfigurationsModel();
}
Qt4MeegoTarget::~Qt4MeegoTarget() {}

View File

@@ -46,7 +46,6 @@ QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher)
namespace Qt4ProjectManager {
class Qt4Project;
namespace Internal {
class MaemoPerTargetDeviceConfigurationListModel;
class Qt4MaemoDeployConfigurationFactory;
class AbstractQt4MaemoTarget : public Qt4BaseTarget
@@ -58,7 +57,6 @@ public:
virtual ~AbstractQt4MaemoTarget();
Internal::Qt4BuildConfigurationFactory *buildConfigurationFactory() const;
ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
QString defaultBuildDirectory() const;
void createApplicationProFiles();
QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n);
@@ -87,9 +85,6 @@ public:
// TODO: Is this needed with the ABI info we have?
DebugArchitecture debugArchitecture() const;
MaemoPerTargetDeviceConfigurationListModel *deviceConfigurationsModel() const {
return m_deviceConfigurationsListModel;
}
QList<ProjectExplorer::ToolChain *> possibleToolChains(ProjectExplorer::BuildConfiguration *bc) const;
protected:
@@ -122,8 +117,6 @@ private:
virtual bool initAdditionalPackagingSettingsFromOtherTarget()=0;
Qt4BuildConfigurationFactory *m_buildConfigurationFactory;
Qt4MaemoDeployConfigurationFactory *m_deployConfigurationFactory;
MaemoPerTargetDeviceConfigurationListModel * m_deviceConfigurationsListModel;
};

View File

@@ -35,11 +35,11 @@
#include "buildconfigurationinfo.h"
#include "qt4project.h"
#include "qt4projectmanagerconstants.h"
#include "qt-maemo/maemodeploystep.h"
#include "maemoglobal.h"
#include "qt-maemo/maemopackagecreationstep.h"
#include "qt-maemo/maemorunconfiguration.h"
#include "qt-maemo/qt4maemotarget.h"
#include "maemopackagecreationstep.h"
#include "maemorunconfiguration.h"
#include "qt4maemodeployconfiguration.h"
#include "qt4maemotarget.h"
#include <projectexplorer/deployconfiguration.h>
#include <projectexplorer/projectexplorerconstants.h>
@@ -198,12 +198,18 @@ ProjectExplorer::Target *Qt4MaemoTargetFactory::create(ProjectExplorer::Project
return 0;
AbstractQt4MaemoTarget *target = 0;
if (id == QLatin1String(Constants::MAEMO5_DEVICE_TARGET_ID))
QStringList deployConfigIds;
if (id == QLatin1String(Constants::MAEMO5_DEVICE_TARGET_ID)) {
target = new Qt4Maemo5Target(static_cast<Qt4Project *>(parent), id);
else if (id == QLatin1String(Constants::HARMATTAN_DEVICE_TARGET_ID))
deployConfigIds << Qt4MaemoDeployConfiguration::FremantleWithPackagingId
<< Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId;
} else if (id == QLatin1String(Constants::HARMATTAN_DEVICE_TARGET_ID)) {
target = new Qt4HarmattanTarget(static_cast<Qt4Project *>(parent), id);
else if (id == QLatin1String(Constants::MEEGO_DEVICE_TARGET_ID))
deployConfigIds << Qt4MaemoDeployConfiguration::HarmattanId;
} else if (id == QLatin1String(Constants::MEEGO_DEVICE_TARGET_ID)) {
target = new Qt4MeegoTarget(static_cast<Qt4Project *>(parent), id);
deployConfigIds << Qt4MaemoDeployConfiguration::MeegoId;
}
Q_ASSERT(target);
foreach (const BuildConfigurationInfo &info, infos)
@@ -211,7 +217,9 @@ ProjectExplorer::Target *Qt4MaemoTargetFactory::create(ProjectExplorer::Project
info.version, info.buildConfig,
info.additionalArguments, info.directory);
target->addDeployConfiguration(target->deployConfigurationFactory()->create(target, ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
foreach (const QString &deployConfigId, deployConfigIds) {
target->addDeployConfiguration(target->createDeployConfiguration(deployConfigId));
}
target->createApplicationProFiles();
if (target->runConfigurations().isEmpty())
target->addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(target));

View File

@@ -43,6 +43,7 @@
#include <projectexplorer/project.h>
#include <projectexplorer/toolchainmanager.h>
#include <symbianutils/symbiandevicemanager.h>
#include <extensionsystem/pluginmanager.h>
#include <QtGui/QPainter>
#include <QtGui/QApplication>
@@ -53,8 +54,7 @@ Qt4SymbianTarget::Qt4SymbianTarget(Qt4Project *parent, const QString &id) :
Qt4BaseTarget(parent, id),
m_connectedPixmap(QLatin1String(":/projectexplorer/images/ConnectionOn.png")),
m_disconnectedPixmap(QLatin1String(":/projectexplorer/images/ConnectionOff.png")),
m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this)),
m_deployConfigurationFactory(new S60DeployConfigurationFactory(this))
m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this))
{
setDisplayName(defaultDisplayName(id));
setIcon(iconForId(id));
@@ -92,11 +92,6 @@ Qt4BuildConfigurationFactory *Qt4SymbianTarget::buildConfigurationFactory() cons
return m_buildConfigurationFactory;
}
ProjectExplorer::DeployConfigurationFactory *Qt4SymbianTarget::deployConfigurationFactory() const
{
return m_deployConfigurationFactory;
}
QList<ProjectExplorer::ToolChain *> Qt4SymbianTarget::possibleToolChains(ProjectExplorer::BuildConfiguration *bc) const
{
QList<ProjectExplorer::ToolChain *> candidates = Qt4BaseTarget::possibleToolChains(bc);

View File

@@ -52,7 +52,6 @@ public:
virtual ~Qt4SymbianTarget();
Internal::Qt4BuildConfigurationFactory *buildConfigurationFactory() const;
ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
QList<ProjectExplorer::ToolChain *> possibleToolChains(ProjectExplorer::BuildConfiguration *bc) const;
@@ -76,7 +75,6 @@ private:
const QPixmap m_disconnectedPixmap;
Internal::Qt4BuildConfigurationFactory *m_buildConfigurationFactory;
ProjectExplorer::DeployConfigurationFactory *m_deployConfigurationFactory;
};
} // namespace Internal
} // namespace Qt4ProjectManager

View File

@@ -197,7 +197,7 @@ ProjectExplorer::Target *Qt4SymbianTargetFactory::create(ProjectExplorer::Projec
info.version, info.buildConfig,
info.additionalArguments, info.directory);
t->addDeployConfiguration(t->deployConfigurationFactory()->create(t, ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
t->addDeployConfiguration(t->createDeployConfiguration(ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID));
t->createApplicationProFiles();

View File

@@ -38,6 +38,7 @@
#include "s60emulatorrunconfiguration.h"
#include "s60devicerunconfiguration.h"
#include "s60createpackagestep.h"
#include "s60deployconfiguration.h"
#include "s60deploystep.h"
#include "s60runcontrolfactory.h"
@@ -125,6 +126,7 @@ S60Manager::S60Manager(QObject *parent) : QObject(parent)
addAutoReleasedObject(new S60DeviceDebugRunControlFactory);
addAutoReleasedObject(new Qt4SymbianTargetFactory);
addAutoReleasedObject(new S60DeployConfigurationFactory);
addAutoReleasedObject(new S60PublishingWizardFactoryOvi);