diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp index cf2220012fc..801400b3f34 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp @@ -47,6 +47,7 @@ #include #include #include +#include using namespace ProjectExplorer; using namespace Qnx; @@ -55,15 +56,17 @@ using namespace Qnx::Internal; namespace { const char DEVICENAME_FIELD_ID[] = "DeviceName"; -QString defaultDeviceHostIp(IDevice::MachineType type) +enum DeviceListUserRole { - return type == IDevice::Hardware ? QLatin1String("169.254.0.1") : QString(); -} + ItemKindRole = Qt::UserRole, DeviceNameRole, DeviceIpRole, DeviceTypeRole +}; } BlackBerryDeviceConfigurationWizardSetupPage::BlackBerryDeviceConfigurationWizardSetupPage(QWidget *parent) : QWizardPage(parent) , m_ui(new Ui::BlackBerryDeviceConfigurationWizardSetupPage) + , m_deviceListDetector(new BlackBerryDeviceListDetector(this)) + { m_ui->setupUi(this); setTitle(tr("Connection Details")); @@ -76,9 +79,12 @@ BlackBerryDeviceConfigurationWizardSetupPage::BlackBerryDeviceConfigurationWizar debugTokenBrowsePath = QDir::homePath(); m_ui->debugToken->setInitialBrowsePathBackup(debugTokenBrowsePath); + connect(m_ui->deviceListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(onDeviceSelectionChanged())); + connect(m_deviceListDetector, SIGNAL(deviceDetected(QString,QString,BlackBerryDeviceListDetector::DeviceType)), + this, SLOT(onDeviceDetected(QString,QString,BlackBerryDeviceListDetector::DeviceType))); + connect(m_deviceListDetector, SIGNAL(finished()), this, SLOT(onDeviceListDetectorFinished())); connect(m_ui->deviceName, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged())); connect(m_ui->deviceHostIp, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged())); - connect(m_ui->physicalDevice, SIGNAL(toggled(bool)), this, SLOT(handleMachineTypeChanged())); connect(m_ui->physicalDevice, SIGNAL(toggled(bool)), this, SIGNAL(completeChanged())); connect(m_ui->debugToken, SIGNAL(changed(QString)), this, SIGNAL(completeChanged())); connect(m_ui->requestButton, SIGNAL(clicked()), this, SLOT(requestDebugToken())); @@ -94,10 +100,128 @@ BlackBerryDeviceConfigurationWizardSetupPage::~BlackBerryDeviceConfigurationWiza void BlackBerryDeviceConfigurationWizardSetupPage::initializePage() { - m_ui->deviceName->setText(tr("BlackBerry Device")); - m_ui->password->setText(QString()); - m_ui->physicalDevice->setChecked(true); - m_ui->deviceHostIp->setText(defaultDeviceHostIp(machineType())); + m_ui->password->clear(); + refreshDeviceList(); +} + +void BlackBerryDeviceConfigurationWizardSetupPage::refreshDeviceList() +{ + m_ui->deviceListWidget->clear(); + + QListWidgetItem *manual = createDeviceListItem(tr("Specify device manually"), SpecifyManually); + m_ui->deviceListWidget->addItem(manual); + manual->setSelected(true); + + QListWidgetItem *pleaseWait = + createDeviceListItem(tr("Auto-detecting devices - please wait..."), PleaseWait); + m_ui->deviceListWidget->addItem(pleaseWait); + + m_deviceListDetector->detectDeviceList(); +} + +void BlackBerryDeviceConfigurationWizardSetupPage::onDeviceListDetectorFinished() +{ + QListWidgetItem *pleaseWait = findDeviceListItem(PleaseWait); + if (pleaseWait) { + m_ui->deviceListWidget->removeItemWidget(pleaseWait); + delete pleaseWait; + } + + if (!findDeviceListItem(Autodetected)) { + QListWidgetItem *note = createDeviceListItem(tr("No device has been auto-detected."), Note); + note->setToolTip(tr("Device auto-detection is available in BB NDK 10.2. " + "Make sure that your device is in Development Mode.")); + m_ui->deviceListWidget->addItem(note); + } +} + +void BlackBerryDeviceConfigurationWizardSetupPage::onDeviceDetected( + const QString &deviceName, const QString &hostName, + const BlackBerryDeviceListDetector::DeviceType deviceType) +{ + QString displayName(deviceName); + if (displayName != hostName) + displayName.append(QLatin1String(" (")).append(hostName).append(QLatin1String(")")); + + QListWidgetItem *device = createDeviceListItem(displayName, Autodetected); + device->setData(DeviceNameRole, displayName); + device->setData(DeviceIpRole, hostName); + device->setData(DeviceTypeRole, QVariant::fromValue(deviceType)); + QListWidgetItem *pleaseWait = findDeviceListItem(PleaseWait); + int row = pleaseWait ? m_ui->deviceListWidget->row(pleaseWait) : m_ui->deviceListWidget->count(); + m_ui->deviceListWidget->insertItem(row, device); +} + +void BlackBerryDeviceConfigurationWizardSetupPage::onDeviceSelectionChanged() +{ + QList selectedItems = m_ui->deviceListWidget->selectedItems(); + const QListWidgetItem *selected = selectedItems.count() == 1 ? selectedItems[0] : 0; + const ItemKind itemKind = selected ? selected->data(ItemKindRole).value() : Note; + const BlackBerryDeviceListDetector::DeviceType deviceType = selected && itemKind == Autodetected + ? selected->data(DeviceTypeRole).value() + : BlackBerryDeviceListDetector::Device; + switch (itemKind) { + case SpecifyManually: + m_ui->deviceName->setEnabled(true); + m_ui->deviceName->setText(tr("BlackBerry Device")); + m_ui->deviceHostIp->setEnabled(true); + m_ui->deviceHostIp->setText(QLatin1String("169.254.0.1")); + m_ui->physicalDevice->setEnabled(true); + m_ui->physicalDevice->setChecked(true); + m_ui->simulator->setEnabled(true); + m_ui->simulator->setChecked(false); + m_ui->deviceHostIp->selectAll(); + m_ui->deviceHostIp->setFocus(); + break; + case Autodetected: + m_ui->deviceName->setEnabled(true); + m_ui->deviceName->setText(selected->data(DeviceNameRole).toString()); + m_ui->deviceHostIp->setEnabled(false); + m_ui->deviceHostIp->setText(selected->data(DeviceIpRole).toString()); + m_ui->physicalDevice->setEnabled(false); + m_ui->physicalDevice->setChecked(deviceType == BlackBerryDeviceListDetector::Device); + m_ui->simulator->setEnabled(false); + m_ui->simulator->setChecked(deviceType == BlackBerryDeviceListDetector::Simulator); + m_ui->password->setFocus(); + break; + case PleaseWait: + case Note: + m_ui->deviceName->setEnabled(false); + m_ui->deviceName->clear(); + m_ui->deviceHostIp->setEnabled(false); + m_ui->deviceHostIp->clear(); + m_ui->physicalDevice->setEnabled(false); + m_ui->physicalDevice->setChecked(false); + m_ui->simulator->setEnabled(false); + m_ui->simulator->setChecked(false); + break; + } +} + +QListWidgetItem *BlackBerryDeviceConfigurationWizardSetupPage::createDeviceListItem( + const QString &displayName, ItemKind itemKind) const +{ + QListWidgetItem *item = new QListWidgetItem(displayName); + if (itemKind == PleaseWait || itemKind == Note) { + item->setFlags(item->flags() & ~Qt::ItemIsSelectable); + QFont font = item->font(); + font.setItalic(true); + item->setFont(font); + } + item->setData(ItemKindRole, QVariant::fromValue(itemKind)); + return item; +} + +QListWidgetItem *BlackBerryDeviceConfigurationWizardSetupPage::findDeviceListItem(ItemKind itemKind) const +{ + int count = m_ui->deviceListWidget->count(); + for (int i = 0; i < count; ++i) { + QListWidgetItem *item = m_ui->deviceListWidget->item(i); + if (item->data(ItemKindRole).value() == itemKind) { + return item; + } + } + return 0; } bool BlackBerryDeviceConfigurationWizardSetupPage::isComplete() const @@ -135,12 +259,6 @@ IDevice::MachineType BlackBerryDeviceConfigurationWizardSetupPage::machineType() return m_ui->physicalDevice->isChecked() ? IDevice::Hardware : IDevice::Emulator; } -void BlackBerryDeviceConfigurationWizardSetupPage::handleMachineTypeChanged() -{ - if (m_ui->deviceHostIp->text().isEmpty()) - m_ui->deviceHostIp->setText(defaultDeviceHostIp(machineType())); -} - void BlackBerryDeviceConfigurationWizardSetupPage::requestDebugToken() { BlackBerryDebugTokenRequestDialog dialog; diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h index 0fd4106f783..6cf7467f1e9 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h @@ -32,9 +32,12 @@ #ifndef QNX_INTERNAL_BLACKBERRYDEVICECONFIGURATIONWIZARDPAGES_H #define QNX_INTERNAL_BLACKBERRYDEVICECONFIGURATIONWIZARDPAGES_H +#include "blackberrydevicelistdetector.h" + #include #include +#include namespace QSsh { class SshKeyGenerator; @@ -52,6 +55,10 @@ class BlackBerryDeviceConfigurationWizardSetupPage : public QWizardPage { Q_OBJECT public: + enum ItemKind { + SpecifyManually, Autodetected, PleaseWait, Note + }; + explicit BlackBerryDeviceConfigurationWizardSetupPage(QWidget *parent = 0); ~BlackBerryDeviceConfigurationWizardSetupPage(); @@ -63,13 +70,19 @@ public: QString password() const; QString debugToken() const; ProjectExplorer::IDevice::MachineType machineType() const; - private slots: - void handleMachineTypeChanged(); void requestDebugToken(); + void onDeviceSelectionChanged(); + void onDeviceDetected(const QString &deviceName, const QString &hostName, const BlackBerryDeviceListDetector::DeviceType deviceType); + void onDeviceListDetectorFinished(); private: + void refreshDeviceList(); + QListWidgetItem *createDeviceListItem(const QString &displayName, ItemKind itemKind) const; + QListWidgetItem *findDeviceListItem(ItemKind itemKind) const; + Ui::BlackBerryDeviceConfigurationWizardSetupPage *m_ui; + BlackBerryDeviceListDetector *m_deviceListDetector; }; class BlackBerryDeviceConfigurationWizardSshKeyPage : public QWizardPage @@ -109,4 +122,6 @@ public: } // namespace Internal } // namespace Qnx +Q_DECLARE_METATYPE(Qnx::Internal::BlackBerryDeviceConfigurationWizardSetupPage::ItemKind) + #endif // QNX_INTERNAL_BLACKBERRYDEVICECONFIGURATIONWIZARDPAGES_H diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardsetuppage.ui b/src/plugins/qnx/blackberrydeviceconfigurationwizardsetuppage.ui index 4437a2d7d80..9295ae46a07 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizardsetuppage.ui +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardsetuppage.ui @@ -6,126 +6,119 @@ 0 0 - 546 - 170 + 612 + 303 WizardPage - - - - - The name to identify this configuration: - - + + + - - - - - - - Device type: - - - - - - - + + + + - Physical device + Configuration name: - - + + + + + - Simulator + Device type: - - - - - - The device's host name or IP address: - - - - - - + + + + + + Physical device + + + + + + + Simulator + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Device host name or IP address: + + + + - - - - Qt::Horizontal + + + + Device password: - - - 40 - 20 - - - + - - - - - - Device password: - - - - - - + QLineEdit::Password - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Debug token: - - - - - - - - - - + + - Request + Debug token: + + + + + + + 0 + 0 + + + + + + + + Request + + + + + diff --git a/src/plugins/qnx/blackberrydevicelistdetector.cpp b/src/plugins/qnx/blackberrydevicelistdetector.cpp new file mode 100644 index 00000000000..5f69d292767 --- /dev/null +++ b/src/plugins/qnx/blackberrydevicelistdetector.cpp @@ -0,0 +1,92 @@ +/************************************************************************** +** +** Copyright (C) 2011 - 2013 Research In Motion +** +** Contact: Research In Motion (blackberry-qt@qnx.com) +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "blackberrydevicelistdetector.h" + +#include + +namespace Qnx { +namespace Internal { + +BlackBerryDeviceListDetector::BlackBerryDeviceListDetector(QObject *parent) + : QObject(parent) + , m_process(new QProcess(this)) +{ + m_process->setProcessChannelMode(QProcess::MergedChannels); + + connect(m_process, SIGNAL(readyRead()), this, SLOT(processReadyRead())); + connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished())); + connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processFinished())); +} + +void BlackBerryDeviceListDetector::detectDeviceList() +{ + if (m_process->state() != QProcess::NotRunning) + return; + + const QString command = BlackBerryNdkProcess::resolveNdkToolPath(QLatin1String("blackberry-deploy")); + QStringList arguments; + arguments << QLatin1String("-devices"); + + m_process->start(command, arguments, QIODevice::ReadWrite | QIODevice::Unbuffered); +} + +void BlackBerryDeviceListDetector::processReadyRead() +{ + while (m_process->canReadLine()) + processData(readProcessLine()); +} + +void BlackBerryDeviceListDetector::processFinished() +{ + while (!m_process->atEnd()) + processData(readProcessLine()); + emit finished(); +} + +const QString BlackBerryDeviceListDetector::readProcessLine() +{ + QByteArray bytes = m_process->readLine(); + while (bytes.endsWith('\r') || bytes.endsWith('\n')) + bytes.chop(1); + return QString::fromLocal8Bit(bytes); +} + +void BlackBerryDeviceListDetector::processData(const QString &line) +{ + // line format is: deviceName,deviceHostName,deviceType,deviceDisplayName + QStringList list = line.split(QLatin1String(",")); + if (list.count() == 4) { + emit deviceDetected (list[3].isEmpty() ? list[0] : list[3], list[1], QLatin1String("Simulator") == list[2] ? Simulator : Device); + } +} + +} // namespace Internal +} // namespace Qnx diff --git a/src/plugins/qnx/blackberrydevicelistdetector.h b/src/plugins/qnx/blackberrydevicelistdetector.h new file mode 100644 index 00000000000..97e091abaf1 --- /dev/null +++ b/src/plugins/qnx/blackberrydevicelistdetector.h @@ -0,0 +1,78 @@ +/************************************************************************** +** +** Copyright (C) 2011 - 2013 Research In Motion +** +** Contact: Research In Motion (blackberry-qt@qnx.com) +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QNX_INTERNAL_BLACKBERRYDEVICELISTDETECTOR_H +#define QNX_INTERNAL_BLACKBERRYDEVICELISTDETECTOR_H + +#include "blackberryndkprocess.h" + +#include +#include + +namespace Qnx { + +namespace Internal { + +class BlackBerryDeviceListDetector : public QObject +{ + Q_OBJECT +public: + enum DeviceType { + Device, + Simulator + }; + + explicit BlackBerryDeviceListDetector(QObject *parent = 0); + + void detectDeviceList(); + +signals: + void deviceDetected( + const QString &deviceName, const QString &deviceHostName, + const BlackBerryDeviceListDetector::DeviceType deviceType); + void finished(); + +private slots: + void processReadyRead(); + void processFinished(); + +private: + const QString readProcessLine(); + void processData(const QString &line); + + QProcess *m_process; +}; + +} // namespace Internal +} // namespace Qnx + +Q_DECLARE_METATYPE(Qnx::Internal::BlackBerryDeviceListDetector::DeviceType) + +#endif // QNX_INTERNAL_BLACKBERRYDEVICELISTDETECTOR_H diff --git a/src/plugins/qnx/blackberryndkprocess.cpp b/src/plugins/qnx/blackberryndkprocess.cpp index 98f4e9ff30e..50fe534a998 100644 --- a/src/plugins/qnx/blackberryndkprocess.cpp +++ b/src/plugins/qnx/blackberryndkprocess.cpp @@ -53,19 +53,24 @@ BlackBerryNdkProcess::BlackBerryNdkProcess(const QString &command, QObject *pare this, SLOT(processError(QProcess::ProcessError))); } -QString BlackBerryNdkProcess::command() const +const QString BlackBerryNdkProcess::resolveNdkToolPath(const QString &tool) { - QString command; + QString toolPath; QMultiMap qnxEnv = BlackBerryConfigurationManager::instance().defaultQnxEnv(); if (!qnxEnv.isEmpty()) { - command = qnxEnv.value(QLatin1String("QNX_HOST")) - + (QLatin1String("/usr/bin/")) + m_command; + toolPath = qnxEnv.value(QLatin1String("QNX_HOST")) + + (QLatin1String("/usr/bin/")) + tool; if (Utils::HostOsInfo::isWindowsHost()) - command += QLatin1String(".bat"); + toolPath += QLatin1String(".bat"); } - return command; + return toolPath; +} + +QString BlackBerryNdkProcess::command() const +{ + return resolveNdkToolPath(m_command); } void BlackBerryNdkProcess::start(const QStringList &arguments) diff --git a/src/plugins/qnx/blackberryndkprocess.h b/src/plugins/qnx/blackberryndkprocess.h index f6236289652..c3b692f9690 100644 --- a/src/plugins/qnx/blackberryndkprocess.h +++ b/src/plugins/qnx/blackberryndkprocess.h @@ -56,6 +56,13 @@ public: UserStatus }; + /** + * @brief Resolves full path to an NDK cmd-line tool. + * @return a full-path to the NDK cmd-line tool; + * or empty QString when no default QNX configuration is found. + */ + static const QString resolveNdkToolPath(const QString &tool); + signals: void finished(int status); diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro index f138a91270b..3ef3e5924f6 100644 --- a/src/plugins/qnx/qnx.pro +++ b/src/plugins/qnx/qnx.pro @@ -94,7 +94,8 @@ SOURCES += qnxplugin.cpp \ blackberrysetupwizardpages.cpp \ blackberryutils.cpp \ qnxdevicetester.cpp \ - blackberryconfigurationmanager.cpp + blackberryconfigurationmanager.cpp \ + blackberrydevicelistdetector.cpp HEADERS += qnxplugin.h\ qnxconstants.h \ @@ -188,7 +189,8 @@ HEADERS += qnxplugin.h\ blackberrysetupwizardpages.h \ blackberryutils.h \ qnxdevicetester.h \ - blackberryconfigurationmanager.h + blackberryconfigurationmanager.h \ + blackberrydevicelistdetector.h FORMS += \ blackberrydeviceconfigurationwizardsetuppage.ui \ diff --git a/src/plugins/qnx/qnx.qbs b/src/plugins/qnx/qnx.qbs index eb53368cd61..74b81b81f90 100644 --- a/src/plugins/qnx/qnx.qbs +++ b/src/plugins/qnx/qnx.qbs @@ -113,6 +113,8 @@ QtcPlugin { "blackberrydeviceconnection.h", "blackberrydeviceconnectionmanager.cpp", "blackberrydeviceconnectionmanager.h", + "blackberrydevicelistdetector.cpp", + "blackberrydevicelistdetector.h", "blackberrydeviceprocesssupport.h", "blackberrydeviceprocesssupport.cpp", "blackberryqtversion.cpp",