From 6039c31133fa71b9e9230475a852f52dc2c91fbf Mon Sep 17 00:00:00 2001
From: con <qtc-committer@nokia.com>
Date: Wed, 28 Oct 2009 17:21:27 +0100
Subject: [PATCH] Show a dialog in case of mismatching build/run
 configurations.

---
 .../projectexplorer/projectexplorer.cpp       | 109 ++++++++++++++++++
 src/plugins/projectexplorer/projectexplorer.h |  29 +++++
 .../projectexplorer/runconfiguration.cpp      |  10 ++
 .../projectexplorer/runconfiguration.h        |   4 +-
 .../runsettingspropertiespage.cpp             |   5 -
 .../qt-s60/s60devicerunconfiguration.cpp      |  12 +-
 .../qt-s60/s60devicerunconfiguration.h        |   3 +-
 .../qt-s60/s60emulatorrunconfiguration.cpp    |   4 +-
 .../qt-s60/s60emulatorrunconfiguration.h      |   2 +-
 src/plugins/qt4projectmanager/qt4project.cpp  |   9 --
 .../qt4projectmanager/qt4runconfiguration.cpp |   4 +-
 .../qt4projectmanager/qt4runconfiguration.h   |   2 +-
 12 files changed, 169 insertions(+), 24 deletions(-)

diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 034dd07469e..9d0021aeb69 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -98,6 +98,7 @@
 #include <QtGui/QFileDialog>
 #include <QtGui/QMenu>
 #include <QtGui/QMessageBox>
+#include <QtGui/QVBoxLayout>
 
 Q_DECLARE_METATYPE(QSharedPointer<ProjectExplorer::RunConfiguration>);
 Q_DECLARE_METATYPE(Core::IEditorFactory*);
