From 7d300a29bf9474aeec5a1c0e7395ef84d75606df Mon Sep 17 00:00:00 2001
From: Tobias Hunger <tobias.hunger@digia.com>
Date: Thu, 13 Jun 2013 17:15:44 +0200
Subject: [PATCH] Qbs: Add support for QML debugging

Change-Id: I3ce493274b949bf9065909337a8dd57760f1e12f
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
---
 .../qbsprojectmanager/qbsbuildstep.cpp        | 68 ++++++++++++++++++-
 src/plugins/qbsprojectmanager/qbsbuildstep.h  |  7 ++
 .../qbsbuildstepconfigwidget.ui               | 59 ++++++++++++++--
 .../qbsprojectmanagerconstants.h              |  2 +
 src/shared/qbs                                |  2 +-
 5 files changed, 129 insertions(+), 9 deletions(-)

diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
index b830ef4cef5..e9705a85b24 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
@@ -40,6 +40,8 @@
 #include <projectexplorer/kit.h>
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/target.h>
+#include <qtsupport/debugginghelperbuildtask.h>
+#include <qtsupport/qtversionmanager.h>
 #include <utils/qtcassert.h>
 #include <utils/qtcprocess.h>
 
@@ -293,6 +295,13 @@ QString QbsBuildStep::buildVariant() const
     return qbsConfiguration().value(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY)).toString();
 }
 
+bool QbsBuildStep::isQmlDebuggingEnabled() const
+{
+    QVariantMap data = qbsConfiguration();
+    return data.value(QLatin1String(Constants::QBS_CONFIG_DECLARATIVE_DEBUG_KEY), false).toBool()
+            || data.value(QLatin1String(Constants::QBS_CONFIG_QUICK_DEBUG_KEY), false).toBool();
+}
+
 void QbsBuildStep::setBuildVariant(const QString &variant)
 {
     if (m_qbsConfiguration.value(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY)).toString() == variant)
@@ -353,7 +362,12 @@ QbsBuildStepConfigWidget::QbsBuildStepConfigWidget(QbsBuildStep *step) :
     connect(m_ui->keepGoingCheckBox, SIGNAL(toggled(bool)), this, SLOT(changeKeepGoing(bool)));
     connect(m_ui->jobSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeJobCount(int)));
     connect(m_ui->propertyEdit, SIGNAL(propertiesChanged()), this, SLOT(changeProperties()));
-
+    connect(m_ui->qmlDebuggingLibraryCheckBox, SIGNAL(toggled(bool)),
+            this, SLOT(linkQmlDebuggingLibraryChecked(bool)));
+    connect(m_ui->qmlDebuggingWarningText, SIGNAL(linkActivated(QString)),
+            this, SLOT(buildQmlDebuggingHelper()));
+    connect(QtSupport::QtVersionManager::instance(), SIGNAL(dumpUpdatedFor(Utils::FileName)),
+            this, SLOT(updateQmlDebuggingOption()));
     updateState();
 }
 
@@ -374,8 +388,11 @@ void QbsBuildStepConfigWidget::updateState()
         m_ui->keepGoingCheckBox->setChecked(m_step->keepGoing());
         m_ui->jobSpinBox->setValue(m_step->maxJobs());
         updatePropertyEdit(m_step->qbsConfiguration());
+        m_ui->qmlDebuggingLibraryCheckBox->setChecked(m_step->isQmlDebuggingEnabled());
     }
 
+    updateQmlDebuggingOption();
+
     const QString buildVariant = m_step->buildVariant();
     const int idx = (buildVariant == QLatin1String(Constants::QBS_VARIANT_DEBUG)) ? 0 : 1;
     m_ui->buildVariantComboBox->setCurrentIndex(idx);
@@ -394,6 +411,9 @@ void QbsBuildStepConfigWidget::updateState()
                 + QLatin1Char(':') + propertyList.at(i).second;
     }
 
