From 45dd1ad7f502daf48f4f92d9719c63e24b9ce7f2 Mon Sep 17 00:00:00 2001
From: dt <qtc-committer@nokia.com>
Date: Wed, 27 Oct 2010 16:27:22 +0200
Subject: [PATCH] Disable Run Configurations while parsing .pro files

Initial patch and idea by hunger.
Reviewed-By: hunger
---
 .../qt-maemo/maemodeployables.cpp             | 16 +++---
 .../qt-maemo/maemorunconfiguration.cpp        | 36 +++++++++++--
 .../qt-maemo/maemorunconfiguration.h          |  7 ++-
 .../qt-maemo/maemorunconfigurationwidget.cpp  |  9 ++++
 .../qt-maemo/maemorunconfigurationwidget.h    |  3 +-
 .../qt-s60/s60deployconfiguration.cpp         |  4 ++
 .../qt-s60/s60devicerunconfiguration.cpp      | 41 ++++++++++++---
 .../qt-s60/s60devicerunconfiguration.h        | 11 ++--
 .../s60devicerunconfigurationwidget.cpp       |  8 +++
 .../qt-s60/s60devicerunconfigurationwidget.h  |  4 +-
 .../qt-s60/s60emulatorrunconfiguration.cpp    | 52 +++++++++++++++----
 .../qt-s60/s60emulatorrunconfiguration.h      | 11 ++--
 src/plugins/qt4projectmanager/qt4nodes.cpp    | 37 ++++++++++++-
 src/plugins/qt4projectmanager/qt4nodes.h      |  9 +++-
 src/plugins/qt4projectmanager/qt4project.cpp  | 18 ++++++-
 src/plugins/qt4projectmanager/qt4project.h    |  6 ++-
 .../qt4projectmanager/qt4runconfiguration.cpp | 46 +++++++++++++---
 .../qt4projectmanager/qt4runconfiguration.h   |  8 ++-
 18 files changed, 273 insertions(+), 53 deletions(-)

diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeployables.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeployables.cpp
index 9148b27df29..6add3d99d50 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemodeployables.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeployables.cpp
@@ -67,9 +67,12 @@ MaemoDeployables::~MaemoDeployables() {}
 
 void MaemoDeployables::init()
 {
-    connect(qt4BuildConfiguration()->qt4Target()->qt4Project(),
-        SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
-        m_updateTimer, SLOT(start()));
+    Qt4Project *pro = qt4BuildConfiguration()->qt4Target()->qt4Project();
+    connect(pro,  SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)),
+            m_updateTimer, SLOT(start()));
+
+    // TODO do we want to disable the view
+
     createModels();
 }
 
@@ -85,7 +88,7 @@ void MaemoDeployables::createModels()
         return;
     m_updateTimer->stop();
     disconnect(qt4BuildConfiguration()->qt4Target()->qt4Project(),
-        SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
+        SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)),
         m_updateTimer, SLOT(start()));
     beginResetModel();
     qDeleteAll(m_listModels);
@@ -116,9 +119,8 @@ void MaemoDeployables::createModels()
     }
 
     endResetModel();
-    connect(qt4BuildConfiguration()->qt4Target()->qt4Project(),
-        SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
-        m_updateTimer, SLOT(start()));
+    connect(pro, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)),
+            m_updateTimer, SLOT(start()));
 }
 
 void MaemoDeployables::createModels(const Qt4ProFileNode *proFileNode)
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
index fcb737ced87..50af781b185 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
@@ -67,6 +67,7 @@ MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent,
     , m_proFilePath(proFilePath)
     , m_useRemoteGdb(DefaultUseRemoteGdbValue)
     , m_baseEnvironmentBase(SystemEnvironmentBase)
+    , m_validParse(parent->qt4Project()->validParse(m_proFilePath))
 {
     init();
 }
@@ -81,6 +82,7 @@ MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent,
     , m_baseEnvironmentBase(source->m_baseEnvironmentBase)
     , m_systemEnvironment(source->m_systemEnvironment)
     , m_userEnvironmentChanges(source->m_userEnvironmentChanges)
+    , m_validParse(source->m_validParse)
 {
     init();
 }
@@ -97,9 +99,11 @@ void MaemoRunConfiguration::init()
         this, SLOT(handleDeployConfigChanged()));
     handleDeployConfigChanged();
 
