1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "s60deployconfigurationwidget.h"
34 #include "s60deployconfiguration.h"
35 #include "s60devicerunconfiguration.h"
37 #include "s60runconfigbluetoothstarter.h"
38 #include <symbianutils/bluetoothlistener_gui.h>
40 #include <symbianutils/launcher.h>
41 #include <symbianutils/bluetoothlistener.h>
42 #include <symbianutils/symbiandevicemanager.h>
43 #include <codadevice.h>
45 #include <coreplugin/helpmanager.h>
47 #include "codaruncontrol.h"
48 #include "trkruncontrol.h"
50 #include <utils/detailswidget.h>
51 #include <utils/ipaddresslineedit.h>
52 #include <utils/qtcassert.h>
53 #include <utils/pathchooser.h>
55 #include <QtCore/QDir>
56 #include <QtCore/QTimer>
57 #include <QtGui/QLabel>
58 #include <QtGui/QLineEdit>
59 #include <QtGui/QComboBox>
60 #include <QtGui/QVBoxLayout>
61 #include <QtGui/QHBoxLayout>
62 #include <QtGui/QFormLayout>
63 #include <QtGui/QToolButton>
64 #include <QtGui/QStyle>
65 #include <QtGui/QApplication>
66 #include <QtGui/QSpacerItem>
67 #include <QtGui/QMessageBox>
68 #include <QtGui/QCheckBox>
69 #include <QtGui/QGroupBox>
70 #include <QtGui/QRadioButton>
71 #include <QtGui/QValidator>
73 #include <QtNetwork/QTcpSocket>
75 Q_DECLARE_METATYPE(SymbianUtils::SymbianDevice)
77 namespace Qt4ProjectManager {
80 const char STARTING_DRIVE_LETTER = 'C';
81 const char LAST_DRIVE_LETTER = 'Z';
83 static const quint32 CODA_UID = 0x20021F96;
84 static const quint32 QTMOBILITY_UID = 0x2002AC89;
86 QString formatDriveText(const S60DeployConfiguration::DeviceDrive &drive)
88 char driveLetter = QChar::toUpper(static_cast<ushort>(drive.first));
89 if (drive.second <= 0)
90 return QString("%1:").arg(driveLetter);
91 if (drive.second >= 1024)
92 return QString("%1:%2 MB").arg(driveLetter).arg(drive.second);
93 return QString("%1:%2 kB").arg(driveLetter).arg(drive.second);
96 void startTable(QString &text)
98 const char startTableC[] = "<html></head><body><table>";
99 if (text.contains(startTableC))
101 text.append(startTableC);
104 void finishTable(QString &text)
106 const char stopTableC[] = "</table></body></html>";
107 text.replace(stopTableC, QLatin1String(""));
108 text.append(stopTableC);
111 void addToTable(QTextStream &stream, const QString &key, const QString &value)
113 const char tableRowStartC[] = "<tr><td><b>";
114 const char tableRowSeparatorC[] = "</b></td><td>";
115 const char tableRowEndC[] = "</td></tr>";
116 stream << tableRowStartC << key << tableRowSeparatorC << value << tableRowEndC;
119 void addErrorToTable(QTextStream &stream, const QString &key, const QString &value)
121 const char tableRowStartC[] = "<tr><td><b>";
122 const char tableRowSeparatorC[] = "</b></td><td>";
123 const char tableRowEndC[] = "</td></tr>";
124 const char errorSpanStartC[] = "<span style=\"font-weight:600; color:red; \">";
125 const char errorSpanEndC[] = "</span>";
126 stream << tableRowStartC << errorSpanStartC << key << tableRowSeparatorC << value << errorSpanEndC << tableRowEndC;
129 S60DeployConfigurationWidget::S60DeployConfigurationWidget(QWidget *parent)
130 : ProjectExplorer::DeployConfigurationWidget(parent),
131 m_detailsWidget(new Utils::DetailsWidget),
132 m_serialPortsCombo(new QComboBox),
133 m_sisFileLabel(new QLabel),
134 m_deviceInfoButton(new QToolButton),
135 m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))),
136 m_deviceInfoLabel(new QLabel),
137 m_installationDriveCombo(new QComboBox()),
138 m_silentInstallCheckBox(new QCheckBox(tr("Silent installation"))),
139 m_serialRadioButton(new QRadioButton(tr("Serial:"))),
140 m_wlanRadioButton(new QRadioButton(tr("WLAN:"))),
141 m_ipAddress(new Utils::IpAddressLineEdit),
142 m_trkRadioButton(new QRadioButton(tr("TRK"))),
143 m_codaRadioButton(new QRadioButton(tr("CODA"))),
144 m_codaInfoLabel(new QLabel(tr("<a href=\"qthelp://com.nokia.qtcreator/doc/creator-developing-symbian.html\">What are the prerequisites?</a>"))),
145 m_codaTimeout(new QTimer(this))
149 S60DeployConfigurationWidget::~S60DeployConfigurationWidget()
153 void S60DeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc)
155 m_deployConfiguration = qobject_cast<S60DeployConfiguration *>(dc);
157 m_detailsWidget->setState(Utils::DetailsWidget::NoSummary);
159 QVBoxLayout *mainBoxLayout = new QVBoxLayout();
160 mainBoxLayout->setMargin(0);
161 setLayout(mainBoxLayout);
162 mainBoxLayout->addWidget(m_detailsWidget);
163 QWidget *detailsContainer = new QWidget;
164 m_detailsWidget->setWidget(detailsContainer);
166 QVBoxLayout *detailsBoxLayout = new QVBoxLayout();
167 detailsBoxLayout->setMargin(0);
168 detailsContainer->setLayout(detailsBoxLayout);
170 QFormLayout *formLayout = new QFormLayout();
171 formLayout->setMargin(0);
172 detailsBoxLayout->addLayout(formLayout);
173 formLayout->addRow(tr("Installation file:"), m_sisFileLabel);
175 // Installation Drive control
176 updateInstallationDrives();
178 QHBoxLayout *installationBoxLayout = new QHBoxLayout();
179 m_installationDriveCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
180 connect(m_installationDriveCombo, SIGNAL(activated(int)), this, SLOT(setInstallationDrive(int)));
181 QHBoxLayout *installationDriveHBoxLayout = new QHBoxLayout;
182 installationDriveHBoxLayout->addWidget(m_installationDriveCombo);
183 installationBoxLayout->addLayout(installationDriveHBoxLayout);
185 // Non-silent installs are a fallback if one wants to override missing dependencies.
186 m_silentInstallCheckBox->setChecked(m_deployConfiguration->silentInstall());
187 m_silentInstallCheckBox->setToolTip(tr("Silent installation is an installation mode "
188 "that does not require user's intervention. "
189 "In case it fails the non silent installation is launched."));
190 connect(m_silentInstallCheckBox, SIGNAL(stateChanged(int)), this, SLOT(silentInstallChanged(int)));
191 installationBoxLayout->addWidget(m_silentInstallCheckBox);
192 installationBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
193 formLayout->addRow(tr("Installation drive:"), installationBoxLayout);
195 updateSerialDevices();
196 connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(updated()),
197 this, SLOT(updateSerialDevices()));
200 QVBoxLayout *debugClientContentVBoxLayout = new QVBoxLayout;
201 debugClientContentVBoxLayout->addWidget(m_codaInfoLabel);
203 QHBoxLayout *debugClientHBoxLayout = new QHBoxLayout;
204 debugClientContentVBoxLayout->addLayout(debugClientHBoxLayout);
206 QVBoxLayout *debugClientVBoxLayout = new QVBoxLayout;
207 debugClientVBoxLayout->addWidget(m_trkRadioButton);
208 debugClientVBoxLayout->addWidget(m_codaRadioButton);
210 debugClientVBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::Expanding));
212 debugClientHBoxLayout->addLayout(debugClientVBoxLayout);
214 debugClientHBoxLayout->addWidget(createCommunicationChannel());
215 debugClientHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
217 QGroupBox *debugClientGroupBox = new QGroupBox(tr("Device Agent"));
218 debugClientGroupBox->setLayout(debugClientContentVBoxLayout);
220 bool usingTrk = m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationTrkSerialConnection;
221 m_trkRadioButton->setChecked(usingTrk);
222 m_codaRadioButton->setChecked(!usingTrk);
224 bool usingTcp = m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection;
225 m_serialRadioButton->setChecked(!usingTcp);
226 m_wlanRadioButton->setChecked(usingTcp);
228 connect(m_trkRadioButton, SIGNAL(clicked()), this, SLOT(updateCommunicationChannel()));
229 connect(m_codaRadioButton, SIGNAL(clicked()), this, SLOT(updateCommunicationChannel()));
230 connect(m_codaInfoLabel, SIGNAL(linkActivated(QString)),
231 Core::HelpManager::instance(), SLOT(handleHelpRequest(QString)));
233 formLayout->addRow(debugClientGroupBox);
235 // Device Info with button. Widgets are enabled in above call to updateSerialDevices()
236 QHBoxLayout *infoHBoxLayout = new QHBoxLayout;
237 m_deviceInfoLabel->setWordWrap(true);
238 m_deviceInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
239 m_deviceInfoLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
240 infoHBoxLayout->addWidget(m_deviceInfoLabel);
241 infoHBoxLayout->addWidget(m_deviceInfoButton);
242 m_deviceInfoButton->setIcon(qApp->style()->standardIcon(QStyle::SP_MessageBoxInformation));
243 m_deviceInfoButton->setToolTip(tr("Queries the device for information"));
244 connect(m_deviceInfoButton, SIGNAL(clicked()), this, SLOT(updateDeviceInfo()));
245 formLayout->addRow(m_deviceInfoDescriptionLabel, infoHBoxLayout);
246 updateTargetInformation();
247 connect(m_deployConfiguration, SIGNAL(targetInformationChanged()),
248 this, SLOT(updateTargetInformation()));
249 connect(m_deployConfiguration, SIGNAL(availableDeviceDrivesChanged()),
250 this, SLOT(updateInstallationDrives()));
251 connect(this, SIGNAL(infoCollected()),
252 this, SLOT(collectingInfoFinished()));
254 m_codaTimeout->setSingleShot(true);
255 connect(m_codaTimeout, SIGNAL(timeout()), this, SLOT(codaTimeout()));
258 QWidget *S60DeployConfigurationWidget::createCommunicationChannel()
260 m_serialPortsCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
261 connect(m_serialPortsCombo, SIGNAL(activated(int)), this, SLOT(setSerialPort(int)));
262 connect(m_serialRadioButton, SIGNAL(clicked()), this, SLOT(updateCommunicationChannel()));
263 connect(m_wlanRadioButton, SIGNAL(clicked()), this, SLOT(updateCommunicationChannel()));
264 connect(m_ipAddress, SIGNAL(validAddressChanged(QString)), this, SLOT(updateWlanAddress(QString)));
265 connect(m_ipAddress, SIGNAL(invalidAddressChanged()), this, SLOT(cleanWlanAddress()));
267 QHBoxLayout *serialPortHBoxLayout = new QHBoxLayout;
268 serialPortHBoxLayout->addWidget(new QLabel(tr("Serial port:")));
269 serialPortHBoxLayout->addWidget(m_serialPortsCombo);
270 serialPortHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
273 // Update device list: on Linux only.
274 QToolButton *updateSerialDevicesButton(new QToolButton);
275 updateSerialDevicesButton->setIcon(qApp->style()->standardIcon(QStyle::SP_BrowserReload));
276 connect(updateSerialDevicesButton, SIGNAL(clicked()),
277 SymbianUtils::SymbianDeviceManager::instance(), SLOT(update()));
278 serialPortHBoxLayout->addWidget(updateSerialDevicesButton);
281 QGroupBox *communicationChannelGroupBox = new QGroupBox(tr("Communication Channel"));
282 QGridLayout *communicationChannelGridLayout = new QGridLayout;
283 communicationChannelGridLayout->addWidget(m_serialRadioButton, 0, 0);
284 communicationChannelGridLayout->addWidget(m_wlanRadioButton, 1, 0);
286 m_ipAddress->setMinimumWidth(30);
287 m_ipAddress->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
289 if(!m_deployConfiguration->deviceAddress().isEmpty())
290 m_ipAddress->setText(QString("%1:%2")
291 .arg(m_deployConfiguration->deviceAddress())
292 .arg(m_deployConfiguration->devicePort()));
294 QHBoxLayout *wlanChannelLayout = new QHBoxLayout();
295 wlanChannelLayout->addWidget(new QLabel(tr("Address:")));
296 wlanChannelLayout->addWidget(m_ipAddress);
297 wlanChannelLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
299 communicationChannelGridLayout->addLayout(serialPortHBoxLayout, 0, 1);
300 communicationChannelGridLayout->addLayout(wlanChannelLayout, 1, 1);
302 communicationChannelGroupBox->setLayout(communicationChannelGridLayout);
304 updateCommunicationChannelUi();
306 return communicationChannelGroupBox;
309 void S60DeployConfigurationWidget::updateInstallationDrives()
311 m_installationDriveCombo->clear();
312 const QList<S60DeployConfiguration::DeviceDrive> &availableDrives(m_deployConfiguration->availableDeviceDrives());
314 char currentDrive = QChar::toUpper(static_cast<ushort>(m_deployConfiguration->installationDrive()));
315 if (availableDrives.isEmpty()) {
316 for (int i = STARTING_DRIVE_LETTER; i <= LAST_DRIVE_LETTER; ++i) {
317 m_installationDriveCombo->addItem(QString("%1:").arg(static_cast<char>(i)), QChar(i));
319 index = currentDrive - STARTING_DRIVE_LETTER;
321 for (int i = 0; i < availableDrives.count(); ++i) {
322 const S60DeployConfiguration::DeviceDrive& drive(availableDrives.at(i));
323 char driveLetter = QChar::toUpper(static_cast<ushort>(drive.first));
324 m_installationDriveCombo->addItem(formatDriveText(drive),
326 if (currentDrive == driveLetter)
330 QTC_ASSERT(index >= 0 && index <= m_installationDriveCombo->count(), return);
332 m_installationDriveCombo->setCurrentIndex(index);
333 setInstallationDrive(index);
336 void S60DeployConfigurationWidget::silentInstallChanged(int state)
338 m_deployConfiguration->setSilentInstall(state == Qt::Checked);
341 void S60DeployConfigurationWidget::updateSerialDevices()
343 m_serialPortsCombo->clear();
344 const QString previouPortName = m_deployConfiguration->serialPortName();
345 const QList<SymbianUtils::SymbianDevice> devices = SymbianUtils::SymbianDeviceManager::instance()->devices();
347 for (int i = 0; i < devices.size(); ++i) {
348 const SymbianUtils::SymbianDevice &device = devices.at(i);
349 m_serialPortsCombo->addItem(device.friendlyName(), qVariantFromValue(device));
350 if (device.portName() == previouPortName)
354 if(m_deployConfiguration->communicationChannel()
355 == S60DeployConfiguration::CommunicationCodaTcpConnection) {
356 m_deviceInfoButton->setEnabled(true);
361 // Set new index: prefer to keep old or set to 0, if available.
362 if (newIndex == -1 && !devices.empty())
364 m_serialPortsCombo->setCurrentIndex(newIndex);
365 if (newIndex == -1) {
366 m_deviceInfoButton->setEnabled(false);
367 m_deployConfiguration->setSerialPortName(QString());
369 m_deviceInfoButton->setEnabled(true);
370 const QString newPortName = device(newIndex).portName();
371 m_deployConfiguration->setSerialPortName(newPortName);
375 SymbianUtils::SymbianDevice S60DeployConfigurationWidget::device(int i) const
377 const QVariant data = m_serialPortsCombo->itemData(i);
378 if (data.isValid() && qVariantCanConvert<SymbianUtils::SymbianDevice>(data))
379 return qVariantValue<SymbianUtils::SymbianDevice>(data);
380 return SymbianUtils::SymbianDevice();
383 SymbianUtils::SymbianDevice S60DeployConfigurationWidget::currentDevice() const
385 return device(m_serialPortsCombo->currentIndex());
388 void S60DeployConfigurationWidget::updateTargetInformation()
391 for (int i = 0; i < m_deployConfiguration->signedPackages().count(); ++i)
392 package += m_deployConfiguration->signedPackages()[i] + QLatin1String("\n");
393 if (!package.isEmpty())
394 package.remove(package.length()-1, 1);
395 m_sisFileLabel->setText(QDir::toNativeSeparators(package));
398 void S60DeployConfigurationWidget::setInstallationDrive(int index)
400 QTC_ASSERT(index >= 0, return);
401 QTC_ASSERT(index < m_installationDriveCombo->count(), return);
403 QChar driveLetter(m_installationDriveCombo->itemData(index).toChar());
404 m_deployConfiguration->setInstallationDrive(driveLetter.toAscii());
407 void S60DeployConfigurationWidget::setSerialPort(int index)
409 const SymbianUtils::SymbianDevice d = device(index);
410 m_deployConfiguration->setSerialPortName(d.portName());
411 m_deviceInfoButton->setEnabled(index >= 0);
415 void S60DeployConfigurationWidget::updateCommunicationChannelUi()
417 S60DeployConfiguration::CommunicationChannel channel = m_deployConfiguration->communicationChannel();
418 if (channel == S60DeployConfiguration::CommunicationTrkSerialConnection) {
419 m_trkRadioButton->setChecked(true);
420 m_codaRadioButton->setChecked(false);
421 m_serialRadioButton->setChecked(true);
422 m_wlanRadioButton->setDisabled(true);
423 m_ipAddress->setDisabled(true);
424 m_serialPortsCombo->setDisabled(false);
425 updateSerialDevices();
427 m_trkRadioButton->setChecked(false);
428 m_codaRadioButton->setChecked(true);
429 m_wlanRadioButton->setDisabled(false);
430 if (channel == S60DeployConfiguration::CommunicationCodaTcpConnection) {
431 m_ipAddress->setDisabled(false);
432 m_serialPortsCombo->setDisabled(true);
433 m_deviceInfoButton->setEnabled(true);
435 m_ipAddress->setDisabled(true);
436 m_serialPortsCombo->setDisabled(false);
437 updateSerialDevices();
442 void S60DeployConfigurationWidget::updateCommunicationChannel()
444 if (!m_trkRadioButton->isChecked() && !m_codaRadioButton->isChecked())
445 m_trkRadioButton->setChecked(true);
447 if (m_trkRadioButton->isChecked()) {
448 m_serialRadioButton->setChecked(true);
449 m_wlanRadioButton->setDisabled(true);
450 m_ipAddress->setDisabled(true);
451 m_serialPortsCombo->setDisabled(false);
452 m_deployConfiguration->setCommunicationChannel(S60DeployConfiguration::CommunicationTrkSerialConnection);
453 updateSerialDevices();
454 } else if (m_codaRadioButton->isChecked()) {
455 if (!m_wlanRadioButton->isChecked() && !m_serialRadioButton->isChecked())
456 m_serialRadioButton->setChecked(true);
457 m_wlanRadioButton->setDisabled(false);
459 if (m_wlanRadioButton->isChecked()) {
460 m_ipAddress->setDisabled(false);
461 m_serialPortsCombo->setDisabled(true);
462 m_deployConfiguration->setCommunicationChannel(S60DeployConfiguration::CommunicationCodaTcpConnection);
463 m_deviceInfoButton->setEnabled(true);
465 m_ipAddress->setDisabled(true);
466 m_serialPortsCombo->setDisabled(false);
467 m_deployConfiguration->setCommunicationChannel(S60DeployConfiguration::CommunicationCodaSerialConnection);
468 updateSerialDevices();
473 void S60DeployConfigurationWidget::updateWlanAddress(const QString &address)
475 QStringList addressList = address.split(QLatin1String(":"), QString::SkipEmptyParts);
476 if (addressList.count() > 0) {
477 m_deployConfiguration->setDeviceAddress(addressList.at(0));
478 if (addressList.count() > 1)
479 m_deployConfiguration->setDevicePort(addressList.at(1));
481 m_deployConfiguration->setDevicePort(QString());
485 void S60DeployConfigurationWidget::cleanWlanAddress()
487 if (!m_deployConfiguration->deviceAddress().isEmpty())
488 m_deployConfiguration->setDeviceAddress(QString());
490 if (!m_deployConfiguration->devicePort().isEmpty())
491 m_deployConfiguration->setDevicePort(QString());
494 void S60DeployConfigurationWidget::clearDeviceInfo()
496 // Restore text & color
497 m_deviceInfoLabel->clear();
498 m_deviceInfoLabel->setStyleSheet(QString());
501 void S60DeployConfigurationWidget::setDeviceInfoLabel(const QString &message, bool isError)
503 m_deviceInfoLabel->setStyleSheet(isError ?
504 QString(QLatin1String("background-color: red;")) :
506 m_deviceInfoLabel->setText(message);
507 m_deviceInfoLabel->adjustSize();
510 void S60DeployConfigurationWidget::slotLauncherStateChanged(int s)
513 case trk::Launcher::WaitingForTrk: {
514 // Entered trk wait state..open message box
515 QMessageBox *mb = TrkRunControl::createTrkWaitingMessageBox(m_infoLauncher->trkServerName(), this);
516 connect(m_infoLauncher, SIGNAL(stateChanged(int)), mb, SLOT(close()));
517 connect(mb, SIGNAL(finished(int)), this, SLOT(slotWaitingForTrkClosed()));
521 case trk::Launcher::DeviceDescriptionReceived: // All ok, done
522 setDeviceInfoLabel(m_infoLauncher->deviceDescription());
523 m_deviceInfoButton->setEnabled(true);
524 m_infoLauncher->deleteLater();
529 void S60DeployConfigurationWidget::slotWaitingForTrkClosed()
531 if (m_infoLauncher && m_infoLauncher->state() == trk::Launcher::WaitingForTrk) {
532 m_infoLauncher->deleteLater();
534 m_deviceInfoButton->setEnabled(true);
538 void S60DeployConfigurationWidget::updateDeviceInfo()
540 setDeviceInfoLabel(tr("Connecting"));
541 if (m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationTrkSerialConnection) {
542 QTC_ASSERT(!m_infoLauncher, return)
544 // Do a launcher run with the ping protocol. Prompt to connect and
545 // go asynchronous afterwards to pop up launch trk box if a timeout occurs.
547 const SymbianUtils::SymbianDevice commDev = currentDevice();
548 m_infoLauncher = trk::Launcher::acquireFromDeviceManager(commDev.portName(), this, &message);
549 if (!m_infoLauncher) {
550 setDeviceInfoLabel(message, true);
553 connect(m_infoLauncher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
555 m_infoLauncher->setSerialFrame(commDev.type() == SymbianUtils::SerialPortCommunication);
556 m_infoLauncher->setTrkServerName(commDev.portName());
559 const trk::PromptStartCommunicationResult src =
560 S60RunConfigBluetoothStarter::startCommunication(m_infoLauncher->trkDevice(),
563 case trk::PromptStartCommunicationConnected:
565 case trk::PromptStartCommunicationCanceled:
567 m_infoLauncher->deleteLater();
569 case trk::PromptStartCommunicationError:
570 setDeviceInfoLabel(message, true);
571 m_infoLauncher->deleteLater();
574 if (!m_infoLauncher->startServer(&message)) {
575 setDeviceInfoLabel(message, true);
576 m_infoLauncher->deleteLater();
579 // Wait for either timeout or results
580 m_deviceInfoButton->setEnabled(false);
581 } else if (m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationCodaSerialConnection) {
582 const SymbianUtils::SymbianDevice commDev = currentDevice();
583 m_codaInfoDevice = SymbianUtils::SymbianDeviceManager::instance()->getCodaDevice(commDev.portName());
584 if (m_codaInfoDevice.isNull()) {
585 setDeviceInfoLabel(tr("Unable to create CODA connection. Please try again."), true);
588 if (!m_codaInfoDevice->device()->isOpen()) {
589 setDeviceInfoLabel(m_codaInfoDevice->device()->errorString(), true);
592 //TODO error handling - for now just throw the command at coda
593 m_codaInfoDevice->sendSymbianOsDataGetQtVersionCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getQtVersionCommandResult));
594 m_deviceInfoButton->setEnabled(false);
595 m_codaTimeout->start(1000);
596 } else if(m_deployConfiguration->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection) {
597 // collectingInfoFinished, which deletes m_codaDevice, can get called from within a coda callback, so need to use deleteLater
598 m_codaInfoDevice = QSharedPointer<Coda::CodaDevice>(new Coda::CodaDevice, &QObject::deleteLater);
599 connect(m_codaInfoDevice.data(), SIGNAL(tcfEvent(Coda::CodaEvent)), this, SLOT(codaEvent(Coda::CodaEvent)));
601 const QSharedPointer<QTcpSocket> codaSocket(new QTcpSocket);
602 m_codaInfoDevice->setDevice(codaSocket);
603 codaSocket->connectToHost(m_deployConfiguration->deviceAddress(),
604 m_deployConfiguration->devicePort().toInt());
605 m_deviceInfoButton->setEnabled(false);
606 m_codaTimeout->start(1500);
608 setDeviceInfoLabel(tr("Currently there is no information about the device for this connection type."), true);
611 void S60DeployConfigurationWidget::codaEvent(const Coda::CodaEvent &event)
613 switch (event.type()) {
614 case Coda::CodaEvent::LocatorHello: // Commands accepted now
615 codaIncreaseProgress();
616 m_codaInfoDevice->sendSymbianOsDataGetQtVersionCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getQtVersionCommandResult));
623 void S60DeployConfigurationWidget::getQtVersionCommandResult(const Coda::CodaCommandResult &result)
625 m_deviceInfo.clear();
626 if (result.type == Coda::CodaCommandResult::FailReply) {
627 setDeviceInfoLabel(tr("No device information available"), true);
628 SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice);
629 m_deviceInfoButton->setEnabled(true);
630 m_codaTimeout->stop();
632 } else if (result.type == Coda::CodaCommandResult::CommandErrorReply){
633 startTable(m_deviceInfo);
634 QTextStream str(&m_deviceInfo);
635 addErrorToTable(str, tr("Qt version: "), tr("Not installed on device"));
636 finishTable(m_deviceInfo);
638 if (result.values.count()) {
639 QHash<QString, QVariant> obj = result.values[0].toVariant().toHash();
640 QString ver = obj.value("qVersion").toString();
642 startTable(m_deviceInfo);
643 QTextStream str(&m_deviceInfo);
644 addToTable(str, tr("Qt version:"), ver);
645 QString systemVersion;
647 int symVer = obj.value("symbianVersion").toInt();
648 // Ugh why won't QSysInfo define these on non-symbian builds...
651 systemVersion.append("Symbian OS v9.2");
654 systemVersion.append("Symbian OS v9.3");
657 systemVersion.append("Symbian OS v9.4 / Symbian^1");
660 systemVersion.append("Symbian^2");
663 systemVersion.append("Symbian^3");
666 systemVersion.append("Symbian^4");
669 systemVersion.append(tr("Unrecognised Symbian version 0x%1").arg(symVer, 0, 16));
672 systemVersion.append(", ");
673 int s60Ver = obj.value("s60Version").toInt();
676 systemVersion.append("S60 3rd Edition Feature Pack 1");
679 systemVersion.append("S60 3rd Edition Feature Pack 2");
682 systemVersion.append("S60 5th Edition");
685 systemVersion.append("S60 5th Edition Feature Pack 1");
688 systemVersion.append("S60 5th Edition Feature Pack 2");
691 systemVersion.append(tr("Unrecognised S60 version 0x%1").arg(symVer, 0, 16));
694 addToTable(str, tr("OS version:"), systemVersion);
695 finishTable(m_deviceInfo);
698 codaIncreaseProgress();
699 m_codaInfoDevice->sendSymbianOsDataGetRomInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getRomInfoResult));
702 void S60DeployConfigurationWidget::getRomInfoResult(const Coda::CodaCommandResult &result)
704 codaIncreaseProgress();
705 if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) {
706 startTable(m_deviceInfo);
707 QTextStream str(&m_deviceInfo);
709 QVariantHash obj = result.values[0].toVariant().toHash();
710 QString romVersion = obj.value("romVersion", tr("unknown")).toString();
711 romVersion.replace('\n', " "); // The ROM string is split across multiple lines, for some reason.
712 addToTable(str, tr("ROM version:"), romVersion);
714 QString pr = obj.value("prInfo").toString();
716 addToTable(str, tr("Release:"), pr);
717 finishTable(m_deviceInfo);
720 QList<quint32> packagesOfInterest;
721 packagesOfInterest.append(CODA_UID);
722 packagesOfInterest.append(QTMOBILITY_UID);
723 m_codaInfoDevice->sendSymbianInstallGetPackageInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getInstalledPackagesResult), packagesOfInterest);
726 void S60DeployConfigurationWidget::getInstalledPackagesResult(const Coda::CodaCommandResult &result)
728 codaIncreaseProgress();
729 if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) {
730 startTable(m_deviceInfo);
731 QTextStream str(&m_deviceInfo);
733 QVariantList resultsList = result.values[0].toVariant().toList();
734 foreach (const QVariant& var, resultsList) {
735 QVariantHash obj = var.toHash();
737 uint uid = obj.value("uid").toString().toUInt(&ok, 16);
739 bool error = !obj.value("error").isNull();
740 QString versionString;
742 QVariantList version = obj.value("version").toList();
743 versionString = QString("%1.%2.%3").arg(version[0].toInt())
744 .arg(version[1].toInt())
745 .arg(version[2].toInt());
750 // How can coda not be installed? Presumably some UID wrongness...
751 addErrorToTable(str, tr("CODA version: "), tr("Error reading CODA version"));
753 addToTable(str, tr("CODA version: "), versionString);
756 case QTMOBILITY_UID: {
758 addErrorToTable(str, tr("QtMobility version: "), tr("Error reading QtMobility version"));
760 addToTable(str, tr("QtMobility version: "), versionString);
767 finishTable(m_deviceInfo);
771 keys << QLatin1String("EDisplayXPixels");
772 keys << QLatin1String("EDisplayYPixels");
773 //keys << "EMemoryRAMFree";
774 m_codaInfoDevice->sendSymbianOsDataGetHalInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getHalResult), keys);
777 void S60DeployConfigurationWidget::getHalResult(const Coda::CodaCommandResult &result)
779 codaIncreaseProgress();
780 if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) {
781 QVariantList resultsList = result.values[0].toVariant().toList();
784 foreach (const QVariant& var, resultsList) {
785 QVariantHash obj = var.toHash();
786 if (obj.value("name").toString() == "EDisplayXPixels")
787 x = obj.value("value").toInt();
788 else if (obj.value("name").toString() == "EDisplayYPixels")
789 y = obj.value("value").toInt();
792 startTable(m_deviceInfo);
793 QTextStream str(&m_deviceInfo);
794 addToTable(str, tr("Screen size:"), QString("%1x%2").arg(x).arg(y));
795 finishTable(m_deviceInfo);
799 // Done with collecting info
800 emit infoCollected();
803 void S60DeployConfigurationWidget::codaIncreaseProgress()
805 m_codaTimeout->start();
806 setDeviceInfoLabel(m_deviceInfoLabel->text() + '.');
809 void S60DeployConfigurationWidget::collectingInfoFinished()
811 m_codaTimeout->stop();
812 emit codaConnected();
813 m_deviceInfoButton->setEnabled(true);
814 setDeviceInfoLabel(m_deviceInfo);
815 SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice);
818 void S60DeployConfigurationWidget::codaTimeout()
820 QMessageBox *mb = CodaRunControl::createCodaWaitingMessageBox(this);
821 connect(this, SIGNAL(codaConnected()), mb, SLOT(close()));
822 connect(mb, SIGNAL(finished(int)), this, SLOT(codaCanceled()));
826 void S60DeployConfigurationWidget::codaCanceled()
829 m_deviceInfoButton->setEnabled(true);
830 SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice);
833 } // namespace Internal
834 } // namespace Qt4ProjectManager