From fcbb38988bd8ba8f8e29b5051179ac6bf25904f6 Mon Sep 17 00:00:00 2001
From: dt <qtc-committer@nokia.com>
Date: Thu, 31 Mar 2011 17:43:48 +0200
Subject: [PATCH] CMakeProjectManager: Change editing cmake files to not pop up
 a dialog

Stop watching the cmake files for changes, instead watch the cbp file
for changes. Warn the user that changes in the CMakeLists.txt via a
infobar.

Fixes or obsolets a few bug reports:
Task-Nr: QTCREATORBUG-3123
Task-Nr: QTCREATORBUG-3353
Task-Nr: QTCREATORBUG-2487
---
 .../cmakeprojectmanager/cmakeeditor.cpp       | 32 ++++++++++++++++-
 src/plugins/cmakeprojectmanager/cmakeeditor.h |  4 +++
 .../cmakeprojectmanager/cmakeproject.cpp      | 36 +++++++++----------
 .../cmakeprojectmanager/cmakeproject.h        |  7 ++--
 .../projectexplorer/projectexplorer.cpp       |  6 ++++
 src/plugins/projectexplorer/projectexplorer.h |  2 ++
 6 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
index 1dbc697899a..a69fcb3ded7 100644
--- a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
@@ -36,7 +36,10 @@
 #include "cmakehighlighter.h"
 #include "cmakeeditorfactory.h"
 #include "cmakeprojectconstants.h"
+#include "cmakeproject.h"
 
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/session.h>
 #include <texteditor/fontsettings.h>
 #include <texteditor/texteditoractionhandler.h>
 #include <texteditor/texteditorconstants.h>
@@ -55,7 +58,10 @@ CMakeEditor::CMakeEditor(CMakeEditorWidget *editor)
   : BaseTextEditor(editor),
     m_context(CMakeProjectManager::Constants::C_CMAKEEDITOR,
               TextEditor::Constants::C_TEXTEDITOR)
-{ }
+{
+    connect (this, SIGNAL(changed()),
+             this, SLOT(markAsChanged()));
+}
 
 Core::Context CMakeEditor::context() const
 {
@@ -76,6 +82,30 @@ QString CMakeEditor::id() const
     return QLatin1String(CMakeProjectManager::Constants::CMAKE_EDITOR_ID);
 }
 
+void CMakeEditor::markAsChanged()
+{
+    Core::EditorManager::instance()->
+            showEditorInfoBar(QLatin1String("CMakeEditor.RunCMake"),
+                              tr("Changes to cmake files are shown in the project tree after building."),
+                              tr("Build now"),
+                              this, SLOT(build()));
+}
+
+void CMakeEditor::build()
+{
+    QList<ProjectExplorer::Project *> projects =
+            ProjectExplorer::ProjectExplorerPlugin::instance()->session()->projects();
+    foreach (ProjectExplorer::Project *p, projects) {
+        CMakeProject *cmakeProject = qobject_cast<CMakeProject *>(p);
+        if (cmakeProject) {
+            if (cmakeProject->isProjectFile(file()->fileName())) {
+                ProjectExplorer::ProjectExplorerPlugin::instance()->buildProject(cmakeProject);
+                break;
+            }
+        }
+    }
+}
+
 //
 // CMakeEditor
 //
diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.h b/src/plugins/cmakeprojectmanager/cmakeeditor.h
index 460f90eb81e..2ce08908df0 100644
--- a/src/plugins/cmakeprojectmanager/cmakeeditor.h
+++ b/src/plugins/cmakeprojectmanager/cmakeeditor.h
@@ -53,6 +53,7 @@ class CMakeManager;
 
 class CMakeEditor : public TextEditor::BaseTextEditor
 {
+    Q_OBJECT
 public:
     CMakeEditor(CMakeEditorWidget *);
     Core::Context context() const;
@@ -61,6 +62,9 @@ public:
     Core::IEditor *duplicate(QWidget *parent);
     QString id() const;
     bool isTemporary() const { return false; }
+private slots:
+    void markAsChanged();
+    void build();
 private:
     const Core::Context m_context;
 };
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index 399e83f0c23..a882e5ebf93 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -97,7 +97,6 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
     : m_manager(manager),
       m_fileName(fileName),
       m_rootNode(new CMakeProjectNode(m_fileName)),
-      m_insideFileChanged(false),
       m_lastEditor(0)
 {
     m_file = new CMakeFile(this, fileName);
@@ -126,15 +125,8 @@ CMakeProject::~CMakeProject()
 void CMakeProject::fileChanged(const QString &fileName)
 {
     Q_UNUSED(fileName)
-    if (!activeTarget() ||
-        !activeTarget()->activeBuildConfiguration())
-        return;
 
-    if (m_insideFileChanged)
-        return;
-    m_insideFileChanged = true;
-    changeActiveBuildConfiguration(activeTarget()->activeBuildConfiguration());
-    m_insideFileChanged = false;
+    parseCMakeLists();
 }
 
 void CMakeProject::changeActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *bc)
@@ -201,6 +193,8 @@ bool CMakeProject::parseCMakeLists()
         !activeTarget()->activeBuildConfiguration())
         return false;
 