-    connect(qt4Target()->qt4Project(),
-        SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
-        this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
+    Qt4Project *pro = qt4Target()->qt4Project();
+    connect(pro, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)),
+            this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)));
+    connect(pro, SIGNAL(profFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
+            this, SLOT(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
 }
 
 MaemoRunConfiguration::~MaemoRunConfiguration()
@@ -118,6 +122,8 @@ Qt4BuildConfiguration *MaemoRunConfiguration::activeQt4BuildConfiguration() cons
 
 bool MaemoRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *config) const
 {
+    if (!m_validParse)
+        return false;
     Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration*>(config);
     QTC_ASSERT(qt4bc, return false);
     ToolChain::ToolChainType type = qt4bc->toolChainType();
@@ -134,10 +140,30 @@ ProjectExplorer::OutputFormatter *MaemoRunConfiguration::createOutputFormatter()
     return new QtOutputFormatter(qt4Target()->qt4Project());
 }
 
-void MaemoRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
+void MaemoRunConfiguration::handleParseState(bool success)
+{
+    bool enabled = isEnabled();
+    m_validParse = success;
+    if (enabled != isEnabled()) {
+        qDebug()<<"Emitting isEnabledChanged()"<<!enabled;
+        emit isEnabledChanged(!enabled);
+    }
+}
+
+void MaemoRunConfiguration::proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
 {
-    if (m_proFilePath == pro->path())
+    if (m_proFilePath != pro->path())
+        return;
+    qDebug()<<"proFileInvalidated";
+    handleParseState(false);
+}
+
+void MaemoRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro, bool success)
+{
+    if (m_proFilePath == pro->path()) {
+        handleParseState(success);
         emit targetInformationChanged();
+    }
 }
 
 QVariantMap MaemoRunConfiguration::toMap() const
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h
index 5ca8db29d93..652d5050091 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h
@@ -76,6 +76,7 @@ public:
     MaemoRunConfiguration(Qt4Target *parent, const QString &proFilePath);
     virtual ~MaemoRunConfiguration();
 
+    using ProjectExplorer::RunConfiguration::isEnabled;
     bool isEnabled(ProjectExplorer::BuildConfiguration *config) const;
     QWidget *createConfigurationWidget();
     ProjectExplorer::OutputFormatter *createOutputFormatter() const;
@@ -135,14 +136,15 @@ protected:
     QString defaultDisplayName();
 
 private slots:
-    void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
+    void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro, bool success);
+    void proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
     void updateDeviceConfigurations();
     void handleDeployConfigChanged();
 
 private:
     void init();
+    void handleParseState(bool success);
 
-private:
     QString m_proFilePath;
     mutable QString m_gdbPath;
     MaemoRemoteMountsModel *m_remoteMounts;
@@ -152,6 +154,7 @@ private:
     BaseEnvironmentBase m_baseEnvironmentBase;
     Utils::Environment m_systemEnvironment;
     QList<Utils::EnvironmentItem> m_userEnvironmentChanges;
+    bool m_validParse;
 };
 
     } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.cpp
index 72ccb2ad716..1be512c501a 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.cpp
@@ -96,9 +96,18 @@ MaemoRunConfigurationWidget::MaemoRunConfigurationWidget(
     connect(m_runConfiguration->qt4Target(),
         SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
         this, SLOT(handleBuildConfigChanged()));
+
+    connect(m_runConfiguration, SIGNAL(isEnabledChanged(bool)),
+            this, SLOT(runConfigurationEnabledChange(bool)));
+
     handleBuildConfigChanged();
 }
 
+void MaemoRunConfigurationWidget::runConfigurationEnabledChange(bool enabled)
+{
+    setEnabled(enabled);
+}
+
 void MaemoRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayout)
 {
     QFormLayout *formLayout = new QFormLayout;
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.h b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.h
index e97c10712e8..56954ae55ca 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.h
@@ -71,9 +71,10 @@ class MaemoRunConfigurationWidget : public QWidget
     Q_OBJECT
 public:
     explicit MaemoRunConfigurationWidget(MaemoRunConfiguration *runConfiguration,
-        QWidget *parent = 0);
+                                         QWidget *parent = 0);
 
 private slots:
