Commit 051011bc authored by Pawel Polanski's avatar Pawel Polanski
Browse files

Symbian: Adjust Creator to work with CODA

Reviewed-by: hjk
parent d5b2954d
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "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
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef 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
......@@ -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 \
......
......@@ -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
......
......@@ -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);
}
}
......
......@@ -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('/'));
......
......@@ -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);
}
......@@ -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
......
......@@ -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(tar