+    Core::EditorManager::instance()->hideEditorInfoBar("CMakeEditor.RunCMake");
+
     // Find cbp file
     CMakeBuildConfiguration *activeBC = activeTarget()->activeBuildConfiguration();
     QString cbpFile = CMakeManager::findCbpFile(activeBC->buildDirectory());
@@ -212,12 +206,17 @@ bool CMakeProject::parseCMakeLists()
     //qDebug()<<"Parsing file "<<cbpFile;
     if (!cbpparser.parseCbpFile(cbpFile)) {
         // TODO report error
-        qDebug()<<"Parsing failed";
-        // activeBC->updateToolChain(QString::null);
         emit buildTargetsChanged();
         return false;
     }
 
+    foreach (const QString &file, m_watcher->files())
+        if (file != cbpFile)
+            m_watcher->removePath(file);
+
+    // how can we ensure that it is completly written?
+    m_watcher->addPath(cbpFile);
+
     // ToolChain
     // activeBC->updateToolChain(cbpparser.compilerName());
     m_projectName = cbpparser.projectName();
@@ -238,12 +237,6 @@ bool CMakeProject::parseCMakeLists()
         projectFiles.insert(cmakeListTxt);
     }
 
-    QSet<QString> added = projectFiles;
-    added.subtract(m_watchedFiles);
-    foreach(const QString &add, added)
-        m_watcher->addFile(add);
-    foreach(const QString &remove, m_watchedFiles.subtract(projectFiles))
-        m_watcher->removeFile(remove);
     m_watchedFiles = projectFiles;
 
     m_files.clear();
@@ -279,7 +272,6 @@ bool CMakeProject::parseCMakeLists()
     }
     cmakeCache.close();
 
-    //qDebug()<<"Updating CodeModel";
     createUiCodeModelSupport();
 
     if (!activeBC->toolChain())
@@ -317,12 +309,16 @@ bool CMakeProject::parseCMakeLists()
             m_codeModelFuture = modelmanager->updateSourceFiles(pinfo.sourceFiles);
         }
     }
-
     emit buildTargetsChanged();
     emit fileListChanged();
     return true;
 }
 
+bool CMakeProject::isProjectFile(const QString &fileName)
+{
+    return m_watchedFiles.contains(fileName);
+}
+
 QList<CMakeBuildTarget> CMakeProject::buildTargets() const
 {
     return m_buildTargets;
@@ -562,7 +558,7 @@ bool CMakeProject::fromMap(const QVariantMap &map)
         }
     }
 
-    m_watcher = new ProjectExplorer::FileWatcher(this);
+    m_watcher = new QFileSystemWatcher(this);
     connect(m_watcher, SIGNAL(fileChanged(QString)), this, SLOT(fileChanged(QString)));
 
     if (!parseCMakeLists()) // Gets the directory from the active buildconfiguration
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h
index df1b9a7a577..52540fba229 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.h
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.h
@@ -46,9 +46,11 @@
 #include <projectexplorer/filewatcher.h>
 #include <projectexplorer/buildconfiguration.h>
 #include <coreplugin/ifile.h>
+#include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/editormanager/ieditor.h>
 
 #include <QtCore/QXmlStreamReader>
+#include <QtCore/QFileSystemWatcher>
 #include <QtGui/QPushButton>
 #include <QtGui/QLineEdit>
 
@@ -105,6 +107,8 @@ public:
 
     QString uicCommand() const;
 
+    bool isProjectFile(const QString &fileName);
+
 signals:
     /// emitted after parsing
     void buildTargetsChanged();
@@ -142,8 +146,7 @@ private:
     CMakeProjectNode *m_rootNode;
     QStringList m_files;
     QList<CMakeBuildTarget> m_buildTargets;
-    ProjectExplorer::FileWatcher *m_watcher;
-    bool m_insideFileChanged;
+    QFileSystemWatcher *m_watcher;
     QSet<QString> m_watchedFiles;
     QFuture<void> m_codeModelFuture;
 
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 06f9dc4901b..72d6ffb5b96 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -1690,6 +1690,12 @@ void ProjectExplorerPlugin::buildProjectOnly()
     queue(QList<Project *>() << session()->startupProject(), QStringList() << Constants::BUILDSTEPS_BUILD);
 }
 
+void ProjectExplorerPlugin::buildProject(ProjectExplorer::Project *p)
+{
+    queue(d->m_session->projectOrder(p),
+          QStringList() << Constants::BUILDSTEPS_BUILD);
+}
+
 void ProjectExplorerPlugin::buildProject()
 {
     queue(d->m_session->projectOrder(session()->startupProject()),
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index 85cc013fb85..8b09c7df8b0 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -124,6 +124,8 @@ public:
     void addExistingFiles(ProjectExplorer::ProjectNode *projectNode, const QStringList &filePaths);
     void addExistingFiles(const QStringList &filePaths);
 
+    void buildProject(ProjectExplorer::Project *p);
+
 signals:
     void aboutToShowContextMenu(ProjectExplorer::Project *project,
                                 ProjectExplorer::Node *node);
-- 
GitLab