+    void runConfigurationEnabledChange(bool enabled);
     void argumentsEdited(const QString &args);
     void showSettingsDialog(const QString &link);
     void updateTargetInformation();
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
index cd4a04a64e0..860effb9dbc 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
@@ -110,6 +110,10 @@ S60DeployConfiguration::S60DeployConfiguration(Target *target, S60DeployConfigur
 void S60DeployConfiguration::ctor()
 {
     setDefaultDisplayName(defaultDisplayName());
+    // TODO disable S60 Deploy Configuration while parsing
+    // requires keeping track of the parsing state of the project
+//    connect(qt4Target()->qt4Project(), SIGNAL(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
+//            this, SLOT(targetInformationInvalidated()));
     connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
             this, SIGNAL(targetInformationChanged()));
     connect(qt4Target(), SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 4c4b7ba9b3b..08221988cf1 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -107,17 +107,19 @@ QString pathToId(const QString &path)
 
 // ======== S60DeviceRunConfiguration
 
-S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *parent, const QString &proFilePath) :
+S60DeviceRunConfiguration::S60DeviceRunConfiguration(Qt4Target *parent, const QString &proFilePath) :
     RunConfiguration(parent,  QLatin1String(S60_DEVICE_RC_ID)),
-    m_proFilePath(proFilePath)
+    m_proFilePath(proFilePath),
+    m_validParse(parent->qt4Project()->validParse(proFilePath))
 {
     ctor();
 }
 
-S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *target, S60DeviceRunConfiguration *source) :
+S60DeviceRunConfiguration::S60DeviceRunConfiguration(Qt4Target *target, S60DeviceRunConfiguration *source) :
     RunConfiguration(target, source),
     m_proFilePath(source->m_proFilePath),
-    m_commandLineArguments(source->m_commandLineArguments)
+    m_commandLineArguments(source->m_commandLineArguments),
+    m_validParse(source->m_validParse)
 {
     ctor();
 }
@@ -130,12 +132,35 @@ void S60DeviceRunConfiguration::ctor()
     else
         //: S60 device runconfiguration default display name (no profile set)
         setDefaultDisplayName(tr("Run on Symbian device"));
+
+    Qt4Project *pro = qt4Target()->qt4Project();
+    connect(pro, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)),
+            this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)));
+    connect(pro, SIGNAL(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
+            this, SLOT(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
+}
+
+void S60DeviceRunConfiguration::handleParserState(bool success)
+{
+    bool enabled = isEnabled();
+    m_validParse = success;
+    if (enabled != isEnabled())
+        emit isEnabledChanged(!enabled);
+}
+
+void S60DeviceRunConfiguration::proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
+{
+    if (m_proFilePath != pro->path())
+        return;
+    handleParserState(false);
 }
 
-void S60DeviceRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
+void S60DeviceRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro, bool success)
 {
-    if (m_proFilePath == pro->path())
-        emit targetInformationChanged();
+    if (m_proFilePath != pro->path())
+        return;
+    handleParserState(success);
+    emit targetInformationChanged();
 }
 
 S60DeviceRunConfiguration::~S60DeviceRunConfiguration()
@@ -164,6 +189,8 @@ ProjectExplorer::ToolChain::ToolChainType S60DeviceRunConfiguration::toolChainTy
 
 bool S60DeviceRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
 {
+    if (!m_validParse)
+        return false;
     const Qt4BuildConfiguration *qt4bc = static_cast<const Qt4BuildConfiguration *>(configuration);
     switch (qt4bc->toolChainType()) {
     case ToolChain::GCCE:
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index 8ed9ed543cd..a0b3cdae8b3 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -69,12 +69,13 @@ class S60DeviceRunConfiguration : public ProjectExplorer::RunConfiguration
     friend class S60DeviceRunConfigurationFactory;
 
 public:
-    S60DeviceRunConfiguration(ProjectExplorer::Target *parent, const QString &proFilePath);
+    S60DeviceRunConfiguration(Qt4ProjectManager::Internal::Qt4Target *parent, const QString &proFilePath);
     virtual ~S60DeviceRunConfiguration();
 
     Qt4Target *qt4Target() const;
     const QtVersion *qtVersion() const;
 
+    using ProjectExplorer::RunConfiguration::isEnabled;
     bool isEnabled(ProjectExplorer::BuildConfiguration *configuration) const;
     QWidget *createConfigurationWidget();
 
@@ -97,22 +98,26 @@ public:
 
     QVariantMap toMap() const;
 
-    void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
 
 signals:
     void targetInformationChanged();
 
 protected:
-    S60DeviceRunConfiguration(ProjectExplorer::Target *parent, S60DeviceRunConfiguration *source);
+    S60DeviceRunConfiguration(Qt4ProjectManager::Internal::Qt4Target *parent, S60DeviceRunConfiguration *source);
     QString defaultDisplayName() const;
     virtual bool fromMap(const QVariantMap &map);
+private slots:
+    void proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
+    void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro, bool success);
 
 private:
     ProjectExplorer::ToolChain::ToolChainType toolChainType(ProjectExplorer::BuildConfiguration *configuration) const;
     void ctor();
+    void handleParserState(bool sucess);
 
     QString m_proFilePath;
     QStringList m_commandLineArguments;
+    bool m_validParse;
 };
 
 class S60DeviceRunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp
index cefc6aa2c0d..2273d81c0f4 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp
@@ -73,6 +73,9 @@ S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(
 
     connect(m_argumentsLineEdit, SIGNAL(textEdited(QString)),
             this, SLOT(argumentsEdited(QString)));
+
+    connect(m_runConfiguration, SIGNAL(isEnabledChanged(bool)),
+            this, SLOT(runConfigurationEnabledChange(bool)));
 }
 
 void S60DeviceRunConfigurationWidget::argumentsEdited(const QString &text)
@@ -86,5 +89,10 @@ void S60DeviceRunConfigurationWidget::argumentsEdited(const QString &text)
     }
 }
 
