diff options
23 files changed, 1459 insertions, 829 deletions
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index d1c5ff6988..f5d77d4fc9 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -34,6 +34,8 @@ #include <projectexplorer/projectexplorer_export.h> +#include <coreplugin/id.h> + #include <QSharedPointer> #include <QStringList> #include <QVariantMap> @@ -43,8 +45,6 @@ class QDialog; class QWidget; QT_END_NAMESPACE -namespace Core { class Id; } - namespace ProjectExplorer { namespace Internal { class IDevicePrivate; } class IDeviceWidget; diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp index 4ee674d3ef..14f5e4c4a3 100644 --- a/src/plugins/projectexplorer/target.cpp +++ b/src/plugins/projectexplorer/target.cpp @@ -41,12 +41,16 @@ #include "toolchainmanager.h" #include <limits> -#include <extensionsystem/pluginmanager.h> +#include <coreplugin/coreconstants.h> #include <projectexplorer/buildmanager.h> +#include <projectexplorer/devicesupport/devicemanager.h> +#include <projectexplorer/devicesupport/idevice.h> +#include <extensionsystem/pluginmanager.h> #include <projectexplorer/projectexplorer.h> #include <utils/qtcassert.h> #include <QIcon> +#include <QPainter> namespace { const char ACTIVE_BC_KEY[] = "ProjectExplorer.Target.ActiveBuildConfiguration"; @@ -87,13 +91,18 @@ public: DeployConfiguration *m_activeDeployConfiguration; QList<RunConfiguration *> m_runConfigurations; RunConfiguration* m_activeRunConfiguration; + + QPixmap m_connectedPixmap; + QPixmap m_disconnectedPixmap; }; TargetPrivate::TargetPrivate() : m_isEnabled(true), m_activeBuildConfiguration(0), m_activeDeployConfiguration(0), - m_activeRunConfiguration(0) + m_activeRunConfiguration(0), + m_connectedPixmap(QLatin1String(":/projectexplorer/images/ConnectionOn.png")), + m_disconnectedPixmap(QLatin1String(":/projectexplorer/images/ConnectionOff.png")) { } @@ -106,6 +115,11 @@ QList<DeployConfigurationFactory *> TargetPrivate::deployFactories() const Target::Target(Project *project, const QString &id) : ProjectConfiguration(project, id), d(new TargetPrivate) { + connect(DeviceManager::instance(), SIGNAL(deviceUpdated(ProjectExplorer::IDevice::Id)), + this, SLOT(updateDeviceState(ProjectExplorer::IDevice::Id))); + // everything changed... + connect(DeviceManager::instance(), SIGNAL(deviceListChanged()), + this, SLOT(updateDeviceState())); } Target::~Target() @@ -311,6 +325,7 @@ void Target::setActiveDeployConfiguration(DeployConfiguration *dc) emit activeDeployConfigurationChanged(d->m_activeDeployConfiguration); emit deployConfigurationEnabledChanged(); } + updateDeviceState(); } QStringList Target::availableDeployConfigurationIds() @@ -398,6 +413,7 @@ void Target::setActiveRunConfiguration(RunConfiguration* configuration) emit activeRunConfigurationChanged(d->m_activeRunConfiguration); emit runConfigurationEnabledChanged(); } + updateDeviceState(); } bool Target::isEnabled() const @@ -483,6 +499,59 @@ QVariantMap Target::toMap() const return map; } +static QString formatToolTip(const IDevice::DeviceInfo &input) +{ + QStringList lines; + foreach (const IDevice::DeviceInfoItem &item, input) + lines << QString::fromLatin1("<b>%1:</b> %2").arg(item.key, item.value); + return lines.join(QLatin1String("<br>")); +} + +void Target::updateDeviceState() +{ + updateDeviceState(currentDevice()->id()); +} + +void Target::updateDeviceState(Core::Id devId) +{ + IDevice::ConstPtr dev = DeviceManager::instance()->find(devId); + QTC_ASSERT(!dev.isNull(), return); + + IDevice::ConstPtr current = currentDevice(); + if (current.isNull() + || devId != current->id() + || dev->availability() == IDevice::DeviceAvailabilityUnknown) { + setOverlayIcon(QIcon()); + setToolTip(QString()); + return; + } + + static const int TARGET_OVERLAY_ORIGINAL_SIZE = 32; + + QPixmap overlay; + if (dev->availability() == IDevice::DeviceAvailable) + overlay = d->m_connectedPixmap; + else + overlay = d->m_disconnectedPixmap; + + 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); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.drawPixmap(Core::Constants::TARGET_ICON_SIZE - overlaySize.width(), + Core::Constants::TARGET_ICON_SIZE - overlaySize.height(), + overlay.scaled(overlaySize)); + + setOverlayIcon(QIcon(pixmap)); + setToolTip(formatToolTip(dev->deviceInformation())); +} + +ProjectExplorer::IDevice::ConstPtr Target::currentDevice() const +{ + return IDevice::ConstPtr(0); +} + void Target::setEnabled(bool enabled) { if (enabled == d->m_isEnabled) @@ -580,7 +649,6 @@ bool Target::fromMap(const QVariantMap &map) return true; } - // ------------------------------------------------------------------------- // ITargetFactory // ------------------------------------------------------------------------- diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h index d15c1b0420..743025ce62 100644 --- a/src/plugins/projectexplorer/target.h +++ b/src/plugins/projectexplorer/target.h @@ -33,14 +33,13 @@ #ifndef TARGET_H #define TARGET_H +#include "devicesupport/idevice.h" #include "projectconfiguration.h" #include "projectexplorer_export.h" QT_FORWARD_DECLARE_CLASS(QIcon) -namespace Utils { -class Environment; -} +namespace Utils { class Environment; } namespace ProjectExplorer { class RunConfiguration; @@ -147,11 +146,15 @@ signals: protected: Target(Project *parent, const QString &id); + virtual ProjectExplorer::IDevice::ConstPtr currentDevice() const; + void setEnabled(bool); virtual bool fromMap(const QVariantMap &map); private slots: + void updateDeviceState(); + void updateDeviceState(Core::Id devId); void changeEnvironment(); void changeBuildConfigurationEnabled(); void changeDeployConfigurationEnabled(); diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 6a16546e1a..b654f03b63 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -75,6 +75,7 @@ #include <qt4projectmanager/qt-s60/s60devicedebugruncontrol.h> #include <qt4projectmanager/qt-s60/s60devicerunconfiguration.h> #include <qt4projectmanager/qt-s60/s60deployconfiguration.h> +#include <qt4projectmanager/qt-s60/symbianidevice.h> #include <QApplication> #include <QHBoxLayout> @@ -253,9 +254,9 @@ IAnalyzerEngine *QmlProfilerTool::createEngine(const AnalyzerStartParameters &sp if (Qt4ProjectManager::S60DeployConfiguration *deployConfig = qobject_cast<Qt4ProjectManager::S60DeployConfiguration*>( runConfiguration->target()->activeDeployConfiguration())) { - if (deployConfig->communicationChannel() - == Qt4ProjectManager::S60DeployConfiguration::CommunicationCodaSerialConnection) { - d->m_profilerConnections->setOstConnection(deployConfig->serialPortName()); + if (deployConfig->device()->communicationChannel() + == Qt4ProjectManager::SymbianIDevice::CommunicationCodaSerialConnection) { + d->m_profilerConnections->setOstConnection(deployConfig->device()->serialPortName()); isTcpConnection = false; } } @@ -352,7 +353,7 @@ AnalyzerStartParameters QmlProfilerTool::createStartParameters(RunConfiguration sp.debuggeeArgs = rc4->commandLineArguments(); sp.displayName = rc4->displayName(); - sp.connParams.host = deployConf->deviceAddress(); + sp.connParams.host = deployConf->device()->address(); sp.connParams.port = rc4->debuggerAspect()->qmlDebugServerPort(); } else { // What could that be? diff --git a/src/plugins/qt4projectmanager/qt-s60/codaruncontrol.cpp b/src/plugins/qt4projectmanager/qt-s60/codaruncontrol.cpp index 89b53ccb7c..f9f5753356 100644 --- a/src/plugins/qt4projectmanager/qt-s60/codaruncontrol.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/codaruncontrol.cpp @@ -34,6 +34,7 @@ #include "s60deployconfiguration.h" #include "s60devicerunconfiguration.h" +#include "symbianidevice.h" #include "codadevice.h" #include "codamessage.h" @@ -75,13 +76,14 @@ CodaRunControl::CodaRunControl(RunConfiguration *runConfiguration, RunMode mode) QTC_ASSERT(s60runConfig, return); const S60DeployConfiguration *activeDeployConf = qobject_cast<S60DeployConfiguration *>(s60runConfig->target()->activeDeployConfiguration()); QTC_ASSERT(activeDeployConf, return); - - S60DeployConfiguration::CommunicationChannel channel = activeDeployConf->communicationChannel(); - if (channel == S60DeployConfiguration::CommunicationCodaTcpConnection) { - m_address = activeDeployConf->deviceAddress(); - m_port = activeDeployConf->devicePort().toInt(); - } else if (channel == S60DeployConfiguration::CommunicationCodaSerialConnection) { - m_serialPort = activeDeployConf->serialPortName(); + QTC_ASSERT(activeDeployConf->device(), return); + + SymbianIDevice::CommunicationChannel channel = activeDeployConf->device()->communicationChannel(); + if (channel == SymbianIDevice::CommunicationCodaTcpConnection) { + m_address = activeDeployConf->device()->address(); + m_port = activeDeployConf->device()->port().toInt(); + } else if (channel == SymbianIDevice::CommunicationCodaSerialConnection) { + m_serialPort = activeDeployConf->device()->serialPortName(); } else { QTC_ASSERT(false, return); } diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri index 6faede1458..75b8fcc487 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri +++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri @@ -1,4 +1,7 @@ SOURCES += $$PWD/s60manager.cpp \ + $$PWD/symbianidevice.cpp \ + $$PWD/symbianideviceconfigwidget.cpp \ + $$PWD/symbianidevicefactory.cpp \ $$PWD/sbsv2parser.cpp \ $$PWD/winscwtoolchain.cpp \ $$PWD/gccetoolchain.cpp \ @@ -35,6 +38,9 @@ SOURCES += $$PWD/s60manager.cpp \ $$PWD/s60devicedebugruncontrol.cpp HEADERS += $$PWD/s60manager.h \ + $$PWD/symbianidevice.h \ + $$PWD/symbianideviceconfigwidget.h \ + $$PWD/symbianidevicefactory.h \ $$PWD/sbsv2parser.h \ $$PWD/winscwtoolchain.h \ $$PWD/gccetoolchain.h \ diff --git a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.cpp b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.cpp index 6c3107cdde..89ae8a468b 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.cpp @@ -35,19 +35,17 @@ #include "qt4project.h" #include "qt4nodes.h" #include "qt4buildconfiguration.h" +#include "symbianidevice.h" #include "qt-s60/s60deployconfiguration.h" #include "qt-s60/s60emulatorrunconfiguration.h" #include "qt-s60/s60devicerunconfiguration.h" -#include <coreplugin/coreconstants.h> #include <projectexplorer/customexecutablerunconfiguration.h> #include <projectexplorer/project.h> #include <projectexplorer/toolchainmanager.h> #include <projectexplorer/toolchain.h> -#include <symbianutils/symbiandevicemanager.h> #include <extensionsystem/pluginmanager.h> -#include <QPainter> #include <QApplication> using namespace Qt4ProjectManager; @@ -55,22 +53,14 @@ using namespace Qt4ProjectManager::Internal; Qt4SymbianTarget::Qt4SymbianTarget(Qt4Project *parent, const QString &id) : Qt4BaseTarget(parent, id), - m_connectedPixmap(QLatin1String(":/projectexplorer/images/ConnectionOn.png")), - m_disconnectedPixmap(QLatin1String(":/projectexplorer/images/ConnectionOff.png")), m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this)) { setDisplayName(defaultDisplayName(id)); setIcon(iconForId(id)); - connect(this, SIGNAL(addedDeployConfiguration(ProjectExplorer::DeployConfiguration*)), - this, SLOT(onAddedDeployConfiguration(ProjectExplorer::DeployConfiguration*))); - connect(this, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)), - this, SLOT(updateToolTipAndIcon())); } Qt4SymbianTarget::~Qt4SymbianTarget() -{ - -} +{ } QString Qt4SymbianTarget::defaultDisplayName(const QString &id) { @@ -167,91 +157,8 @@ QList<ProjectExplorer::RunConfiguration *> Qt4SymbianTarget::runConfigurationsFo return result; } -bool Qt4SymbianTarget::isSymbianConnectionAvailable(QString &tooltipText) -{ - const S60DeployConfiguration *s60DeployConf = qobject_cast<S60DeployConfiguration *>(activeDeployConfiguration()); - if (!s60DeployConf) - return false; - switch (s60DeployConf->communicationChannel()) { - case S60DeployConfiguration::CommunicationCodaSerialConnection: { - 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::CommunicationCodaTcpConnection: { - 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; -} - -void Qt4SymbianTarget::onAddedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc) +ProjectExplorer::IDevice::ConstPtr Qt4SymbianTarget::currentDevice() const { - Q_ASSERT(dc); - S60DeployConfiguration *deployConf(qobject_cast<S60DeployConfiguration *>(dc)); - if (!deployConf) - 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 Qt4SymbianTarget::slotUpdateDeviceInformation() -{ - S60DeployConfiguration *dc(qobject_cast<S60DeployConfiguration *>(sender())); - if (dc && dc == activeDeployConfiguration()) { - updateToolTipAndIcon(); - } -} - -void Qt4SymbianTarget::updateToolTipAndIcon() -{ - static const int TARGET_OVERLAY_ORIGINAL_SIZE = 32; - - if (qobject_cast<S60DeployConfiguration *>(activeDeployConfiguration())) { - QPixmap overlay; - 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); - pixmap.fill(Qt::transparent); - QPainter painter(&pixmap); - painter.drawPixmap(Core::Constants::TARGET_ICON_SIZE - overlaySize.width(), - Core::Constants::TARGET_ICON_SIZE - overlaySize.height(), - overlay.scaled(overlaySize)); - - setOverlayIcon(QIcon(pixmap)); - } else { - setToolTip(QString()); - setOverlayIcon(QIcon()); - } + S60DeployConfiguration *dc = dynamic_cast<S60DeployConfiguration *>(activeDeployConfiguration()); + return ProjectExplorer::IDevice::ConstPtr(dc ? dc->device() : 0); } diff --git a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.h b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.h index 5f4ef5519f..f02b6b3e25 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.h +++ b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.h @@ -60,18 +60,11 @@ public: static QString defaultDisplayName(const QString &id); static QIcon iconForId(const QString &id); -private: - bool isSymbianConnectionAvailable(QString &tooltipText); -private slots: - void onAddedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc); - void slotUpdateDeviceInformation(); - void updateToolTipAndIcon(); +protected: + ProjectExplorer::IDevice::ConstPtr currentDevice() const; private: - const QPixmap m_connectedPixmap; - const QPixmap m_disconnectedPixmap; - Qt4BuildConfigurationFactory *m_buildConfigurationFactory; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp index dc0b3733a4..6b97dcf988 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp @@ -41,14 +41,18 @@ #include "qt4symbiantarget.h" #include "s60createpackagestep.h" #include "s60deploystep.h" +#include "symbianidevice.h" +#include "symbianidevicefactory.h" #include <utils/qtcassert.h> #include <symbianutils/symbiandevicemanager.h> #include <projectexplorer/buildconfiguration.h> #include <projectexplorer/buildsteplist.h> +#include <projectexplorer/devicesupport/devicemanager.h> #include <projectexplorer/project.h> #include <projectexplorer/toolchain.h> +#include <projectexplorer/devicesupport/devicemanager.h> #include <QFileInfo> @@ -59,14 +63,8 @@ using namespace Qt4ProjectManager::Internal; namespace { const char S60_DC_PREFIX[] = "Qt4ProjectManager.S60DeployConfiguration."; -const char SERIAL_PORT_NAME_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.SerialPortName"; const char INSTALLATION_DRIVE_LETTER_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.InstallationDriveLetter"; const char SILENT_INSTALL_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.SilentInstall"; -const char DEVICE_ADDRESS_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.DeviceAddress"; -const char DEVICE_PORT_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.DevicePort"; -const char COMMUNICATION_CHANNEL_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.CommunicationChannel"; - -const char DEFAULT_CODA_TCP_PORT[] = "65029"; QString pathFromId(const QString &id) { @@ -82,15 +80,8 @@ QString pathFromId(const QString &id) S60DeployConfiguration::S60DeployConfiguration(Target *parent) : DeployConfiguration(parent, QLatin1String(S60_DEPLOYCONFIGURATION_ID)), m_activeBuildConfiguration(0), -#ifdef Q_OS_WIN - m_serialPortName(QLatin1String("COM5")), -#else - m_serialPortName(QLatin1String(SymbianUtils::SymbianDeviceManager::linuxBlueToothDeviceRootC) + QLatin1Char('0')), -#endif m_installationDrive('C'), - m_silentInstall(true), - m_devicePort(QLatin1String(DEFAULT_CODA_TCP_PORT)), - m_communicationChannel(CommunicationCodaSerialConnection) + m_silentInstall(true) { ctor(); } @@ -98,18 +89,18 @@ S60DeployConfiguration::S60DeployConfiguration(Target *parent) : S60DeployConfiguration::S60DeployConfiguration(Target *target, S60DeployConfiguration *source) : DeployConfiguration(target, source), m_activeBuildConfiguration(0), - m_serialPortName(source->m_serialPortName), + m_deviceId(source->m_deviceId), m_installationDrive(source->m_installationDrive), - m_silentInstall(source->m_silentInstall), - m_deviceAddress(source->m_deviceAddress), - m_devicePort(source->m_devicePort), - m_communicationChannel(source->m_communicationChannel) + m_silentInstall(source->m_silentInstall) { ctor(); } void S60DeployConfiguration::ctor() { + ProjectExplorer::DeviceManager *dm = ProjectExplorer::DeviceManager::instance(); + m_deviceId = dm->defaultDevice(Internal::SymbianIDeviceFactory::deviceType())->id(); + setDefaultDisplayName(defaultDisplayName()); // TODO disable S60 Deploy Configuration while parsing // requires keeping track of the parsing state of the project @@ -123,8 +114,7 @@ void S60DeployConfiguration::ctor() } S60DeployConfiguration::~S60DeployConfiguration() -{ -} +{ } ProjectExplorer::DeployConfigurationWidget *S60DeployConfiguration::configurationWidget() const { @@ -181,6 +171,11 @@ QString S60DeployConfiguration::createPackageName(const QString &baseName) const return name; } +SymbianIDevice *S60DeployConfiguration::device() const +{ + return dynamic_cast<SymbianIDevice *>(const_cast<ProjectExplorer::IDevice *>(ProjectExplorer::DeviceManager::instance()->find(m_deviceId).data())); +} + QStringList S60DeployConfiguration::packageFileNamesWithTargetInfo() const { QList<Qt4ProFileNode *> leafs = qt4Target()->qt4Project()->allProFiles(); @@ -303,12 +298,8 @@ void S60DeployConfiguration::updateActiveRunConfiguration(ProjectExplorer::RunCo QVariantMap S60DeployConfiguration::toMap() const { QVariantMap map(ProjectExplorer::DeployConfiguration::toMap()); - map.insert(QLatin1String(SERIAL_PORT_NAME_KEY), m_serialPortName); map.insert(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar(QLatin1Char(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; } @@ -328,14 +319,9 @@ bool S60DeployConfiguration::fromMap(const QVariantMap &map) { if (!DeployConfiguration::fromMap(map)) return false; - m_serialPortName = map.value(QLatin1String(SERIAL_PORT_NAME_KEY)).toString().trimmed(); m_installationDrive = map.value(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar(QLatin1Char('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_CODA_TCP_PORT))).toString(); - m_communicationChannel = static_cast<CommunicationChannel>(map.value(QLatin1String(COMMUNICATION_CHANNEL_KEY), - QVariant(CommunicationCodaSerialConnection)).toInt()); setDefaultDisplayName(defaultDisplayName()); return true; @@ -346,20 +332,6 @@ Qt4SymbianTarget *S60DeployConfiguration::qt4Target() const return static_cast<Qt4SymbianTarget *>(target()); } -QString S60DeployConfiguration::serialPortName() const -{ - return m_serialPortName; -} - -void S60DeployConfiguration::setSerialPortName(const QString &name) -{ - const QString &candidate = name.trimmed(); - if (m_serialPortName == candidate) - return; - m_serialPortName = candidate; - emit serialPortNameChanged(); -} - char S60DeployConfiguration::installationDrive() const { return m_installationDrive; @@ -383,48 +355,6 @@ 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_CODA_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(); - } -} - void S60DeployConfiguration::setAvailableDeviceDrives(QList<DeviceDrive> drives) { m_availableDeviceDrives = drives; diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h index af281344e1..68e4218531 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h @@ -33,6 +33,8 @@ #ifndef S60DEPLOYCONFIGURATION_H #define S60DEPLOYCONFIGURATION_H +#include <projectexplorer/devicesupport/idevice.h> + #include <projectexplorer/deployconfiguration.h> #include <qt4projectmanager/qt4projectmanager_global.h> @@ -49,6 +51,7 @@ class BaseQtVersion; namespace Qt4ProjectManager { class Qt4ProFileNode; class S60DeployConfigurationFactory; +class SymbianIDevice; namespace Internal { class Qt4SymbianTarget; @@ -62,11 +65,6 @@ class QT4PROJECTMANAGER_EXPORT S60DeployConfiguration : public ProjectExplorer:: friend class S60DeployConfigurationFactory; public: - enum CommunicationChannel { - CommunicationCodaSerialConnection, - CommunicationCodaTcpConnection - }; - typedef QPair<char, int> DeviceDrive; explicit S60DeployConfiguration(ProjectExplorer::Target *parent); @@ -77,24 +75,12 @@ public: const QtSupport::BaseQtVersion *qtVersion() const; ProjectExplorer::ToolChain *toolChain() const; - QString serialPortName() const; - void setSerialPortName(const QString &name); - char installationDrive() const; void setInstallationDrive(char drive); 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; - void setAvailableDeviceDrives(QList<DeviceDrive> drives); const QList<DeviceDrive> &availableDeviceDrives() const; @@ -104,15 +90,13 @@ public: QStringList appPackageTemplateFileNames() const; bool runSmartInstaller() const; + SymbianIDevice *device() const; QVariantMap toMap() const; signals: + void deviceChanged(); void targetInformationChanged(); - void serialPortNameChanged(); - void communicationChannelChanged(); - void deviceAddressChanged(); - void devicePortChanged(); void availableDeviceDrivesChanged(); void installationDriveChanged(); @@ -139,14 +123,10 @@ private: private: ProjectExplorer::BuildConfiguration *m_activeBuildConfiguration; - QString m_serialPortName; + Core::Id m_deviceId; char m_installationDrive; bool m_silentInstall; - QString m_deviceAddress; - QString m_devicePort; - CommunicationChannel m_communicationChannel; - QList<DeviceDrive> m_availableDeviceDrives; }; diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp index 943700a0c6..4b5730313a 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp @@ -33,6 +33,7 @@ #include "s60deployconfigurationwidget.h" #include "s60deployconfiguration.h" #include "s60devicerunconfiguration.h" +#include "symbianidevice.h" #include <symbianutils/symbiandevicemanager.h> #include <codadevice.h> @@ -68,18 +69,10 @@ Q_DECLARE_METATYPE(SymbianUtils::SymbianDevice) -namespace Qt4ProjectManager { -namespace Internal { - -const char STARTING_DRIVE_LETTER = 'C'; -const char LAST_DRIVE_LETTER = 'Z'; - -static const quint32 CODA_UID = 0x20021F96; -static const quint32 QTMOBILITY_UID = 0x2002AC89; -static const quint32 QTCOMPONENTS_UID = 0x200346DE; -static const quint32 QMLVIEWER_UID = 0x20021317; +static const char STARTING_DRIVE_LETTER = 'C'; +static const char LAST_DRIVE_LETTER = 'Z'; -QString formatDriveText(const S60DeployConfiguration::DeviceDrive &drive) +static QString formatDriveText(const Qt4ProjectManager::S60DeployConfiguration::DeviceDrive &drive) { const QChar driveLetter = QChar(QLatin1Char(drive.first)).toUpper(); if (drive.second <= 0) @@ -89,52 +82,17 @@ QString formatDriveText(const S60DeployConfiguration::DeviceDrive &drive) return QString::fromLatin1("%1:%2 kB").arg(driveLetter).arg(drive.second); } -void startTable(QString &text) -{ - const char startTableC[] = "<html></head><body><table>"; - if (!text.contains(QLatin1String(startTableC))) - text.append(QLatin1String(startTableC)); -} - -void finishTable(QString &text) -{ - const QString stopTable = QLatin1String("</table></body></html>"); - text.remove(stopTable); - text.append(stopTable); -} - -void addToTable(QTextStream &stream, const QString &key, const QString &value) -{ - const char tableRowStartC[] = "<tr><td><b>"; - const char tableRowSeparatorC[] = "</b></td><td>"; - const char tableRowEndC[] = "</td></tr>"; - stream << tableRowStartC << key << tableRowSeparatorC << value << tableRowEndC; -} +namespace Qt4ProjectManager { +namespace Internal { -void addErrorToTable(QTextStream &stream, const QString &key, const QString &value) -{ - const char tableRowStartC[] = "<tr><td><b>"; - const char tableRowSeparatorC[] = "</b></td><td>"; - const char tableRowEndC[] = "</td></tr>"; - const char errorSpanStartC[] = "<span style=\"font-weight:600; color:red; \">"; - const char errorSpanEndC[] = "</span>"; - stream << tableRowStartC << errorSpanStartC << key << tableRowSeparatorC << value << errorSpanEndC << tableRowEndC; -} S60DeployConfigurationWidget::S60DeployConfigurationWidget(QWidget *parent) : ProjectExplorer::DeployConfigurationWidget(parent), m_detailsWidget(new Utils::DetailsWidget), - m_serialPortsCombo(new QComboBox), m_sisFileLabel(new QLabel), m_deviceInfoButton(new QToolButton), - m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))), - m_deviceInfoLabel(new QLabel), m_installationDriveCombo(new QComboBox()), - m_silentInstallCheckBox(new QCheckBox(tr("Silent installation"))), - m_serialRadioButton(new QRadioButton(tr("Serial:"))), - m_wlanRadioButton(new QRadioButton(tr("WLAN:"))), - m_ipAddress(new Utils::IpAddressLineEdit), - m_codaTimeout(new QTimer(this)) + m_silentInstallCheckBox(new QCheckBox(tr("Silent installation"))) { } @@ -184,87 +142,11 @@ void S60DeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc installationBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); formLayout->addRow(tr("Installation drive:"), installationBoxLayout); - updateSerialDevices(); - connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(updated()), - this, SLOT(updateSerialDevices())); - - bool usingTcp = m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection; - m_serialRadioButton->setChecked(!usingTcp); - m_wlanRadioButton->setChecked(usingTcp); - - 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); - m_deviceInfoLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - 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())); connect(m_deployConfiguration, SIGNAL(availableDeviceDrivesChanged()), this, SLOT(updateInstallationDrives())); - connect(this, SIGNAL(infoCollected()), - this, SLOT(collectingInfoFinished())); - - m_codaTimeout->setSingleShot(true); - connect(m_codaTimeout, SIGNAL(timeout()), this, SLOT(codaTimeout())); -} - -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)); - -#if !defined(Q_OS_WIN) && !defined(Q_OS_MACX) - // Update device list: only needed on linux. - QToolButton *updateSerialDevicesButton(new QToolButton); - updateSerialDevicesButton->setIcon(qApp->style()->standardIcon(QStyle::SP_BrowserReload)); - connect(updateSerialDevicesButton, SIGNAL(clicked()), - SymbianUtils::SymbianDeviceManager::instance(), SLOT(update())); - serialPortHBoxLayout->addWidget(updateSerialDevicesButton); -#endif - - QGroupBox *communicationChannelGroupBox = new QGroupBox(tr("Communication Channel")); - QGridLayout *communicationChannelGridLayout = new QGridLayout; - communicationChannelGridLayout->addWidget(m_serialRadioButton, 0, 0); - communicationChannelGridLayout->addWidget(m_wlanRadioButton, 1, 0); - - m_ipAddress->setMinimumWidth(30); - m_ipAddress->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); - - if( !m_deployConfiguration->deviceAddress().isEmpty()) - m_ipAddress->setText(m_deployConfiguration->deviceAddress() + QLatin1Char(':') - + 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)); - - communicationChannelGridLayout->addLayout(serialPortHBoxLayout, 0, 1); - communicationChannelGridLayout->addLayout(wlanChannelLayout, 1, 1); - - communicationChannelGroupBox->setLayout(communicationChannelGridLayout); - - updateCommunicationChannelUi(); - - return communicationChannelGroupBox; } void S60DeployConfigurationWidget::updateInstallationDrives() @@ -300,53 +182,6 @@ void S60DeployConfigurationWidget::silentInstallChanged(int state) m_deployConfiguration->setSilentInstall(state == Qt::Checked); } -void S60DeployConfigurationWidget::updateSerialDevices() -{ - m_serialPortsCombo->clear(); - const QString previouPortName = m_deployConfiguration->serialPortName(); - const QList<SymbianUtils::SymbianDevice> devices = SymbianUtils::SymbianDeviceManager::instance()->devices(); - int newIndex = -1; - for (int i = 0; i < devices.size(); ++i) { - const SymbianUtils::SymbianDevice &device = devices.at(i); - m_serialPortsCombo->addItem(device.friendlyName(), qVariantFromValue(device)); - if (device.portName() == previouPortName) - newIndex = i; - } - - if(m_deployConfiguration->communicationChannel() - == S60DeployConfiguration::CommunicationCodaTcpConnection) { - m_deviceInfoButton->setEnabled(true); - return; - } - - clearDeviceInfo(); - // Set new index: prefer to keep old or set to 0, if available. - if (newIndex == -1 && !devices.empty()) - newIndex = 0; - m_serialPortsCombo->setCurrentIndex(newIndex); - if (newIndex == -1) { - m_deviceInfoButton->setEnabled(false); - m_deployConfiguration->setSerialPortName(QString()); - } else { - m_deviceInfoButton->setEnabled(true); - const QString newPortName = device(newIndex).portName(); - m_deployConfiguration->setSerialPortName(newPortName); - } -} - -SymbianUtils::SymbianDevice S60DeployConfigurationWidget::device(int i) const -{ - const QVariant data = m_serialPortsCombo->itemData(i); - if (data.isValid() && qVariantCanConvert<SymbianUtils::SymbianDevice>(data)) - return qVariantValue<SymbianUtils::SymbianDevice>(data); - return SymbianUtils::SymbianDevice(); -} - -SymbianUtils::SymbianDevice S60DeployConfigurationWidget::currentDevice() const -{ - return device(m_serialPortsCombo->currentIndex()); -} - void S60DeployConfigurationWidget::updateTargetInformation() { QString package; @@ -366,363 +201,5 @@ void S60DeployConfigurationWidget::setInstallationDrive(int index) m_deployConfiguration->setInstallationDrive(driveLetter.toAscii()); } -void S60DeployConfigurationWidget::setSerialPort(int index) -{ - const SymbianUtils::SymbianDevice d = device(index); - m_deployConfiguration->setSerialPortName(d.portName()); - m_deviceInfoButton->setEnabled(index >= 0); - clearDeviceInfo(); -} - -void S60DeployConfigurationWidget::updateCommunicationChannelUi() -{ - S60DeployConfiguration::CommunicationChannel channel = m_deployConfiguration->communicationChannel(); - if (channel == S60DeployConfiguration::CommunicationCodaTcpConnection) { - m_ipAddress->setDisabled(false); - m_serialPortsCombo->setDisabled(true); - m_deviceInfoButton->setEnabled(true); - } else { - m_ipAddress->setDisabled(true); - m_serialPortsCombo->setDisabled(false); - updateSerialDevices(); - } -} - -void S60DeployConfigurationWidget::updateCommunicationChannel() -{ - if (!m_wlanRadioButton->isChecked() && !m_serialRadioButton->isChecked()) - m_serialRadioButton->setChecked(true); - - if (m_wlanRadioButton->isChecked()) { - m_ipAddress->setDisabled(false); - m_serialPortsCombo->setDisabled(true); - m_deployConfiguration->setCommunicationChannel(S60DeployConfiguration::CommunicationCodaTcpConnection); - m_deviceInfoButton->setEnabled(true); - } else { - m_ipAddress->setDisabled(true); - m_serialPortsCombo->setDisabled(false); - m_deployConfiguration->setCommunicationChannel(S60DeployConfiguration::CommunicationCodaSerialConnection); - updateSerialDevices(); - } -} - -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 - m_deviceInfoLabel->clear(); - m_deviceInfoLabel->setStyleSheet(QString()); -} - -void S60DeployConfigurationWidget::setDeviceInfoLabel(const QString &message, bool isError) -{ - m_deviceInfoLabel->setStyleSheet(isError ? - QString(QLatin1String("background-color: red;")) : - QString()); - m_deviceInfoLabel->setText(message); - m_deviceInfoLabel->adjustSize(); -} - -void S60DeployConfigurationWidget::updateDeviceInfo() -{ - setDeviceInfoLabel(tr("Connecting")); - if (m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationCodaSerialConnection) { - const SymbianUtils::SymbianDevice commDev = currentDevice(); - m_codaInfoDevice = SymbianUtils::SymbianDeviceManager::instance()->getCodaDevice(commDev.portName()); - if (m_codaInfoDevice.isNull()) { - setDeviceInfoLabel(tr("Unable to create CODA connection. Please try again."), true); - return; - } - if (!m_codaInfoDevice->device()->isOpen()) { - setDeviceInfoLabel(m_codaInfoDevice->device()->errorString(), true); - return; - } - //TODO error handling - for now just throw the command at coda - m_codaInfoDevice->sendSymbianOsDataGetQtVersionCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getQtVersionCommandResult)); - m_deviceInfoButton->setEnabled(false); - m_codaTimeout->start(1000); - } else if(m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection) { - // collectingInfoFinished, which deletes m_codaDevice, can get called from within a coda callback, so need to use deleteLater - m_codaInfoDevice = QSharedPointer<Coda::CodaDevice>(new Coda::CodaDevice, &QObject::deleteLater); - connect(m_codaInfoDevice.data(), SIGNAL(codaEvent(Coda::CodaEvent)), this, SLOT(codaEvent(Coda::CodaEvent))); - - const QSharedPointer<QTcpSocket> codaSocket(new QTcpSocket); - m_codaInfoDevice->setDevice(codaSocket); - codaSocket->connectToHost(m_deployConfiguration->deviceAddress(), - m_deployConfiguration->devicePort().toInt()); - m_deviceInfoButton->setEnabled(false); - m_codaTimeout->start(1500); - } else - setDeviceInfoLabel(tr("Currently there is no information about the device for this connection type."), true); -} - -void S60DeployConfigurationWidget::codaEvent(const Coda::CodaEvent &event) -{ - switch (event.type()) { - case Coda::CodaEvent::LocatorHello: // Commands accepted now - codaIncreaseProgress(); - if (m_codaInfoDevice) - m_codaInfoDevice->sendSymbianOsDataGetQtVersionCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getQtVersionCommandResult)); - break; - default: - break; - } -} - -void S60DeployConfigurationWidget::getQtVersionCommandResult(const Coda::CodaCommandResult &result) -{ - m_deviceInfo.clear(); - if (result.type == Coda::CodaCommandResult::FailReply) { - setDeviceInfoLabel(tr("No device information available"), true); - SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); - m_deviceInfoButton->setEnabled(true); - m_codaTimeout->stop(); - return; - } else if (result.type == Coda::CodaCommandResult::CommandErrorReply){ - startTable(m_deviceInfo); - QTextStream str(&m_deviceInfo); - addErrorToTable(str, tr("Qt version: "), tr("Not installed on device")); - finishTable(m_deviceInfo); - } else { - if (result.values.count()) { - QHash<QString, QVariant> obj = result.values[0].toVariant().toHash(); - QString ver = obj.value(QLatin1String("qVersion")).toString(); - - startTable(m_deviceInfo); - QTextStream str(&m_deviceInfo); - addToTable(str, tr("Qt version:"), ver); - QString systemVersion; - - const int symVer = obj.value(QLatin1String("symbianVersion")).toInt(); - // Ugh why won't QSysInfo define these on non-symbian builds... - switch (symVer) { - case 10: - systemVersion.append(QLatin1String("Symbian OS v9.2")); - break; - case 20: - systemVersion.append(QLatin1String("Symbian OS v9.3")); - break; - case 30: - systemVersion.append(QLatin1String("Symbian OS v9.4 / Symbian^1")); - break; - case 40: - systemVersion.append(QLatin1String("Symbian^2")); - break; - case 50: - systemVersion.append(QLatin1String("Symbian^3")); - break; - case 60: - systemVersion.append(QLatin1String("Symbian^4")); - break; - case 70: - systemVersion.append(QLatin1String("Symbian^3")); // TODO: might change - break; - default: - systemVersion.append(tr("Unrecognised Symbian version 0x%1").arg(symVer, 0, 16)); - break; - } - systemVersion.append(QLatin1String(", ")); - int s60Ver = obj.value(QLatin1String("s60Version")).toInt(); - switch (s60Ver) { - case 10: - systemVersion.append(QLatin1String("S60 3rd Edition Feature Pack 1")); - break; - case 20: - systemVersion.append(QLatin1String("S60 3rd Edition Feature Pack 2")); - break; - case 30: - systemVersion.append(QLatin1String("S60 5th Edition")); - break; - case 40: - systemVersion.append(QLatin1String("S60 5th Edition Feature Pack 1")); - break; - case 50: - systemVersion.append(QLatin1String("S60 5th Edition Feature Pack 2")); - break; - case 70: - systemVersion.append(QLatin1String("S60 5th Edition Feature Pack 3")); // TODO: might change - break; - default: - systemVersion.append(tr("Unrecognised S60 version 0x%1").arg(symVer, 0, 16)); - break; - } - addToTable(str, tr("OS version:"), systemVersion); - finishTable(m_deviceInfo); - } - } - codaIncreaseProgress(); - if (m_codaInfoDevice) - m_codaInfoDevice->sendSymbianOsDataGetRomInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getRomInfoResult)); -} - -void S60DeployConfigurationWidget::getRomInfoResult(const Coda::CodaCommandResult &result) -{ - codaIncreaseProgress(); - if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { - startTable(m_deviceInfo); - QTextStream str(&m_deviceInfo); - - QVariantHash obj = result.values[0].toVariant().toHash(); - QString romVersion = obj.value(QLatin1String("romVersion"), tr("unknown")).toString(); - romVersion.replace(QLatin1Char('\n'), QLatin1Char(' ')); // The ROM string is split across multiple lines, for some reason. - addToTable(str, tr("ROM version:"), romVersion); - - QString pr = obj.value(QLatin1String("prInfo")).toString(); - if (pr.length()) - addToTable(str, tr("Release:"), pr); - finishTable(m_deviceInfo); - } - - QList<quint32> packagesOfInterest; - packagesOfInterest.append(CODA_UID); - packagesOfInterest.append(QTMOBILITY_UID); - packagesOfInterest.append(QTCOMPONENTS_UID); - packagesOfInterest.append(QMLVIEWER_UID); - if (m_codaInfoDevice) - m_codaInfoDevice->sendSymbianInstallGetPackageInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getInstalledPackagesResult), packagesOfInterest); -} - -void S60DeployConfigurationWidget::getInstalledPackagesResult(const Coda::CodaCommandResult &result) -{ - codaIncreaseProgress(); - if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { - startTable(m_deviceInfo); - QTextStream str(&m_deviceInfo); - - QVariantList resultsList = result.values[0].toVariant().toList(); - const QString uidKey = QLatin1String("uid"); - const QString errorKey = QLatin1String("error"); - const QString versionKey = QLatin1String("version"); - foreach (const QVariant& var, resultsList) { - QVariantHash obj = var.toHash(); - bool ok = false; - uint uid = obj.value(uidKey).toString().toUInt(&ok, 16); - if (ok) { - const bool error = !obj.value(errorKey).isNull(); - QString versionString; - if (!error) { - QVariantList version = obj.value(versionKey).toList(); - versionString = QString::fromLatin1("%1.%2.%3").arg(version[0].toInt()) - .arg(version[1].toInt()) - .arg(version[2].toInt()); - } - switch (uid) { - case CODA_UID: { - if (error) { - // How can coda not be installed? Presumably some UID wrongness... - addErrorToTable(str, tr("CODA version: "), tr("Error reading CODA version")); - } else - addToTable(str, tr("CODA version: "), versionString); - } - break; - case QTMOBILITY_UID: { - if (error) - addErrorToTable(str, tr("Qt Mobility version: "), tr("Error reading Qt Mobility version")); - else - addToTable(str, tr("Qt Mobility version: "), versionString); - } - break; - case QTCOMPONENTS_UID: { - addToTable(str, tr("Qt Quick components version: "), error ? tr("Not installed") : versionString); - } - break; - case QMLVIEWER_UID: { - addToTable(str, tr("QML Viewer version: "), error ? tr("Not installed") : versionString); - } - break; - default: break; - } - } - } - finishTable(m_deviceInfo); - } - - QStringList keys; - keys << QLatin1String("EDisplayXPixels"); - keys << QLatin1String("EDisplayYPixels"); - - if (m_codaInfoDevice) - m_codaInfoDevice->sendSymbianOsDataGetHalInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getHalResult), keys); -} - -void S60DeployConfigurationWidget::getHalResult(const Coda::CodaCommandResult &result) -{ - codaIncreaseProgress(); - if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { - QVariantList resultsList = result.values[0].toVariant().toList(); - int x = 0; - int y = 0; - const QString nameKey = QLatin1String("name"); - const QString valueKey = QLatin1String("value"); - foreach (const QVariant& var, resultsList) { - QVariantHash obj = var.toHash(); - const QString name = obj.value(nameKey).toString(); - if (name == QLatin1String("EDisplayXPixels")) - x = obj.value(valueKey).toInt(); - else if (name == QLatin1String("EDisplayYPixels")) - y = obj.value(valueKey).toInt(); - } - if (x && y) { - startTable(m_deviceInfo); - QTextStream str(&m_deviceInfo); - addToTable(str, tr("Screen size:"), QString::number(x) + QLatin1Char('x') + QString::number(y)); - finishTable(m_deviceInfo); - } - } - - // Done with collecting info - emit infoCollected(); -} - -void S60DeployConfigurationWidget::codaIncreaseProgress() -{ - m_codaTimeout->start(); - setDeviceInfoLabel(m_deviceInfoLabel->text() + QLatin1Char('.')); -} - -void S60DeployConfigurationWidget::collectingInfoFinished() -{ - m_codaTimeout->stop(); - emit codaConnected(); - m_deviceInfoButton->setEnabled(true); - setDeviceInfoLabel(m_deviceInfo); - SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); -} - -void S60DeployConfigurationWidget::codaTimeout() -{ - QMessageBox *mb = CodaRunControl::createCodaWaitingMessageBox(this); - connect(this, SIGNAL(codaConnected()), mb, SLOT(close())); - connect(mb, SIGNAL(finished(int)), this, SLOT(codaCanceled())); - mb->open(); -} - -void S60DeployConfigurationWidget::codaCanceled() -{ - clearDeviceInfo(); - m_deviceInfoButton->setEnabled(true); - SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); -} - } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.h b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.h index 09645a8d40..c1c875c648 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.h @@ -80,57 +80,21 @@ public: void init(ProjectExplorer::DeployConfiguration *dc); -signals: - void infoCollected(); - void codaConnected(); - private slots: void updateTargetInformation(); void updateInstallationDrives(); - void updateSerialDevices(); void setInstallationDrive(int index); - void setSerialPort(int index); - void updateDeviceInfo(); - void clearDeviceInfo(); void silentInstallChanged(int); - void updateCommunicationChannel(); - void updateCommunicationChannelUi(); - void updateWlanAddress(const QString &address); - void cleanWlanAddress(); - void codaEvent(const Coda::CodaEvent &event); - void collectingInfoFinished(); - void codaTimeout(); - void codaCanceled(); - void codaIncreaseProgress(); private: - inline SymbianUtils::SymbianDevice device(int i) const; - inline SymbianUtils::SymbianDevice currentDevice() const; - void setDeviceInfoLabel(const QString &message, bool isError = false); - QWidget * createCommunicationChannel(); - - void getQtVersionCommandResult(const Coda::CodaCommandResult &result); - void getRomInfoResult(const Coda::CodaCommandResult &result); - void getInstalledPackagesResult(const Coda::CodaCommandResult &result); - void getHalResult(const Coda::CodaCommandResult &result); - S60DeployConfiguration *m_deployConfiguration; Utils::DetailsWidget *m_detailsWidget; - QComboBox *m_serialPortsCombo; QLabel *m_sisFileLabel; QToolButton *m_deviceInfoButton; - QLabel *m_deviceInfoDescriptionLabel; - QLabel *m_deviceInfoLabel; QComboBox *m_installationDriveCombo; QCheckBox *m_silentInstallCheckBox; - QRadioButton *m_serialRadioButton; - QRadioButton *m_wlanRadioButton; - Utils::IpAddressLineEdit *m_ipAddress; - QSharedPointer<Coda::CodaDevice> m_codaInfoDevice; - QString m_deviceInfo; - QTimer *m_codaTimeout; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deploystep.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deploystep.cpp index b7b196b9dd..0cac072fb6 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60deploystep.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60deploystep.cpp @@ -35,6 +35,7 @@ #include "qt4buildconfiguration.h" #include "s60deployconfiguration.h" #include "s60devicerunconfiguration.h" +#include "symbianidevice.h" #include "codadevice.h" #include "codaruncontrol.h" @@ -60,7 +61,6 @@ #include <QTcpSocket> using namespace ProjectExplorer; -using namespace SymbianUtils; using namespace Qt4ProjectManager::Internal; enum { debug = 0 }; @@ -125,7 +125,7 @@ S60DeployStep::S60DeployStep(ProjectExplorer::BuildStepList *bc): m_putLastChunkSize(0), m_putChunkSize(DEFAULT_CHUNK_SIZE), m_currentFileIndex(0), - m_channel(S60DeployConfiguration::CommunicationCodaSerialConnection), + m_channel(SymbianIDevice::CommunicationCodaSerialConnection), m_deployCanceled(false), m_copyProgress(0) { @@ -154,22 +154,22 @@ bool S60DeployStep::init() S60DeployConfiguration *deployConfiguration = static_cast<S60DeployConfiguration *>(bc->target()->activeDeployConfiguration()); if (!deployConfiguration) return false; - m_serialPortName = deployConfiguration->serialPortName(); - m_serialPortFriendlyName = SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName); + m_serialPortName = deployConfiguration->device()->serialPortName(); + m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName); m_packageFileNamesWithTarget = deployConfiguration->packageFileNamesWithTargetInfo(); m_signedPackages = deployConfiguration->signedPackages(); m_installationDrive = deployConfiguration->installationDrive(); m_silentInstall = deployConfiguration->silentInstall(); - m_channel = deployConfiguration->communicationChannel(); + m_channel = deployConfiguration->device()->communicationChannel(); if (m_signedPackages.isEmpty()) { appendMessage(tr("No package has been found. Specify at least one installation package."), true); return false; } - if (m_channel == S60DeployConfiguration::CommunicationCodaTcpConnection) { - m_address = deployConfiguration->deviceAddress(); - m_port = deployConfiguration->devicePort().toInt(); + if (m_channel == SymbianIDevice::CommunicationCodaTcpConnection) { + m_address = deployConfiguration->device()->address(); + m_port = deployConfiguration->device()->port().toInt(); } return true; } @@ -235,7 +235,7 @@ void S60DeployStep::start() { QString errorMessage; - bool serialConnection = m_channel == S60DeployConfiguration::CommunicationCodaSerialConnection; + bool serialConnection = m_channel == SymbianIDevice::CommunicationCodaSerialConnection; if (serialConnection && m_serialPortName.isEmpty()) { errorMessage = tr("No device is connected. Connect a device and try again."); @@ -270,7 +270,7 @@ void S60DeployStep::stop() break; //should also stop the package installation, but CODA does not support it yet } disconnect(m_codaDevice.data(), 0, this, 0); - SymbianDeviceManager::instance()->releaseCodaDevice(m_codaDevice); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaDevice); } setState(StateUninit); emit s60DeploymentFinished(false); @@ -278,8 +278,9 @@ void S60DeployStep::stop() void S60DeployStep::setupConnections() { - if (m_channel == S60DeployConfiguration::CommunicationCodaSerialConnection) - connect(SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)), this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice))); + if (m_channel == SymbianIDevice::CommunicationCodaSerialConnection) + connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)), + this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice))); connect(m_codaDevice.data(), SIGNAL(error(QString)), this, SLOT(slotError(QString))); connect(m_codaDevice.data(), SIGNAL(logMessage(QString)), this, SLOT(slotCodaLogMessage(QString))); @@ -295,9 +296,9 @@ void S60DeployStep::startDeployment() // We need to defer setupConnections() in the case of CommunicationCodaSerialConnection //setupConnections(); - if (m_channel == S60DeployConfiguration::CommunicationCodaSerialConnection) { + if (m_channel == SymbianIDevice::CommunicationCodaSerialConnection) { appendMessage(tr("Deploying application to '%1'...").arg(m_serialPortFriendlyName), false); - m_codaDevice = SymbianDeviceManager::instance()->getCodaDevice(m_serialPortName); + m_codaDevice = SymbianUtils::SymbianDeviceManager::instance()->getCodaDevice(m_serialPortName); bool ok = m_codaDevice && m_codaDevice->device()->isOpen(); if (!ok) { QString deviceError = tr("No such port"); @@ -349,7 +350,7 @@ void S60DeployStep::run(QFutureInterface<bool> &fi) if (m_codaDevice) { disconnect(m_codaDevice.data(), 0, this, 0); - SymbianDeviceManager::instance()->releaseCodaDevice(m_codaDevice); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaDevice); } delete m_eventLoop; @@ -619,7 +620,7 @@ void S60DeployStep::deploymentFinished(bool success) m_eventLoop->exit(); } -void S60DeployStep::deviceRemoved(const SymbianDevice &device) +void S60DeployStep::deviceRemoved(const SymbianUtils::SymbianDevice &device) { if (device.portName() == m_serialPortName) reportError(tr("The device '%1' has been disconnected").arg(device.friendlyName())); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicedebugruncontrol.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicedebugruncontrol.cpp index fd892ef067..9331b5e346 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicedebugruncontrol.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicedebugruncontrol.cpp @@ -36,6 +36,7 @@ #include "qt4symbiantarget.h" #include "s60deployconfiguration.h" #include "s60devicerunconfiguration.h" +#include "symbianidevice.h" #include <coreplugin/icore.h> #include <debugger/debuggerengine.h> @@ -82,7 +83,7 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR const QString debugFileName = QString::fromLatin1("%1:\\sys\\bin\\%2.exe") .arg(activeDeployConf->installationDrive()).arg(rc->targetName()); - sp.remoteChannel = activeDeployConf->serialPortName(); + sp.remoteChannel = activeDeployConf->device()->serialPortName(); sp.processArgs = rc->commandLineArguments(); if (rc->debuggerAspect()->useQmlDebugger() && !rc->debuggerAspect()->useCppDebugger()) { sp.requestRemoteSetup = true; @@ -94,10 +95,10 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR sp.toolChainAbi = rc->abi(); sp.executable = debugFileName; sp.executableUid = rc->executableUid(); - sp.serverAddress = activeDeployConf->deviceAddress(); - sp.serverPort = activeDeployConf->devicePort().toInt(); + sp.serverAddress = activeDeployConf->device()->address(); + sp.serverPort = activeDeployConf->device()->port().toInt(); sp.displayName = rc->displayName(); - sp.qmlServerAddress = activeDeployConf->deviceAddress(); + sp.qmlServerAddress = activeDeployConf->device()->address(); sp.qmlServerPort = rc->debuggerAspect()->qmlDebugServerPort(); if (rc->debuggerAspect()->useQmlDebugger()) { sp.languages |= Debugger::QmlLanguage; @@ -109,7 +110,7 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR if (rc->debuggerAspect()->useCppDebugger()) sp.languages |= Debugger::CppLanguage; - sp.communicationChannel = activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection? + sp.communicationChannel = activeDeployConf->device()->communicationChannel() == SymbianIDevice::CommunicationCodaTcpConnection? Debugger::DebuggerStartParameters::CommunicationChannelTcpIp: Debugger::DebuggerStartParameters::CommunicationChannelUsb; diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp index ce74f2e8fa..278a658602 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp @@ -41,6 +41,7 @@ #include "s60deployconfiguration.h" #include "s60devicerunconfigurationwidget.h" #include "s60manager.h" +#include "symbianidevice.h" #include "symbianqtversion.h" #include <utils/qtcassert.h> @@ -291,7 +292,7 @@ QString S60DeviceRunConfiguration::qmlCommandLineArguments() const qobject_cast<S60DeployConfiguration *>(qt4Target()->activeDeployConfiguration()); QTC_ASSERT(activeDeployConf, return args); - if (activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection) + if (activeDeployConf->device()->communicationChannel() == SymbianIDevice::CommunicationCodaTcpConnection) args = QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(debuggerAspect()->qmlDebugServerPort()); else args = QLatin1String("-qmljsdebugger=ost"); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp index 703ea9df2b..2edb915fff 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp @@ -41,6 +41,8 @@ #include "s60deploystep.h" #include "s60runcontrolfactory.h" #include "s60devicedebugruncontrol.h" +#include "symbianidevice.h" +#include "symbianidevicefactory.h" #include "qt4symbiantargetfactory.h" #include "s60publishingwizardfactories.h" @@ -54,6 +56,7 @@ #include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> +#include <projectexplorer/devicesupport/devicemanager.h> #include <projectexplorer/projectexplorerconstants.h> #include <debugger/debuggerconstants.h> #include <utils/qtcassert.h> @@ -131,8 +134,19 @@ S60Manager::S60Manager(QObject *parent) : QObject(parent) addAutoReleasedObject(new S60PublishingWizardFactoryOvi); addAutoReleasedObject(new SymbianQtVersionFactory); + addAutoReleasedObject(new Internal::SymbianIDeviceFactory); + + ProjectExplorer::IDevice::Ptr dev(new SymbianIDevice); + ProjectExplorer::DeviceManager::instance()->addDevice(dev); + connect(Core::ICore::mainWindow(), SIGNAL(deviceChange()), SymbianUtils::SymbianDeviceManager::instance(), SLOT(update())); + + SymbianUtils::SymbianDeviceManager *dm = SymbianUtils::SymbianDeviceManager::instance(); + connect(dm, SIGNAL(deviceAdded(SymbianUtils::SymbianDevice)), + this, SLOT(symbianDeviceAdded(SymbianUtils::SymbianDevice))); + connect(dm, SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)), + this, SLOT(symbianDeviceRemoved(SymbianUtils::SymbianDevice))); } S60Manager::~S60Manager() @@ -152,6 +166,34 @@ QString S60Manager::platform(const ProjectExplorer::ToolChain *tc) return target.right(target.lastIndexOf(QLatin1Char('-'))); } +void S60Manager::symbianDeviceRemoved(const SymbianUtils::SymbianDevice &d) +{ + handleSymbianDeviceStateChange(d, ProjectExplorer::IDevice::DeviceUnavailable); +} + +void S60Manager::symbianDeviceAdded(const SymbianUtils::SymbianDevice &d) +{ + handleSymbianDeviceStateChange(d, ProjectExplorer::IDevice::DeviceAvailable); +} + +void S60Manager::handleSymbianDeviceStateChange(const SymbianUtils::SymbianDevice &d, ProjectExplorer::IDevice::AvailabilityState s) +{ + ProjectExplorer::DeviceManager *dm = ProjectExplorer::DeviceManager::instance(); + for (int i = 0; i < dm->deviceCount(); ++i) { + ProjectExplorer::IDevice::ConstPtr dev = dm->deviceAt(i); + const SymbianIDevice *sdev = dynamic_cast<const SymbianIDevice *>(dev.data()); + if (!sdev || sdev->communicationChannel() != SymbianIDevice::CommunicationCodaSerialConnection) + continue; + if (sdev->serialPortName() != d.portName()) + continue; + + SymbianIDevice *newDev = new SymbianIDevice(*sdev); // Get a new device to replace the current one + newDev->setAvailability(s); + dm->addDevice(ProjectExplorer::IDevice::Ptr(newDev)); + break; + } +} + void S60Manager::addAutoReleasedObject(QObject *o) { ExtensionSystem::PluginManager::instance()->addObject(o); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.h b/src/plugins/qt4projectmanager/qt-s60/s60manager.h index fc1ba2f4e2..fa861424e4 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.h @@ -33,11 +33,12 @@ #ifndef S60MANAGER_H #define S60MANAGER_H +#include <projectexplorer/devicesupport/idevice.h> +#include <symbianutils/symbiandevicemanager.h> + #include <QObject> -namespace ProjectExplorer { -class ToolChain; -} +namespace ProjectExplorer { class ToolChain; } namespace Qt4ProjectManager { namespace Internal { @@ -52,7 +53,14 @@ public: static QString platform(const ProjectExplorer::ToolChain *tc); +private slots: + void symbianDeviceRemoved(const SymbianUtils::SymbianDevice &d); + void symbianDeviceAdded(const SymbianUtils::SymbianDevice &d); + private: + void handleSymbianDeviceStateChange(const SymbianUtils::SymbianDevice &d, + ProjectExplorer::IDevice::AvailabilityState s); + void addAutoReleasedObject(QObject *p); static S60Manager *m_instance; diff --git a/src/plugins/qt4projectmanager/qt-s60/symbianidevice.cpp b/src/plugins/qt4projectmanager/qt-s60/symbianidevice.cpp new file mode 100644 index 0000000000..2c31947a22 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/symbianidevice.cpp @@ -0,0 +1,252 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#include "symbianidevice.h" + +#include "symbianideviceconfigwidget.h" +#include "symbianidevicefactory.h" + +#include <symbianutils/symbiandevicemanager.h> + +#include <QCoreApplication> + +namespace { +const char SERIAL_PORT_NAME_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.SerialPortName"; +const char DEVICE_ADDRESS_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.DeviceAddress"; +const char DEVICE_PORT_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.DevicePort"; +const char COMMUNICATION_CHANNEL_KEY[] = "Qt4ProjectManager.S60DeployConfiguration.CommunicationChannel"; + +const char DEFAULT_CODA_TCP_PORT[] = "65029"; +} // namespace + +namespace Qt4ProjectManager { + +SymbianIDevice::SymbianIDevice() : + ProjectExplorer::IDevice(Internal::SymbianIDeviceFactory::deviceType(), + ProjectExplorer::IDevice::AutoDetected, + QLatin1String("Symbian Device")), + m_port(QLatin1String(DEFAULT_CODA_TCP_PORT)), + m_communicationChannel(CommunicationCodaSerialConnection) +{ + setDisplayName("Symbian Device"); + updateState(); +} + +SymbianIDevice::SymbianIDevice(const QVariantMap &map) +{ + fromMap(map); +} + +ProjectExplorer::IDevice::DeviceInfo SymbianIDevice::deviceInformation() const +{ + ProjectExplorer::IDevice::DeviceInfo result; + switch (communicationChannel()) { + case SymbianIDevice::CommunicationCodaSerialConnection: { + const SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance(); + const int deviceIndex = sdm->findByPortName(serialPortName()); + if (deviceIndex == -1) { + result << ProjectExplorer::IDevice::DeviceInfoItem( + QCoreApplication::translate("Qt4ProjectManager::SymbianIDevice", "Device"), + QCoreApplication::translate("Qt4ProjectManager::SymbianIDevice", "Not connected")); + } else { + // device connected + const SymbianUtils::SymbianDevice device = sdm->devices().at(deviceIndex); + result << ProjectExplorer::IDevice::DeviceInfoItem( + QCoreApplication::translate("Qt4ProjectManager::SymbianIDevice", "Device"), + //: %1 device friendly name, %2 additional information + QCoreApplication::translate("Qt4ProjectManager::SymbianIDevice", "%1, %2") + .arg(device.friendlyName(), device.additionalInformation())); + } + } + break; + case SymbianIDevice::CommunicationCodaTcpConnection: { + if (!address().isEmpty() && !port().isEmpty()) { + result << ProjectExplorer::IDevice::DeviceInfoItem( + QCoreApplication::translate("Qt4ProjectManager::SymbianIDevice", "IP address"), + QCoreApplication::translate("Qt4ProjectManager::SymbianIDevice", "%1:%2") + .arg(address(), port())); + } + } + break; + default: + break; + } + return result; +} + +SymbianIDevice::SymbianIDevice(const SymbianIDevice &other) : + ProjectExplorer::IDevice(other) +{ + m_address = other.m_address; + m_communicationChannel = other.m_communicationChannel; + m_port = other.m_port; + m_serialPortName = other.m_serialPortName; +} + +ProjectExplorer::IDevice::Ptr SymbianIDevice::clone() const +{ + return Ptr(new SymbianIDevice(*this)); +} + +QString SymbianIDevice::serialPortName() const +{ + return m_serialPortName; +} + +void SymbianIDevice::setSerialPortName(const QString &name) +{ + const QString &candidate = name.trimmed(); + if (m_serialPortName == candidate) + return; + m_serialPortName = candidate; + updateState(); +} + +QString SymbianIDevice::address() const +{ + return m_address; +} + +void SymbianIDevice::setAddress(const QString &address) +{ + if (m_address != address) { + m_address = address; + setAvailability(IDevice::DeviceAvailabilityUnknown); + } +} + + +QString SymbianIDevice::port() const +{ + return m_port; +} + +void SymbianIDevice::setPort(const QString &port) +{ + if (m_port != port) { + if (port.isEmpty()) //setup the default CODA's port + m_port = QLatin1String(DEFAULT_CODA_TCP_PORT); + else + m_port = port; + setAvailability(IDevice::DeviceAvailabilityUnknown); + } +} + +SymbianIDevice::CommunicationChannel SymbianIDevice::communicationChannel() const +{ + return m_communicationChannel; +} + +void SymbianIDevice::setCommunicationChannel(CommunicationChannel channel) +{ + if (m_communicationChannel != channel) { + m_communicationChannel = channel; + setAvailability(IDevice::DeviceAvailabilityUnknown); + } + updateState(); +} + +void SymbianIDevice::fromMap(const QVariantMap &map) +{ + ProjectExplorer::IDevice::fromMap(map); + m_serialPortName = map.value(QLatin1String(SERIAL_PORT_NAME_KEY)).toString().trimmed(); + m_address = map.value(QLatin1String(DEVICE_ADDRESS_KEY)).toString(); + m_port = map.value(QLatin1String(DEVICE_PORT_KEY), QString(QLatin1String(DEFAULT_CODA_TCP_PORT))).toString(); + m_communicationChannel = static_cast<CommunicationChannel>(map.value(QLatin1String(COMMUNICATION_CHANNEL_KEY), + QVariant(CommunicationCodaSerialConnection)).toInt()); + updateState(); +} + +QString SymbianIDevice::displayType() const +{ + return QCoreApplication::translate("Qt4ProjectManager::SymbianIDevice", "Symbian Device"); +} + +ProjectExplorer::IDeviceWidget *SymbianIDevice::createWidget() +{ + return new Internal::SymbianIDeviceConfigurationWidget(sharedFromThis()); +} + +QStringList SymbianIDevice::actionIds() const +{ + return QStringList(); +} + +QString SymbianIDevice::displayNameForActionId(const QString &actionId) const +{ + Q_UNUSED(actionId); + return QString(); +} + +QDialog *SymbianIDevice::createAction(const QString &actionId, QWidget *parent) const +{ + Q_UNUSED(actionId); + Q_UNUSED(parent); + return 0; +} + +QVariantMap SymbianIDevice::toMap() const +{ + QVariantMap map(ProjectExplorer::IDevice::toMap()); + map.insert(QLatin1String(SERIAL_PORT_NAME_KEY), m_serialPortName); + map.insert(QLatin1String(DEVICE_ADDRESS_KEY), QVariant(m_address)); + map.insert(QLatin1String(DEVICE_PORT_KEY), m_port); + map.insert(QLatin1String(COMMUNICATION_CHANNEL_KEY), QVariant(m_communicationChannel)); + return map; +} + +void SymbianIDevice::updateState() +{ + if (m_communicationChannel == CommunicationCodaSerialConnection) { + SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance(); + if (m_serialPortName.isEmpty()) { + // Find first port in use: + SymbianUtils::SymbianDeviceManager::SymbianDeviceList deviceList + = sdm->devices(); + foreach (const SymbianUtils::SymbianDevice &d, deviceList) { + if (d.portName().isEmpty()) + continue; + + m_serialPortName = d.portName(); + break; + } + } + + setAvailability(sdm->findByPortName(m_serialPortName) >= 0 + ? ProjectExplorer::IDevice::DeviceAvailable + : ProjectExplorer::IDevice::DeviceUnavailable); + } else { + setAvailability(ProjectExplorer::IDevice::DeviceAvailabilityUnknown); + } +} + +} // namespace qt4projectmanager diff --git a/src/plugins/qt4projectmanager/qt-s60/symbianidevice.h b/src/plugins/qt4projectmanager/qt-s60/symbianidevice.h new file mode 100644 index 0000000000..bdb6c5092d --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/symbianidevice.h @@ -0,0 +1,100 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#ifndef SYMBIANIDEVICE_H +#define SYMBIANIDEVICE_H + +#include "../qt4projectmanager_global.h" + +#include <projectexplorer/devicesupport/idevice.h> + +namespace Qt4ProjectManager { +namespace Internal { class S60Manager; } + +// TODO: Make the idevice interface powerful enough that this class is no longer +// needed in other plugins and then move this into Internal namespace and +// do not export it. +class QT4PROJECTMANAGER_EXPORT SymbianIDevice : public ProjectExplorer::IDevice +{ +public: + enum CommunicationChannel { + CommunicationCodaSerialConnection, + CommunicationCodaTcpConnection + }; + + SymbianIDevice(); + SymbianIDevice(const QVariantMap &map); + + DeviceInfo deviceInformation() const; + + ProjectExplorer::IDevice::Ptr clone() const; + + QString serialPortName() const; + void setSerialPortName(const QString &name); + + QString address() const; + void setAddress(const QString &address); + + void setPort(const QString &port); + QString port() const; + + void setCommunicationChannel(CommunicationChannel channel); + CommunicationChannel communicationChannel() const; + + void fromMap(const QVariantMap &map); + + QString displayType() const; + ProjectExplorer::IDeviceWidget* createWidget(); + QStringList actionIds() const; + QString displayNameForActionId(const QString&actionId) const; + QDialog* createAction(const QString&, QWidget*parent) const; + +protected: + SymbianIDevice(const SymbianIDevice &other); + SymbianIDevice &operator=(const SymbianIDevice &); // no impl. + + QVariantMap toMap() const; + +private: + void updateState(); + + QString m_serialPortName; + QString m_address; + QString m_port; + CommunicationChannel m_communicationChannel; + + friend class Internal::S60Manager; +}; + +} // namespace Qt4ProjectManager + +#endif // SYMBIANIDEVICE_H diff --git a/src/plugins/qt4projectmanager/qt-s60/symbianideviceconfigwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/symbianideviceconfigwidget.cpp new file mode 100644 index 0000000000..18a0e37da6 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/symbianideviceconfigwidget.cpp @@ -0,0 +1,626 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#include "symbianideviceconfigwidget.h" + +#include "symbianidevice.h" + +#include <symbianutils/symbiandevicemanager.h> +#include <codadevice.h> + +#include "codaruncontrol.h" + +#include <utils/detailswidget.h> +#include <utils/ipaddresslineedit.h> +#include <utils/qtcassert.h> +#include <utils/pathchooser.h> + +#include <QTimer> +#include <QLabel> +#include <QLineEdit> +#include <QComboBox> +#include <QVBoxLayout> +#include <QHBoxLayout> +#include <QFormLayout> +#include <QToolButton> +#include <QStyle> +#include <QApplication> +#include <QSpacerItem> +#include <QMessageBox> +#include <QCheckBox> +#include <QGroupBox> +#include <QRadioButton> +#include <QValidator> + +#include <QTcpSocket> + +Q_DECLARE_METATYPE(SymbianUtils::SymbianDevice) + +static const quint32 CODA_UID = 0x20021F96; + +static const quint32 QTMOBILITY_UID = 0x2002AC89; +static const quint32 QTCOMPONENTS_UID = 0x200346DE; +static const quint32 QMLVIEWER_UID = 0x20021317; + +static void startTable(QString &text) +{ + const char startTableC[] = "<html></head><body><table>"; + if (!text.contains(QLatin1String(startTableC))) + text.append(QLatin1String(startTableC)); +} + +static void finishTable(QString &text) +{ + const QString stopTable = QLatin1String("</table></body></html>"); + text.remove(stopTable); + text.append(stopTable); +} + +static void addToTable(QTextStream &stream, const QString &key, const QString &value) +{ + const char tableRowStartC[] = "<tr><td><b>"; + const char tableRowSeparatorC[] = "</b></td><td>"; + const char tableRowEndC[] = "</td></tr>"; + stream << tableRowStartC << key << tableRowSeparatorC << value << tableRowEndC; +} + +static void addErrorToTable(QTextStream &stream, const QString &key, const QString &value) +{ + const char tableRowStartC[] = "<tr><td><b>"; + const char tableRowSeparatorC[] = "</b></td><td>"; + const char tableRowEndC[] = "</td></tr>"; + const char errorSpanStartC[] = "<span style=\"font-weight:600; color:red; \">"; + const char errorSpanEndC[] = "</span>"; + stream << tableRowStartC << errorSpanStartC << key << tableRowSeparatorC << value << errorSpanEndC << tableRowEndC; +} + +namespace Qt4ProjectManager { +namespace Internal { + +SymbianIDeviceConfigurationWidget::SymbianIDeviceConfigurationWidget(const ProjectExplorer::IDevice::Ptr &device, + QWidget *parent) + : ProjectExplorer::IDeviceWidget(device, parent), + m_detailsWidget(new Utils::DetailsWidget), + m_serialPortsCombo(new QComboBox), + m_deviceInfoButton(new QToolButton), + m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))), + m_deviceInfoLabel(new QLabel), + m_serialRadioButton(new QRadioButton(tr("Serial:"))), + m_wlanRadioButton(new QRadioButton(tr("WLAN:"))), + m_ipAddress(new Utils::IpAddressLineEdit), + m_codaTimeout(new QTimer(this)) +{ + m_detailsWidget->setState(Utils::DetailsWidget::NoSummary); + + QVBoxLayout *mainBoxLayout = new QVBoxLayout(); + mainBoxLayout->setMargin(0); + setLayout(mainBoxLayout); + mainBoxLayout->addWidget(m_detailsWidget); + QWidget *detailsContainer = new QWidget; + m_detailsWidget->setWidget(detailsContainer); + + QFormLayout *detailsLayout = new QFormLayout(detailsContainer); + + updateSerialDevices(); + connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(updated()), + this, SLOT(updateSerialDevices())); + + bool usingTcp = symbianDevice()->communicationChannel() == SymbianIDevice::CommunicationCodaTcpConnection; + m_serialRadioButton->setChecked(!usingTcp); + m_wlanRadioButton->setChecked(usingTcp); + + detailsLayout->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); + m_deviceInfoLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + 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())); + detailsLayout->addRow(m_deviceInfoDescriptionLabel, infoHBoxLayout); + + connect(this, SIGNAL(infoCollected()), + this, SLOT(collectingInfoFinished())); + + m_codaTimeout->setSingleShot(true); + connect(m_codaTimeout, SIGNAL(timeout()), this, SLOT(codaTimeout())); +} + +SymbianIDeviceConfigurationWidget::~SymbianIDeviceConfigurationWidget() +{ } + +QWidget *SymbianIDeviceConfigurationWidget::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)); + +#if !defined(Q_OS_WIN) && !defined(Q_OS_MACX) + // Update device list: only needed on linux. + QToolButton *updateSerialDevicesButton(new QToolButton); + updateSerialDevicesButton->setIcon(qApp->style()->standardIcon(QStyle::SP_BrowserReload)); + connect(updateSerialDevicesButton, SIGNAL(clicked()), + SymbianUtils::SymbianDeviceManager::instance(), SLOT(update())); + serialPortHBoxLayout->addWidget(updateSerialDevicesButton); +#endif + + QGroupBox *communicationChannelGroupBox = new QGroupBox(tr("Communication Channel")); + QGridLayout *communicationChannelGridLayout = new QGridLayout; + communicationChannelGridLayout->addWidget(m_serialRadioButton, 0, 0); + communicationChannelGridLayout->addWidget(m_wlanRadioButton, 1, 0); + + m_ipAddress->setMinimumWidth(30); + m_ipAddress->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); + + if (!symbianDevice()->address().isEmpty()) + m_ipAddress->setText(symbianDevice()->address() + QLatin1Char(':') + + symbianDevice()->port()); + + QHBoxLayout *wlanChannelLayout = new QHBoxLayout(); + wlanChannelLayout->addWidget(new QLabel(tr("Address:"))); + wlanChannelLayout->addWidget(m_ipAddress); + wlanChannelLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + + communicationChannelGridLayout->addLayout(serialPortHBoxLayout, 0, 1); + communicationChannelGridLayout->addLayout(wlanChannelLayout, 1, 1); + + communicationChannelGroupBox->setLayout(communicationChannelGridLayout); + + updateCommunicationChannelUi(); + + return communicationChannelGroupBox; +} + +void SymbianIDeviceConfigurationWidget::updateSerialDevices() +{ + m_serialPortsCombo->clear(); + const QString previouPortName = symbianDevice()->serialPortName(); + const QList<SymbianUtils::SymbianDevice> devices = SymbianUtils::SymbianDeviceManager::instance()->devices(); + int newIndex = -1; + for (int i = 0; i < devices.size(); ++i) { + const SymbianUtils::SymbianDevice &device = devices.at(i); + m_serialPortsCombo->addItem(device.friendlyName(), qVariantFromValue(device)); + if (device.portName() == previouPortName) + newIndex = i; + } + + if (symbianDevice()->communicationChannel() + == SymbianIDevice::CommunicationCodaTcpConnection) { + m_deviceInfoButton->setEnabled(true); + return; + } + + clearDeviceInfo(); + // Set new index: prefer to keep old or set to 0, if available. + if (newIndex == -1 && !devices.empty()) + newIndex = 0; + m_serialPortsCombo->setCurrentIndex(newIndex); + if (newIndex == -1) { + m_deviceInfoButton->setEnabled(false); + symbianDevice()->setSerialPortName(QString()); + } else { + m_deviceInfoButton->setEnabled(true); + const QString newPortName = rawDevice(newIndex).portName(); + symbianDevice()->setSerialPortName(newPortName); + } +} + +SymbianUtils::SymbianDevice SymbianIDeviceConfigurationWidget::rawDevice(int i) const +{ + const QVariant data = m_serialPortsCombo->itemData(i); + if (data.isValid() && qVariantCanConvert<SymbianUtils::SymbianDevice>(data)) + return qVariantValue<SymbianUtils::SymbianDevice>(data); + return SymbianUtils::SymbianDevice(); +} + +SymbianUtils::SymbianDevice SymbianIDeviceConfigurationWidget::currentRawDevice() const +{ + return rawDevice(m_serialPortsCombo->currentIndex()); +} + +void SymbianIDeviceConfigurationWidget::setSerialPort(int index) +{ + const SymbianUtils::SymbianDevice d = rawDevice(index); + symbianDevice()->setSerialPortName(d.portName()); + m_deviceInfoButton->setEnabled(index >= 0); + clearDeviceInfo(); +} + +void SymbianIDeviceConfigurationWidget::updateCommunicationChannelUi() +{ + SymbianIDevice::CommunicationChannel channel = symbianDevice()->communicationChannel(); + if (channel == SymbianIDevice::CommunicationCodaTcpConnection) { + m_ipAddress->setDisabled(false); + m_serialPortsCombo->setDisabled(true); + m_deviceInfoButton->setEnabled(true); + } else { + m_ipAddress->setDisabled(true); + m_serialPortsCombo->setDisabled(false); + updateSerialDevices(); + } +} + +void SymbianIDeviceConfigurationWidget::updateCommunicationChannel() +{ + if (!m_wlanRadioButton->isChecked() && !m_serialRadioButton->isChecked()) + m_serialRadioButton->setChecked(true); + + if (m_wlanRadioButton->isChecked()) { + m_ipAddress->setDisabled(false); + m_serialPortsCombo->setDisabled(true); + symbianDevice()->setCommunicationChannel(SymbianIDevice::CommunicationCodaTcpConnection); + m_deviceInfoButton->setEnabled(true); + } else { + m_ipAddress->setDisabled(true); + m_serialPortsCombo->setDisabled(false); + symbianDevice()->setCommunicationChannel(SymbianIDevice::CommunicationCodaSerialConnection); + updateSerialDevices(); + } +} + +void SymbianIDeviceConfigurationWidget::updateWlanAddress(const QString &address) +{ + QStringList addressList = address.split(QLatin1String(":"), QString::SkipEmptyParts); + if (addressList.count() > 0) { + symbianDevice()->setAddress(addressList.at(0)); + if (addressList.count() > 1) + symbianDevice()->setPort(addressList.at(1)); + else + symbianDevice()->setPort(QString()); + } +} + +void SymbianIDeviceConfigurationWidget::cleanWlanAddress() +{ + if (!symbianDevice()->address().isEmpty()) + symbianDevice()->setAddress(QString()); + + if (!symbianDevice()->port().isEmpty()) + symbianDevice()->setPort(QString()); +} + +void SymbianIDeviceConfigurationWidget::clearDeviceInfo() +{ + // Restore text & color + m_deviceInfoLabel->clear(); + m_deviceInfoLabel->setStyleSheet(QString()); +} + +void SymbianIDeviceConfigurationWidget::setDeviceInfoLabel(const QString &message, bool isError) +{ + m_deviceInfoLabel->setStyleSheet(isError ? + QString(QLatin1String("background-color: red;")) : + QString()); + m_deviceInfoLabel->setText(message); + m_deviceInfoLabel->adjustSize(); +} + +void SymbianIDeviceConfigurationWidget::updateDeviceInfo() +{ + setDeviceInfoLabel(tr("Connecting")); + if (symbianDevice()->communicationChannel() == SymbianIDevice::CommunicationCodaSerialConnection) { + const SymbianUtils::SymbianDevice commDev = currentRawDevice(); + m_codaInfoDevice = SymbianUtils::SymbianDeviceManager::instance()->getCodaDevice(commDev.portName()); + if (m_codaInfoDevice.isNull()) { + setDeviceInfoLabel(tr("Unable to create CODA connection. Please try again."), true); + return; + } + if (!m_codaInfoDevice->device()->isOpen()) { + setDeviceInfoLabel(m_codaInfoDevice->device()->errorString(), true); + return; + } + //TODO error handling - for now just throw the command at coda + m_codaInfoDevice->sendSymbianOsDataGetQtVersionCommand(Coda::CodaCallback(this, &SymbianIDeviceConfigurationWidget::getQtVersionCommandResult)); + m_deviceInfoButton->setEnabled(false); + m_codaTimeout->start(1000); + } else if (symbianDevice()->communicationChannel() == SymbianIDevice::CommunicationCodaTcpConnection) { + // collectingInfoFinished, which deletes m_codaDevice, can get called from within a coda callback, so need to use deleteLater + m_codaInfoDevice = QSharedPointer<Coda::CodaDevice>(new Coda::CodaDevice, &QObject::deleteLater); + connect(m_codaInfoDevice.data(), SIGNAL(codaEvent(Coda::CodaEvent)), this, SLOT(codaEvent(Coda::CodaEvent))); + + const QSharedPointer<QTcpSocket> codaSocket(new QTcpSocket); + m_codaInfoDevice->setDevice(codaSocket); + codaSocket->connectToHost(symbianDevice()->address(), + symbianDevice()->port().toInt()); + m_deviceInfoButton->setEnabled(false); + m_codaTimeout->start(1500); + } else + setDeviceInfoLabel(tr("Currently there is no information about the device for this connection type."), true); +} + +void SymbianIDeviceConfigurationWidget::codaEvent(const Coda::CodaEvent &event) +{ + switch (event.type()) { + case Coda::CodaEvent::LocatorHello: // Commands accepted now + codaIncreaseProgress(); + if (m_codaInfoDevice) + m_codaInfoDevice->sendSymbianOsDataGetQtVersionCommand(Coda::CodaCallback(this, &SymbianIDeviceConfigurationWidget::getQtVersionCommandResult)); + break; + default: + break; + } +} + +void SymbianIDeviceConfigurationWidget::getQtVersionCommandResult(const Coda::CodaCommandResult &result) +{ + m_deviceInfo.clear(); + if (result.type == Coda::CodaCommandResult::FailReply) { + setDeviceInfoLabel(tr("No device information available"), true); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); + m_deviceInfoButton->setEnabled(true); + m_codaTimeout->stop(); + return; + } else if (result.type == Coda::CodaCommandResult::CommandErrorReply){ + startTable(m_deviceInfo); + QTextStream str(&m_deviceInfo); + addErrorToTable(str, tr("Qt version: "), tr("Not installed on device")); + finishTable(m_deviceInfo); + } else { + if (result.values.count()) { + QHash<QString, QVariant> obj = result.values[0].toVariant().toHash(); + QString ver = obj.value(QLatin1String("qVersion")).toString(); + + startTable(m_deviceInfo); + QTextStream str(&m_deviceInfo); + addToTable(str, tr("Qt version:"), ver); + QString systemVersion; + + const int symVer = obj.value(QLatin1String("symbianVersion")).toInt(); + // Ugh why won't QSysInfo define these on non-symbian builds... + switch (symVer) { + case 10: + systemVersion.append(QLatin1String("Symbian OS v9.2")); + break; + case 20: + systemVersion.append(QLatin1String("Symbian OS v9.3")); + break; + case 30: + systemVersion.append(QLatin1String("Symbian OS v9.4 / Symbian^1")); + break; + case 40: + systemVersion.append(QLatin1String("Symbian^2")); + break; + case 50: + systemVersion.append(QLatin1String("Symbian^3")); + break; + case 60: + systemVersion.append(QLatin1String("Symbian^4")); + break; + case 70: + systemVersion.append(QLatin1String("Symbian^3")); // TODO: might change + break; + default: + systemVersion.append(tr("Unrecognised Symbian version 0x%1").arg(symVer, 0, 16)); + break; + } + systemVersion.append(QLatin1String(", ")); + int s60Ver = obj.value(QLatin1String("s60Version")).toInt(); + switch (s60Ver) { + case 10: + systemVersion.append(QLatin1String("S60 3rd Edition Feature Pack 1")); + break; + case 20: + systemVersion.append(QLatin1String("S60 3rd Edition Feature Pack 2")); + break; + case 30: + systemVersion.append(QLatin1String("S60 5th Edition")); + break; + case 40: + systemVersion.append(QLatin1String("S60 5th Edition Feature Pack 1")); + break; + case 50: + systemVersion.append(QLatin1String("S60 5th Edition Feature Pack 2")); + break; + case 70: + systemVersion.append(QLatin1String("S60 5th Edition Feature Pack 3")); // TODO: might change + break; + default: + systemVersion.append(tr("Unrecognised S60 version 0x%1").arg(symVer, 0, 16)); + break; + } + addToTable(str, tr("OS version:"), systemVersion); + finishTable(m_deviceInfo); + } + } + codaIncreaseProgress(); + if (m_codaInfoDevice) + m_codaInfoDevice->sendSymbianOsDataGetRomInfoCommand(Coda::CodaCallback(this, &SymbianIDeviceConfigurationWidget::getRomInfoResult)); +} + +void SymbianIDeviceConfigurationWidget::getRomInfoResult(const Coda::CodaCommandResult &result) +{ + codaIncreaseProgress(); + if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { + startTable(m_deviceInfo); + QTextStream str(&m_deviceInfo); + + QVariantHash obj = result.values[0].toVariant().toHash(); + QString romVersion = obj.value(QLatin1String("romVersion"), tr("unknown")).toString(); + romVersion.replace(QLatin1Char('\n'), QLatin1Char(' ')); // The ROM string is split across multiple lines, for some reason. + addToTable(str, tr("ROM version:"), romVersion); + + QString pr = obj.value(QLatin1String("prInfo")).toString(); + if (pr.length()) + addToTable(str, tr("Release:"), pr); + finishTable(m_deviceInfo); + } + + QList<quint32> packagesOfInterest; + packagesOfInterest.append(CODA_UID); + packagesOfInterest.append(QTMOBILITY_UID); + packagesOfInterest.append(QTCOMPONENTS_UID); + packagesOfInterest.append(QMLVIEWER_UID); + if (m_codaInfoDevice) + m_codaInfoDevice->sendSymbianInstallGetPackageInfoCommand(Coda::CodaCallback(this, &SymbianIDeviceConfigurationWidget::getInstalledPackagesResult), packagesOfInterest); +} + +void SymbianIDeviceConfigurationWidget::getInstalledPackagesResult(const Coda::CodaCommandResult &result) +{ + codaIncreaseProgress(); + if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { + startTable(m_deviceInfo); + QTextStream str(&m_deviceInfo); + + QVariantList resultsList = result.values[0].toVariant().toList(); + const QString uidKey = QLatin1String("uid"); + const QString errorKey = QLatin1String("error"); + const QString versionKey = QLatin1String("version"); + foreach (const QVariant& var, resultsList) { + QVariantHash obj = var.toHash(); + bool ok = false; + uint uid = obj.value(uidKey).toString().toUInt(&ok, 16); + if (ok) { + const bool error = !obj.value(errorKey).isNull(); + QString versionString; + if (!error) { + QVariantList version = obj.value(versionKey).toList(); + versionString = QString::fromLatin1("%1.%2.%3").arg(version[0].toInt()) + .arg(version[1].toInt()) + .arg(version[2].toInt()); + } + switch (uid) { + case CODA_UID: { + if (error) { + // How can coda not be installed? Presumably some UID wrongness... + addErrorToTable(str, tr("CODA version: "), tr("Error reading CODA version")); + } else + addToTable(str, tr("CODA version: "), versionString); + } + break; + case QTMOBILITY_UID: { + if (error) + addErrorToTable(str, tr("Qt Mobility version: "), tr("Error reading Qt Mobility version")); + else + addToTable(str, tr("Qt Mobility version: "), versionString); + } + break; + case QTCOMPONENTS_UID: { + addToTable(str, tr("Qt Quick components version: "), error ? tr("Not installed") : versionString); + } + break; + case QMLVIEWER_UID: { + addToTable(str, tr("QML Viewer version: "), error ? tr("Not installed") : versionString); + } + break; + default: break; + } + } + } + finishTable(m_deviceInfo); + } + + QStringList keys; + keys << QLatin1String("EDisplayXPixels"); + keys << QLatin1String("EDisplayYPixels"); + + if (m_codaInfoDevice) + m_codaInfoDevice->sendSymbianOsDataGetHalInfoCommand(Coda::CodaCallback(this, &SymbianIDeviceConfigurationWidget::getHalResult), keys); +} + +void SymbianIDeviceConfigurationWidget::getHalResult(const Coda::CodaCommandResult &result) +{ + codaIncreaseProgress(); + if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { + QVariantList resultsList = result.values[0].toVariant().toList(); + int x = 0; + int y = 0; + const QString nameKey = QLatin1String("name"); + const QString valueKey = QLatin1String("value"); + foreach (const QVariant& var, resultsList) { + QVariantHash obj = var.toHash(); + const QString name = obj.value(nameKey).toString(); + if (name == QLatin1String("EDisplayXPixels")) + x = obj.value(valueKey).toInt(); + else if (name == QLatin1String("EDisplayYPixels")) + y = obj.value(valueKey).toInt(); + } + if (x && y) { + startTable(m_deviceInfo); + QTextStream str(&m_deviceInfo); + addToTable(str, tr("Screen size:"), QString::number(x) + QLatin1Char('x') + QString::number(y)); + finishTable(m_deviceInfo); + } + } + + // Done with collecting info + emit infoCollected(); +} + +void SymbianIDeviceConfigurationWidget::codaIncreaseProgress() +{ + m_codaTimeout->start(); + setDeviceInfoLabel(m_deviceInfoLabel->text() + QLatin1Char('.')); +} + +SymbianIDevice *SymbianIDeviceConfigurationWidget::symbianDevice() const +{ + return dynamic_cast<SymbianIDevice *>(device().data()); +} + +void SymbianIDeviceConfigurationWidget::collectingInfoFinished() +{ + m_codaTimeout->stop(); + emit codaConnected(); + m_deviceInfoButton->setEnabled(true); + setDeviceInfoLabel(m_deviceInfo); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); +} + +void SymbianIDeviceConfigurationWidget::codaTimeout() +{ + QMessageBox *mb = CodaRunControl::createCodaWaitingMessageBox(this); + connect(this, SIGNAL(codaConnected()), mb, SLOT(close())); + connect(mb, SIGNAL(finished(int)), this, SLOT(codaCanceled())); + mb->open(); +} + +void SymbianIDeviceConfigurationWidget::codaCanceled() +{ + clearDeviceInfo(); + m_deviceInfoButton->setEnabled(true); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); +} + +} // namespace Internal +} // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-s60/symbianideviceconfigwidget.h b/src/plugins/qt4projectmanager/qt-s60/symbianideviceconfigwidget.h new file mode 100644 index 0000000000..8ace160342 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/symbianideviceconfigwidget.h @@ -0,0 +1,129 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#ifndef SYMBIANIDEVICECONFIGURATIONWIDGET_H +#define SYMBIANIDEVICECONFIGURATIONWIDGET_H + +#include <projectexplorer/devicesupport/idevicewidget.h> + +#include <QWidget> +#include <QPointer> + +QT_BEGIN_NAMESPACE +class QLabel; +class QLineEdit; +class QComboBox; +class QToolButton; +class QCheckBox; +class QRadioButton; +QT_END_NAMESPACE + +namespace Utils { + class DetailsWidget; + class IpAddressLineEdit; +} + +namespace SymbianUtils { +class SymbianDevice; +} + +namespace Coda { + class CodaDevice; + class CodaEvent; + struct CodaCommandResult; +} + +namespace Qt4ProjectManager { + +class SymbianIDevice; + +namespace Internal { + +class SymbianIDeviceConfigurationWidget : public ProjectExplorer::IDeviceWidget +{ + Q_OBJECT + +public: + explicit SymbianIDeviceConfigurationWidget(const ProjectExplorer::IDevice::Ptr &rawDevice, QWidget *parent = 0); + ~SymbianIDeviceConfigurationWidget(); + +signals: + void infoCollected(); + void codaConnected(); + +private slots: + void updateSerialDevices(); + void setSerialPort(int index); + void updateDeviceInfo(); + void clearDeviceInfo(); + void updateCommunicationChannel(); + void updateCommunicationChannelUi(); + void updateWlanAddress(const QString &address); + void cleanWlanAddress(); + void codaEvent(const Coda::CodaEvent &event); + void collectingInfoFinished(); + void codaTimeout(); + void codaCanceled(); + void codaIncreaseProgress(); + +private: + SymbianIDevice *symbianDevice() const; + + inline SymbianUtils::SymbianDevice rawDevice(int i) const; + inline SymbianUtils::SymbianDevice currentRawDevice() const; + + void setDeviceInfoLabel(const QString &message, bool isError = false); + + QWidget * createCommunicationChannel(); + + void getQtVersionCommandResult(const Coda::CodaCommandResult &result); + void getRomInfoResult(const Coda::CodaCommandResult &result); + void getInstalledPackagesResult(const Coda::CodaCommandResult &result); + void getHalResult(const Coda::CodaCommandResult &result); + + Utils::DetailsWidget *m_detailsWidget; + QComboBox *m_serialPortsCombo; + QToolButton *m_deviceInfoButton; + QLabel *m_deviceInfoDescriptionLabel; + QLabel *m_deviceInfoLabel; + QRadioButton *m_serialRadioButton; + QRadioButton *m_wlanRadioButton; + Utils::IpAddressLineEdit *m_ipAddress; + QSharedPointer<Coda::CodaDevice> m_codaInfoDevice; + QString m_deviceInfo; + QTimer *m_codaTimeout; +}; + +} // namespace Internal +} // namespace Qt4ProjectManager + +#endif // SYMBIANIDEVICECONFIGURATIONWIDGET_H diff --git a/src/plugins/qt4projectmanager/qt-s60/symbianidevicefactory.cpp b/src/plugins/qt4projectmanager/qt-s60/symbianidevicefactory.cpp new file mode 100644 index 0000000000..271fa200cb --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/symbianidevicefactory.cpp @@ -0,0 +1,79 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#include "symbianidevicefactory.h" + +#include "symbianidevice.h" + +#include <utils/qtcassert.h> + +namespace Qt4ProjectManager { +namespace Internal { + +SymbianIDeviceFactory::SymbianIDeviceFactory(QObject *parent) : IDeviceFactory(parent) +{ } + +QString SymbianIDeviceFactory::displayName() const +{ + return tr("Symbian Device"); +} + +bool SymbianIDeviceFactory::canCreate() const +{ + return false; +} + +ProjectExplorer::IDevice::Ptr SymbianIDeviceFactory::create() const +{ + return ProjectExplorer::IDevice::Ptr(); +} + +ProjectExplorer::IDevice::Ptr SymbianIDeviceFactory::loadDevice(const QVariantMap &map) const +{ + QTC_ASSERT(supportsDeviceType(ProjectExplorer::IDevice::typeFromMap(map)), + return ProjectExplorer::IDevice::Ptr()); + SymbianIDevice *dev = new SymbianIDevice(map); + return ProjectExplorer::IDevice::Ptr(dev); +} + +bool SymbianIDeviceFactory::supportsDeviceType(const QString &type) const +{ + return type == deviceType(); +} + +QString SymbianIDeviceFactory::deviceType() +{ + return QLatin1String("Qt4ProjectManager.SymbianDevice"); +} + +} // namespace internal +} // namespace qt4projectmanager diff --git a/src/plugins/qt4projectmanager/qt-s60/symbianidevicefactory.h b/src/plugins/qt4projectmanager/qt-s60/symbianidevicefactory.h new file mode 100644 index 0000000000..360c432345 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/symbianidevicefactory.h @@ -0,0 +1,60 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#ifndef SYMBIANIDEVICEFACTORY_H +#define SYMBIANIDEVICEFACTORY_H + +#include <projectexplorer/devicesupport/idevicefactory.h> + +namespace Qt4ProjectManager { +namespace Internal { + +class SymbianIDeviceFactory : public ProjectExplorer::IDeviceFactory +{ + Q_OBJECT + +public: + SymbianIDeviceFactory(QObject *parent = 0); + + QString displayName() const; + bool canCreate() const; + ProjectExplorer::IDevice::Ptr create() const; + ProjectExplorer::IDevice::Ptr loadDevice(const QVariantMap &map) const; + bool supportsDeviceType(const QString &type) const; + + static QString deviceType(); +}; + +} // namespace Internal +} // namespace Qt4ProjectManager + +#endif // SYMBIANIDEVICEFACTORY_H |