+    if (m_step->isQmlDebuggingEnabled())
+        command += QLatin1String(" Qt.declarative.qmlDebugging:true Qt.quick.qmlDebugging:true");
+
     QString summary = tr("<b>Qbs:</b> %1").arg(command);
     if (m_summary != summary) {
         m_summary = summary;
@@ -401,6 +421,21 @@ void QbsBuildStepConfigWidget::updateState()
     }
 }
 
+void QbsBuildStepConfigWidget::updateQmlDebuggingOption()
+{
+    QString warningText;
+    bool supported = QtSupport::BaseQtVersion::isQmlDebuggingSupported(m_step->target()->kit(),
+                                                                       &warningText);
+    m_ui->qmlDebuggingLibraryCheckBox->setEnabled(supported);
+
+    if (supported && m_step->isQmlDebuggingEnabled())
+        warningText = tr("Might make your application vulnerable. Only use in a safe environment.");
+
+    m_ui->qmlDebuggingWarningText->setText(warningText);
+    m_ui->qmlDebuggingWarningIcon->setVisible(!warningText.isEmpty());
+}
+
+
 void QbsBuildStepConfigWidget::updatePropertyEdit(const QVariantMap &data)
 {
     QVariantMap editable = data;
@@ -408,6 +443,8 @@ void QbsBuildStepConfigWidget::updatePropertyEdit(const QVariantMap &data)
     // remove data that is edited with special UIs:
     editable.remove(QLatin1String(Constants::QBS_CONFIG_PROFILE_KEY));
     editable.remove(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY));
+    editable.remove(QLatin1String(Constants::QBS_CONFIG_DECLARATIVE_DEBUG_KEY));
+    editable.remove(QLatin1String(Constants::QBS_CONFIG_QUICK_DEBUG_KEY));
 
     QStringList propertyList;
     for (QVariantMap::const_iterator i = editable.constBegin(); i != editable.constEnd(); ++i)
@@ -459,6 +496,13 @@ void QbsBuildStepConfigWidget::changeProperties()
                 tmp.value(QLatin1String(Constants::QBS_CONFIG_PROFILE_KEY)));
     data.insert(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY),
                 tmp.value(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY)));
+    if (tmp.contains(QLatin1String(Constants::QBS_CONFIG_DECLARATIVE_DEBUG_KEY)))
+        data.insert(QLatin1String(Constants::QBS_CONFIG_DECLARATIVE_DEBUG_KEY),
+                    tmp.value(QLatin1String(Constants::QBS_CONFIG_DECLARATIVE_DEBUG_KEY)));
+    if (tmp.contains(QLatin1String(Constants::QBS_CONFIG_QUICK_DEBUG_KEY)))
+        data.insert(QLatin1String(Constants::QBS_CONFIG_QUICK_DEBUG_KEY),
+                    tmp.value(QLatin1String(Constants::QBS_CONFIG_QUICK_DEBUG_KEY)));
+
     QList<QPair<QString, QString> > propertyList = m_ui->propertyEdit->properties();
     for (int i = 0; i < propertyList.count(); ++i)
         data.insert(propertyList.at(i).first, propertyList.at(i).second);
@@ -468,6 +512,28 @@ void QbsBuildStepConfigWidget::changeProperties()
     m_ignoreChange = false;
 }
 
+void QbsBuildStepConfigWidget::linkQmlDebuggingLibraryChecked(bool checked)
+{
+    QVariantMap data = m_step->qbsConfiguration();
+    if (checked) {
+        data.insert(QLatin1String(Constants::QBS_CONFIG_DECLARATIVE_DEBUG_KEY), checked);
+        data.insert(QLatin1String(Constants::QBS_CONFIG_QUICK_DEBUG_KEY), checked);
+    } else {
+        data.remove(QLatin1String(Constants::QBS_CONFIG_DECLARATIVE_DEBUG_KEY));
+        data.remove(QLatin1String(Constants::QBS_CONFIG_QUICK_DEBUG_KEY));
+    }
+
+    m_ignoreChange = true;
+    m_step->setQbsConfiguration(data);
+    m_ignoreChange = false;
+}
+
+void QbsBuildStepConfigWidget::buildQmlDebuggingHelper()
+{
+    QtSupport::BaseQtVersion::buildDebuggingHelper(m_step->target()->kit(),
+                                                   static_cast<int>(QtSupport::DebuggingHelperBuildTask::QmlDebugging));
+}
+
 // --------------------------------------------------------------------
 // QbsBuildStepFactory:
 // --------------------------------------------------------------------
diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.h b/src/plugins/qbsprojectmanager/qbsbuildstep.h
index 7f2b73c965b..fce407b6584 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildstep.h
+++ b/src/plugins/qbsprojectmanager/qbsbuildstep.h
@@ -68,6 +68,8 @@ public:
     int maxJobs() const;
     QString buildVariant() const;
 
+    bool isQmlDebuggingEnabled() const;
+
     bool fromMap(const QVariantMap &map);
     QVariantMap toMap() const;
 
@@ -120,6 +122,7 @@ public:
 
 private slots:
     void updateState();
+    void updateQmlDebuggingOption();
     void updatePropertyEdit(const QVariantMap &data);
 
     void changeBuildVariant(int);
@@ -128,6 +131,10 @@ private slots:
     void changeJobCount(int count);
     void changeProperties();
 
+    // QML debugging:
+    void linkQmlDebuggingLibraryChecked(bool checked);
+    void buildQmlDebuggingHelper();
+
 private:
     Ui::QbsBuildStepConfigWidget *m_ui;
 
diff --git a/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui b/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui
index 4f4702c32fb..c0284b63152 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui
+++ b/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>281</width>
-    <height>79</height>
+    <width>463</width>
+    <height>121</height>
    </rect>
   </property>
   <layout class="QGridLayout" name="gridLayout">
@@ -23,9 +23,6 @@
    <property name="bottomMargin">
     <number>0</number>
    </property>
-   <property name="horizontalSpacing">
-    <number>12</number>
-   </property>
    <item row="0" column="0">
     <widget class="QLabel" name="buildVariantLabel">
      <property name="text">
@@ -77,16 +74,64 @@
     </spacer>
    </item>
    <item row="1" column="0">
+    <widget class="QLabel" name="qmlDebuggingLabel">
+     <property name="text">
+      <string>Enable QML debugging:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1" colspan="4">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QCheckBox" name="qmlDebuggingLibraryCheckBox">
+       <property name="text">
+        <string/>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="qmlDebuggingWarningIcon">
+       <property name="text">
+        <string/>
+       </property>
+       <property name="pixmap">
+        <pixmap>:/projectexplorer/images/compile_warning.png</pixmap>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="qmlDebuggingWarningText">
+       <property name="text">
+        <string/>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>5</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="2" column="0">
     <widget class="QLabel" name="propertyLabel">
      <property name="text">
       <string>Properties:</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="1" colspan="4">
+   <item row="2" column="1" colspan="4">
     <widget class="QbsPropertyLineEdit" name="propertyEdit"/>
    </item>
-   <item row="2" column="0" colspan="5">
+   <item row="3" column="0" colspan="5">
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <widget class="QCheckBox" name="dryRunCheckBox">
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h
index 32e8f7962a7..e59a0ede8c1 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h
@@ -63,6 +63,8 @@ static const char QBS_VARIANT_RELEASE[] = "release";
 
 static const char QBS_CONFIG_VARIANT_KEY[] = "qbs.buildVariant";
 static const char QBS_CONFIG_PROFILE_KEY[] = "qbs.profile";
+static const char QBS_CONFIG_DECLARATIVE_DEBUG_KEY[] = "Qt.declarative.qmlDebugging";
+static const char QBS_CONFIG_QUICK_DEBUG_KEY[] = "Qt.quick.qmlDebugging";
 
 } // namespace Constants
 } // namespace QbsProjectManager
diff --git a/src/shared/qbs b/src/shared/qbs
index 53da25e9f89..f8b65305729 160000
--- a/src/shared/qbs
+++ b/src/shared/qbs
@@ -1 +1 @@
-Subproject commit 53da25e9f894471c487c91cb476d2b48b1984ecd
+Subproject commit f8b65305729e5806b14e25172a1ee5bc9f7df4ec
-- 
GitLab