@@ -1541,6 +1542,10 @@ void ProjectExplorerPlugin::runProjectImpl(Project *pro)
         return;
 
     if (d->m_projectExplorerSettings.buildBeforeRun && pro->hasBuildSettings()) {
+        if (!pro->activeRunConfiguration()->isEnabled()) {
+            if (!showBuildConfigDialog())
+                return;
+        }
         if (saveModifiedFiles()) {
             d->m_runMode = ProjectExplorer::Constants::RUNMODE;
             d->m_delayedRunConfiguration = pro->activeRunConfiguration();
@@ -1560,6 +1565,10 @@ void ProjectExplorerPlugin::debugProject()
         return;
 
     if (d->m_projectExplorerSettings.buildBeforeRun && pro->hasBuildSettings()) {
+        if (!pro->activeRunConfiguration()->isEnabled()) {
+            if (!showBuildConfigDialog())
+                return;
+        }
         if (saveModifiedFiles()) {
             d->m_runMode = ProjectExplorer::Constants::DEBUGMODE;
             d->m_delayedRunConfiguration = pro->activeRunConfiguration();
@@ -1574,6 +1583,31 @@ void ProjectExplorerPlugin::debugProject()
     }
 }
 
+bool ProjectExplorerPlugin::showBuildConfigDialog()
+{
+    Project *pro = startupProject();
+    BuildConfigDialog *dialog = new BuildConfigDialog(pro,
+                                                      Core::ICore::instance()->mainWindow());
+    dialog->exec();
+    BuildConfiguration *otherConfig = dialog->selectedBuildConfiguration();
+    int result = dialog->result();
+    dialog->deleteLater();
+    switch (result) {
+    case BuildConfigDialog::ChangeBuild:
+        if (otherConfig) {
+            pro->setActiveBuildConfiguration(otherConfig);
+            return true;
+        }
+        return false;
+    case BuildConfigDialog::Cancel:
+        return false;
+    case BuildConfigDialog::Continue:
+        return true;
+    default:
+        return false;
+    }
+}
+
 void ProjectExplorerPlugin::addToApplicationOutputWindow(RunControl *rc, const QString &line)
 {
     d->m_outputPane->appendOutput(rc, line);
@@ -2095,4 +2129,79 @@ Internal::ProjectExplorerSettings ProjectExplorerPlugin::projectExplorerSettings
     return d->m_projectExplorerSettings;
 }
 
+// ---------- BuildConfigDialog -----------
+Q_DECLARE_METATYPE(BuildConfiguration*);
+
+BuildConfigDialog::BuildConfigDialog(Project *project, QWidget *parent)
+    : QDialog(parent),
+    m_project(project)
+{
+    QVBoxLayout *vlayout = new QVBoxLayout;
+    setLayout(vlayout);
+    QDialogButtonBox *buttonBox = new QDialogButtonBox;
+    m_changeBuildConfiguration = buttonBox->addButton(tr("Change build configuration && continue"),
+        QDialogButtonBox::ActionRole);
+    m_cancel = buttonBox->addButton(tr("Cancel"),
+        QDialogButtonBox::RejectRole);
+    m_justContinue = buttonBox->addButton(tr("Continue anyway"),
+        QDialogButtonBox::AcceptRole);
+    connect(m_changeBuildConfiguration, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+    connect(m_cancel, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+    connect(m_justContinue, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+    setWindowTitle(tr("Run configuration doesn't match build configuration"));
+    QLabel *shortText = new QLabel(tr(
+            "The active build configuration builds a target "
+            "that cannot be used by the active run configuration."
+            ));
+    vlayout->addWidget(shortText);
+    QLabel *descriptiveText = new QLabel(tr(
+        "This can happen if the active build configuration "
+        "uses the wrong Qt version and/or tool chain for the active run configuration "
+        "(e.g. running in Symbian emulator requires building with WINSCW tool chain)."
+    ));
+    descriptiveText->setWordWrap(true);
+    vlayout->addWidget(descriptiveText);
+    QHBoxLayout *hlayout = new QHBoxLayout;
+    hlayout->addWidget(new QLabel(tr("Choose build configuration:")));
+    m_configCombo = new QComboBox;
+    QSharedPointer<RunConfiguration> activeRun = m_project->activeRunConfiguration();
+    foreach (BuildConfiguration *config, m_project->buildConfigurations()) {
+        if (activeRun->isEnabled(config)) {
+            m_configCombo->addItem(config->name(), qVariantFromValue(config));
+        }
+    }
+    if (m_configCombo->count() == 0) {
+        m_configCombo->addItem(tr("No valid build configuration found."));
+        m_configCombo->setEnabled(false);
+        m_changeBuildConfiguration->setEnabled(false);
+    }
+
+
+    hlayout->addWidget(m_configCombo);
+    hlayout->addStretch(10);
+    vlayout->addLayout(hlayout);
+    vlayout->addWidget(buttonBox);
+    m_cancel->setDefault(true);
+}
+
+BuildConfiguration *BuildConfigDialog::selectedBuildConfiguration() const
+{
+    int index = m_configCombo->currentIndex();
+    if (index < 0)
+        return 0;
+    return m_configCombo->itemData(index, Qt::UserRole).value<BuildConfiguration*>();
+}
+
+void BuildConfigDialog::buttonClicked()
+{
+    QPushButton *button = qobject_cast<QPushButton *>(sender());
+    if (button == m_changeBuildConfiguration) {
+        done(ChangeBuild);
+    } else if (button == m_cancel) {
+        done(Cancel);
+    } else if (button == m_justContinue) {
+        done(Continue);
+    }
+}
+
 Q_EXPORT_PLUGIN(ProjectExplorerPlugin)
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index 6066b9e69d8..1d0d49afb81 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -35,10 +35,12 @@
 #include <extensionsystem/iplugin.h>
 
 #include <QtCore/QSharedPointer>
+#include <QtGui/QDialog>
 
 QT_BEGIN_NAMESPACE
 class QPoint;
 class QAction;
+class QComboBox;
 QT_END_NAMESPACE
 
 namespace Core {
@@ -59,10 +61,36 @@ class RunConfiguration;
 class IRunControlFactory;
 class Project;
 class Node;
+class BuildConfiguration;
 
 namespace Internal {
 class ProjectFileFactory;
 struct ProjectExplorerSettings;
+
+class BuildConfigDialog : public QDialog
+{
+    Q_OBJECT
+public:
+    enum DialogResult {
+        ChangeBuild = 10,
+        Cancel = 11,
+        Continue = 12
+    };
+    BuildConfigDialog(Project *project, QWidget *parent = 0);
+
+    BuildConfiguration *selectedBuildConfiguration() const;
+
+private slots:
+    void buttonClicked();
+
+private:
+    Project *m_project;
+    QPushButton *m_changeBuildConfiguration;
+    QPushButton *m_cancel;
+    QPushButton *m_justContinue;
+    QComboBox *m_configCombo;
+};
+
 } // namespace Internal
 
 struct ProjectExplorerPluginPrivate;
@@ -187,6 +215,7 @@ private slots:
 private:
     void runProjectImpl(Project *pro);
     void executeRunConfiguration(const QSharedPointer<RunConfiguration> &, const QString &mode);
+    bool showBuildConfigDialog();
     void setCurrent(Project *project, QString filePath, Node *node);
 
     QStringList allFilesWithDependencies(Project *pro);
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index c9765ad5cd5..6aa8ea34de8 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -30,6 +30,7 @@
 #include "runconfiguration.h"
 #include "project.h"
 #include "persistentsettings.h"
+#include "buildconfiguration.h"
 
 #include <QtCore/QTimer>
 
@@ -56,6 +57,15 @@ Project *RunConfiguration::project() const
     return m_project.data();
 }
 
+bool RunConfiguration::isEnabled() const
+{
+    if (!m_project)
+        return false;
+    if (!m_project->activeBuildConfiguration())
+        return false;
+    return isEnabled(m_project->activeBuildConfiguration());
+}
+
 QString RunConfiguration::name() const
 {
     return m_name;
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index 07f1ad79561..d775856cd77 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -49,6 +49,7 @@ class PersistentSettingsReader;
 class PersistentSettingsWriter;
 
 class RunControl;
+class BuildConfiguration;
 
 /* Base class for a run configuration. A run configuration specifies how a
  * project should be run, while the runner (see below) does the actual running.
@@ -75,7 +76,8 @@ public:
     QString name() const;
     void setName(const QString &name);
 
-    virtual bool isEnabled() const { return true; }
+    virtual bool isEnabled(BuildConfiguration *) const { return true; }
+    bool isEnabled() const;
 
     // Returns the widget used to configure this run configuration. Ownership is transferred to the caller
     // rename to createConfigurationWidget
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
index 98b86a3ff89..03b38082614 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
@@ -288,11 +288,6 @@ void RunSettingsWidget::initRunConfigurationComboBox()
         m_ui->runConfigurationCombo->setCurrentIndex(runConfigurations.indexOf(currentSelection));
     else
         m_ui->runConfigurationCombo->setCurrentIndex(runConfigurations.indexOf(activeRunConfiguration));
-    QList<QSharedPointer<RunConfiguration> > enabledRunConfigurations;
-    for (int i = 0; i < runConfigurations.size(); ++i) {
-        if (runConfigurations.at(i)->isEnabled())
-            enabledRunConfigurations.append(runConfigurations.at(i));
-    }
     m_ui->removeToolButton->setEnabled(runConfigurations.size() > 1);
     updateMakeActiveLabel();
 }
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 2cb8caf38f4..94dfb99aec6 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -101,6 +101,14 @@ QString S60DeviceRunConfiguration::type() const
     return QLatin1String("Qt4ProjectManager.DeviceRunConfiguration");
 }
 
+ProjectExplorer::ToolChain::ToolChainType S60DeviceRunConfiguration::toolChainType(
+        ProjectExplorer::BuildConfiguration *configuration) const
+{
+    if (const Qt4Project *pro = qobject_cast<const Qt4Project*>(project()))
+        return pro->toolChainType(configuration);
+    return ProjectExplorer::ToolChain::INVALID;
+}
+
 ProjectExplorer::ToolChain::ToolChainType S60DeviceRunConfiguration::toolChainType() const
 {
     if (const Qt4Project *pro = qobject_cast<const Qt4Project*>(project()))
@@ -108,9 +116,9 @@ ProjectExplorer::ToolChain::ToolChainType S60DeviceRunConfiguration::toolChainTy
     return ProjectExplorer::ToolChain::INVALID;
 }
 
-bool S60DeviceRunConfiguration::isEnabled() const
+bool S60DeviceRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
 {
-    const ToolChain::ToolChainType type = toolChainType();
+    const ToolChain::ToolChainType type = toolChainType(configuration);
     return type == ToolChain::GCCE || type == ToolChain::RVCT_ARMV5 || type == ToolChain::RVCT_ARMV6;
 }
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index fa7651a2fb7..04616bf109a 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -62,7 +62,7 @@ public:
     ~S60DeviceRunConfiguration();
 
     QString type() const;
-    bool isEnabled() const;
+    bool isEnabled(ProjectExplorer::BuildConfiguration *configuration) const;
     QWidget *configurationWidget();
     void save(ProjectExplorer::PersistentSettingsWriter &writer) const;
     void restore(const ProjectExplorer::PersistentSettingsReader &reader);
@@ -97,6 +97,7 @@ private slots:
     void invalidateCachedTargetInformation();
 
 private:
+    ProjectExplorer::ToolChain::ToolChainType toolChainType(ProjectExplorer::BuildConfiguration *configuration) const;
     void updateTarget();
 
     QString m_proFilePath;
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
index b1c65fa0e92..6b734e63149 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
@@ -76,11 +76,11 @@ QString S60EmulatorRunConfiguration::type() const
     return "Qt4ProjectManager.EmulatorRunConfiguration";
 }
 
-bool S60EmulatorRunConfiguration::isEnabled() const
+bool S60EmulatorRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
 {
     Qt4Project *pro = qobject_cast<Qt4Project*>(project());
     QTC_ASSERT(pro, return false);
-    ToolChain::ToolChainType type = pro->toolChainType(pro->activeBuildConfiguration());
+    ToolChain::ToolChainType type = pro->toolChainType(configuration);
     return type == ToolChain::WINSCW;
 }
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
index 8ba0aeded4d..ec84e7900d3 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
@@ -55,7 +55,7 @@ public:
     ~S60EmulatorRunConfiguration();
 
     QString type() const;
-    bool isEnabled() const;
+    bool isEnabled(ProjectExplorer::BuildConfiguration *configuration) const;
     QWidget *configurationWidget();
     void save(ProjectExplorer::PersistentSettingsWriter &writer) const;
     void restore(const ProjectExplorer::PersistentSettingsReader &reader);
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index a9fd57afe74..2acc04c7b96 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -994,15 +994,6 @@ void Qt4Project::setToolChainType(BuildConfiguration *configuration, ProjectExpl
 
 void Qt4Project::updateActiveRunConfiguration()
 {
-    const QSharedPointer<RunConfiguration> activeRunConfig = activeRunConfiguration();
-    if (!activeRunConfig.isNull() && !activeRunConfig->isEnabled()) {
-        foreach (const QSharedPointer<RunConfiguration> &runConfiguration, runConfigurations()) {
-            if (runConfiguration->isEnabled()) {
-                setActiveRunConfiguration(runConfiguration);
-                break;
-            }
-        }
-    }
     emit runConfigurationsEnabledStateChanged();
     emit targetInformationChanged();
 }
diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
index 4c7a31e13bc..413122224b1 100644
--- a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
@@ -93,12 +93,12 @@ QString Qt4RunConfiguration::type() const
     return "Qt4ProjectManager.Qt4RunConfiguration";
 }
 
-bool Qt4RunConfiguration::isEnabled() const
+bool Qt4RunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
 {
 #ifdef QTCREATOR_WITH_S60
     Qt4Project *pro = qobject_cast<Qt4Project*>(project());
     QTC_ASSERT(pro, return false);
-    ProjectExplorer::ToolChain::ToolChainType type = pro->toolChainType(pro->activeBuildConfiguration());
+    ProjectExplorer::ToolChain::ToolChainType type = pro->toolChainType(configuration);
     return type != ProjectExplorer::ToolChain::WINSCW
             && type != ProjectExplorer::ToolChain::GCCE
             && type != ProjectExplorer::ToolChain::RVCT_ARMV5
diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.h b/src/plugins/qt4projectmanager/qt4runconfiguration.h
index 69fa0d6575f..f4d953cad87 100644
--- a/src/plugins/qt4projectmanager/qt4runconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt4runconfiguration.h
@@ -66,7 +66,7 @@ public:
     virtual ~Qt4RunConfiguration();
 
     virtual QString type() const;
-    virtual bool isEnabled() const;
+    virtual bool isEnabled(ProjectExplorer::BuildConfiguration *configuration) const;
     virtual QWidget *configurationWidget();
     virtual void save(ProjectExplorer::PersistentSettingsWriter &writer) const;
     virtual void restore(const ProjectExplorer::PersistentSettingsReader &reader);
-- 
GitLab