From cbb6db1232e454dcce83c73a68ce1c970e9b36c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tobias=20N=C3=A4tterlund?= <tobias.naetterlund.qnx@kdab.com>
Date: Thu, 30 May 2013 14:31:41 +0200
Subject: [PATCH] ProjectExplorer/QNX: Add build step for checking device
 existence

This introduces a DeviceCheckBuildStep which any DeployConfigurationFactory
could use to insert a step to check whether a device is set up for the
current kit or not. Currently only used in the QNX deploy configuration.

If there is no device known to a QNX kit, ask the user
to add one. Launch the appropriate device wizard if the user agrees
to add a device.

Change-Id: I42db995f50890e2a2dd7aacc24a0049cdd6a6fee
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
---
 .../devicesupport/devicecheckbuildstep.cpp    | 109 ++++++++++++++++++
 .../devicesupport/devicecheckbuildstep.h      |  61 ++++++++++
 .../projectexplorer/projectexplorer.pro       |   2 +
 .../projectexplorer/projectexplorer.qbs       |   2 +
 .../qnx/qnxdeployconfigurationfactory.cpp     |   5 +-
 src/plugins/qnx/qnxdeploystepfactory.cpp      |  22 +++-
 6 files changed, 197 insertions(+), 4 deletions(-)
 create mode 100644 src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.cpp
 create mode 100644 src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.h