+void S60DeviceRunConfigurationWidget::runConfigurationEnabledChange(bool enabled)
+{
+    setEnabled(enabled);
+}
+
 } // namespace Internal
 } // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h
index bd640fc4742..02ca1b1c3f0 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h
@@ -50,10 +50,10 @@ class S60DeviceRunConfigurationWidget : public QWidget
     Q_OBJECT
 public:
     explicit S60DeviceRunConfigurationWidget(S60DeviceRunConfiguration *runConfiguration,
-                                      QWidget *parent = 0);
-
+                                             QWidget *parent = 0);
 private slots:
     void argumentsEdited(const QString &text);
+    void runConfigurationEnabledChange(bool enabled);
 
 private:
     S60DeviceRunConfiguration *m_runConfiguration;
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
index 3ffa86e413c..afa6c1be418 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
@@ -78,16 +78,18 @@ QString pathToId(const QString &path)
 
 // ======== S60EmulatorRunConfiguration
 
-S60EmulatorRunConfiguration::S60EmulatorRunConfiguration(Target *parent, const QString &proFilePath) :
+S60EmulatorRunConfiguration::S60EmulatorRunConfiguration(Qt4Target *parent, const QString &proFilePath) :
     RunConfiguration(parent, QLatin1String(S60_EMULATOR_RC_ID)),
-    m_proFilePath(proFilePath)
+    m_proFilePath(proFilePath),
+    m_validParse(parent->qt4Project()->validParse(proFilePath))
 {
     ctor();
 }
 
-S60EmulatorRunConfiguration::S60EmulatorRunConfiguration(Target *parent, S60EmulatorRunConfiguration *source) :
+S60EmulatorRunConfiguration::S60EmulatorRunConfiguration(Qt4Target *parent, S60EmulatorRunConfiguration *source) :
     RunConfiguration(parent, source),
-    m_proFilePath(source->m_proFilePath)
+    m_proFilePath(source->m_proFilePath),
+    m_validParse(source->m_validParse)
 {
     ctor();
 }
@@ -100,8 +102,11 @@ void S60EmulatorRunConfiguration::ctor()
     else
         //: S60 emulator run configuration default display name (no pro-file name)
         setDefaultDisplayName(tr("Run on Symbian Emulator"));
