1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "s60deployconfigurationwidget.h"
35 #include "s60deployconfiguration.h"
36 #include "s60devicerunconfiguration.h"
38 #include "s60runconfigbluetoothstarter.h"
39 #include <symbianutils/bluetoothlistener_gui.h>
41 #include <symbianutils/launcher.h>
42 #include <symbianutils/bluetoothlistener.h>
43 #include <symbianutils/symbiandevicemanager.h>
45 #include <utils/detailswidget.h>
46 #include <utils/qtcassert.h>
47 #include <utils/pathchooser.h>
49 #include <QtCore/QDir>
50 #include <QtGui/QLabel>
51 #include <QtGui/QLineEdit>
52 #include <QtGui/QComboBox>
53 #include <QtGui/QVBoxLayout>
54 #include <QtGui/QHBoxLayout>
55 #include <QtGui/QFormLayout>
56 #include <QtGui/QToolButton>
57 #include <QtGui/QStyle>
58 #include <QtGui/QApplication>
59 #include <QtGui/QSpacerItem>
60 #include <QtGui/QMessageBox>
61 #include <QtGui/QCheckBox>
63 Q_DECLARE_METATYPE(SymbianUtils::SymbianDevice)
65 namespace Qt4ProjectManager {
68 const char STARTING_DRIVE_LETTER = 'C';
69 const char LAST_DRIVE_LETTER = 'Z';
71 S60DeployConfigurationWidget::S60DeployConfigurationWidget(QWidget *parent)
72 : ProjectExplorer::DeployConfigurationWidget(parent),
73 m_detailsWidget(new Utils::DetailsWidget),
74 m_serialPortsCombo(new QComboBox),
75 m_sisFileLabel(new QLabel),
76 m_deviceInfoButton(new QToolButton),
77 m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))),
78 m_deviceInfoLabel(new QLabel),
79 m_installationDriveCombo(new QComboBox()),
80 m_silentInstallCheckBox(new QCheckBox(tr("Silent installation")))
84 S60DeployConfigurationWidget::~S60DeployConfigurationWidget()
88 void S60DeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc)
90 m_deployConfiguration = qobject_cast<S60DeployConfiguration *>(dc);
92 m_detailsWidget->setState(Utils::DetailsWidget::NoSummary);
94 QVBoxLayout *mainBoxLayout = new QVBoxLayout();
95 mainBoxLayout->setMargin(0);
96 setLayout(mainBoxLayout);
97 mainBoxLayout->addWidget(m_detailsWidget);
98 QWidget *detailsContainer = new QWidget;
99 m_detailsWidget->setWidget(detailsContainer);
101 QVBoxLayout *detailsBoxLayout = new QVBoxLayout();
102 detailsBoxLayout->setMargin(0);
103 detailsContainer->setLayout(detailsBoxLayout);
105 QFormLayout *formLayout = new QFormLayout();
106 formLayout->setMargin(0);
107 detailsBoxLayout->addLayout(formLayout);
108 formLayout->addRow(tr("Installation file:"), m_sisFileLabel);
110 // Installation Drive control
111 updateInstallationDrives();
113 QHBoxLayout *installationBoxLayout = new QHBoxLayout();
114 m_installationDriveCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
115 connect(m_installationDriveCombo, SIGNAL(activated(int)), this, SLOT(setInstallationDrive(int)));
116 QHBoxLayout *installationDriveHBoxLayout = new QHBoxLayout;
117 installationDriveHBoxLayout->addWidget(m_installationDriveCombo);
118 installationBoxLayout->addLayout(installationDriveHBoxLayout);
120 // Non-silent installs are a fallback if one wants to override missing dependencies.
121 m_silentInstallCheckBox->setChecked(m_deployConfiguration->silentInstall());
122 m_silentInstallCheckBox->setToolTip(tr("Silent installation is an installation mode "
123 "that does not require user's intervention. "
124 "In case it fails the non silent installation is launched."));
125 connect(m_silentInstallCheckBox, SIGNAL(stateChanged(int)), this, SLOT(silentInstallChanged(int)));
126 installationBoxLayout->addWidget(m_silentInstallCheckBox);
127 installationBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
128 formLayout->addRow(tr("Installation drive:"), installationBoxLayout);
130 updateSerialDevices();
131 connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(updated()),
132 this, SLOT(updateSerialDevices()));
133 // Serial devices control
134 m_serialPortsCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
135 connect(m_serialPortsCombo, SIGNAL(activated(int)), this, SLOT(setSerialPort(int)));
136 QHBoxLayout *serialPortHBoxLayout = new QHBoxLayout;
137 serialPortHBoxLayout->addWidget(m_serialPortsCombo);
138 serialPortHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
141 // Update device list: on Linux only.
142 QToolButton *updateSerialDevicesButton(new QToolButton);
143 updateSerialDevicesButton->setIcon(qApp->style()->standardIcon(QStyle::SP_BrowserReload));
144 connect(updateSerialDevicesButton, SIGNAL(clicked()),
145 SymbianUtils::SymbianDeviceManager::instance(), SLOT(update()));
146 serialPortHBoxLayout->addWidget(updateSerialDevicesButton);
149 formLayout->addRow(tr("Device on serial port:"), serialPortHBoxLayout);
151 // Device Info with button. Widgets are enabled in above call to updateSerialDevices()
152 QHBoxLayout *infoHBoxLayout = new QHBoxLayout;
153 m_deviceInfoLabel->setWordWrap(true);
154 m_deviceInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
155 infoHBoxLayout->addWidget(m_deviceInfoLabel);
156 infoHBoxLayout->addWidget(m_deviceInfoButton);
157 m_deviceInfoButton->setIcon(qApp->style()->standardIcon(QStyle::SP_MessageBoxInformation));
158 m_deviceInfoButton->setToolTip(tr("Queries the device for information"));
159 connect(m_deviceInfoButton, SIGNAL(clicked()), this, SLOT(updateDeviceInfo()));
160 formLayout->addRow(m_deviceInfoDescriptionLabel, infoHBoxLayout);
161 updateTargetInformation();
162 connect(m_deployConfiguration, SIGNAL(targetInformationChanged()),
163 this, SLOT(updateTargetInformation()));
166 void S60DeployConfigurationWidget::updateInstallationDrives()
168 m_installationDriveCombo->clear();
169 for (int i = STARTING_DRIVE_LETTER; i <= LAST_DRIVE_LETTER; ++i) {
170 m_installationDriveCombo->addItem(QString("%1:").arg(static_cast<char>(i)), qVariantFromValue(i));
172 int index = QChar::toUpper(static_cast<ushort>(m_deployConfiguration->installationDrive())) - STARTING_DRIVE_LETTER;
174 Q_ASSERT(index >= 0 && index <= LAST_DRIVE_LETTER-STARTING_DRIVE_LETTER);
176 m_installationDriveCombo->setCurrentIndex(index);
179 void S60DeployConfigurationWidget::silentInstallChanged(int state)
181 m_deployConfiguration->setSilentInstall(state == Qt::Checked);
184 void S60DeployConfigurationWidget::updateSerialDevices()
186 m_serialPortsCombo->clear();
188 const QString previouPortName = m_deployConfiguration->serialPortName();
189 const QList<SymbianUtils::SymbianDevice> devices = SymbianUtils::SymbianDeviceManager::instance()->devices();
191 for (int i = 0; i < devices.size(); ++i) {
192 const SymbianUtils::SymbianDevice &device = devices.at(i);
193 m_serialPortsCombo->addItem(device.friendlyName(), qVariantFromValue(device));
194 if (device.portName() == previouPortName)
197 // Set new index: prefer to keep old or set to 0, if available.
198 if (newIndex == -1 && !devices.empty())
200 m_serialPortsCombo->setCurrentIndex(newIndex);
201 if (newIndex == -1) {
202 m_deviceInfoButton->setEnabled(false);
203 m_deployConfiguration->setSerialPortName(QString());
205 m_deviceInfoButton->setEnabled(true);
206 const QString newPortName = device(newIndex).portName();
207 m_deployConfiguration->setSerialPortName(newPortName);
211 SymbianUtils::SymbianDevice S60DeployConfigurationWidget::device(int i) const
213 const QVariant data = m_serialPortsCombo->itemData(i);
214 if (data.isValid() && qVariantCanConvert<SymbianUtils::SymbianDevice>(data))
215 return qVariantValue<SymbianUtils::SymbianDevice>(data);
216 return SymbianUtils::SymbianDevice();
219 SymbianUtils::SymbianDevice S60DeployConfigurationWidget::currentDevice() const
221 return device(m_serialPortsCombo->currentIndex());
224 void S60DeployConfigurationWidget::updateTargetInformation()
227 for (int i = 0; i < m_deployConfiguration->signedPackages().count(); ++i)
228 package += m_deployConfiguration->signedPackages()[i] + QLatin1String("\n");
229 if (!package.isEmpty())
230 package.remove(package.length()-1, 1);
231 m_sisFileLabel->setText(QDir::toNativeSeparators(package));
234 void S60DeployConfigurationWidget::setInstallationDrive(int index)
236 m_deployConfiguration->setInstallationDrive(static_cast<char>(STARTING_DRIVE_LETTER + index));
239 void S60DeployConfigurationWidget::setSerialPort(int index)
241 const SymbianUtils::SymbianDevice d = device(index);
242 m_deployConfiguration->setSerialPortName(d.portName());
243 m_deviceInfoButton->setEnabled(index >= 0);
247 void S60DeployConfigurationWidget::clearDeviceInfo()
249 // Restore text & color
250 m_deviceInfoLabel->clear();
251 m_deviceInfoLabel->setStyleSheet(QString());
254 void S60DeployConfigurationWidget::setDeviceInfoLabel(const QString &message, bool isError)
256 m_deviceInfoLabel->setStyleSheet(isError ?
257 QString(QLatin1String("background-color: red;")) :
259 m_deviceInfoLabel->setText(message);
260 m_deviceInfoLabel->adjustSize();
263 void S60DeployConfigurationWidget::slotLauncherStateChanged(int s)
266 case trk::Launcher::WaitingForTrk: {
267 // Entered trk wait state..open message box
268 QMessageBox *mb = S60DeviceRunControl::createTrkWaitingMessageBox(m_infoLauncher->trkServerName(), this);
269 connect(m_infoLauncher, SIGNAL(stateChanged(int)), mb, SLOT(close()));
270 connect(mb, SIGNAL(finished(int)), this, SLOT(slotWaitingForTrkClosed()));
274 case trk::Launcher::DeviceDescriptionReceived: // All ok, done
275 setDeviceInfoLabel(m_infoLauncher->deviceDescription());
276 m_deviceInfoButton->setEnabled(true);
277 m_infoLauncher->deleteLater();
282 void S60DeployConfigurationWidget::slotWaitingForTrkClosed()
284 if (m_infoLauncher && m_infoLauncher->state() == trk::Launcher::WaitingForTrk) {
285 m_infoLauncher->deleteLater();
287 m_deviceInfoButton->setEnabled(true);
291 void S60DeployConfigurationWidget::updateDeviceInfo()
293 QTC_ASSERT(!m_infoLauncher, return)
294 setDeviceInfoLabel(tr("Connecting..."));
295 // Do a launcher run with the ping protocol. Prompt to connect and
296 // go asynchronous afterwards to pop up launch trk box if a timeout occurs.
298 const SymbianUtils::SymbianDevice commDev = currentDevice();
299 m_infoLauncher = trk::Launcher::acquireFromDeviceManager(commDev.portName(), this, &message);
300 if (!m_infoLauncher) {
301 setDeviceInfoLabel(message, true);
304 connect(m_infoLauncher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
306 m_infoLauncher->setSerialFrame(commDev.type() == SymbianUtils::SerialPortCommunication);
307 m_infoLauncher->setTrkServerName(commDev.portName());
310 const trk::PromptStartCommunicationResult src =
311 S60RunConfigBluetoothStarter::startCommunication(m_infoLauncher->trkDevice(),
314 case trk::PromptStartCommunicationConnected:
316 case trk::PromptStartCommunicationCanceled:
318 m_infoLauncher->deleteLater();
320 case trk::PromptStartCommunicationError:
321 setDeviceInfoLabel(message, true);
322 m_infoLauncher->deleteLater();
325 if (!m_infoLauncher->startServer(&message)) {
326 setDeviceInfoLabel(message, true);
327 m_infoLauncher->deleteLater();
330 // Wait for either timeout or results
331 m_deviceInfoButton->setEnabled(false);
335 } // namespace Internal
336 } // namespace Qt4ProjectManager