Commit 59a578d4 authored by El Mehdi Fekari's avatar El Mehdi Fekari Committed by Mehdi Fekari

Qnx: Install/uninstall NDK targets

Basic implementation of an install/uninstall targets utility.

Note: This does not support 10.1 NKDs.

Change-Id: I3bb29ef467dd24a121ee59e11abb2237dcff696a
Reviewed-by: Nicolas Arnaud-Cormos's avatarNicolas Arnaud-Cormos <nicolas@kdab.com>
parent 668a50b7
......@@ -65,6 +65,8 @@ public:
QMultiMap<QString, QString> defaultQnxEnv();
void loadAutoDetectedConfigurations();
public slots:
void loadSettings();
void saveSettings();
......@@ -78,7 +80,6 @@ private:
QList<BlackBerryConfiguration*> m_configs;
void loadManualConfigurations();
void loadAutoDetectedConfigurations();
void saveManualConfigurations();
void saveActiveConfigurationNdkEnvPath();
void clearInvalidConfigurations();
......
/**************************************************************************
**
** Copyright (C) 2013 BlackBerry Limited. All rights reserved
**
** Contact: BlackBerry (qt@blackberry.com)
** Contact: KDAB (info@kdab.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 "blackberryinstallwizard.h"
#include "blackberryinstallwizardpages.h"
#include <QAbstractButton>
#include <QMessageBox>
using namespace Qnx;
using namespace Qnx::Internal;
BlackBerryInstallWizard::BlackBerryInstallWizard(BlackBerryInstallerDataHandler::Mode mode,
const QString& version,
QWidget *parent)
: QWizard(parent)
, m_ndkPage(0)
, m_targetPage(0)
{
setWindowTitle(tr("BlackBerry NDK Installation Wizard"));
m_data.mode = mode;
m_data.version = version;
if (m_data.mode != BlackBerryInstallerDataHandler::UninstallMode) {
m_optionPage = new BlackBerryInstallWizardOptionPage(m_data, this);
m_ndkPage = new BlackBerryInstallWizardNdkPage(m_data, this);
m_targetPage = new BlackBerryInstallWizardTargetPage(m_data, this);
setPage(OptionPage, m_optionPage);
setPage(NdkPageId, m_ndkPage);
setPage(TargetPageId, m_targetPage);
}
m_processPage = new BlackBerryInstallWizardProcessPage(m_data, this);
m_finalPage = new BlackBerryInstallWizardFinalPage(m_data, this);
connect(m_finalPage, SIGNAL(done()), this, SIGNAL(processFinished()));
disconnect(button(CancelButton), SIGNAL(clicked()), this, SLOT(reject()));
connect(button(CancelButton), SIGNAL(clicked()), this, SLOT(handleProcessCancelled()));
setPage(ProcessPageId, m_processPage);
setPage(FinalPageId, m_finalPage);
m_finalPage->setCommitPage(true);
setOption(DisabledBackButtonOnLastPage, true);
}
void BlackBerryInstallWizard::handleProcessCancelled()
{
if ((m_targetPage && m_targetPage->isProcessRunning())
|| m_processPage->isProcessRunning()) {
const QMessageBox::StandardButton answer = QMessageBox::question(this, tr("Confirmation"),
tr("Are you sure you want to cancel?"),
QMessageBox::Yes | QMessageBox::No);
if (answer == QMessageBox::No)
return;
}
reject();
}
/**************************************************************************
**
** Copyright (C) 2013 BlackBerry Limited. All rights reserved
**
** Contact: BlackBerry (qt@blackberry.com)
** Contact: KDAB (info@kdab.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_BLACKBERRYDEVICECONFIGURATIONWIZARD_H
#define QNX_INTERNAL_BLACKBERRYDEVICECONFIGURATIONWIZARD_H
#include <QProcess>
#include <QWizard>
namespace Qnx {
namespace Internal {
class BlackBerryInstallWizardOptionPage;
class BlackBerryInstallWizardNdkPage;
class BlackBerryInstallWizardTargetPage;
class BlackBerryInstallWizardProcessPage;
class BlackBerryInstallWizardFinalPage;
class BlackBerryInstallerDataHandler {
public:
enum Mode {
InstallMode,
UninstallMode,
ManuallMode
};
QString ndkPath;
QString target;
QString version;
int exitCode;
QProcess::ExitStatus exitStatus;
Mode mode;
};
class BlackBerryInstallWizard : public QWizard
{
Q_OBJECT
public:
enum PageId {
OptionPage,
NdkPageId,
TargetPageId,
ProcessPageId,
FinalPageId
};
explicit BlackBerryInstallWizard(BlackBerryInstallerDataHandler::Mode mode = BlackBerryInstallerDataHandler::InstallMode,
const QString& version = QString(),
QWidget *parent = 0);
signals:
void processFinished();
private slots:
void handleProcessCancelled();
private:
BlackBerryInstallWizardOptionPage *m_optionPage;
BlackBerryInstallWizardNdkPage *m_ndkPage;
BlackBerryInstallWizardTargetPage *m_targetPage;
BlackBerryInstallWizardProcessPage *m_processPage;
BlackBerryInstallWizardFinalPage *m_finalPage;
BlackBerryInstallerDataHandler m_data;
};
} // namespace Internal
} // namespace Qnx
#endif // QNX_INTERNAL_BLACKBERRYDEVICECONFIGURATIONWIZARD_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Qnx::Internal::BlackBerryInstallWizardNdkPage</class>
<widget class="QWidget" name="Qnx::Internal::BlackBerryInstallWizardNdkPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Select NDK Path</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="ndkPathListWidget"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
/**************************************************************************
**
** Copyright (C) 2013 BlackBerry Limited. All rights reserved
**
** Contact: BlackBerry (qt@blackberry.com)
** Contact: KDAB (info@kdab.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 "blackberryinstallwizardpages.h"
#include "blackberryconfigurationmanager.h"
#include "blackberryconfiguration.h"
#include "ui_blackberryinstallwizardtargetpage.h"
#include "ui_blackberryinstallwizardprocesspage.h"
#include "ui_blackberryinstallwizardndkpage.h"
#include "qnxutils.h"
#include <utils/synchronousprocess.h>
#include <utils/pathchooser.h>
#include <QProcess>
#include <QTreeWidgetItem>
#include <QFileInfo>
#include <QDir>
#include <QMessageBox>
#include <QLayout>
#include <QRadioButton>
namespace Qnx {
namespace Internal {
namespace {
const QLatin1String targetKeyWord("Native SDK");
}
NdkPathChooser::NdkPathChooser(Mode mode, QWidget *parent)
: Utils::PathChooser(parent)
, m_mode(mode)
{
if (m_mode == NdkPathChooser::InstallMode)
setExpectedKind(Utils::PathChooser::Directory);
else
setExpectedKind(Utils::PathChooser::File);
}
bool NdkPathChooser::validatePath(const QString &path, QString *errorMessage)
{
bool result = PathChooser::validatePath(path, errorMessage);
if (!result)
return false;
if (m_mode == NdkPathChooser::InstallMode)
return !(QnxUtils::sdkInstallerPath(path).isEmpty());
QFileInfo fi(path);
return (fi.suffix() == QLatin1String("sh") || fi.suffix() == QLatin1String("bat"));
}
//------------------------------------------------------------------
BlackBerryInstallWizardOptionPage::BlackBerryInstallWizardOptionPage(BlackBerryInstallerDataHandler &data,
QWidget *parent)
: QWizardPage(parent)
, m_layout(new QVBoxLayout(this))
, m_installButton(new QRadioButton)
, m_addButton(new QRadioButton)
, m_envFileChooser(new NdkPathChooser(NdkPathChooser::ManualMode))
, m_data(data)
{
connect(m_addButton, SIGNAL(toggled(bool)), this, SLOT(handleOptionChanged()));
connect(m_envFileChooser, SIGNAL(pathChanged(QString)), this, SLOT(handlePathChanged(QString)));
}
void BlackBerryInstallWizardOptionPage::initializePage()
{
m_installButton->setText(tr("Install a new target"));
m_addButton->setText(tr("Add an existing target"));
if (m_data.mode == BlackBerryInstallerDataHandler::ManuallMode)
m_addButton->setChecked(true);
else
m_installButton->setChecked(true);
m_envFileChooser->setEnabled(m_addButton->isChecked());
m_layout->addWidget(m_installButton);
m_layout->addWidget(m_addButton);
m_layout->addWidget(m_envFileChooser);
}
bool BlackBerryInstallWizardOptionPage::isComplete() const
{
return (m_installButton->isChecked()
|| (m_addButton->isChecked() && m_envFileChooser->isValid()));
}
int BlackBerryInstallWizardOptionPage::nextId() const
{
if (m_addButton->isChecked())
return BlackBerryInstallWizard::FinalPageId;
return BlackBerryInstallWizard::NdkPageId;
}
void BlackBerryInstallWizardOptionPage::handleOptionChanged()
{
if (m_addButton->isChecked())
m_data.mode = BlackBerryInstallerDataHandler::ManuallMode;
else
m_data.mode = BlackBerryInstallerDataHandler::InstallMode;
m_envFileChooser->setEnabled(m_addButton->isChecked());
emit completeChanged();
}
void BlackBerryInstallWizardOptionPage::handlePathChanged(const QString &envFilePath)
{
if (m_envFileChooser->isValid())
m_data.ndkPath = envFilePath;
emit completeChanged();
}
//------------------------------------------------------------------
BlackBerryInstallWizardNdkPage::BlackBerryInstallWizardNdkPage(BlackBerryInstallerDataHandler &data, QWidget *parent)
: QWizardPage(parent)
, m_ui(new Ui_BlackBerryInstallWizardNdkPage)
, m_data(data)
, m_ndkPathChooser(new NdkPathChooser(NdkPathChooser::InstallMode))
, m_manual(new QListWidgetItem)
, m_validNdkPath(false)
{
m_ui->setupUi(this);
m_ui->verticalLayout->addWidget(m_ndkPathChooser);
connect(m_ui->ndkPathListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(setNdkPath()));
connect(m_ndkPathChooser, SIGNAL(pathChanged(QString)), this, SLOT(setManualNdkPath()));
}
BlackBerryInstallWizardNdkPage::~BlackBerryInstallWizardNdkPage()
{
delete m_ui;
}
void BlackBerryInstallWizardNdkPage::initializePage()
{
m_manual->setText(tr("Specify 10.2 NDK path manually"));
m_ui->ndkPathListWidget->addItem(m_manual);
m_manual->setSelected(true);
QFont font;
font.setItalic(true);
m_manual->setFont(font);
foreach (const NdkInstallInformation &ndk, QnxUtils::installedNdks()) {
bool found = false;
for (int i = 0; i < m_ui->ndkPathListWidget->count(); i++) {
QListWidgetItem* item = m_ui->ndkPathListWidget->item(i);
if (item->text() == ndk.path) {
found = true;
break;
}
}
if (found)
continue;
if (!QnxUtils::sdkInstallerPath(ndk.path).isEmpty()) {
QListWidgetItem *ndkItem = new QListWidgetItem(m_ui->ndkPathListWidget);
ndkItem->setText(ndk.path);
}
}
}
void BlackBerryInstallWizardNdkPage::setNdkPath()
{
if (m_ui->ndkPathListWidget->selectedItems().isEmpty())
return;
m_ndkPathChooser->setEnabled(m_manual->isSelected());
QString selected = m_ui->ndkPathListWidget->selectedItems().first()->text();
if (!QnxUtils::sdkInstallerPath(selected).isEmpty()) {
m_validNdkPath = true;
m_data.ndkPath = selected;
} else {
m_validNdkPath = false;
}
emit completeChanged();
}
void BlackBerryInstallWizardNdkPage::setManualNdkPath()
{
if (m_ndkPathChooser->isValid()) {
m_validNdkPath = true;
m_data.ndkPath = m_ndkPathChooser->path();
} else {
m_validNdkPath = false;
}
emit completeChanged();
}
bool BlackBerryInstallWizardNdkPage::isComplete() const
{
return m_validNdkPath;
}
//------------------------------------------------------------------
BlackBerryInstallWizardTargetPage::BlackBerryInstallWizardTargetPage(BlackBerryInstallerDataHandler &data,
QWidget *parent)
: QWizardPage(parent)
, m_data(data)
, m_ui(new Ui_BlackBerryInstallWizardTargetPage)
, m_isTargetValid(false)
, m_targetListProcess(new QProcess(this))
{
m_ui->setupUi(this);
connect(m_targetListProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(targetsListProcessFinished()));
connect(m_ui->targetsTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(setTarget()));
}
BlackBerryInstallWizardTargetPage::~BlackBerryInstallWizardTargetPage()
{
Utils::SynchronousProcess::stopProcess(*m_targetListProcess);
delete m_ui;
}
void BlackBerryInstallWizardTargetPage::initializePage()
{
// process may be running if going back and forth
if (m_targetListProcess->state() == QProcess::Running) {
disconnect(m_targetListProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(targetsListProcessFinished()));
Utils::SynchronousProcess::stopProcess(*m_targetListProcess);
connect(m_targetListProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(targetsListProcessFinished()));
}
updateAvailableTargetsList();
}
bool BlackBerryInstallWizardTargetPage::isComplete() const
{
return m_isTargetValid;
}
bool BlackBerryInstallWizardTargetPage::isProcessRunning() const
{
return (m_targetListProcess->state() == QProcess::Running);
}
void BlackBerryInstallWizardTargetPage::targetsListProcessFinished()
{
initTargetsTreeWidget();
QString output = Utils::SynchronousProcess::normalizeNewlines(QString::fromLatin1(m_targetListProcess->readAll()));
QList<QString> targetList = output.split(QLatin1Char('\n'));
m_ui->targetsTreeWidget->clear();
foreach (const QString &target, targetList) {
if (!target.isEmpty() && target.contains(targetKeyWord)) {
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui->targetsTreeWidget);
QStringList res = target.split(QLatin1Char('-'));
if (res.count() > 1) {
item->setText(0, res.at(0));
item->setText(1, res.at(1));
}
}
}
m_ui->targetsTreeWidget->sortByColumn(0, Qt::DescendingOrder);
}
void BlackBerryInstallWizardTargetPage::setTarget()
{
if (m_ui->targetsTreeWidget->selectedItems().isEmpty())
return;
QString version = m_ui->targetsTreeWidget->selectedItems().first()->text(0);
QString target = m_ui->targetsTreeWidget->selectedItems().first()->text(1);
if (target.contains(targetKeyWord)) {
m_data.target = target;
m_data.version = version;
m_isTargetValid = true;
} else {
m_isTargetValid = false;
}
emit completeChanged();
}
void BlackBerryInstallWizardTargetPage::initTargetsTreeWidget()
{
m_ui->targetsTreeWidget->clear();
m_ui->targetsTreeWidget->setHeaderHidden(false);
m_ui->targetsTreeWidget->header()->setResizeMode(QHeaderView::ResizeToContents);
m_ui->targetsTreeWidget->setHeaderItem(new QTreeWidgetItem(QStringList() << tr("Version") << tr("Target")));
m_ui->targetsTreeWidget->setTextElideMode(Qt::ElideNone);
m_ui->targetsTreeWidget->setColumnCount(2);
}
void BlackBerryInstallWizardTargetPage::updateAvailableTargetsList()
{
m_ui->targetsTreeWidget->clear();
m_ui->targetsTreeWidget->setHeaderHidden(true);
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui->targetsTreeWidget);
item->setText(0, tr("Querying available targets. Please wait.."));
QFont font;
font.setItalic(true);
item->setFont(0, font);
QString qdeProcess = QnxUtils::qdeInstallProcess(m_data.ndkPath, QLatin1String(" --list"));
QTC_ASSERT(!qdeProcess.isEmpty(), return);
m_targetListProcess->start(qdeProcess);
}
//------------------------------------------------------------------
BlackBerryInstallWizardProcessPage::BlackBerryInstallWizardProcessPage(BlackBerryInstallerDataHandler &data,
QWidget *parent)
: QWizardPage(parent)
, m_ui(new Ui_BlackBerryInstallWizardProcessPage)
, m_data(data)
, m_targetProcess(new QProcess(this))
{
m_ui->setupUi(this);
connect(m_targetProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(handleProcessFinished(int, QProcess::ExitStatus)));
}
BlackBerryInstallWizardProcessPage::~BlackBerryInstallWizardProcessPage()