-    connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
-            this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
+    Qt4Project *pro = qt4Target()->qt4Project();
+    connect(pro, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)),
+            this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)));
+    connect(pro, SIGNAL(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
+            this, SLOT(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
 }
 
 
@@ -109,10 +114,29 @@ S60EmulatorRunConfiguration::~S60EmulatorRunConfiguration()
 {
 }
 
-void S60EmulatorRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
+void S60EmulatorRunConfiguration::handleParserState(bool success)
 {
-    if (m_proFilePath == pro->path())
-        emit targetInformationChanged();
+    bool enabled = isEnabled();
+    m_validParse = success;
+    if (enabled != isEnabled()) {
+        qDebug()<<"Emitting isEnabledChanged()"<<!enabled;
+        emit isEnabledChanged(!enabled);
+    }
+}
+
+void S60EmulatorRunConfiguration::proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
+{
+    if (m_proFilePath != pro->path())
+        return;
+    handleParserState(false);
+}
+
+void S60EmulatorRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro, bool success)
+{
+    if (m_proFilePath != pro->path())
+        return;
+    handleParserState(success);
+    emit targetInformationChanged();
 }
 
 Qt4Target *S60EmulatorRunConfiguration::qt4Target() const
@@ -122,6 +146,8 @@ Qt4Target *S60EmulatorRunConfiguration::qt4Target() const
 
 bool S60EmulatorRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
 {
+    if (!m_validParse)
+        return false;
     Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration *>(configuration);
     QTC_ASSERT(qt4bc, return false);
     ToolChain::ToolChainType type = qt4bc->toolChainType();
@@ -203,6 +229,9 @@ S60EmulatorRunConfigurationWidget::S60EmulatorRunConfigurationWidget(S60Emulator
 
     connect(m_runConfiguration, SIGNAL(targetInformationChanged()),
             this, SLOT(updateTargetInformation()));
+
+    connect(m_runConfiguration, SIGNAL(isEnabledChanged(bool)),
+            this, SLOT(runConfigurationEnabledChange(bool)));
 }
 
 void S60EmulatorRunConfigurationWidget::updateTargetInformation()
@@ -210,6 +239,11 @@ void S60EmulatorRunConfigurationWidget::updateTargetInformation()
     m_executableLabel->setText(m_runConfiguration->executable());
 }
 
+void S60EmulatorRunConfigurationWidget::runConfigurationEnabledChange(bool enabled)
+{
+    setEnabled(enabled);
+}
+
 // ======== S60EmulatorRunConfigurationFactory
 
 S60EmulatorRunConfigurationFactory::S60EmulatorRunConfigurationFactory(QObject *parent)
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
index 1f272a2cc59..e4d1c7673f9 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
@@ -59,11 +59,12 @@ class S60EmulatorRunConfiguration : public ProjectExplorer::RunConfiguration
     friend class S60EmulatorRunConfigurationFactory;
 
 public:
-    S60EmulatorRunConfiguration(ProjectExplorer::Target *parent, const QString &proFilePath);
+    S60EmulatorRunConfiguration(Qt4ProjectManager::Internal::Qt4Target *parent, const QString &proFilePath);
     virtual ~S60EmulatorRunConfiguration();
 
     Qt4Target *qt4Target() const;
 
+    using ProjectExplorer::RunConfiguration::isEnabled;
     bool isEnabled(ProjectExplorer::BuildConfiguration *configuration) const;
     QWidget *createConfigurationWidget();
 
@@ -77,17 +78,20 @@ signals:
     void targetInformationChanged();
 
 private slots:
-    void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
+    void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro, bool success);
+    void proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
 
 protected:
-    S60EmulatorRunConfiguration(ProjectExplorer::Target *parent, S60EmulatorRunConfiguration *source);
+    S60EmulatorRunConfiguration(Qt4ProjectManager::Internal::Qt4Target *parent, S60EmulatorRunConfiguration *source);
     virtual bool fromMap(const QVariantMap &map);
 
 private:
     void ctor();
+    void handleParserState(bool sucess);
     void updateTarget();
 
     QString m_proFilePath;
+    bool m_validParse;
 };
 
 class S60EmulatorRunConfigurationWidget : public QWidget
@@ -99,6 +103,7 @@ public:
 
 private slots:
     void updateTargetInformation();
+    void runConfigurationEnabledChange(bool enabled);
 
 private:
     S60EmulatorRunConfiguration *m_runConfiguration;
diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp
index f68c76b9540..9b4ba73449d 100644
--- a/src/plugins/qt4projectmanager/qt4nodes.cpp
+++ b/src/plugins/qt4projectmanager/qt4nodes.cpp
@@ -1243,6 +1243,7 @@ Qt4ProFileNode::Qt4ProFileNode(Qt4Project *project,
                                QObject *parent)
         : Qt4PriFileNode(project, this, filePath),
           m_projectType(InvalidProject),
