aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPawel Polanski <[email protected]>2011-01-07 15:47:22 +0100
committerPawel Polanski <[email protected]>2011-01-14 14:21:06 +0100
commit051011bc37c08977977777bb436ab3bd0bc3daf8 (patch)
tree314bb8fe521fa6bfbea4f4a03203d5d4c0305e4c /src
parentd5b2954da839cbe60aea8ae78756c10c67c8cfa4 (diff)
Symbian: Adjust Creator to work with CODA
Reviewed-by: hjk
Diffstat (limited to 'src')
-rw-r--r--src/libs/utils/ipaddresslineedit.cpp112
-rw-r--r--src/libs/utils/ipaddresslineedit.h73
-rw-r--r--src/libs/utils/utils-lib.pri6
-rw-r--r--src/plugins/debugger/debuggerstartparameters.h12
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp47
-rw-r--r--src/plugins/debugger/gdb/tcftrkgdbadapter.cpp14
-rw-r--r--src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp76
-rw-r--r--src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h20
-rw-r--r--src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp124
-rw-r--r--src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.h10
-rw-r--r--src/plugins/qt4projectmanager/qt-s60/s60deploystep.cpp548
-rw-r--r--src/plugins/qt4projectmanager/qt-s60/s60deploystep.h67
-rw-r--r--src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp380
-rw-r--r--src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h50
-rw-r--r--src/plugins/qt4projectmanager/qt4target.cpp65
-rw-r--r--src/plugins/qt4projectmanager/qt4target.h3
-rw-r--r--src/shared/symbianutils/launcher.cpp4
-rw-r--r--src/shared/symbianutils/tcftrkdevice.cpp44
-rw-r--r--src/shared/symbianutils/tcftrkdevice.h7
-rw-r--r--src/shared/symbianutils/tcftrkmessage.cpp6
-rw-r--r--src/shared/symbianutils/tcftrkmessage.h1
21 files changed, 1391 insertions, 278 deletions
diff --git a/src/libs/utils/ipaddresslineedit.cpp b/src/libs/utils/ipaddresslineedit.cpp
new file mode 100644
index 00000000000..3eaf683af28
--- /dev/null
+++ b/src/libs/utils/ipaddresslineedit.cpp
@@ -0,0 +1,112 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation ([email protected])
+**
+** 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 [email protected].
+**
+**************************************************************************/
+
+#include "ipaddresslineedit.h"
+
+#include <QtGui/QRegExpValidator>
+
+namespace Utils {
+
+// ------------------ IpAddressLineEditPrivate
+
+class IpAddressLineEditPrivate
+{
+public:
+ IpAddressLineEditPrivate();
+
+ QValidator *m_ipAddressValidator;
+ QColor m_validColor;
+ bool m_addressIsValid;
+};
+
+IpAddressLineEditPrivate::IpAddressLineEditPrivate() :
+ m_addressIsValid(true)
+{
+}
+
+IpAddressLineEdit::IpAddressLineEdit(QWidget* parent) :
+ QLineEdit(parent),
+ m_d(new IpAddressLineEditPrivate())
+{
+ m_d->m_validColor = palette().color(QPalette::Text);
+
+ const char * ipAddressRegExpPattern = "^\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
+ "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
+ "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
+ "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"
+ "((:)(6553[0-5]|655[0-2]\\d|65[0-4]\\d\\d|6[0-4]\\d{3}|[1-5]\\d{4}|[1-9]\\d{0,3}|0))?$";
+
+ QRegExp ipAddressRegExp(ipAddressRegExpPattern);
+ m_d->m_ipAddressValidator = new QRegExpValidator(ipAddressRegExp, this);
+
+ connect(this, SIGNAL(textChanged(QString)), this, SLOT(validateAddress(QString)));
+}
+
+IpAddressLineEdit::~IpAddressLineEdit()
+{
+ delete m_d;
+}
+
+bool IpAddressLineEdit::isValid() const
+{
+ return m_d->m_addressIsValid;
+}
+
+void IpAddressLineEdit::validateAddress(const QString &string)
+{
+ QString copy(string);
+ int offset(0);
+ bool isValid = m_d->m_ipAddressValidator->validate(copy, offset) == QValidator::Acceptable;
+
+ if (isValid != m_d->m_addressIsValid) {
+ if (isValid) {
+ QPalette palette(palette());
+ palette.setColor(QPalette::Text, m_d->m_validColor);
+ setPalette(palette);
+ emit validAddressChanged(copy);
+ } else {
+ QPalette palette(palette());
+ palette.setColor(QPalette::Text, Qt::red);
+ setPalette(palette);
+ setToolTip(tr("The IP address is not valid."));
+ }
+ m_d->m_addressIsValid = isValid;
+ } else {
+ if (isValid)
+ emit validAddressChanged(copy);
+ else
+ emit invalidAddressChanged();
+ }
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/ipaddresslineedit.h b/src/libs/utils/ipaddresslineedit.h
new file mode 100644
index 00000000000..05ef956274a
--- /dev/null
+++ b/src/libs/utils/ipaddresslineedit.h
@@ -0,0 +1,73 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation ([email protected])
+**
+** 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 [email protected].
+**
+**************************************************************************/
+
+#ifndef IPADDRESSLINEEDIT_H
+#define IPADDRESSLINEEDIT_H
+
+#include "utils_global.h"
+
+#include <QtGui/QLineEdit>
+
+namespace Utils {
+
+class IpAddressLineEditPrivate;
+
+/**
+ * A LineEdit widget that validates the IP address inserted.
+ * The valid address example is 192.168.1.12 or 192.168.1.12:8080
+ */
+
+class QTCREATOR_UTILS_EXPORT IpAddressLineEdit : public QLineEdit
+{
+ Q_OBJECT
+public:
+ explicit IpAddressLineEdit(QWidget* parent = 0);
+ virtual ~IpAddressLineEdit();
+
+ bool isValid() const;
+
+signals:
+ void validAddressChanged(const QString& address);
+ void invalidAddressChanged();
+
+private slots:
+ void validateAddress(const QString &string);
+
+private:
+ IpAddressLineEditPrivate *m_d;
+};
+
+} // namespace Utils
+
+
+#endif // IPADDRESSLINEEDIT_H
diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri
index 8f710f64221..7d83452b788 100644
--- a/src/libs/utils/utils-lib.pri
+++ b/src/libs/utils/utils-lib.pri
@@ -54,7 +54,8 @@ SOURCES += $$PWD/environment.cpp \
$$PWD/historycompleter.cpp \
$$PWD/buildablehelperlibrary.cpp \
$$PWD/annotateditemdelegate.cpp \
- $$PWD/fileinprojectfinder.cpp
+ $$PWD/fileinprojectfinder.cpp \
+ $$PWD/ipaddresslineedit.cpp
win32 {
SOURCES += $$PWD/abstractprocess_win.cpp \
@@ -119,7 +120,8 @@ HEADERS += $$PWD/environment.h \
$$PWD/historycompleter.h \
$$PWD/buildablehelperlibrary.h \
$$PWD/annotateditemdelegate.h \
- $$PWD/fileinprojectfinder.h
+ $$PWD/fileinprojectfinder.h \
+ $$PWD/ipaddresslineedit.h
FORMS += $$PWD/filewizardpage.ui \
$$PWD/projectintropage.ui \
diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h
index 5e02a131f65..d2dc6c83b9d 100644
--- a/src/plugins/debugger/debuggerstartparameters.h
+++ b/src/plugins/debugger/debuggerstartparameters.h
@@ -51,6 +51,11 @@ namespace Debugger {
class DEBUGGER_EXPORT DebuggerStartParameters
{
public:
+ enum CommunicationChannel {
+ CommunicationChannelTcpIp,
+ CommunicationChannelUsb
+ };
+
DebuggerStartParameters()
: isSnapshot(false),
attachPID(-1),
@@ -62,7 +67,9 @@ public:
connParams(Core::SshConnectionParameters::NoProxy),
toolChainType(ProjectExplorer::ToolChain_UNKNOWN),
startMode(NoStartMode),
- executableUid(0)
+ executableUid(0),
+ communicationChannel(CommunicationChannelTcpIp),
+ serverPort(0)
{}
QString executable;
@@ -112,6 +119,9 @@ public:
// For Symbian debugging.
quint32 executableUid;
+ CommunicationChannel communicationChannel;
+ QString serverAddress;
+ quint16 serverPort;
};
} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index a7c0ac61e44..b5b12dc0230 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1717,33 +1717,34 @@ AbstractGdbAdapter *GdbEngine::createAdapter()
{
const DebuggerStartParameters &sp = startParameters();
switch (sp.toolChainType) {
- case ProjectExplorer::ToolChain_WINSCW: // S60
- case ProjectExplorer::ToolChain_GCCE:
- case ProjectExplorer::ToolChain_RVCT2_ARMV5:
- case ProjectExplorer::ToolChain_RVCT2_ARMV6:
- case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
- case ProjectExplorer::ToolChain_GCCE_GNUPOC:
- // FIXME: 1 of 3 testing hacks.
- if (sp.processArgs.startsWith(__("@tcf@ ")))
- return new TcfTrkGdbAdapter(this);
+ case ProjectExplorer::ToolChain_WINSCW: // S60
+ case ProjectExplorer::ToolChain_GCCE:
+ case ProjectExplorer::ToolChain_RVCT2_ARMV5:
+ case ProjectExplorer::ToolChain_RVCT2_ARMV6:
+ case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
+ case ProjectExplorer::ToolChain_GCCE_GNUPOC:
+ // FIXME: 1 of 3 testing hacks.
+ if (sp.communicationChannel == DebuggerStartParameters::CommunicationChannelTcpIp)
+ return new TcfTrkGdbAdapter(this);
+ else
return new TrkGdbAdapter(this);
- default:
- break;
+ default:
+ break;
}
switch (sp.startMode) {
- case AttachCore:
- return new CoreGdbAdapter(this);
- case AttachToRemote:
- return new RemoteGdbServerAdapter(this, sp.toolChainType);
- case StartRemoteGdb:
- return new RemotePlainGdbAdapter(this);
- case AttachExternal:
- return new AttachGdbAdapter(this);
- default:
- if (sp.useTerminal)
- return new TermGdbAdapter(this);
- return new LocalPlainGdbAdapter(this);
+ case AttachCore:
+ return new CoreGdbAdapter(this);
+ case AttachToRemote:
+ return new RemoteGdbServerAdapter(this, sp.toolChainType);
+ case StartRemoteGdb:
+ return new RemotePlainGdbAdapter(this);
+ case AttachExternal:
+ return new AttachGdbAdapter(this);
+ default:
+ if (sp.useTerminal)
+ return new TermGdbAdapter(this);
+ return new LocalPlainGdbAdapter(this);
}
}
diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp
index d67cdf35393..240afa8d001 100644
--- a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp
@@ -997,7 +997,6 @@ void TcfTrkGdbAdapter::interruptInferior()
void TcfTrkGdbAdapter::startAdapter()
{
-
m_snapshot.fullReset();
m_session.reset();
m_firstResumableExeLoadedEvent = true;
@@ -1019,17 +1018,10 @@ void TcfTrkGdbAdapter::startAdapter()
if (debug)
qDebug() << parameters.processArgs;
- // Fixme: 1 of 3 testing hacks.
- if (m_remoteArguments.size() < 5 || m_remoteArguments.at(0) != __("@tcf@")) {
- m_engine->handleAdapterStartFailed(_("Parameter error"), QString());
- return;
- }
- m_remoteExecutable = m_remoteArguments.at(1);
- m_uid = m_remoteArguments.at(2).toUInt(0, 16);
- m_symbolFile = m_remoteArguments.at(3);
- tcfTrkAddress = splitIpAddressSpec(m_remoteArguments.at(4), 1534);
- m_remoteArguments.clear();
+ m_uid = parameters.executableUid;
+ tcfTrkAddress = QPair<QString, unsigned short>(parameters.serverAddress, parameters.serverPort);
+// m_remoteArguments.clear(); FIXME: Should this be here?
// Unixish gdbs accept only forward slashes
m_symbolFile.replace(QLatin1Char('\\'), QLatin1Char('/'));
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
index 411ecb9b072..fcbf9f6ddd4 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
@@ -58,6 +58,11 @@ const char * const S60_DC_PREFIX("Qt4ProjectManager.S60DeployConfiguration.");
const char * const SERIAL_PORT_NAME_KEY("Qt4ProjectManager.S60DeployConfiguration.SerialPortName");
const char * const INSTALLATION_DRIVE_LETTER_KEY("Qt4ProjectManager.S60DeployConfiguration.InstallationDriveLetter");
const char * const SILENT_INSTALL_KEY("Qt4ProjectManager.S60DeployConfiguration.SilentInstall");
+const char * const DEVICE_ADDRESS_KEY("Qt4ProjectManager.S60DeployConfiguration.DeviceAddress");
+const char * const DEVICE_PORT_KEY("Qt4ProjectManager.S60DeployConfiguration.DevicePort");
+const char * const COMMUNICATION_CHANNEL_KEY("Qt4ProjectManager.S60DeployConfiguration.CommunicationChannel");
+
+const char * const DEFAULT_TCF_TRK_TCP_PORT("65029");
QString pathFromId(const QString &id)
{
@@ -83,7 +88,9 @@ S60DeployConfiguration::S60DeployConfiguration(Target *parent) :
m_serialPortName(QLatin1String(SymbianUtils::SymbianDeviceManager::linuxBlueToothDeviceRootC) + QLatin1Char('0')),
#endif
m_installationDrive('C'),
- m_silentInstall(true)
+ m_silentInstall(true),
+ m_devicePort(QLatin1String(DEFAULT_TCF_TRK_TCP_PORT)),
+ m_communicationChannel(CommunicationSerialConnection)
{
ctor();
}
@@ -93,7 +100,10 @@ S60DeployConfiguration::S60DeployConfiguration(Target *target, S60DeployConfigur
m_activeBuildConfiguration(0),
m_serialPortName(source->m_serialPortName),
m_installationDrive(source->m_installationDrive),
- m_silentInstall(source->m_silentInstall)
+ m_silentInstall(source->m_silentInstall),
+ m_deviceAddress(source->m_deviceAddress),
+ m_devicePort(source->m_devicePort),
+ m_communicationChannel(source->m_communicationChannel)
{
ctor();
}
@@ -297,6 +307,9 @@ QVariantMap S60DeployConfiguration::toMap() const
map.insert(QLatin1String(SERIAL_PORT_NAME_KEY), m_serialPortName);
map.insert(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar(m_installationDrive));
map.insert(QLatin1String(SILENT_INSTALL_KEY), QVariant(m_silentInstall));
+ map.insert(QLatin1String(DEVICE_ADDRESS_KEY), QVariant(m_deviceAddress));
+ map.insert(QLatin1String(DEVICE_PORT_KEY), m_devicePort);
+ map.insert(QLatin1String(COMMUNICATION_CHANNEL_KEY), QVariant(m_communicationChannel));
return map;
}
@@ -320,6 +333,11 @@ bool S60DeployConfiguration::fromMap(const QVariantMap &map)
m_installationDrive = map.value(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar('C'))
.toChar().toAscii();
m_silentInstall = map.value(QLatin1String(SILENT_INSTALL_KEY), QVariant(true)).toBool();
+ m_deviceAddress = map.value(QLatin1String(DEVICE_ADDRESS_KEY)).toString();
+ m_devicePort = map.value(QLatin1String(DEVICE_PORT_KEY), QString(QLatin1String(DEFAULT_TCF_TRK_TCP_PORT))).toString();
+ m_communicationChannel = static_cast<CommunicationChannel>(map.value(QLatin1String(COMMUNICATION_CHANNEL_KEY),
+ QVariant(CommunicationSerialConnection)).toInt());
+
setDefaultDisplayName(defaultDisplayName());
return true;
}
@@ -363,6 +381,48 @@ void S60DeployConfiguration::setSilentInstall(bool silent)
m_silentInstall = silent;
}
+QString S60DeployConfiguration::deviceAddress() const
+{
+ return m_deviceAddress;
+}
+
+void S60DeployConfiguration::setDeviceAddress(const QString &address)
+{
+ if (m_deviceAddress != address) {
+ m_deviceAddress = address;
+ emit deviceAddressChanged();
+ }
+}
+
+QString S60DeployConfiguration::devicePort() const
+{
+ return m_devicePort;
+}
+
+void S60DeployConfiguration::setDevicePort(const QString &port)
+{
+ if (m_devicePort != port) {
+ if (port.isEmpty()) //setup the default CODA's port
+ m_devicePort = QLatin1String(DEFAULT_TCF_TRK_TCP_PORT);
+ else
+ m_devicePort = port;
+ emit devicePortChanged();
+ }
+}
+
+S60DeployConfiguration::CommunicationChannel S60DeployConfiguration::communicationChannel() const
+{
+ return m_communicationChannel;
+}
+
+void S60DeployConfiguration::setCommunicationChannel(CommunicationChannel channel)
+{
+ if (m_communicationChannel != channel) {
+ m_communicationChannel = channel;
+ emit communicationChannelChanged();
+ }
+}
+
// ======== S60DeployConfigurationFactory
S60DeployConfigurationFactory::S60DeployConfigurationFactory(QObject *parent) :
@@ -402,18 +462,16 @@ DeployConfiguration *S60DeployConfigurationFactory::create(Target *parent, const
bool S60DeployConfigurationFactory::canCreate(Target *parent, const QString& /*id*/) const
{
- Qt4Target * t(qobject_cast<Qt4Target *>(parent));
- if (!t ||
- t->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
+ Qt4Target *t = qobject_cast<Qt4Target *>(parent);
+ if (!t || t->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
return false;
return true;
}
bool S60DeployConfigurationFactory::canRestore(Target *parent, const QVariantMap& /*map*/) const
{
- Qt4Target * t(qobject_cast<Qt4Target *>(parent));
- return t &&
- t->id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID);
+ Qt4Target *t = qobject_cast<Qt4Target *>(parent);
+ return t && t->id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID);
}
DeployConfiguration *S60DeployConfigurationFactory::restore(Target *parent, const QVariantMap &map)
@@ -441,6 +499,6 @@ DeployConfiguration *S60DeployConfigurationFactory::clone(Target *parent, Deploy
if (!canClone(parent, source))
return 0;
Qt4Target *t = static_cast<Qt4Target *>(parent);
- S60DeployConfiguration * old(static_cast<S60DeployConfiguration *>(source));
+ S60DeployConfiguration *old = static_cast<S60DeployConfiguration *>(source);
return new S60DeployConfiguration(t, old);
}
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h
index 7655768cc29..1f2b780e4dc 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h
@@ -57,6 +57,11 @@ class S60DeployConfiguration : public ProjectExplorer::DeployConfiguration
friend class S60DeployConfigurationFactory;
public:
+ enum CommunicationChannel {
+ CommunicationSerialConnection,
+ CommunicationTcpConnection
+ };
+
explicit S60DeployConfiguration(ProjectExplorer::Target *parent);
virtual ~S60DeployConfiguration();
@@ -77,6 +82,15 @@ public:
bool silentInstall() const;
void setSilentInstall(bool silent);
+ QString deviceAddress() const;
+ void setDeviceAddress(const QString &address);
+
+ void setDevicePort(const QString &port);
+ QString devicePort() const;
+
+ void setCommunicationChannel(CommunicationChannel channel);
+ S60DeployConfiguration::CommunicationChannel communicationChannel() const;
+
QStringList signedPackages() const;
QStringList packageFileNamesWithTargetInfo() const;
QStringList packageTemplateFileNames() const;
@@ -87,6 +101,9 @@ public:
signals:
void targetInformationChanged();
void serialPortNameChanged();
+ void communicationChannelChanged();
+ void deviceAddressChanged();
+ void devicePortChanged();
private slots:
void updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfiguration);
@@ -113,6 +130,9 @@ private:
char m_installationDrive;
bool m_silentInstall;
+ QString m_deviceAddress;
+ QString m_devicePort;
+ CommunicationChannel m_communicationChannel;
};
class S60DeployConfigurationFactory : public ProjectExplorer::DeployConfigurationFactory
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp
index 3cd51b92c47..8fe98294d90 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp
@@ -43,6 +43,7 @@
#include <symbianutils/symbiandevicemanager.h>
#include <utils/detailswidget.h>
+#include <utils/ipaddresslineedit.h>
#include <utils/qtcassert.h>
#include <utils/pathchooser.h>
@@ -59,6 +60,9 @@
#include <QtGui/QSpacerItem>
#include <QtGui/QMessageBox>
#include <QtGui/QCheckBox>
+#include <QtGui/QGroupBox>
+#include <QtGui/QRadioButton>
+#include <QtGui/QValidator>
Q_DECLARE_METATYPE(SymbianUtils::SymbianDevice)
@@ -77,7 +81,10 @@ S60DeployConfigurationWidget::S60DeployConfigurationWidget(QWidget *parent)
m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))),
m_deviceInfoLabel(new QLabel),
m_installationDriveCombo(new QComboBox()),
- m_silentInstallCheckBox(new QCheckBox(tr("Silent installation")))
+ m_silentInstallCheckBox(new QCheckBox(tr("Silent installation"))),
+ m_serialRadioButton(new QRadioButton(tr("Serial:"))),
+ m_wlanRadioButton(new QRadioButton(tr("Experimental WLAN:"))), //TODO: Remove ""Experimental" when CODA is stable and official
+ m_ipAddress(new Utils::IpAddressLineEdit)
{
}
@@ -130,10 +137,35 @@ void S60DeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc
updateSerialDevices();
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(updated()),
this, SLOT(updateSerialDevices()));
- // Serial devices control
+
+ formLayout->addRow(createCommunicationChannel());
+
+ // Device Info with button. Widgets are enabled in above call to updateSerialDevices()
+ QHBoxLayout *infoHBoxLayout = new QHBoxLayout;
+ m_deviceInfoLabel->setWordWrap(true);
+ m_deviceInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+ infoHBoxLayout->addWidget(m_deviceInfoLabel);
+ infoHBoxLayout->addWidget(m_deviceInfoButton);
+ m_deviceInfoButton->setIcon(qApp->style()->standardIcon(QStyle::SP_MessageBoxInformation));
+ m_deviceInfoButton->setToolTip(tr("Queries the device for information"));
+ connect(m_deviceInfoButton, SIGNAL(clicked()), this, SLOT(updateDeviceInfo()));
+ formLayout->addRow(m_deviceInfoDescriptionLabel, infoHBoxLayout);
+ updateTargetInformation();
+ connect(m_deployConfiguration, SIGNAL(targetInformationChanged()),
+ this, SLOT(updateTargetInformation()));
+}
+
+QWidget *S60DeployConfigurationWidget::createCommunicationChannel()
+{
m_serialPortsCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
connect(m_serialPortsCombo, SIGNAL(activated(int)), this, SLOT(setSerialPort(int)));
+ connect(m_serialRadioButton, SIGNAL(clicked()), this, SLOT(updateCommunicationChannel()));
+ connect(m_wlanRadioButton, SIGNAL(clicked()), this, SLOT(updateCommunicationChannel()));
+ connect(m_ipAddress, SIGNAL(validAddressChanged(QString)), this, SLOT(updateWlanAddress(QString)));
+ connect(m_ipAddress, SIGNAL(invalidAddressChanged()), this, SLOT(cleanWlanAddress()));
+
QHBoxLayout *serialPortHBoxLayout = new QHBoxLayout;
+ serialPortHBoxLayout->addWidget(new QLabel(tr("Serial port:")));
serialPortHBoxLayout->addWidget(m_serialPortsCombo);
serialPortHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
@@ -146,21 +178,44 @@ void S60DeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc
serialPortHBoxLayout->addWidget(updateSerialDevicesButton);
#endif
- formLayout->addRow(tr("Device on serial port:"), serialPortHBoxLayout);
+ QGroupBox *communicationChannelGroupBox = new QGroupBox(tr("Communication channel"));
+ QFormLayout *communicationChannelFormLayout = new QFormLayout();
+ communicationChannelFormLayout->setWidget(0, QFormLayout::LabelRole, m_serialRadioButton);
+ communicationChannelFormLayout->setWidget(1, QFormLayout::LabelRole, m_wlanRadioButton);
- // Device Info with button. Widgets are enabled in above call to updateSerialDevices()
- QHBoxLayout *infoHBoxLayout = new QHBoxLayout;
- m_deviceInfoLabel->setWordWrap(true);
- m_deviceInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
- infoHBoxLayout->addWidget(m_deviceInfoLabel);
- infoHBoxLayout->addWidget(m_deviceInfoButton);
- m_deviceInfoButton->setIcon(qApp->style()->standardIcon(QStyle::SP_MessageBoxInformation));
- m_deviceInfoButton->setToolTip(tr("Queries the device for information"));
- connect(m_deviceInfoButton, SIGNAL(clicked()), this, SLOT(updateDeviceInfo()));
- formLayout->addRow(m_deviceInfoDescriptionLabel, infoHBoxLayout);
- updateTargetInformation();
- connect(m_deployConfiguration, SIGNAL(targetInformationChanged()),
- this, SLOT(updateTargetInformation()));
+ m_ipAddress->setMinimumWidth(30);
+ m_ipAddress->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
+
+ if(!m_deployConfiguration->deviceAddress().isEmpty())
+ m_ipAddress->setText(QString("%1:%2")
+ .arg(m_deployConfiguration->deviceAddress())
+ .arg(m_deployConfiguration->devicePort()));
+
+ QHBoxLayout *wlanChannelLayout = new QHBoxLayout();
+ wlanChannelLayout->addWidget(new QLabel(tr("Address:")));
+ wlanChannelLayout->addWidget(m_ipAddress);
+ wlanChannelLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
+
+ communicationChannelFormLayout->setLayout(0, QFormLayout::FieldRole, serialPortHBoxLayout);
+ communicationChannelFormLayout->setLayout(1, QFormLayout::FieldRole, wlanChannelLayout);
+
+ switch (m_deployConfiguration->communicationChannel()) {
+ case S60DeployConfiguration::CommunicationSerialConnection:
+ m_serialRadioButton->setChecked(true);
+ m_ipAddress->setDisabled(true);
+ m_serialPortsCombo->setDisabled(false);
+ break;
+ case S60DeployConfiguration::CommunicationTcpConnection:
+ m_wlanRadioButton->setChecked(true);
+ m_ipAddress->setDisabled(false);
+ m_serialPortsCombo->setDisabled(true);
+ break;
+ default:
+ break;
+ }
+
+ communicationChannelGroupBox->setLayout(communicationChannelFormLayout);
+ return communicationChannelGroupBox;
}
void S60DeployConfigurationWidget::updateInstallationDrives()
@@ -244,6 +299,43 @@ void S60DeployConfigurationWidget::setSerialPort(int index)
clearDeviceInfo();
}
+void S60DeployConfigurationWidget::updateCommunicationChannel()
+{
+ if (m_serialRadioButton->isChecked()) {
+ m_ipAddress->setDisabled(true);
+ m_serialPortsCombo->setDisabled(false);
+ m_deployConfiguration->setCommunicationChannel(S60DeployConfiguration::CommunicationSerialConnection);
+ } else if(m_wlanRadioButton->isChecked()) {
+ QMessageBox::information(this, tr("CODA required"),
+ tr("You need to have CODA v4.0.14 (or newer) installed on your device "
+ "in order to use the WLAN functionality.")); //TODO: Remove this when CODA is stable and official
+ m_ipAddress->setDisabled(false);
+ m_serialPortsCombo->setDisabled(true);
+ m_deployConfiguration->setCommunicationChannel(S60DeployConfiguration::CommunicationTcpConnection);
+ }
+}
+
+void S60DeployConfigurationWidget::updateWlanAddress(const QString &address)
+{
+ QStringList addressList = address.split(QLatin1String(":"), QString::SkipEmptyParts);
+ if (addressList.count() > 0) {
+ m_deployConfiguration->setDeviceAddress(addressList.at(0));
+ if (addressList.count() > 1)
+ m_deployConfiguration->setDevicePort(addressList.at(1));
+ else
+ m_deployConfiguration->setDevicePort(QString());
+ }
+}
+
+void S60DeployConfigurationWidget::cleanWlanAddress()
+{
+ if (!m_deployConfiguration->deviceAddress().isEmpty())
+ m_deployConfiguration->setDeviceAddress(QString());
+
+ if (!m_deployConfiguration->devicePort().isEmpty())
+ m_deployConfiguration->setDevicePort(QString());
+}
+
void S60DeployConfigurationWidget::clearDeviceInfo()
{
// Restore text & color
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.h b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.h
index bc5a3431f01..287a4a9d6c7 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.h
@@ -45,10 +45,12 @@ class QLineEdit;
class QComboBox;
class QToolButton;
class QCheckBox;
+class QRadioButton;
QT_END_NAMESPACE
namespace Utils {
class DetailsWidget;
+ class IpAddressLineEdit;
}
namespace trk {
@@ -87,6 +89,9 @@ private slots:
void slotLauncherStateChanged(int);
void slotWaitingForTrkClosed();
void silentInstallChanged(int);
+ void updateCommunicationChannel();
+ void updateWlanAddress(const QString &address);
+ void cleanWlanAddress();
private:
inline SymbianUtils::SymbianDevice device(int i) const;
@@ -94,6 +99,8 @@ private:
void setDeviceInfoLabel(const QString &message, bool isError = false);
+ QWidget * createCommunicationChannel();
+
S60DeployConfiguration *m_deployConfiguration;
Utils::DetailsWidget *m_detailsWidget;
QComboBox *m_serialPortsCombo;
@@ -104,6 +111,9 @@ private:
QPointer<trk::Launcher> m_infoLauncher;
QComboBox *m_installationDriveCombo;
QCheckBox *m_silentInstallCheckBox;
+ QRadioButton *m_serialRadioButton;
+ QRadioButton *m_wlanRadioButton;
+ Utils::IpAddressLineEdit *m_ipAddress;
};
} // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deploystep.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deploystep.cpp
index adf4d3d3a76..a127cc34c54 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deploystep.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deploystep.cpp
@@ -37,6 +37,7 @@
#include "s60deployconfiguration.h"
#include "s60devicerunconfiguration.h"
#include "s60runconfigbluetoothstarter.h"
+#include "tcftrkdevice.h"
#include <coreplugin/icore.h>
#include <projectexplorer/buildsteplist.h>
@@ -47,6 +48,8 @@
#include <symbianutils/launcher.h>
#include <symbianutils/symbiandevicemanager.h>
+#include <utils/qtcassert.h>
+
#include <QtGui/QMessageBox>
#include <QtGui/QMainWindow>
@@ -54,12 +57,20 @@
#include <QtCore/QDateTime>
#include <QtCore/QDir>
#include <QtCore/QEventLoop>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+
+#include <QtNetwork/QTcpSocket>
using namespace ProjectExplorer;
using namespace Qt4ProjectManager::Internal;
+enum {debug = 0};
+
+static const quint64 DEFAULT_CHUNK_SIZE = 10240;
+
namespace {
- const char * const S60_DEPLOY_STEP_ID = "Qt4ProjectManager.S60DeployStep";
+const char * const S60_DEPLOY_STEP_ID = "Qt4ProjectManager.S60DeployStep";
}
static inline bool ensureDeleteFile(const QString &fileName, QString *errorMessage)
@@ -82,7 +93,7 @@ static inline bool renameFile(const QString &sourceName, const QString &targetNa
QFile source(sourceName);
if (!source.rename(targetName)) {
*errorMessage = S60DeployStep::tr("Unable to rename file '%1' to '%2': %3")
- .arg(sourceName, targetName, source.errorString());
+ .arg(sourceName, targetName, source.errorString());
return false;
}
return true;
@@ -92,18 +103,37 @@ static inline bool renameFile(const QString &sourceName, const QString &targetNa
S60DeployStep::S60DeployStep(ProjectExplorer::BuildStepList *bc,
S60DeployStep *bs):
- BuildStep(bc, bs), m_timer(0),
- m_releaseDeviceAfterLauncherFinish(bs->m_releaseDeviceAfterLauncherFinish),
- m_handleDeviceRemoval(bs->m_handleDeviceRemoval),
- m_launcher(0), m_eventLoop(0)
+ BuildStep(bc, bs), m_timer(0),
+ m_releaseDeviceAfterLauncherFinish(bs->m_releaseDeviceAfterLauncherFinish),
+ m_handleDeviceRemoval(bs->m_handleDeviceRemoval),
+ m_launcher(0),
+ m_trkDevice(0),
+ m_eventLoop(0),
+ m_state(StateUninit),
+ m_putWriteOk(false),
+ m_putChunkSize(DEFAULT_CHUNK_SIZE),
+ m_putLastChunkSize(0),
+ m_currentFileIndex(0),
+ m_channel(bs->m_channel),
+ m_deployCanceled(false)
{
ctor();
}
S60DeployStep::S60DeployStep(ProjectExplorer::BuildStepList *bc):
- BuildStep(bc, QLatin1String(S60_DEPLOY_STEP_ID)), m_timer(0),
- m_releaseDeviceAfterLauncherFinish(true),
- m_handleDeviceRemoval(true), m_launcher(0), m_eventLoop(0)
+ BuildStep(bc, QLatin1String(S60_DEPLOY_STEP_ID)), m_timer(0),
+ m_releaseDeviceAfterLauncherFinish(true),
+ m_handleDeviceRemoval(true),
+ m_launcher(0),
+ m_trkDevice(0),
+ m_eventLoop(0),
+ m_state(StateUninit),
+ m_putWriteOk(false),
+ m_putChunkSize(DEFAULT_CHUNK_SIZE),
+ m_putLastChunkSize(0),
+ m_currentFileIndex(0),
+ m_channel(S60DeployConfiguration::CommunicationSerialConnection),
+ m_deployCanceled(false)
{
ctor();
}
@@ -118,6 +148,7 @@ S60DeployStep::~S60DeployStep()
{
delete m_timer;
delete m_launcher;
+ delete m_trkDevice;
delete m_eventLoop;
}
@@ -125,8 +156,8 @@ S60DeployStep::~S60DeployStep()
bool S60DeployStep::init()
{
Qt4BuildConfiguration *bc = static_cast<Qt4BuildConfiguration *>(buildConfiguration());
- S60DeployConfiguration* deployConfiguration = static_cast<S60DeployConfiguration *>(bc->target()->activeDeployConfiguration());
- if(!deployConfiguration)
+ S60DeployConfiguration *deployConfiguration = static_cast<S60DeployConfiguration *>(bc->target()->activeDeployConfiguration());
+ if (!deployConfiguration)
return false;
m_serialPortName = deployConfiguration->serialPortName();
m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
@@ -135,33 +166,44 @@ bool S60DeployStep::init()
m_installationDrive = deployConfiguration->installationDrive();
m_silentInstall = deployConfiguration->silentInstall();
- QString message;
- if (m_launcher) {
- trk::Launcher::releaseToDeviceManager(m_launcher);
- delete m_launcher;
- m_launcher = 0;
+ switch (deployConfiguration->communicationChannel()) {
+ case S60DeployConfiguration::CommunicationSerialConnection:
+ break;
+ case S60DeployConfiguration::CommunicationTcpConnection:
+ m_address = deployConfiguration->deviceAddress();
+ m_port = deployConfiguration->devicePort().toInt();
}
+ m_channel = deployConfiguration->communicationChannel();
- m_launcher = trk::Launcher::acquireFromDeviceManager(m_serialPortName, this, &message);
- if (!message.isEmpty() || !m_launcher) {
- if (m_launcher)
- trk::Launcher::releaseToDeviceManager(m_launcher);
- delete m_launcher;
- m_launcher = 0;
- appendMessage(message, true);
- return true;
- }
- // Prompt the user to start up the Blue tooth connection
- const trk::PromptStartCommunicationResult src =
- S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(),
- 0, &message);
- if (src != trk::PromptStartCommunicationConnected) {
- if (!message.isEmpty())
+ if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
+ QString message;
+ if (m_launcher) {
trk::Launcher::releaseToDeviceManager(m_launcher);
- delete m_launcher;
- m_launcher = 0;
- appendMessage(message, true);
- return false;
+ delete m_launcher;
+ m_launcher = 0;
+ }
+
+ m_launcher = trk::Launcher::acquireFromDeviceManager(m_serialPortName, this, &message);
+ if (!message.isEmpty() || !m_launcher) {
+ if (m_launcher)
+ trk::Launcher::releaseToDeviceManager(m_launcher);
+ delete m_launcher;
+ m_launcher = 0;
+ appendMessage(message, true);
+ return true;
+ }
+ // Prompt the user to start up the Bluetooth connection
+ const trk::PromptStartCommunicationResult src =
+ S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(),
+ 0, &message);
+ if (src != trk::PromptStartCommunicationConnected) {
+ if (!message.isEmpty())
+ trk::Launcher::releaseToDeviceManager(m_launcher);
+ delete m_launcher;
+ m_launcher = 0;
+ appendMessage(message, true);
+ return false;
+ }
}
return true;
}
@@ -182,6 +224,16 @@ void S60DeployStep::appendMessage(const QString &error, bool isError)
ProjectExplorer::BuildStep::MessageOutput);
}
+void S60DeployStep::reportError(const QString &error)
+{
+ emit addOutput(error, ProjectExplorer::BuildStep::ErrorMessageOutput);
+ emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
+ error,
+ QString(), -1,
+ ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
+ emit finished(false);
+}
+
bool S60DeployStep::processPackageName(QString &errorMessage)
{
for (int i = 0; i < m_signedPackages.count(); ++i) {
@@ -217,15 +269,20 @@ void S60DeployStep::start()
{
QString errorMessage;
- if (m_serialPortName.isEmpty() || !m_launcher) {
- errorMessage = tr("No device is connected. Please connect a device and try again.");
- appendMessage(errorMessage, true);
- emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
- errorMessage,
- QString(), -1,
- ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
- emit finished();
- return;
+ if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
+ if (m_serialPortName.isEmpty() || !m_launcher) {
+ errorMessage = tr("No device is connected. Please connect a device and try again.");
+ reportError(errorMessage);
+ return;
+ }
+ } else {
+ QTC_ASSERT(!m_trkDevice, return);
+ m_trkDevice = new tcftrk::TcfTrkDevice;
+ if (m_address.isEmpty() || !m_trkDevice) {
+ errorMessage = tr("No address for a device has been defined. Please define an address and try again.");
+ reportError(errorMessage);
+ return;
+ }
}
// make sure we have the right name of the sis package
@@ -233,67 +290,89 @@ void S60DeployStep::start()
startDeployment();
} else {
errorMessage = tr("Failed to find package %1").arg(errorMessage);
- appendMessage(errorMessage, true);
- emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
- errorMessage,
- QString(), -1,
- ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
+ reportError(errorMessage);
stop();
- emit finished();
}
}
void S60DeployStep::stop()
{
- if (m_launcher)
- m_launcher->terminate();
- emit finished();
+ if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
+ if (m_launcher)
+ m_launcher->terminate();
+ } else {
+ if (m_trkDevice) {
+ delete m_trkDevice;
+ m_trkDevice = 0;
+ }
+ }
+ emit finished(false);
}
void S60DeployStep::setupConnections()
{
- connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)),
- this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice)));
- connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
-
- connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(connectFailed(QString)));
- connect(m_launcher, SIGNAL(copyingStarted(QString)), this, SLOT(printCopyingNotice(QString)));
- connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(createFileFailed(QString,QString)));
- connect(m_launcher, SIGNAL(canNotWriteFile(QString,QString)), this, SLOT(writeFileFailed(QString,QString)));
- connect(m_launcher, SIGNAL(canNotCloseFile(QString,QString)), this, SLOT(closeFileFailed(QString,QString)));
- connect(m_launcher, SIGNAL(installingStarted(QString)), this, SLOT(printInstallingNotice(QString)));
- connect(m_launcher, SIGNAL(canNotInstall(QString,QString)), this, SLOT(installFailed(QString,QString)));
- connect(m_launcher, SIGNAL(installingFinished()), this, SLOT(printInstallingFinished()));
- connect(m_launcher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
+ if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
+ connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)),
+ this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice)));
+ connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
+
+ connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(connectFailed(QString)));
+ connect(m_launcher, SIGNAL(copyingStarted(QString)), this, SLOT(printCopyingNotice(QString)));
+ connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(createFileFailed(QString,QString)));
+ connect(m_launcher, SIGNAL(canNotWriteFile(QString,QString)), this, SLOT(writeFileFailed(QString,QString)));
+ connect(m_launcher, SIGNAL(canNotCloseFile(QString,QString)), this, SLOT(closeFileFailed(QString,QString)));
+ connect(m_launcher, SIGNAL(installingStarted(QString)), this, SLOT(printInstallingNotice(QString)));
+ connect(m_launcher, SIGNAL(canNotInstall(QString,QString)), this, SLOT(installFailed(QString,QString)));
+ connect(m_launcher, SIGNAL(installingFinished()), this, SLOT(printInstallingFinished()));
+ connect(m_launcher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
+ } else {
+ connect(m_trkDevice, SIGNAL(error(QString)), this, SLOT(slotError(QString)));
+ connect(m_trkDevice, SIGNAL(logMessage(QString)), this, SLOT(slotTrkLogMessage(QString)));
+ connect(m_trkDevice, SIGNAL(tcfEvent(tcftrk::TcfTrkEvent)), this, SLOT(slotTcftrkEvent(tcftrk::TcfTrkEvent)), Qt::DirectConnection);
+ connect(m_trkDevice, SIGNAL(serialPong(QString)), this, SLOT(slotSerialPong(QString)));
+ connect(this, SIGNAL(manualInstallation()), this, SLOT(showManualInstallationInfo()));
+ }
}
void S60DeployStep::startDeployment()
{
- Q_ASSERT(m_launcher);
+ if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
+ QTC_ASSERT(m_launcher, return);
+ } else {
+ QTC_ASSERT(m_trkDevice, return);
+ }
setupConnections();
- QStringList copyDst;
- foreach (const QString &signedPackage, m_signedPackages)
- copyDst << QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(QFileInfo(signedPackage).fileName());
-
- m_launcher->setCopyFileNames(m_signedPackages, copyDst);
- m_launcher->setInstallFileNames(copyDst);
- m_launcher->setInstallationDrive(m_installationDrive);
- m_launcher->setInstallationMode(m_silentInstall?trk::Launcher::InstallationModeSilentAndUser:
- trk::Launcher::InstallationModeUser);
- m_launcher->addStartupActions(trk::Launcher::ActionCopyInstall);
-
- // TODO readd information about packages? msgListFile(m_signedPackage)
- appendMessage(tr("Deploying application to '%2'...").arg(m_serialPortFriendlyName), false);
-
- QString errorMessage;
- if (!m_launcher->startServer(&errorMessage)) {
- errorMessage = tr("Could not connect to phone on port '%1': %2\n"
- "Check if the phone is connected and App TRK is running.").arg(m_serialPortName, errorMessage);
- appendMessage(errorMessage, true);
- stop();
- emit finished();
+ if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
+ QStringList copyDst;
+ foreach (const QString &signedPackage, m_signedPackages)
+ copyDst << QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(QFileInfo(signedPackage).fileName());
+
+ m_launcher->setCopyFileNames(m_signedPackages, copyDst);
+ m_launcher->setInstallFileNames(copyDst);
+ m_launcher->setInstallationDrive(m_installationDrive);
+ m_launcher->setInstallationMode(m_silentInstall?trk::Launcher::InstallationModeSilentAndUser:
+ trk::Launcher::InstallationModeUser);
+ m_launcher->addStartupActions(trk::Launcher::ActionCopyInstall);
+
+ // TODO readd information about packages? msgListFile(m_signedPackage)
+ appendMessage(tr("Deploying application to '%2'...").arg(m_serialPortFriendlyName), false);
+
+ QString errorMessage;
+ if (!m_launcher->startServer(&errorMessage)) {
+ errorMessage = tr("Could not connect to phone on port '%1': %2\n"
+ "Check if the phone is connected and App TRK is running.").arg(m_serialPortName, errorMessage);
+ reportError(errorMessage);
+ stop();
+ }
+ } else {
+ const QSharedPointer<QTcpSocket> tcfTrkSocket(new QTcpSocket);
+ m_trkDevice->setDevice(tcfTrkSocket);
+ tcfTrkSocket->connectToHost(m_address, m_port);
+ m_state = StateConnecting;
+ appendMessage(tr("Connecting to %1:%2...").arg(m_address).arg(m_port), false);
+ QTimer::singleShot(4000, this, SLOT(checkForTimeout()));
}
}
@@ -301,10 +380,18 @@ void S60DeployStep::run(QFutureInterface<bool> &fi)
{
m_futureInterface = &fi;
m_deployResult = true;
- connect(this, SIGNAL(finished()),
- this, SLOT(launcherFinished()));
- connect(this, SIGNAL(finishNow()),
- this, SLOT(launcherFinished()), Qt::DirectConnection);
+ m_deployCanceled = false;
+ disconnect(this);
+
+ if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
+ connect(this, SIGNAL(finished(bool)), this, SLOT(launcherFinished(bool)));
+ connect(this, SIGNAL(finishNow(bool)), this, SLOT(launcherFinished(bool)), Qt::DirectConnection);
+ } else {
+ connect(this, SIGNAL(finished(bool)), this, SLOT(deploymentFinished(bool)));
+ connect(this, SIGNAL(finishNow(bool)), this, SLOT(deploymentFinished(bool)), Qt::DirectConnection);
+ connect(this, SIGNAL(allFilesSent()), this, SLOT(startInstalling()), Qt::DirectConnection);
+ connect(this, SIGNAL(allFilesInstalled()), this, SIGNAL(finished()), Qt::DirectConnection);
+ }
start();
m_timer = new QTimer();
@@ -316,12 +403,229 @@ void S60DeployStep::run(QFutureInterface<bool> &fi)
delete m_timer;
m_timer = 0;
+ delete m_trkDevice;
+ m_trkDevice = 0;
+
delete m_eventLoop;
m_eventLoop = 0;
fi.reportResult(m_deployResult);
m_futureInterface = 0;
}
+void S60DeployStep::slotError(const QString &error)
+{
+ reportError(tr("Error: %1").arg(error));
+}
+
+void S60DeployStep::slotTrkLogMessage(const QString &log)
+{
+ if (debug)
+ qDebug() << "CODA log:" << log;
+}
+
+void S60DeployStep::slotSerialPong(const QString &message)
+{
+ if (debug)
+ qDebug() << "CODA serial pong:" << message;
+}
+
+void S60DeployStep::slotTcftrkEvent (const tcftrk::TcfTrkEvent &event)
+{
+ if (debug)
+ qDebug() << "CODA event:" << "Type:" << event.type() << "Message:" << event.toString();
+
+ switch (event.type()) {
+ case tcftrk::TcfTrkEvent::LocatorHello: {// Commands accepted now
+ m_state = StateConnected;
+ emit tcpConnected();
+ startTransferring();
+ break;
+ }
+ default:
+ if (debug)
+ qDebug() << "Unhandled event:" << "Type:" << event.type() << "Message:" << event.toString();
+ break;
+ }
+}
+
+void S60DeployStep::initFileSending()
+{
+ QTC_ASSERT(m_currentFileIndex < m_signedPackages.count(), return);
+ QTC_ASSERT(m_currentFileIndex >= 0, return);
+
+ const unsigned flags =
+ tcftrk::TcfTrkDevice::FileSystem_TCF_O_WRITE
+ |tcftrk::TcfTrkDevice::FileSystem_TCF_O_CREAT
+ |tcftrk::TcfTrkDevice::FileSystem_TCF_O_TRUNC;
+ m_putWriteOk = false;
+
+ QString packageName(QFileInfo(m_signedPackages.at(m_currentFileIndex)).fileName());
+ QString remoteFileLocation = QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(packageName);
+ m_trkDevice->sendFileSystemOpenCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleFileSystemOpen),
+ remoteFileLocation.toAscii(), flags);
+ appendMessage(tr("Copying \"%1\"...").arg(packageName), false);
+}
+
+void S60DeployStep::initFileInstallation()
+{
+ QTC_ASSERT(m_currentFileIndex < m_signedPackages.count(), return);
+ QTC_ASSERT(m_currentFileIndex >= 0, return);
+
+ QString packageName(QFileInfo(m_signedPackages.at(m_currentFileIndex)).fileName());
+ QString remoteFileLocation = QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(packageName);
+ if (m_silentInstall) {
+ m_trkDevice->sendSymbianInstallSilentInstallCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleSymbianInstall),
+ remoteFileLocation.toAscii(), QString::fromLatin1("%1:").arg(m_installationDrive).toAscii());
+ appendMessage(tr("Installing package \"%1\" on drive %2:...").arg(packageName).arg(m_installationDrive), false);
+ } else {
+ m_trkDevice->sendSymbianInstallUIInstallCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleSymbianInstall),
+ remoteFileLocation.toAscii());
+ appendMessage(tr("Please continue the installation on your device."), false);
+ emit manualInstallation();
+ }
+}
+
+void S60DeployStep::startTransferring()
+{
+ m_currentFileIndex = 0;
+ initFileSending();
+ m_state = StateSendingData;
+}
+
+void S60DeployStep::startInstalling()
+{
+ m_currentFileIndex = 0;
+ initFileInstallation();
+ m_state = StateInstalling;
+}
+
+void S60DeployStep::handleFileSystemOpen(const tcftrk::TcfTrkCommandResult &result)
+{
+ if (result.type != tcftrk::TcfTrkCommandResult::SuccessReply) {
+ reportError(tr("Open remote file failed: %1").arg(result.errorString()));
+ return;
+ }
+
+ if (result.values.size() < 1 || result.values.at(0).data().isEmpty()) {
+ reportError(tr("Internal error: No filehandle obtained"));
+ return;
+ }
+
+ m_remoteFileHandle = result.values.at(0).data();
+
+ m_putFile.reset(new QFile(m_signedPackages.at(m_currentFileIndex)));
+ if (!m_putFile->open(QIODevice::ReadOnly)) { // Should not fail, was checked before
+ reportError(tr("Open local file failed: %1").arg(m_putFile->errorString()));
+ return;
+ }
+ putSendNextChunk();
+}
+
+void S60DeployStep::handleSymbianInstall(const tcftrk::TcfTrkCommandResult &result)
+{
+ if (result.type == tcftrk::TcfTrkCommandResult::SuccessReply) {
+ appendMessage(tr("Installation has finished"), false);
+ if (++m_currentFileIndex >= m_signedPackages.count())
+ emit allFilesInstalled();
+ else
+ initFileInstallation();
+ } else {
+ reportError(tr("Installation failed: %1").arg(result.errorString()));
+ }
+}
+
+void S60DeployStep::putSendNextChunk()
+{
+ // Read and send off next chunk
+ const quint64 pos = m_putFile->pos();
+ const QByteArray data = m_putFile->read(m_putChunkSize);
+ if (data.isEmpty()) {
+ m_putWriteOk = true;
+ closeRemoteFile();
+ } else {
+ m_putLastChunkSize = data.size();
+ if (debug)
+ qDebug("Writing %llu bytes to remote file '%s' at %llu\n",
+ m_putLastChunkSize,
+ m_remoteFileHandle.constData(), pos);
+ m_trkDevice->sendFileSystemWriteCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleFileSystemWrite),
+ m_remoteFileHandle, data, unsigned(pos));
+ }
+}
+
+void S60DeployStep::closeRemoteFile()
+{
+ m_trkDevice->sendFileSystemCloseCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleFileSystemClose),
+ m_remoteFileHandle);
+}
+
+void S60DeployStep::handleFileSystemWrite(const tcftrk::TcfTrkCommandResult &result)
+{
+ // Close remote file even if copy fails
+ m_putWriteOk = result;
+ if (!m_putWriteOk) {
+ QString packageName(QFileInfo(m_signedPackages.at(m_currentFileIndex)).fileName());
+ reportError(tr("Could not write to file %1 on device: %2").arg(packageName).arg(result.errorString()));
+ }
+
+ if (!m_putWriteOk || m_putLastChunkSize < m_putChunkSize) {
+ closeRemoteFile();
+ } else {
+ putSendNextChunk();
+ }
+}
+
+void S60DeployStep::handleFileSystemClose(const tcftrk::TcfTrkCommandResult &result)
+{
+ if (result.type == tcftrk::TcfTrkCommandResult::SuccessReply) {
+ if (debug)
+ qDebug("File closed.\n");
+ if (++m_currentFileIndex >= m_signedPackages.count())
+ emit allFilesSent();
+ else
+ initFileSending();
+ } else {
+ reportError(tr("File close failed: %1").arg(result.toString()));
+ }
+}
+
+void S60DeployStep::checkForTimeout()
+{
+ if (m_state >= StateConnected)
+ return;
+
+ const QString title = tr("Waiting for CODA");
+ const QString text = tr("Qt Creator is waiting for the CODA application to connect. "
+ "Please make sure the application is running on "
+ "your mobile phone and the right ip address and port are "
+ "configured in the project settings.");
+ QMessageBox *mb = new QMessageBox(QMessageBox::Information, title, text,
+ QMessageBox::Cancel, Core::ICore::instance()->mainWindow());
+ connect(this, SIGNAL(tcpConnected()), mb, SLOT(close()));
+ connect(this, SIGNAL(finished()), mb, SLOT(close()));
+ connect(this, SIGNAL(finishNow()), mb, SLOT(close()));
+ connect(mb, SIGNAL(finished(int)), this, SLOT(slotWaitingForTckTrkClosed(int)));
+ mb->open();
+}
+
+void S60DeployStep::showManualInstallationInfo()
+{
+ const QString title = tr("Installation");
+ const QString text = tr("Please continue the installation on your device.");
+ QMessageBox *mb = new QMessageBox(QMessageBox::Information, title, text,
+ QMessageBox::Ok, Core::ICore::instance()->mainWindow());
+ connect(this, SIGNAL(allFilesInstalled()), mb, SLOT(close()));
+ connect(this, SIGNAL(finished()), mb, SLOT(close()));
+ connect(this, SIGNAL(finishNow()), mb, SLOT(close()));
+ mb->open();
+}
+
+void S60DeployStep::slotWaitingForTckTrkClosed(int result)
+{
+ if (result == QMessageBox::Cancel)
+ m_deployCanceled = true;
+}
+
void S60DeployStep::setReleaseDeviceAfterLauncherFinish(bool v)
{
m_releaseDeviceAfterLauncherFinish = v;
@@ -331,9 +635,9 @@ void S60DeployStep::slotLauncherStateChanged(int s)
{
if (s == trk::Launcher::WaitingForTrk) {
QMessageBox *mb = S60DeviceRunControl::createTrkWaitingMessageBox(m_launcher->trkServerName(),
- Core::ICore::instance()->mainWindow());
+ Core::ICore::instance()->mainWindow());
connect(m_launcher, SIGNAL(stateChanged(int)), mb, SLOT(close()));
- connect(mb, SIGNAL(finished(int)), this, SLOT(slotWaitingForTrkClosed()));
+ connect(mb, SIGNAL(finished(int)), this, SIGNAL(finished()));
mb->open();
}
}
@@ -342,34 +646,29 @@ void S60DeployStep::slotWaitingForTrkClosed()
{
if (m_launcher && m_launcher->state() == trk::Launcher::WaitingForTrk) {
stop();
- appendMessage(tr("Canceled."), true);
- emit finished();
+ reportError(tr("Canceled."));
}
}
void S60DeployStep::createFileFailed(const QString &filename, const QString &errorMessage)
{
- appendMessage(tr("Could not create file %1 on device: %2").arg(filename, errorMessage), true);
- m_deployResult = false;
+ reportError(tr("Could not create file %1 on device: %2").arg(filename, errorMessage));
}
void S60DeployStep::writeFileFailed(const QString &filename, const QString &errorMessage)
{
- appendMessage(tr("Could not write to file %1 on device: %2").arg(filename, errorMessage), true);
- m_deployResult = false;
+ reportError(tr("Could not write to file %1 on device: %2").arg(filename, errorMessage));
}
void S60DeployStep::closeFileFailed(const QString &filename, const QString &errorMessage)
{
const QString msg = tr("Could not close file %1 on device: %2. It will be closed when App TRK is closed.");
- appendMessage( msg.arg(filename, errorMessage), true);
- m_deployResult = false;
+ reportError( msg.arg(filename, errorMessage));
}
void S60DeployStep::connectFailed(const QString &errorMessage)
{
- appendMessage(tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage), true);
- m_deployResult = false;
+ reportError(tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage));
}
void S60DeployStep::printCopyingNotice(const QString &fileName)
@@ -389,39 +688,52 @@ void S60DeployStep::printInstallingFinished()
void S60DeployStep::installFailed(const QString &filename, const QString &errorMessage)
{
- appendMessage(tr("Could not install from package %1 on device: %2").arg(filename, errorMessage), true);
- m_deployResult = false;
+ reportError(tr("Could not install from package %1 on device: %2").arg(filename, errorMessage));
}
void S60DeployStep::checkForCancel()
{
- if (m_futureInterface->isCanceled() && m_timer->isActive()) {
+ if ((m_futureInterface->isCanceled() || m_deployCanceled) && m_timer->isActive()) {
m_timer->stop();
stop();
- appendMessage(tr("Canceled."), true);
- emit finishNow();
+ QString canceledText(tr("Deployment has been cancelled."));
+ appendMessage(canceledText, true);
+ emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
+ canceledText,
+ QString(), -1,
+ ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
+ emit finishNow(false);
}
}
-void S60DeployStep::launcherFinished()
+void S60DeployStep::launcherFinished(bool success)
{
+ m_deployResult = success;
if (m_releaseDeviceAfterLauncherFinish && m_launcher) {
m_handleDeviceRemoval = false;
trk::Launcher::releaseToDeviceManager(m_launcher);
}
- if(m_launcher)
+ if (m_launcher)
m_launcher->deleteLater();
m_launcher = 0;
- if(m_eventLoop)
+ if (m_eventLoop)
+ m_eventLoop->exit();
+}
+
+void S60DeployStep::deploymentFinished(bool success)
+{
+ m_deployResult = success;
+ if (m_trkDevice)
+ m_trkDevice->deleteLater();
+ m_trkDevice = 0;
+ if (m_eventLoop)
m_eventLoop->exit();
}
void S60DeployStep::deviceRemoved(const SymbianUtils::SymbianDevice &d)
{
- if (m_handleDeviceRemoval && d.portName() == m_serialPortName) {
- appendMessage(tr("The device '%1' has been disconnected").arg(d.friendlyName()), true);
- emit finished();
- }
+ if (m_handleDeviceRemoval && d.portName() == m_serialPortName)
+ reportError(tr("The device '%1' has been disconnected").arg(d.friendlyName()));
}
// #pragma mark -- S60DeployStepWidget
@@ -452,7 +764,7 @@ QString S60DeployStepWidget::displayName() const
// #pragma mark -- S60DeployStepFactory
S60DeployStepFactory::S60DeployStepFactory(QObject *parent) :
- ProjectExplorer::IBuildStepFactory(parent)
+ ProjectExplorer::IBuildStepFactory(parent)
{
}
@@ -512,7 +824,7 @@ ProjectExplorer::BuildStep *S60DeployStepFactory::restore(ProjectExplorer::Build
QStringList S60DeployStepFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const
{
if (parent->id() == QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)
- && parent->target()->id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID))
+ && parent->target()->id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID))
return QStringList() << QLatin1String(S60_DEPLOY_STEP_ID);
return QStringList();
}
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deploystep.h b/src/plugins/qt4projectmanager/qt-s60/s60deploystep.h
index ebba59500f0..b17579be615 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deploystep.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deploystep.h
@@ -39,14 +39,22 @@
#include <QtCore/QString>
QT_FORWARD_DECLARE_CLASS(QEventLoop)
+QT_FORWARD_DECLARE_CLASS(QFile)
namespace SymbianUtils {
class SymbianDevice;
}
+
namespace trk{
class Launcher;
}
+namespace tcftrk {
+ struct TcfTrkCommandResult;
+ class TcfTrkDevice;
+ class TcfTrkEvent;
+}
+
namespace ProjectExplorer {
class IOutputParser;
}
@@ -56,6 +64,7 @@ namespace Internal {
class BuildConfiguration;
class S60DeviceRunConfiguration;
+struct CommunicationChannel;
class S60DeployStepFactory : public ProjectExplorer::IBuildStepFactory
{
@@ -111,14 +120,34 @@ private slots:
void printInstallingNotice(const QString &packageName);
void installFailed(const QString &filename, const QString &errorMessage);
void printInstallingFinished();
- void launcherFinished();
+ void launcherFinished(bool success = true);
void slotLauncherStateChanged(int);
void slotWaitingForTrkClosed();
void checkForCancel();
+ void checkForTimeout();
+
+ void slotError(const QString &error);
+ void slotTrkLogMessage(const QString &log);
+ void slotSerialPong(const QString &message);
+ void slotTcftrkEvent(const tcftrk::TcfTrkEvent &event);
+
+ void startInstalling();
+ void startTransferring();
+
+ void deploymentFinished(bool success);
+ void slotWaitingForTckTrkClosed(int result);
+ void showManualInstallationInfo();
signals:
- void finished();
- void finishNow();
+ void finished(bool success = true);
+ void finishNow(bool success = true);
+
+ void allFilesSent();
+ void allFilesInstalled();
+
+ void tcpConnected();
+
+ void manualInstallation();
private:
S60DeployStep(ProjectExplorer::BuildStepList *parent,
@@ -131,11 +160,32 @@ private:
bool processPackageName(QString &errorMessage);
void setupConnections();
void appendMessage(const QString &error, bool isError);
+ void reportError(const QString &error);
+
+ void handleSymbianInstall(const tcftrk::TcfTrkCommandResult &result);
+ void handleFileSystemOpen(const tcftrk::TcfTrkCommandResult &result);
+ void handleFileSystemWrite(const tcftrk::TcfTrkCommandResult &result);
+ void closeRemoteFile();
+ void putSendNextChunk();
+ void handleFileSystemClose(const tcftrk::TcfTrkCommandResult &result);
+
+ void initFileSending();
+ void initFileInstallation();
+
+ enum State {
+ StateUninit,
+ StateConnecting,
+ StateConnected,
+ StateSendingData,
+ StateInstalling
+ };
QString m_serialPortName;
QString m_serialPortFriendlyName;
QStringList m_packageFileNamesWithTarget; // Support for 4.6.1
QStringList m_signedPackages;
+ QString m_address;
+ unsigned short m_port;
QTimer *m_timer;
@@ -145,11 +195,22 @@ private:
QFutureInterface<bool> *m_futureInterface; //not owned
trk::Launcher *m_launcher;
+ tcftrk::TcfTrkDevice *m_trkDevice;
QEventLoop *m_eventLoop;
bool m_deployResult;
char m_installationDrive;
bool m_silentInstall;
+
+ State m_state;
+ bool m_putWriteOk;
+ QScopedPointer<QFile> m_putFile;
+ quint64 m_putLastChunkSize;
+ QByteArray m_remoteFileHandle;
+ quint64 m_putChunkSize;
+ int m_currentFileIndex;
+ int m_channel;
+ volatile bool m_deployCanceled;
};
class S60DeployStepWidget : public ProjectExplorer::BuildStepConfigWidget
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 11104c878e8..b9694492911 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -42,6 +42,9 @@
#include "qt4projectmanagerconstants.h"
#include "qtoutputformatter.h"
+#include "tcftrkdevice.h"
+#include "tcftrkmessage.h"
+
#include <symbianutils/bluetoothlistener_gui.h>
#include <symbianutils/launcher.h>
#include <symbianutils/symbiandevicemanager.h>
@@ -60,9 +63,12 @@
#include <QtCore/QDateTime>
#include <QtCore/QDir>
+#include <QtNetwork/QTcpSocket>
+
using namespace ProjectExplorer;
using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;
+using namespace tcftrk;
namespace {
@@ -102,7 +108,21 @@ QString pathToId(const QString &path)
return QString::fromLatin1(S60_DEVICE_RC_PREFIX) + path;
}
-} // anon namespace
+bool isProcessRunning(const TcfTrkCommandResult &result, const QString &processName)
+{
+ if (result.values.size() && result.values.at(0).type() == JsonValue::Array) {
+ foreach(const JsonValue &threadValue, result.values.at(0).children()) {
+ for (int i = threadValue.children().count()-1; i >= 0; --i) { //Usually our process will be near the end of the list
+ const JsonValue &value(threadValue.childAt(i));
+ if (value.hasName("p_name") && QString::fromLatin1(value.data()).startsWith(processName, Qt::CaseInsensitive))
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+} // anonymous namespace
// ======== S60DeviceRunConfiguration
@@ -172,7 +192,7 @@ Qt4Target *S60DeviceRunConfiguration::qt4Target() const
}
ProjectExplorer::ToolChainType S60DeviceRunConfiguration::toolChainType(
- ProjectExplorer::BuildConfiguration *configuration) const
+ ProjectExplorer::BuildConfiguration *configuration) const
{
if (Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(configuration))
return bc->toolChainType();
@@ -333,12 +353,12 @@ static inline QString localExecutableFromDevice(const QtVersion *qtv,
{
QTC_ASSERT(qtv, return QString(); )
- const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(qtv);
+ const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(qtv);
QString localExecutable;
QTextStream(&localExecutable) << device.epocRoot << "/epoc32/release/"
- << symbianPlatformForToolChain(t)
- << '/' << symbianTarget << '/' << targetName
- << ".exe";
+ << symbianPlatformForToolChain(t)
+ << '/' << symbianTarget << '/' << targetName
+ << ".exe";
return localExecutable;
}
@@ -361,11 +381,11 @@ QString S60DeviceRunConfiguration::localExecutableFileName() const
// As of 4.7.1, qmake-gcce-Raptor builds were changed to put all executables into 'armv5'
const QtVersion *qtv = qtVersion();
QTC_ASSERT(qtv, return QString(); )
- return qtv->isBuildWithSymbianSbsV2() ?
- localExecutableFromDevice(qtv, symbianTarget(), targetName(), ProjectExplorer::ToolChain_RVCT2_ARMV5) :
- localExecutableFromDevice(qtv, symbianTarget(), targetName(), toolChain);
+ return qtv->isBuildWithSymbianSbsV2() ?
+ localExecutableFromDevice(qtv, symbianTarget(), targetName(), ProjectExplorer::ToolChain_RVCT2_ARMV5) :
+ localExecutableFromDevice(qtv, symbianTarget(), targetName(), toolChain);
}
- break;
+ break;
default:
break;
}
@@ -495,10 +515,12 @@ RunConfiguration *S60DeviceRunConfigurationFactory::clone(Target *parent, RunCon
S60DeviceRunControl::S60DeviceRunControl(RunConfiguration *runConfiguration, QString mode) :
RunControl(runConfiguration, mode),
m_toolChain(ProjectExplorer::ToolChain_INVALID),
- m_launcher(0)
+ m_tcfTrkDevice(0),
+ m_launcher(0),
+ m_state(StateUninit)
{
// connect for automatically reporting the "finished deploy" state to the progress manager
- connect(this, SIGNAL(finished()), this, SLOT(reportDeployFinished()));
+ connect(this, SIGNAL(finished()), this, SLOT(reportLaunchFinished()));
S60DeviceRunConfiguration *s60runConfig = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration);
const Qt4BuildConfiguration *activeBuildConf = s60runConfig->qt4Target()->activeBuildConfiguration();
@@ -508,6 +530,7 @@ S60DeviceRunControl::S60DeviceRunControl(RunConfiguration *runConfiguration, QSt
m_toolChain = s60runConfig->toolChainType();
m_serialPortName = activeDeployConf->serialPortName();
m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
+ m_executableUid = s60runConfig->executableUid();
m_targetName = s60runConfig->targetName();
m_commandLineArguments = s60runConfig->commandLineArguments();
m_qtDir = activeBuildConf->qtVersion()->versionInfo().value("QT_INSTALL_DATA");
@@ -516,13 +539,27 @@ S60DeviceRunControl::S60DeviceRunControl(RunConfiguration *runConfiguration, QSt
m_qtBinPath = qtv->versionInfo().value(QLatin1String("QT_INSTALL_BINS"));
QTC_ASSERT(!m_qtBinPath.isEmpty(), return);
m_executableFileName = s60runConfig->localExecutableFileName();
+
+ switch (activeDeployConf->communicationChannel()) {
+ case S60DeployConfiguration::CommunicationSerialConnection:
+ break;
+ case S60DeployConfiguration::CommunicationTcpConnection:
+ m_address = activeDeployConf->deviceAddress();
+ m_port = activeDeployConf->devicePort().toInt();
+ }
+
+ m_useOldTrk = activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationSerialConnection;
if (debug)
qDebug() << "S60DeviceRunControl::CT" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain)
- << m_serialPortName;
+ << m_serialPortName << "Use old TRK" << m_useOldTrk;
}
S60DeviceRunControl::~S60DeviceRunControl()
{
+ if (m_tcfTrkDevice) {
+ m_tcfTrkDevice->deleteLater();
+ m_tcfTrkDevice = 0;
+ }
if (m_launcher) {
m_launcher->deleteLater();
m_launcher = 0;
@@ -539,7 +576,7 @@ void S60DeviceRunControl::start()
m_launchProgress->setProgressValue(0);
m_launchProgress->reportStarted();
emit started();
- if (m_serialPortName.isEmpty()) {
+ if (m_serialPortName.isEmpty() && m_address.isEmpty()) {
m_launchProgress->reportCanceled();
QString msg = tr("No device is connected. Please connect a device and try again.");
appendMessage(msg, NormalMessageFormat);
@@ -568,16 +605,24 @@ void S60DeviceRunControl::start()
RunControl::StopResult S60DeviceRunControl::stop()
{
- if (m_launcher)
- m_launcher->terminate();
+ if (m_useOldTrk) {
+ if (m_launcher)
+ m_launcher->terminate();
+ } else {
+ doStop();
+ }
return AsynchronousStop;
}
bool S60DeviceRunControl::isRunning() const
{
- return m_launcher && (m_launcher->state() == trk::Launcher::Connecting
- || m_launcher->state() == trk::Launcher::Connected
- || m_launcher->state() == trk::Launcher::WaitingForTrk);
+ if (m_useOldTrk) {
+ return m_launcher && (m_launcher->state() == trk::Launcher::Connecting
+ || m_launcher->state() == trk::Launcher::Connected
+ || m_launcher->state() == trk::Launcher::WaitingForTrk);
+ } else {
+ return m_tcfTrkDevice && !m_tcfTrkDevice->device().isNull() && m_state >= StateConnecting;
+ }
}
void S60DeviceRunControl::startLaunching()
@@ -585,7 +630,7 @@ void S60DeviceRunControl::startLaunching()
QString errorMessage;
if (setupLauncher(errorMessage)) {
if (m_launchProgress)
- m_launchProgress->setProgressValue(PROGRESS_MAX/2);
+ m_launchProgress->setProgressValue(PROGRESS_MAX/2);
} else {
if (!errorMessage.isEmpty())
appendMessage(errorMessage, ErrorMessageFormat);
@@ -598,35 +643,232 @@ bool S60DeviceRunControl::setupLauncher(QString &errorMessage)
{
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(const SymbianUtils::SymbianDevice)),
this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice)));
- m_launcher = trk::Launcher::acquireFromDeviceManager(m_serialPortName, 0, &errorMessage);
- if (!m_launcher)
- return false;
- connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
- connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(printConnectFailed(QString)));
- connect(m_launcher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
- connect(m_launcher, SIGNAL(processStopped(uint,uint,uint,QString)),
- this, SLOT(processStopped(uint,uint,uint,QString)));
-
- if (!m_commandLineArguments.isEmpty())
- m_launcher->setCommandLineArgs(m_commandLineArguments);
-
- const QString runFileName = QString::fromLatin1("%1:\\sys\\bin\\%2.exe").arg(m_installationDrive).arg(m_targetName);
- initLauncher(runFileName, m_launcher);
- const trk::PromptStartCommunicationResult src =
- S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(),
- 0, &errorMessage);
- if (src != trk::PromptStartCommunicationConnected)
- return false;
+ if(!m_useOldTrk) { //FIXME: Remove old TRK
+ QTC_ASSERT(!m_tcfTrkDevice, return false);
- if (!m_launcher->startServer(&errorMessage)) {
- errorMessage = tr("Could not connect to phone on port '%1': %2\n"
- "Check if the phone is connected and App TRK is running.").arg(m_serialPortName, errorMessage);
- return false;
+ m_tcfTrkDevice = new TcfTrkDevice;
+ if (debug)
+ m_tcfTrkDevice->setVerbose(1);
+
+ connect(m_tcfTrkDevice, SIGNAL(error(QString)), this, SLOT(slotError(QString)));
+ connect(m_tcfTrkDevice, SIGNAL(logMessage(QString)), this, SLOT(slotTrkLogMessage(QString)));
+ connect(m_tcfTrkDevice, SIGNAL(tcfEvent(tcftrk::TcfTrkEvent)), this, SLOT(slotTcftrkEvent(tcftrk::TcfTrkEvent)));
+ connect(m_tcfTrkDevice, SIGNAL(serialPong(QString)), this, SLOT(slotSerialPong(QString)));
+
+ const QSharedPointer<QTcpSocket> tcfTrkSocket(new QTcpSocket);
+ m_tcfTrkDevice->setDevice(tcfTrkSocket);
+ tcfTrkSocket->connectToHost(m_address, m_port);
+ m_state = StateConnecting;
+ appendMessage(tr("Connecting to %1:%2...").arg(m_address).arg(m_port), NormalMessageFormat);
+ } else {
+ m_launcher = trk::Launcher::acquireFromDeviceManager(m_serialPortName, 0, &errorMessage);
+ if (!m_launcher)
+ return false;
+
+ connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
+ connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(printConnectFailed(QString)));
+ connect(m_launcher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
+ connect(m_launcher, SIGNAL(processStopped(uint,uint,uint,QString)),
+ this, SLOT(processStopped(uint,uint,uint,QString)));
+
+ if (!m_commandLineArguments.isEmpty())
+ m_launcher->setCommandLineArgs(m_commandLineArguments);
+
+ const QString runFileName = QString::fromLatin1("%1:\\sys\\bin\\%2.exe").arg(m_installationDrive).arg(m_targetName);
+ initLauncher(runFileName, m_launcher);
+ const trk::PromptStartCommunicationResult src =
+ S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(),
+ 0, &errorMessage);
+ if (src != trk::PromptStartCommunicationConnected)
+ return false;
+
+ if (!m_launcher->startServer(&errorMessage)) {
+ errorMessage = tr("Could not connect to phone on port '%1': %2\n"
+ "Check if the phone is connected and App TRK is running.").arg(m_serialPortName, errorMessage);
+ return false;
+ }
}
return true;
}
+void S60DeviceRunControl::doStop()
+{
+ if (!m_tcfTrkDevice) {
+ finishRunControl();
+ return;
+ }
+
+ switch (m_state) {
+ case StateUninit:
+ case StateConnecting:
+ case StateConnected:
+ finishRunControl();
+ break;
+ case StateProcessRunning:
+ QTC_ASSERT(!m_runningProcessId.isEmpty(), return);
+ m_tcfTrkDevice->sendRunControlTerminateCommand(TcfTrkCallback(),
+ m_runningProcessId.toAscii());
+ break;
+ }
+}
+
+void S60DeviceRunControl::slotError(const QString &error)
+{
+ appendMessage(tr("Error: %1").arg(error), ErrorMessageFormat);
+ finishRunControl();
+}
+
+void S60DeviceRunControl::slotTrkLogMessage(const QString &log)
+{
+ if (debug) {
+ qDebug("CODA log: %s", qPrintable(log.size()>200?log.left(200).append(QLatin1String(" ...")): log));
+ }
+}
+
+void S60DeviceRunControl::slotSerialPong(const QString &message)
+{
+ if (debug)
+ qDebug() << "CODA serial pong:" << message;
+}
+
+void S60DeviceRunControl::slotTcftrkEvent(const TcfTrkEvent &event)
+{
+ if (debug)
+ qDebug() << "CODA event:" << "Type:" << event.type() << "Message:" << event.toString();
+
+ switch (event.type()) {
+ case TcfTrkEvent::LocatorHello: { // Commands accepted now
+ m_state = StateConnected;
+ appendMessage(tr("Connected!"), NormalMessageFormat);
+ if (m_launchProgress)
+ m_launchProgress->setProgressValue(PROGRESS_MAX*0.80);
+ initCommunication();
+ }
+ break;
+ case TcfTrkEvent::RunControlContextRemoved:
+ handleContextRemoved(event);
+ break;
+ case TcfTrkEvent::RunControlContextAdded:
+ m_state = StateProcessRunning;
+ reportLaunchFinished();
+ handleContextAdded(event);
+ break;
+ case TcfTrkEvent::RunControlSuspended:
+ handleContextSuspended(event);
+ break;
+ case TcfTrkEvent::RunControlModuleLoadSuspended:
+ handleModuleLoadSuspended(event);
+ break;
+ default:
+ if (debug)
+ qDebug() << __FUNCTION__ << "Event not handled" << event.type();
+ break;
+ }
+}
+
+void S60DeviceRunControl::initCommunication()
+{
+ m_tcfTrkDevice->sendSettingsEnableLogCommand();
+ m_tcfTrkDevice->sendLoggingAddListenerCommand(TcfTrkCallback(this, &S60DeviceRunControl::handleAddListener));
+}
+
+void S60DeviceRunControl::handleContextRemoved(const TcfTrkEvent &event)
+{
+ QVector<QByteArray> &removedItems( static_cast<const TcfTrkRunControlContextRemovedEvent &>(event).ids());
+ if (!m_runningProcessId.isEmpty()
+ && removedItems.contains(m_runningProcessId.toAscii())) {
+ appendMessage(tr("Process has finished."), NormalMessageFormat);
+ finishRunControl();
+ }
+}
+
+void S60DeviceRunControl::handleContextAdded(const TcfTrkEvent &event)
+{
+ typedef TcfTrkRunControlContextAddedEvent TcfAddedEvent;
+
+ const TcfAddedEvent &me = static_cast<const TcfAddedEvent &>(event);
+ foreach (const RunControlContext &context, me.contexts()) {
+ if (context.parentId == "root") //is the created context a process
+ m_runningProcessId = QLatin1String(context.id);
+ }
+}
+
+void S60DeviceRunControl::handleContextSuspended(const TcfTrkEvent &event)
+{
+ typedef TcfTrkRunControlContextSuspendedEvent TcfSuspendEvent;
+
+ const TcfSuspendEvent &me = static_cast<const TcfSuspendEvent &>(event);
+
+ switch (me.reason()) {
+ case TcfSuspendEvent::Crash:
+ appendMessage(tr("Process has crashed: %1").arg(QString::fromLatin1(me.message())), ErrorMessageFormat);
+ m_tcfTrkDevice->sendRunControlResumeCommand(TcfTrkCallback(), me.id()); //TODO: Should I resume automaticly
+ break;
+ default:
+ if (debug)
+ qDebug() << "Context suspend not handled:" << "Reason:" << me.reason() << "Message:" << me.message();
+ break;
+ }
+}
+
+void S60DeviceRunControl::handleModuleLoadSuspended(const TcfTrkEvent &event)
+{
+ // Debug mode start: Continue:
+ typedef TcfTrkRunControlModuleLoadContextSuspendedEvent TcfModuleLoadSuspendedEvent;
+
+ const TcfModuleLoadSuspendedEvent &me = static_cast<const TcfModuleLoadSuspendedEvent &>(event);
+ if (me.info().requireResume)
+ m_tcfTrkDevice->sendRunControlResumeCommand(TcfTrkCallback(), me.id());
+}
+
+void S60DeviceRunControl::handleAddListener(const TcfTrkCommandResult &result)
+{
+ if (debug)
+ qDebug() << __FUNCTION__ <<"Add log listener" << result.toString();
+ m_tcfTrkDevice->sendSymbianOsDataGetThreadsCommand(TcfTrkCallback(this, &S60DeviceRunControl::handleGetThreads));
+}
+
+void S60DeviceRunControl::handleGetThreads(const TcfTrkCommandResult &result)
+{
+ if (isProcessRunning(result, m_targetName)) {
+ appendMessage(tr("The process is already running on the device. Please first close it."), ErrorMessageFormat);
+ finishRunControl();
+ } else {
+ if (m_launchProgress)
+ m_launchProgress->setProgressValue(PROGRESS_MAX*0.90);
+ const QString runFileName = QString::fromLatin1("%1.exe").arg(m_targetName);
+ m_tcfTrkDevice->sendProcessStartCommand(TcfTrkCallback(this, &S60DeviceRunControl::handleCreateProcess),
+ runFileName, m_executableUid, m_commandLineArguments.split(" "), QString(), true);
+ appendMessage(tr("Launching: %1").arg(runFileName), NormalMessageFormat);
+ }
+}
+
+void S60DeviceRunControl::handleCreateProcess(const TcfTrkCommandResult &result)
+{
+ const bool ok = result.type == TcfTrkCommandResult::SuccessReply;
+ if (ok) {
+ if (m_launchProgress)
+ m_launchProgress->setProgressValue(PROGRESS_MAX);
+ appendMessage(tr("Launched!"), NormalMessageFormat);
+ } else {
+ appendMessage(tr("Launch failed: %1").arg(result.toString()), ErrorMessageFormat);
+ finishRunControl();
+ }
+}
+
+void S60DeviceRunControl::finishRunControl()
+{
+ m_runningProcessId.clear();
+ if (m_tcfTrkDevice)
+ m_tcfTrkDevice->deleteLater();
+ m_tcfTrkDevice = 0;
+ m_state = StateUninit;
+ handleRunFinished();
+}
+
+//////// Launcher code - to be removed
+
void S60DeviceRunControl::printConnectFailed(const QString &errorMessage)
{
appendMessage(tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage),
@@ -638,10 +880,10 @@ void S60DeviceRunControl::launcherFinished()
trk::Launcher::releaseToDeviceManager(m_launcher);
m_launcher->deleteLater();
m_launcher = 0;
- handleLauncherFinished();
+ handleRunFinished();
}
-void S60DeviceRunControl::reportDeployFinished()
+void S60DeviceRunControl::reportLaunchFinished()
{
if (m_launchProgress) {
m_launchProgress->reportFinished();
@@ -672,7 +914,7 @@ void S60DeviceRunControl::slotLauncherStateChanged(int s)
{
if (s == trk::Launcher::WaitingForTrk) {
QMessageBox *mb = S60DeviceRunControl::createTrkWaitingMessageBox(m_launcher->trkServerName(),
- Core::ICore::instance()->mainWindow());
+ Core::ICore::instance()->mainWindow());
connect(m_launcher, SIGNAL(stateChanged(int)), mb, SLOT(close()));
connect(mb, SIGNAL(finished(int)), this, SLOT(slotWaitingForTrkClosed()));
mb->open();
@@ -710,29 +952,16 @@ void S60DeviceRunControl::deviceRemoved(const SymbianUtils::SymbianDevice &d)
}
}
-bool S60DeviceRunControl::checkConfiguration(QString * /* errorMessage */,
- QString * /* settingsCategory */,
- QString * /* settingsPage */) const
-{
- return true;
-}
-
void S60DeviceRunControl::initLauncher(const QString &executable, trk::Launcher *launcher)
{
- connect(launcher, SIGNAL(startingApplication()), this, SLOT(printStartingNotice()));
- connect(launcher, SIGNAL(applicationRunning(uint)), this, SLOT(applicationRunNotice(uint)));
- connect(launcher, SIGNAL(canNotRun(QString)), this, SLOT(applicationRunFailedNotice(QString)));
- connect(launcher, SIGNAL(applicationOutputReceived(QString)), this, SLOT(printApplicationOutput(QString)));
- launcher->addStartupActions(trk::Launcher::ActionRun);
- launcher->setFileName(executable);
+ connect(launcher, SIGNAL(startingApplication()), this, SLOT(printStartingNotice()));
+ connect(launcher, SIGNAL(applicationRunning(uint)), this, SLOT(applicationRunNotice(uint)));
+ connect(launcher, SIGNAL(canNotRun(QString)), this, SLOT(applicationRunFailedNotice(QString)));
+ connect(launcher, SIGNAL(applicationOutputReceived(QString)), this, SLOT(printApplicationOutput(QString)));
+ launcher->addStartupActions(trk::Launcher::ActionRun);
+ launcher->setFileName(executable);
}
-void S60DeviceRunControl::handleLauncherFinished()
-{
- emit finished();
- appendMessage(tr("Finished."), NormalMessageFormat);
- }
-
void S60DeviceRunControl::printStartingNotice()
{
appendMessage(tr("Starting application..."), NormalMessageFormat);
@@ -750,6 +979,21 @@ void S60DeviceRunControl::applicationRunFailedNotice(const QString &errorMessage
appendMessage(tr("Could not start application: %1").arg(errorMessage), NormalMessageFormat);
}
+// End of Launcher code - to be removed
+
+bool S60DeviceRunControl::checkConfiguration(QString * /* errorMessage */,
+ QString * /* settingsCategory */,
+ QString * /* settingsPage */) const
+{
+ return true;
+}
+
+void S60DeviceRunControl::handleRunFinished()
+{
+ emit finished();
+ appendMessage(tr("Finished."), NormalMessageFormat);
+}
+
// ======== S60DeviceDebugRunControl
// Return symbol file which should co-exist with the executable.
@@ -790,7 +1034,13 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR
sp.executable = debugFileName;
sp.executableUid = rc->executableUid();
sp.enabledEngines = Debugger::GdbEngineType;
+ sp.serverAddress = activeDeployConf->deviceAddress();
+ sp.serverPort = activeDeployConf->devicePort().toInt();
+ //FIXME: there should be only one... trkAdapter
+ sp.communicationChannel = activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationSerialConnection?
+ Debugger::DebuggerStartParameters::CommunicationChannelUsb:
+ Debugger::DebuggerStartParameters::CommunicationChannelTcpIp;
QTC_ASSERT(sp.executableUid, return sp);
// Prefer the '*.sym' file over the '.exe', which should exist at the same
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index 170a251fbc1..77b7f0427cd 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -42,6 +42,8 @@
#include <QtCore/QScopedPointer>
#include <QtCore/QStringList>
+#include <QTime> //TODO: remove
+
QT_BEGIN_NAMESPACE
class QMessageBox;
class QWidget;
@@ -55,6 +57,13 @@ namespace trk {
class Launcher;
}
+
+namespace tcftrk {
+struct TcfTrkCommandResult;
+class TcfTrkDevice;
+class TcfTrkEvent;
+}
+
namespace Qt4ProjectManager {
class QtVersion;
class Qt4Target;
@@ -154,7 +163,7 @@ public:
protected:
virtual void initLauncher(const QString &executable, trk::Launcher *);
- virtual void handleLauncherFinished();
+ virtual void handleRunFinished();
virtual bool checkConfiguration(QString *errorMessage,
QString *settingsCategory,
QString *settingsPage) const;
@@ -166,7 +175,9 @@ protected slots:
void applicationRunNotice(uint pid);
void applicationRunFailedNotice(const QString &errorMessage);
void deviceRemoved(const SymbianUtils::SymbianDevice &);
- void reportDeployFinished();
+ void reportLaunchFinished();
+
+ void finishRunControl();
private slots:
void processStopped(uint pc, uint pid, uint tid, const QString& reason);
@@ -175,23 +186,58 @@ private slots:
void slotLauncherStateChanged(int);
void slotWaitingForTrkClosed();
+private slots:
+ void slotError(const QString &error);
+ void slotTrkLogMessage(const QString &log);
+ void slotTcftrkEvent(const tcftrk::TcfTrkEvent &event);
+ void slotSerialPong(const QString &message);
+
protected:
QFutureInterface<void> *m_launchProgress;
private:
+ void initCommunication();
void startLaunching();
bool setupLauncher(QString &errorMessage);
+ void doStop();
+
+ void handleModuleLoadSuspended(const tcftrk::TcfTrkEvent &event);
+ void handleContextSuspended(const tcftrk::TcfTrkEvent &event);
+ void handleContextAdded(const tcftrk::TcfTrkEvent &event);
+ void handleContextRemoved(const tcftrk::TcfTrkEvent &event);
+
+private:
+ void handleCreateProcess(const tcftrk::TcfTrkCommandResult &result);
+ void handleAddListener(const tcftrk::TcfTrkCommandResult &result);
+ void handleGetThreads(const tcftrk::TcfTrkCommandResult &result);
+
+ enum State {
+ StateUninit,
+ StateConnecting,
+ StateConnected,
+ StateProcessRunning
+ };
ProjectExplorer::ToolChainType m_toolChain;
QString m_serialPortName;
QString m_serialPortFriendlyName;
+ QString m_address;
+ unsigned short m_port;
+ quint32 m_executableUid;
QString m_targetName;
QString m_commandLineArguments;
QString m_executableFileName;
QString m_qtDir;
QString m_qtBinPath;
+
+ tcftrk::TcfTrkDevice *m_tcfTrkDevice;
trk::Launcher *m_launcher;
char m_installationDrive;
+
+ QString m_runningProcessId;
+ State m_state;
+
+ bool m_useOldTrk; //FIXME: remove old TRK
};
// S60DeviceDebugRunControl starts debugging
diff --git a/src/plugins/qt4projectmanager/qt4target.cpp b/src/plugins/qt4projectmanager/qt4target.cpp
index d6d47306e59..ecc01b744f2 100644
--- a/src/plugins/qt4projectmanager/qt4target.cpp
+++ b/src/plugins/qt4projectmanager/qt4target.cpp
@@ -463,6 +463,12 @@ void Qt4Target::onAddedDeployConfiguration(ProjectExplorer::DeployConfiguration
return;
connect(deployConf, SIGNAL(serialPortNameChanged()),
this, SLOT(slotUpdateDeviceInformation()));
+ connect(deployConf, SIGNAL(communicationChannelChanged()),
+ this, SLOT(slotUpdateDeviceInformation()));
+ connect(deployConf, SIGNAL(deviceAddressChanged()),
+ this, SLOT(slotUpdateDeviceInformation()));
+ connect(deployConf, SIGNAL(devicePortChanged()),
+ this, SLOT(slotUpdateDeviceInformation()));
}
void Qt4Target::slotUpdateDeviceInformation()
@@ -487,22 +493,16 @@ void Qt4Target::emitProFileEvaluateNeeded()
void Qt4Target::updateToolTipAndIcon()
{
static const int TARGET_OVERLAY_ORIGINAL_SIZE = 32;
- if (const S60DeployConfiguration *s60DeployConf = qobject_cast<S60DeployConfiguration *>(activeDeployConfiguration())) {
- const SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
- const int deviceIndex = sdm->findByPortName(s60DeployConf->serialPortName());
+
+ if (qobject_cast<S60DeployConfiguration *>(activeDeployConfiguration())) {
QPixmap overlay;
- if (deviceIndex == -1) {
- setToolTip(tr("<b>Device:</b> Not connected"));
- overlay = m_disconnectedPixmap;
- } else {
- // device connected
- const SymbianUtils::SymbianDevice device = sdm->devices().at(deviceIndex);
- const QString tooltip = device.additionalInformation().isEmpty() ?
- tr("<b>Device:</b> %1").arg(device.friendlyName()) :
- tr("<b>Device:</b> %1, %2").arg(device.friendlyName(), device.additionalInformation());
- setToolTip(tooltip);
+ QString tooltip;
+ if (isSymbianConnectionAvailable(tooltip))
overlay = m_connectedPixmap;
- }
+ else
+ overlay = m_disconnectedPixmap;
+ setToolTip(tooltip);
+
double factor = Core::Constants::TARGET_ICON_SIZE / (double)TARGET_OVERLAY_ORIGINAL_SIZE;
QSize overlaySize(overlay.size().width()*factor, overlay.size().height()*factor);
QPixmap pixmap(Core::Constants::TARGET_ICON_SIZE, Core::Constants::TARGET_ICON_SIZE);
@@ -518,3 +518,40 @@ void Qt4Target::updateToolTipAndIcon()
setOverlayIcon(QIcon());
}
}
+
+bool Qt4Target::isSymbianConnectionAvailable(QString &tooltipText)
+{
+ const S60DeployConfiguration *s60DeployConf = qobject_cast<S60DeployConfiguration *>(activeDeployConfiguration());
+ if (!s60DeployConf)
+ return false;
+ switch (s60DeployConf->communicationChannel()) {
+ case S60DeployConfiguration::CommunicationSerialConnection: {
+ const SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
+ const int deviceIndex = sdm->findByPortName(s60DeployConf->serialPortName());
+ if (deviceIndex == -1) {
+ tooltipText = tr("<b>Device:</b> Not connected");
+ return false;
+ } else {
+ // device connected
+ const SymbianUtils::SymbianDevice device = sdm->devices().at(deviceIndex);
+ tooltipText = device.additionalInformation().isEmpty() ?
+ tr("<b>Device:</b> %1").arg(device.friendlyName()) :
+ tr("<b>Device:</b> %1, %2").arg(device.friendlyName(), device.additionalInformation());
+ return true;
+ }
+ }
+ break;
+ case S60DeployConfiguration::CommunicationTcpConnection: {
+ if(!s60DeployConf->deviceAddress().isEmpty() && !s60DeployConf->devicePort().isEmpty()) {
+ tooltipText = tr("<b>IP address:</b> %1:%2").arg(s60DeployConf->deviceAddress(), s60DeployConf->devicePort());
+ return true;
+ }
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
diff --git a/src/plugins/qt4projectmanager/qt4target.h b/src/plugins/qt4projectmanager/qt4target.h
index de7499845f7..0e27c702be3 100644
--- a/src/plugins/qt4projectmanager/qt4target.h
+++ b/src/plugins/qt4projectmanager/qt4target.h
@@ -109,6 +109,9 @@ private slots:
void updateToolTipAndIcon();
private:
+ bool isSymbianConnectionAvailable(QString &tooltipText);
+
+private:
const QPixmap m_connectedPixmap;
const QPixmap m_disconnectedPixmap;
diff --git a/src/shared/symbianutils/launcher.cpp b/src/shared/symbianutils/launcher.cpp
index 7a396c7b1ff..ae59b88751d 100644
--- a/src/shared/symbianutils/launcher.cpp
+++ b/src/shared/symbianutils/launcher.cpp
@@ -932,8 +932,8 @@ void Launcher::installRemotePackage()
void Launcher::handleInstallPackageFinished(const TrkResult &result)
{
if (result.errorCode()) {
- if( installationMode() == InstallationModeSilentAndUser
- && d->m_currentInstallationStep & InstallationModeSilent ) {
+ if (installationMode() == InstallationModeSilentAndUser
+ && d->m_currentInstallationStep & InstallationModeSilent) {
installRemotePackageByUser();
return;
}
diff --git a/src/shared/symbianutils/tcftrkdevice.cpp b/src/shared/symbianutils/tcftrkdevice.cpp
index a11549fb64b..4ed2d79ca15 100644
--- a/src/shared/symbianutils/tcftrkdevice.cpp
+++ b/src/shared/symbianutils/tcftrkdevice.cpp
@@ -952,11 +952,9 @@ void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack,
slashPos = binaryIn.lastIndexOf(backSlash);
const QString sysBin = QLatin1String("c:/sys/bin");
const QString binaryFileName = slashPos == -1 ? binaryIn : binaryIn.mid(slashPos + 1);
- const QString binaryDirectory = slashPos == -1 ? sysBin : binaryIn.left(slashPos);
- const QString binary = fixFileName(binaryDirectory + QLatin1Char('/') + binaryFileName);
// Fixup: Does argv[0] convention exist on Symbian?
- arguments.push_front(binary);
+ arguments.push_front(binaryFileName);
if (workingDirectory.isEmpty())
workingDirectory = sysBin;
@@ -964,11 +962,11 @@ void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack,
QByteArray setData;
JsonInputStream setStr(setData);
setStr << "" << '\0'
- << '[' << "exeToLaunch" << ',' << "addExecutables" << ',' << "addLibraries" << ']'
+ << '[' << "exeToLaunch" << ',' << "addExecutables" << ',' << "addLibraries" << ',' << "logUserTraces" << ']'
<< '\0' << '['
- << binary << ','
+ << binaryFileName << ','
<< '{' << binaryFileName << ':' << QString::number(uid, 16) << '}' << ','
- << additionalLibraries
+ << additionalLibraries << ',' << true
<< ']';
sendTcfTrkMessage(
#if 1
@@ -980,13 +978,32 @@ void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack,
QByteArray startData;
JsonInputStream startStr(startData);
- startStr << fixFileName(workingDirectory)
- << '\0' << binary << '\0' << arguments << '\0'
+ startStr << "" //We dont really know the drive of the working dir
+ << '\0' << binaryFileName << '\0' << arguments << '\0'
<< QStringList() << '\0' // Env is an array ["PATH=value"] (non-standard)
<< debugControl;
sendTcfTrkMessage(MessageWithReply, ProcessesService, "start", startData, callBack, cookie);
}
+void TcfTrkDevice::sendSettingsEnableLogCommand()
+{
+
+ QByteArray setData;
+ JsonInputStream setStr(setData);
+ setStr << "" << '\0'
+ << '[' << "logUserTraces" << ']'
+ << '\0' << '['
+ << true
+ << ']';
+ sendTcfTrkMessage(
+#if 1
+ MessageWithReply, // TCF TRK 4.0.5 onwards
+#else
+ MessageWithoutReply, // TCF TRK 4.0.2
+#endif
+ SettingsService, "set", setData);
+}
+
void TcfTrkDevice::sendProcessTerminateCommand(const TcfTrkCallback &callBack,
const QByteArray &id,
const QVariant &cookie)
@@ -1324,7 +1341,8 @@ void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
value, cookie);
}
-static const char outputListenerIDC[] = "org.eclipse.cdt.debug.edc.ui.ProgramOutputConsoleLogger";
+//static const char outputListenerIDC[] = "org.eclipse.cdt.debug.edc.ui.ProgramOutputConsoleLogger";
+static const char outputListenerIDC[] = "ProgramOutputConsoleLogger"; //TODO: this one might be the correct one
void TcfTrkDevice::sendLoggingAddListenerCommand(const TcfTrkCallback &callBack,
const QVariant &cookie)
@@ -1335,6 +1353,14 @@ void TcfTrkDevice::sendLoggingAddListenerCommand(const TcfTrkCallback &callBack,
sendTcfTrkMessage(MessageWithReply, LoggingService, "addListener", data, callBack, cookie);
}
+void TcfTrkDevice::sendSymbianOsDataGetThreadsCommand(const TcfTrkCallback &callBack,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ sendTcfTrkMessage(MessageWithReply, SymbianOSData, "getThreads", data, callBack, cookie);
+}
+
+
void tcftrk::TcfTrkDevice::sendFileSystemOpenCommand(const tcftrk::TcfTrkCallback &callBack,
const QByteArray &name,
unsigned flags,
diff --git a/src/shared/symbianutils/tcftrkdevice.h b/src/shared/symbianutils/tcftrkdevice.h
index 70582f884aa..e7abc12250b 100644
--- a/src/shared/symbianutils/tcftrkdevice.h
+++ b/src/shared/symbianutils/tcftrkdevice.h
@@ -349,6 +349,13 @@ public:
void sendLoggingAddListenerCommand(const TcfTrkCallback &callBack,
const QVariant &cookie = QVariant());
+ // SymbianOs Data
+ void sendSymbianOsDataGetThreadsCommand(const TcfTrkCallback &callBack,
+ const QVariant &cookie = QVariant());
+
+ // Settings
+ void sendSettingsEnableLogCommand();
+
static QByteArray parseMemoryGet(const TcfTrkCommandResult &r);
static QVector<QByteArray> parseRegisterGetChildren(const TcfTrkCommandResult &r);
static TcfTrkStatResponse parseStat(const TcfTrkCommandResult &r);
diff --git a/src/shared/symbianutils/tcftrkmessage.cpp b/src/shared/symbianutils/tcftrkmessage.cpp
index e3123c0b07b..feadf98a710 100644
--- a/src/shared/symbianutils/tcftrkmessage.cpp
+++ b/src/shared/symbianutils/tcftrkmessage.cpp
@@ -40,7 +40,7 @@
// Names matching the enum
static const char *serviceNamesC[] =
{ "Locator", "RunControl", "Processes", "Memory", "Settings", "Breakpoints",
- "Registers", "Logging", "FileSystem", "SymbianInstall",
+ "Registers", "Logging", "FileSystem", "SymbianInstall", "SymbianOSData",
"UnknownService"};
namespace tcftrk {
@@ -554,8 +554,8 @@ TcfTrkRunControlContextSuspendedEvent::Reason TcfTrkRunControlContextSuspendedEv
if (m_reason == "Breakpoint")
return BreakPoint;
// 'Data abort exception'/'Thread has panicked' ... unfortunately somewhat unspecific.
- if (m_reason.contains("exception") || m_reason.contains("panick"))
- return Crash;
+ if (m_reason.contains("Exception") || m_reason.contains("panick"))
+ return Crash;
return Other;
}
diff --git a/src/shared/symbianutils/tcftrkmessage.h b/src/shared/symbianutils/tcftrkmessage.h
index 974c4eb068c..97e16f79588 100644
--- a/src/shared/symbianutils/tcftrkmessage.h
+++ b/src/shared/symbianutils/tcftrkmessage.h
@@ -59,6 +59,7 @@ enum Services {
LoggingService, // non-standard, trk specific
FileSystemService,
SymbianInstallService, // non-standard, trk specific
+ SymbianOSData, // non-standard, trk specific
UnknownService
}; // Note: Check string array 'serviceNamesC' of same size when modifying this.