OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qt4projectmanager / qt-s60 / s60deployconfigurationwidget.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
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
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
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.
24 **
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.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "s60deployconfigurationwidget.h"
35 #include "s60deployconfiguration.h"
36 #include "s60devicerunconfiguration.h"
37
38 #include "s60runconfigbluetoothstarter.h"
39 #include <symbianutils/bluetoothlistener_gui.h>
40
41 #include <symbianutils/launcher.h>
42 #include <symbianutils/bluetoothlistener.h>
43 #include <symbianutils/symbiandevicemanager.h>
44
45 #include <utils/detailswidget.h>
46 #include <utils/qtcassert.h>
47 #include <utils/pathchooser.h>
48
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>
62
63 Q_DECLARE_METATYPE(SymbianUtils::SymbianDevice)
64
65 namespace Qt4ProjectManager {
66 namespace Internal {
67
68 const char STARTING_DRIVE_LETTER = 'C';
69 const char LAST_DRIVE_LETTER = 'Z';
70
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")))
81 {
82 }
83
84 S60DeployConfigurationWidget::~S60DeployConfigurationWidget()
85 {
86 }
87
88 void S60DeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc)
89 {
90     m_deployConfiguration = qobject_cast<S60DeployConfiguration *>(dc);
91
92     m_detailsWidget->setState(Utils::DetailsWidget::NoSummary);
93
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);
100
101     QVBoxLayout *detailsBoxLayout = new QVBoxLayout();
102     detailsBoxLayout->setMargin(0);
103     detailsContainer->setLayout(detailsBoxLayout);
104
105     QFormLayout *formLayout = new QFormLayout();
106     formLayout->setMargin(0);
107     detailsBoxLayout->addLayout(formLayout);
108     formLayout->addRow(tr("Installation file:"), m_sisFileLabel);
109
110     // Installation Drive control
111     updateInstallationDrives();
112
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);
119
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);
129
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));
139
140 #ifndef Q_OS_WIN
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);
147 #endif
148
149     formLayout->addRow(tr("Device on serial port:"), serialPortHBoxLayout);
150
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()));
164 }
165
166 void S60DeployConfigurationWidget::updateInstallationDrives()
167 {
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));
171     }
172     int index = QChar::toUpper(static_cast<ushort>(m_deployConfiguration->installationDrive())) - STARTING_DRIVE_LETTER;
173
174     Q_ASSERT(index >= 0 && index <= LAST_DRIVE_LETTER-STARTING_DRIVE_LETTER);
175
176     m_installationDriveCombo->setCurrentIndex(index);
177 }
178
179 void S60DeployConfigurationWidget::silentInstallChanged(int state)
180 {
181     m_deployConfiguration->setSilentInstall(state == Qt::Checked);
182 }
183
184 void S60DeployConfigurationWidget::updateSerialDevices()
185 {
186     m_serialPortsCombo->clear();
187     clearDeviceInfo();
188     const QString previouPortName = m_deployConfiguration->serialPortName();
189     const QList<SymbianUtils::SymbianDevice> devices = SymbianUtils::SymbianDeviceManager::instance()->devices();
190     int newIndex = -1;
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)
195             newIndex = i;
196     }
197     // Set new index: prefer to keep old or set to 0, if available.
198     if (newIndex == -1 && !devices.empty())
199         newIndex = 0;
200     m_serialPortsCombo->setCurrentIndex(newIndex);
201     if (newIndex == -1) {
202         m_deviceInfoButton->setEnabled(false);
203         m_deployConfiguration->setSerialPortName(QString());
204     } else {
205         m_deviceInfoButton->setEnabled(true);
206         const QString newPortName = device(newIndex).portName();
207         m_deployConfiguration->setSerialPortName(newPortName);
208     }
209 }
210
211 SymbianUtils::SymbianDevice S60DeployConfigurationWidget::device(int i) const
212 {
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();
217 }
218
219 SymbianUtils::SymbianDevice S60DeployConfigurationWidget::currentDevice() const
220 {
221     return device(m_serialPortsCombo->currentIndex());
222 }
223
224 void S60DeployConfigurationWidget::updateTargetInformation()
225 {
226     QString package;
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));
232 }
233
234 void S60DeployConfigurationWidget::setInstallationDrive(int index)
235 {
236     m_deployConfiguration->setInstallationDrive(static_cast<char>(STARTING_DRIVE_LETTER + index));
237 }
238
239 void S60DeployConfigurationWidget::setSerialPort(int index)
240 {
241     const SymbianUtils::SymbianDevice d = device(index);
242     m_deployConfiguration->setSerialPortName(d.portName());
243     m_deviceInfoButton->setEnabled(index >= 0);
244     clearDeviceInfo();
245 }
246
247 void S60DeployConfigurationWidget::clearDeviceInfo()
248 {
249     // Restore text & color
250     m_deviceInfoLabel->clear();
251     m_deviceInfoLabel->setStyleSheet(QString());
252 }
253
254 void S60DeployConfigurationWidget::setDeviceInfoLabel(const QString &message, bool isError)
255 {
256     m_deviceInfoLabel->setStyleSheet(isError ?
257                                          QString(QLatin1String("background-color: red;")) :
258                                          QString());
259     m_deviceInfoLabel->setText(message);
260     m_deviceInfoLabel->adjustSize();
261 }
262
263 void S60DeployConfigurationWidget::slotLauncherStateChanged(int s)
264 {
265     switch (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()));
271         mb->open();
272     }
273         break;
274     case trk::Launcher::DeviceDescriptionReceived: // All ok, done
275         setDeviceInfoLabel(m_infoLauncher->deviceDescription());
276         m_deviceInfoButton->setEnabled(true);
277         m_infoLauncher->deleteLater();
278         break;
279     }
280 }
281
282 void S60DeployConfigurationWidget::slotWaitingForTrkClosed()
283 {
284     if (m_infoLauncher && m_infoLauncher->state() == trk::Launcher::WaitingForTrk) {
285         m_infoLauncher->deleteLater();
286         clearDeviceInfo();
287         m_deviceInfoButton->setEnabled(true);
288     }
289 }
290
291 void S60DeployConfigurationWidget::updateDeviceInfo()
292 {
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.
297     QString message;
298     const SymbianUtils::SymbianDevice commDev = currentDevice();
299     m_infoLauncher = trk::Launcher::acquireFromDeviceManager(commDev.portName(), this, &message);
300     if (!m_infoLauncher) {
301         setDeviceInfoLabel(message, true);
302         return;
303     }
304     connect(m_infoLauncher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
305
306     m_infoLauncher->setSerialFrame(commDev.type() == SymbianUtils::SerialPortCommunication);
307     m_infoLauncher->setTrkServerName(commDev.portName());
308
309     // Prompt user
310     const trk::PromptStartCommunicationResult src =
311             S60RunConfigBluetoothStarter::startCommunication(m_infoLauncher->trkDevice(),
312                                                              this, &message);
313     switch (src) {
314     case trk::PromptStartCommunicationConnected:
315         break;
316     case trk::PromptStartCommunicationCanceled:
317         clearDeviceInfo();
318         m_infoLauncher->deleteLater();
319         return;
320     case trk::PromptStartCommunicationError:
321         setDeviceInfoLabel(message, true);
322         m_infoLauncher->deleteLater();
323         return;
324     };
325     if (!m_infoLauncher->startServer(&message)) {
326         setDeviceInfoLabel(message, true);
327         m_infoLauncher->deleteLater();
328         return;
329     }
330     // Wait for either timeout or results
331     m_deviceInfoButton->setEnabled(false);
332     return;
333 }
334
335 } // namespace Internal
336 } // namespace Qt4ProjectManager