+          m_validParse(false),
           m_readerExact(0),
           m_readerCumulative(0)
 {
@@ -1307,8 +1308,30 @@ QStringList Qt4ProFileNode::variableValue(const Qt4Variable var) const
     return m_varValues.value(var);
 }
 
+void Qt4ProFileNode::emitProFileInvalidated()
+{
+    foreach (NodesWatcher *watcher, watchers())
+        if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
+            emit qt4Watcher->proFileInvalidated(this);
+
+    foreach (ProjectNode *subNode, subProjectNodes()) {
+        if (Qt4ProFileNode *node = qobject_cast<Qt4ProFileNode *>(subNode)) {
+            node->emitProFileInvalidated();
+        }
+    }
+}
+
+bool Qt4ProFileNode::validParse() const
+{
+    return m_validParse;
+}
+
 void Qt4ProFileNode::scheduleUpdate()
 {
+    if (m_validParse) {
+        m_validParse = false;
+        emitProFileInvalidated();
+    }
     m_project->scheduleAsyncUpdate(this);
 }
 
@@ -1323,6 +1346,13 @@ void Qt4ProFileNode::asyncUpdate()
 
 void Qt4ProFileNode::update()
 {
+    if (m_validParse) {
+        m_validParse = false;
+        foreach (NodesWatcher *watcher, watchers())
+            if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
+                emit qt4Watcher->proFileInvalidated(this);
+    }
+
     setupReader();
     bool parserError = evaluate();
     applyEvaluate(!parserError, false);
@@ -1405,6 +1435,9 @@ void Qt4ProFileNode::applyEvaluate(bool parseResult, bool async)
             m_project->proFileParseError(tr("Error while parsing file %1. Giving up.").arg(m_projectFilePath));
             invalidate();
         }
+        foreach (NodesWatcher *watcher, watchers())
+            if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
+                emit qt4Watcher->proFileUpdated(this, false);
         return;
     }
 
@@ -1634,9 +1667,11 @@ void Qt4ProFileNode::applyEvaluate(bool parseResult, bool async)
     createUiCodeModelSupport();
     updateUiFiles();
 
+    m_validParse = true;
+
     foreach (NodesWatcher *watcher, watchers())
         if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
-            emit qt4Watcher->proFileUpdated(this);
+            emit qt4Watcher->proFileUpdated(this, parseResult);
 
     m_project->destroyProFileReader(m_readerExact);
     if (m_readerCumulative)
diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h
index 104e6e21ca2..222d18dfcc1 100644
--- a/src/plugins/qt4projectmanager/qt4nodes.h
+++ b/src/plugins/qt4projectmanager/qt4nodes.h
@@ -298,6 +298,10 @@ public:
     void update();
     void scheduleUpdate();
 
+    void emitProFileInvalidated();
+
+    bool validParse() const;
+
 public slots:
     void asyncUpdate();
 
@@ -335,6 +339,8 @@ private:
     InstallsList m_installsList;
     friend class Qt4NodeHierarchy;
 
+    bool m_validParse;
+
     // Async stuff
     QFutureWatcher<bool> m_parseFutureWatcher;
     ProFileReader *m_readerExact;
@@ -357,7 +363,8 @@ signals:
                           const QHash<Qt4Variable, QStringList> &oldValues,
                           const QHash<Qt4Variable, QStringList> &newValues);
 
-    void proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *projectNode);
+    void proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *projectNode, bool success);
+    void proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *projectNode);
 
 private:
     // let them emit signals
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index dff2b747cf6..2b5d0f707d5 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -337,8 +337,11 @@ bool Qt4Project::fromMap(const QVariantMap &map)
     connect(QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>)),
             this, SLOT(qtVersionsChanged()));
 