diff --git a/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.cpp b/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.cpp
new file mode 100644
index 00000000000..1c9554755ec
--- /dev/null
+++ b/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.cpp
@@ -0,0 +1,109 @@
+/**************************************************************************
+**
+** Copyright (C) 2011 - 2013 Research In Motion
+**
+** Contact: Research In Motion (blackberry-qt@qnx.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 "devicecheckbuildstep.h"
+
+#include "../kitinformation.h"
+#include "../target.h"
+#include "devicemanager.h"
+#include "idevice.h"
+#include "idevicefactory.h"
+
+#include <QMessageBox>
+
+using namespace ProjectExplorer;
+
+DeviceCheckBuildStep::DeviceCheckBuildStep(BuildStepList *bsl, Core::Id id)
+    : BuildStep(bsl, id)
+{
+    setDefaultDisplayName(stepDisplayName());
+}
+
+DeviceCheckBuildStep::DeviceCheckBuildStep(BuildStepList *bsl, DeviceCheckBuildStep *bs)
+    : BuildStep(bsl, bs)
+{
+    setDefaultDisplayName(stepDisplayName());
+}
+
+bool DeviceCheckBuildStep::init()
+{
+    IDevice::ConstPtr device = DeviceKitInformation::device(target()->kit());
+    if (!device) {
+        Core::Id deviceTypeId = DeviceTypeKitInformation::deviceTypeId(target()->kit());
+        IDeviceFactory *factory = IDeviceFactory::find(deviceTypeId);
+        if (!factory || !factory->canCreate()) {
+            emit addOutput(tr("No device configured."), BuildStep::ErrorMessageOutput);
+            return false;
+        }
+
+        QMessageBox msgBox(QMessageBox::Question, tr("Set Up Device"),
+                              tr("There is no device set up for this kit. Do you want to add a device?"),
+                              QMessageBox::Yes|QMessageBox::No);
+        msgBox.setDefaultButton(QMessageBox::Yes);
+        if (msgBox.exec() == QMessageBox::No) {
+            emit addOutput(tr("No device configured."), BuildStep::ErrorMessageOutput);
+            return false;
+        }
+
+        IDevice::Ptr newDevice = factory->create(deviceTypeId);
+        if (newDevice.isNull()) {
+            emit addOutput(tr("No device configured."), BuildStep::ErrorMessageOutput);
+            return false;
+        }
+
+        DeviceManager *dm = DeviceManager::instance();
+        dm->addDevice(newDevice);
+
+        DeviceKitInformation::setDevice(target()->kit(), newDevice);
+    }
+
+    return true;
+}
+
+void DeviceCheckBuildStep::run(QFutureInterface<bool> &fi)
+{
+    fi.reportResult(true);
+}
+
+BuildStepConfigWidget *DeviceCheckBuildStep::createConfigWidget()
+{
+    return new SimpleBuildStepConfigWidget(this);
+}
+
+Core::Id DeviceCheckBuildStep::stepId()
+{
+    return Core::Id("ProjectExplorer.DeviceCheckBuildStep");
+}
+
+QString DeviceCheckBuildStep::stepDisplayName()
+{
+    return tr("Check for a configured device");
+}
diff --git a/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.h b/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.h
new file mode 100644
index 00000000000..96f982e6496
--- /dev/null
+++ b/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+**
+** Copyright (C) 2011 - 2013 Research In Motion
+**
+** Contact: Research In Motion (blackberry-qt@qnx.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 PROJECTEXPLORER_DEVICECHECKBUILDSTEP_H
+#define PROJECTEXPLORER_DEVICECHECKBUILDSTEP_H
+
+#include "../buildstep.h"
+#include "../projectexplorer_export.h"
+
+namespace ProjectExplorer {
+
+class BuildStepList;
+
+class PROJECTEXPLORER_EXPORT DeviceCheckBuildStep : public BuildStep
+{
+    Q_OBJECT
+public:
+    DeviceCheckBuildStep(BuildStepList *bsl, Core::Id id);
+    DeviceCheckBuildStep(ProjectExplorer::BuildStepList *bsl, DeviceCheckBuildStep *bs);
+
+    bool init();
+
+    void run(QFutureInterface<bool> &fi);
+
+    BuildStepConfigWidget *createConfigWidget();
+
+    static Core::Id stepId();
+    static QString stepDisplayName();
+};
+
+} // namespace ProjectExplorer
+
+#endif // PROJECTEXPLORER_DEVICECHECKBUILDSTEP_H
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index 8c381ecc48d..fb713469583 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -113,6 +113,7 @@ HEADERS += projectexplorer.h \
     devicesupport/desktopdevicefactory.h \
     devicesupport/idevicewidget.h \
     devicesupport/idevicefactory.h \
+    devicesupport/devicecheckbuildstep.h \
     devicesupport/devicemanager.h \
     devicesupport/devicemanagermodel.h \
     devicesupport/devicefactoryselectiondialog.h \
@@ -228,6 +229,7 @@ SOURCES += projectexplorer.cpp \
     devicesupport/desktopdevice.cpp \
     devicesupport/desktopdevicefactory.cpp \
     devicesupport/idevicefactory.cpp \
+    devicesupport/devicecheckbuildstep.cpp \
     devicesupport/devicemanager.cpp \
     devicesupport/devicemanagermodel.cpp \
     devicesupport/devicefactoryselectiondialog.cpp \
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index c8b5785c808..a63070d2b93 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -251,6 +251,8 @@ QtcPlugin {
         "devicesupport/desktopdevicefactory.h",
         "devicesupport/deviceapplicationrunner.cpp",
         "devicesupport/deviceapplicationrunner.h",
+        "devicesupport/devicecheckbuildstep.cpp",
+        "devicesupport/devicecheckbuildstep.h",
         "devicesupport/devicefactoryselectiondialog.cpp",
         "devicesupport/devicefactoryselectiondialog.h",
         "devicesupport/devicefactoryselectiondialog.ui",
diff --git a/src/plugins/qnx/qnxdeployconfigurationfactory.cpp b/src/plugins/qnx/qnxdeployconfigurationfactory.cpp
index e84ea7552b7..f72e7c71430 100644
--- a/src/plugins/qnx/qnxdeployconfigurationfactory.cpp
+++ b/src/plugins/qnx/qnxdeployconfigurationfactory.cpp
@@ -35,6 +35,7 @@
 #include "qnxdeployconfiguration.h"
 #include "qnxdeviceconfigurationfactory.h"
 
+#include <projectexplorer/devicesupport/devicecheckbuildstep.h>
 #include <projectexplorer/kitinformation.h>
 #include <projectexplorer/target.h>
 #include <remotelinux/genericdirectuploadstep.h>
@@ -77,7 +78,9 @@ ProjectExplorer::DeployConfiguration *QnxDeployConfigurationFactory::create(Proj
 
     ProjectExplorer::DeployConfiguration * const dc = new QnxDeployConfiguration(parent, id,
         displayNameForId(id));
-    dc->stepList()->insertStep(0, new RemoteLinux::GenericDirectUploadStep(dc->stepList(),
+    dc->stepList()->insertStep(0, new ProjectExplorer::DeviceCheckBuildStep(dc->stepList(),
+        ProjectExplorer::DeviceCheckBuildStep::stepId()));
+    dc->stepList()->insertStep(1, new RemoteLinux::GenericDirectUploadStep(dc->stepList(),
         RemoteLinux::GenericDirectUploadStep::stepId()));
     return dc;
 }
diff --git a/src/plugins/qnx/qnxdeploystepfactory.cpp b/src/plugins/qnx/qnxdeploystepfactory.cpp
index 579214cb979..3b053761e6f 100644
--- a/src/plugins/qnx/qnxdeploystepfactory.cpp
+++ b/src/plugins/qnx/qnxdeploystepfactory.cpp
@@ -34,6 +34,7 @@
 #include "qnxdeviceconfigurationfactory.h"
 
 #include <projectexplorer/buildsteplist.h>
+#include <projectexplorer/devicesupport/devicecheckbuildstep.h>
 #include <projectexplorer/kitinformation.h>
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/target.h>
@@ -56,13 +57,17 @@ QList<Core::Id> QnxDeployStepFactory::availableCreationIds(ProjectExplorer::Buil
     if (deviceType != QnxDeviceConfigurationFactory::deviceType())
         return QList<Core::Id>();
 
-    return QList<Core::Id>() << RemoteLinux::GenericDirectUploadStep::stepId();
+    return QList<Core::Id>() << RemoteLinux::GenericDirectUploadStep::stepId()
+                             << ProjectExplorer::DeviceCheckBuildStep::stepId();
 }
 
 QString QnxDeployStepFactory::displayNameForId(const Core::Id id) const
 {
     if (id == RemoteLinux::GenericDirectUploadStep::stepId())
         return RemoteLinux::GenericDirectUploadStep::displayName();
+    else if (id == ProjectExplorer::DeviceCheckBuildStep::stepId())
+        return ProjectExplorer::DeviceCheckBuildStep::stepDisplayName();
+
     return QString();
 }
 
@@ -75,7 +80,12 @@ ProjectExplorer::BuildStep *QnxDeployStepFactory::create(ProjectExplorer::BuildS
 {
     if (!canCreate(parent, id))
         return 0;
-    return new RemoteLinux::GenericDirectUploadStep(parent, id);
+
+    if (id == RemoteLinux::GenericDirectUploadStep::stepId())
+        return new RemoteLinux::GenericDirectUploadStep(parent, id);
+    else if (id == ProjectExplorer::DeviceCheckBuildStep::stepId())
+        return new ProjectExplorer::DeviceCheckBuildStep(parent, id);
+    return 0;
 }
 
 bool QnxDeployStepFactory::canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const
@@ -103,5 +113,11 @@ ProjectExplorer::BuildStep *QnxDeployStepFactory::clone(ProjectExplorer::BuildSt
 {
     if (!canClone(parent, product))
         return 0;
-    return new RemoteLinux::GenericDirectUploadStep(parent, static_cast<RemoteLinux::GenericDirectUploadStep *>(product));
+
+    if (RemoteLinux::GenericDirectUploadStep * const other = qobject_cast<RemoteLinux::GenericDirectUploadStep*>(product))
+        return new RemoteLinux::GenericDirectUploadStep(parent, other);
+    else if (ProjectExplorer::DeviceCheckBuildStep * const other = qobject_cast<ProjectExplorer::DeviceCheckBuildStep*>(product))
+        return new ProjectExplorer::DeviceCheckBuildStep(parent, other);
+
+    return 0;
 }
-- 
GitLab