-    connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
-            this, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
+    connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)),
+            this, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *,bool)));
+
+    connect(m_nodesWatcher, SIGNAL(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
+            this, SIGNAL(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
 
     connect(this, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
             this, SLOT(activeTargetWasChanged()));
@@ -618,6 +621,7 @@ void Qt4Project::update()
     if (debug)
         qDebug()<<"Doing sync update";
     m_rootProjectNode->update();
+
     if (debug)
         qDebug()<<"State is now Base";
     m_asyncUpdateState = Base;
@@ -627,6 +631,7 @@ void Qt4Project::scheduleAsyncUpdate(Qt4ProFileNode *node)
 {
     if (m_asyncUpdateState == ShuttingDown)
         return;
+
     if (debug)
         qDebug()<<"schduleAsyncUpdate (node)";
     Q_ASSERT(m_asyncUpdateState != NoState);
@@ -695,6 +700,7 @@ void Qt4Project::scheduleAsyncUpdate()
         qDebug()<<"scheduleAsyncUpdate";
     if (m_asyncUpdateState == ShuttingDown)
         return;
+
     Q_ASSERT(m_asyncUpdateState != NoState);
     if (m_cancelEvaluate) { // we are in progress of canceling
                             // and will start the evaluation after that
@@ -707,12 +713,14 @@ void Qt4Project::scheduleAsyncUpdate()
             qDebug()<<"  update in progress, canceling and setting state to full update pending";
         m_cancelEvaluate = true;
         m_asyncUpdateState = AsyncFullUpdatePending;
+        m_rootProjectNode->emitProFileInvalidated();
         return;
     }
 
     if (debug)
         qDebug()<<"  starting timer for full update, setting state to full update pending";
     m_partialEvaluate.clear();
+    m_rootProjectNode->emitProFileInvalidated();
     m_asyncUpdateState = AsyncFullUpdatePending;
     m_asyncUpdateTimer.start();
 
@@ -950,6 +958,12 @@ Qt4ProFileNode *Qt4Project::rootProjectNode() const
     return m_rootProjectNode;
 }
 
+bool Qt4Project::validParse(const QString &proFilePath) const
+{
+    const Qt4ProFileNode *node = m_rootProjectNode->findProFileFor(proFilePath);
+    return node && node->validParse();
+}
+
 BuildConfigWidget *Qt4Project::createConfigWidget()
 {
     return new Qt4ProjectConfigWidget(this);
diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h
index 6b2f7b21c6b..ac33e968f48 100644
--- a/src/plugins/qt4projectmanager/qt4project.h
+++ b/src/plugins/qt4projectmanager/qt4project.h
@@ -159,6 +159,7 @@ public:
     QList<ProjectExplorer::Project *>dependsOn();
 
     Internal::Qt4ProFileNode *rootProjectNode() const;
+    bool validParse(const QString &proFilePath) const;
 
     virtual QStringList files(FilesMode fileMode) const;
     virtual QString generatedUiHeader(const QString &formFile) const;
@@ -192,9 +193,10 @@ public:
 
     Internal::CentralizedFolderWatcher *centralizedFolderWatcher();
 
+
 signals:
-    /// emitted after parse
-    void proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *node);
+    void proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *node, bool);
+    void proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *node);
     void buildDirectoryInitialized();
 
 public slots:
diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
index 433986b59f4..c53ee3f41ad 100644
--- a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
@@ -102,7 +102,8 @@ Qt4RunConfiguration::Qt4RunConfiguration(Qt4Target *parent, const QString &proFi
     m_runMode(Gui),
     m_isUsingDyldImageSuffix(false),
     m_userSetWokingDirectory(false),
-    m_baseEnvironmentBase(Qt4RunConfiguration::BuildEnvironmentBase)
+    m_baseEnvironmentBase(Qt4RunConfiguration::BuildEnvironmentBase),
+    m_parseSuccess(true)
 {
     ctor();
 }
@@ -116,7 +117,8 @@ Qt4RunConfiguration::Qt4RunConfiguration(Qt4Target *parent, Qt4RunConfiguration
     m_userSetWokingDirectory(source->m_userSetWokingDirectory),
     m_userWorkingDirectory(source->m_userWorkingDirectory),
     m_userEnvironmentChanges(source->m_userEnvironmentChanges),
-    m_baseEnvironmentBase(source->m_baseEnvironmentBase)
+    m_baseEnvironmentBase(source->m_baseEnvironmentBase),
+    m_parseSuccess(source->m_parseSuccess)
 {
     ctor();
 }
@@ -132,6 +134,8 @@ Qt4Target *Qt4RunConfiguration::qt4Target() const
 
 bool Qt4RunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
 {
+    if (!m_parseSuccess)
+        return false;
     Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration *>(configuration);
     QTC_ASSERT(qt4bc, return false);
 
@@ -156,10 +160,26 @@ bool Qt4RunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configu
     return enabled;
 }
 
-void Qt4RunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
+void Qt4RunConfiguration::handleParseState(bool success)
 {
-    if  (m_proFilePath == pro->path())
-        emit effectiveTargetInformationChanged();
+    bool enabled = isEnabled();
+    m_parseSuccess = success;
+    if (enabled != isEnabled())
+        emit isEnabledChanged(!enabled);
+}
+
+void Qt4RunConfiguration::proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro, bool success)
+{
+    if (m_proFilePath != pro->path())
+        return;
+    qDebug()<<"proFileUpdated"<<success;
+    handleParseState(success);
+    emit effectiveTargetInformationChanged();
+}
+
+void Qt4RunConfiguration::proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
+{
+    handleParseState(false);
 }
 
 void Qt4RunConfiguration::ctor()
@@ -168,9 +188,11 @@ void Qt4RunConfiguration::ctor()
 
     connect(qt4Target(), SIGNAL(environmentChanged()),
             this, SIGNAL(baseEnvironmentChanged()));
+    connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)),
+            this, SLOT(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)));
 
-    connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
-            this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
+    connect(qt4Target()->qt4Project(), SIGNAL(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
+            this, SLOT(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
 }
 
 //////
@@ -281,6 +303,8 @@ Qt4RunConfigurationWidget::Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4Run
     m_environmentWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
     vboxTopLayout->addWidget(m_environmentWidget);
 
+    setEnabled(m_qt4RunConfiguration->isEnabled());
+
     connect(m_workingDirectoryEdit, SIGNAL(changed(QString)),
             this, SLOT(workDirectoryEdited()));
 
@@ -319,6 +343,9 @@ Qt4RunConfigurationWidget::Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4Run
 
     connect(qt4RunConfiguration, SIGNAL(baseEnvironmentChanged()),
             this, SLOT(baseEnvironmentChanged()));
+
+    connect(qt4RunConfiguration, SIGNAL(isEnabledChanged(bool)),
+            this, SLOT(runConfigurationEnabledChange(bool)));
 }
 
 Qt4RunConfigurationWidget::~Qt4RunConfigurationWidget()
@@ -374,6 +401,11 @@ void Qt4RunConfigurationWidget::userChangesEdited()
     m_ignoreChange = false;
 }
 
+void Qt4RunConfigurationWidget::runConfigurationEnabledChange(bool enabled)
+{
+    setEnabled(enabled);
+}
+
 void Qt4RunConfigurationWidget::workDirectoryEdited()
 {
     if (m_ignoreChange)
diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.h b/src/plugins/qt4projectmanager/qt4runconfiguration.h
index 0e3850e318d..78861a538da 100644
--- a/src/plugins/qt4projectmanager/qt4runconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt4runconfiguration.h
@@ -75,6 +75,7 @@ public:
     Qt4Target *qt4Target() const;
 
     virtual bool isEnabled(ProjectExplorer::BuildConfiguration *configuration) const;
+    using ProjectExplorer::LocalApplicationRunConfiguration::isEnabled;
     virtual QWidget *createConfigurationWidget();
 
     virtual QString executable() const;
@@ -108,13 +109,15 @@ signals:
     void effectiveTargetInformationChanged();
 
 private slots:
-    void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
+    void proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro, bool success);
+    void proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
 
 protected:
     Qt4RunConfiguration(Qt4Target *parent, Qt4RunConfiguration *source);
     virtual bool fromMap(const QVariantMap &map);
 
 private:
+    void handleParseState(bool success);
     void setRunMode(RunMode runMode);
     void setBaseWorkingDirectory(const QString &workingDirectory);
     QString baseWorkingDirectory() const;
@@ -146,6 +149,7 @@ private:
     QString m_userWorkingDirectory;
     QList<Utils::EnvironmentItem> m_userEnvironmentChanges;
     BaseEnvironmentBase m_baseEnvironmentBase;
+    bool m_parseSuccess;
 };
 
 class Qt4RunConfigurationWidget : public QWidget
@@ -159,7 +163,9 @@ public:
 protected:
     void showEvent(QShowEvent *event);
     void hideEvent(QHideEvent *event);
+
 private slots:
+    void runConfigurationEnabledChange(bool);
     void workDirectoryEdited();
     void workingDirectoryReseted();
     void argumentsEdited(const QString &arguments);
-- 
GitLab