From eb9e7866f2be6e489318829c16a6bdf0fcf478f5 Mon Sep 17 00:00:00 2001
From: Erik Verbruggen <erik.verbruggen@nokia.com>
Date: Tue, 18 May 2010 13:40:35 +0200
Subject: [PATCH] Fixed QTCREATORBUG-1397.

When adding a new file, refreshing semantic errors in the open editor should
have worked. It now also works for removing existing files.

Done-with: Christian Kamm
---
 src/libs/qmljs/qmljsdocument.cpp                | 13 ++++++++++---
 src/libs/qmljs/qmljsdocument.h                  |  1 +
 src/plugins/qmljseditor/qmljsmodelmanager.cpp   | 10 ++++++++++
 src/plugins/qmljseditor/qmljsmodelmanager.h     |  2 +-
 .../qmljseditor/qmljsmodelmanagerinterface.h    |  1 +
 .../fileformat/filefilteritems.cpp              |  9 ++++++++-
 .../fileformat/filefilteritems.h                |  2 +-
 .../fileformat/qmlprojectitem.cpp               |  3 ++-
 .../fileformat/qmlprojectitem.h                 |  2 +-
 src/plugins/qmlprojectmanager/qmlproject.cpp    | 17 +++++------------
 src/plugins/qmlprojectmanager/qmlproject.h      |  5 +----
 .../qmlprojectmanager/qmlprojectmanager.cpp     | 10 ++--------
 .../qmlprojectmanager/qmlprojectplugin.cpp      |  2 ++
 13 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp
index 3cb6162d4fc..40b71bed698 100644
--- a/src/libs/qmljs/qmljsdocument.cpp
+++ b/src/libs/qmljs/qmljsdocument.cpp
@@ -254,9 +254,7 @@ void Snapshot::insert(const Document::Ptr &document)
         const QString fileName = document->fileName();
         const QString path = document->path();
 
-        Document::Ptr old = _documents.value(fileName);
-        if (old)
-            _documentsByPath.remove(path, old);
+        remove(fileName);
         _documentsByPath.insert(path, document);
         _documents.insert(fileName, document);
     }
@@ -267,6 +265,15 @@ void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info)
     _libraries.insert(QDir::cleanPath(path), info);
 }
 
+void Snapshot::remove(const QString &fileName)
+{
+    Document::Ptr doc = _documents.value(fileName);
+    if (!doc.isNull()) {
+        _documentsByPath.remove(doc->path(), doc);
+        _documents.remove(fileName);
+    }
+}
+
 Document::Ptr Snapshot::documentFromSource(const QString &code,
                                            const QString &fileName) const
 {
diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h
index c81c5132902..51b4e5665ff 100644
--- a/src/libs/qmljs/qmljsdocument.h
+++ b/src/libs/qmljs/qmljsdocument.h
@@ -148,6 +148,7 @@ public:
 
     void insert(const Document::Ptr &document);
     void insertLibraryInfo(const QString &path, const LibraryInfo &info);
+    void remove(const QString &fileName);
 
     Document::Ptr document(const QString &fileName) const;
     QList<Document::Ptr> documentsInDirectory(const QString &path) const;
diff --git a/src/plugins/qmljseditor/qmljsmodelmanager.cpp b/src/plugins/qmljseditor/qmljsmodelmanager.cpp
index 58f44fb07fc..405f94d1c37 100644
--- a/src/plugins/qmljseditor/qmljsmodelmanager.cpp
+++ b/src/plugins/qmljseditor/qmljsmodelmanager.cpp
@@ -164,6 +164,16 @@ void ModelManager::fileChangedOnDisk(const QString &path)
                       this, true);
 }
 
+void ModelManager::removeFiles(const QStringList &files)
+{
+    emit aboutToRemoveFiles(files);
+
+    QMutexLocker locker(&m_mutex);
+
+    foreach (const QString &file, files)
+        _snapshot.remove(file);
+}
+
 void ModelManager::emitDocumentChangedOnDisk(Document::Ptr doc)
 { emit documentChangedOnDisk(doc); }
 
diff --git a/src/plugins/qmljseditor/qmljsmodelmanager.h b/src/plugins/qmljseditor/qmljsmodelmanager.h
index 4377731d4eb..05853561098 100644
--- a/src/plugins/qmljseditor/qmljsmodelmanager.h
+++ b/src/plugins/qmljseditor/qmljsmodelmanager.h
@@ -57,6 +57,7 @@ public:
     virtual void updateSourceFiles(const QStringList &files,
                                    bool emitDocumentOnDiskChanged);
     virtual void fileChangedOnDisk(const QString &path);
+    virtual void removeFiles(const QStringList &files);
 
     void emitDocumentUpdated(QmlJS::Document::Ptr doc);
     void emitLibraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info);
@@ -69,7 +70,6 @@ Q_SIGNALS:
     void projectPathChanged(const QString &projectPath);
     void libraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info);
 
-
 private Q_SLOTS:
     // this should be executed in the GUI thread.
     void onDocumentUpdated(QmlJS::Document::Ptr doc);
diff --git a/src/plugins/qmljseditor/qmljsmodelmanagerinterface.h b/src/plugins/qmljseditor/qmljsmodelmanagerinterface.h
index 0f502227dc9..a39a7d2e176 100644
--- a/src/plugins/qmljseditor/qmljsmodelmanagerinterface.h
+++ b/src/plugins/qmljseditor/qmljsmodelmanagerinterface.h
@@ -56,6 +56,7 @@ public:
     virtual void updateSourceFiles(const QStringList &files,
                                    bool emitDocumentOnDiskChanged) = 0;
     virtual void fileChangedOnDisk(const QString &path) = 0;
+    virtual void removeFiles(const QStringList &files) = 0;
 
     virtual void setProjectImportPaths(const QStringList &importPaths) = 0;
     virtual QStringList importPaths() const = 0;
diff --git a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp
index 0080c629198..d6a8256a25d 100644
--- a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp
@@ -169,8 +169,15 @@ void FileFilterBaseItem::updateFileList()
         newFiles += filesInSubTree(QDir(m_defaultDir), QDir(projectDir), &dirsToBeWatched);
 
     if (newFiles != m_files) {
+        QSet<QString> addedFiles = newFiles;
+        QSet<QString> removedFiles = m_files;
+        QSet<QString> unchanged = newFiles;
+        unchanged.intersect(m_files);
+        addedFiles.subtract(unchanged);
+        removedFiles.subtract(unchanged);
+
         m_files = newFiles;
-        emit filesChanged();
+        emit filesChanged(addedFiles, removedFiles);
     }
 
     // update watched directories
diff --git a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h
index 8ded6d75de9..bcfa22d2421 100644
--- a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h
+++ b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h
@@ -45,7 +45,7 @@ signals:
     void directoryChanged();
     void recursiveChanged();
     void pathsChanged();
-    void filesChanged();
+    void filesChanged(const QSet<QString> &added, const QSet<QString> &removed);
     void filterChanged();
 
 private slots:
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
index 0be5f30f98c..19408dbb091 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
@@ -72,7 +72,8 @@ void QmlProjectItem::setSourceDirectory(const QString &directoryPath)
         FileFilterBaseItem *fileFilter = qobject_cast<FileFilterBaseItem*>(contentElement);
         if (fileFilter) {
             fileFilter->setDefaultDirectory(directoryPath);
-            connect(fileFilter, SIGNAL(filesChanged()), this, SIGNAL(qmlFilesChanged()));
+            connect(fileFilter, SIGNAL(filesChanged(QSet<QString>, QSet<QString>)),
+                    this, SIGNAL(qmlFilesChanged(QSet<QString>, QSet<QString>)));
         }
     }
 
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
index 1271146aaaf..32a2f1df53b 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
@@ -44,7 +44,7 @@ public:
     bool matchesFile(const QString &filePath) const;
 
 signals:
-    void qmlFilesChanged();
+    void qmlFilesChanged(const QSet<QString> &, const QSet<QString> &);
     void sourceDirectoryChanged();
     void importPathsChanged();
 
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index 0b2afe68ac0..0daf385c7bd 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -94,7 +94,8 @@ void QmlProject::parseProject(RefreshOptions options)
                 if (component->isReady()
                     && qobject_cast<QmlProjectItem*>(component->create())) {
                     m_projectItem = qobject_cast<QmlProjectItem*>(component->create());
-                    connect(m_projectItem.data(), SIGNAL(qmlFilesChanged()), this, SLOT(refreshFiles()));
+                    connect(m_projectItem.data(), SIGNAL(qmlFilesChanged(QSet<QString>, QSet<QString>)),
+                            this, SLOT(refreshFiles(QSet<QString>, QSet<QString>)));
                     connect(m_projectItem.data(), SIGNAL(importPathsChanged()), this, SLOT(refreshImportPaths()));
                     refreshImportPaths();
                 } else {
@@ -121,20 +122,10 @@ void QmlProject::parseProject(RefreshOptions options)
 
 void QmlProject::refresh(RefreshOptions options)
 {
-    const QSet<QString> oldFiles = m_files.toSet();
-
     parseProject(options);
 
     if (options & Files)
         m_rootNode->refresh();
-
-    const QSet<QString> newFiles = m_files.toSet();
-    QStringList removedPaths;
-    foreach (const QString &oldFile, oldFiles)
-        if (!newFiles.contains(oldFile))
-            removedPaths.append(oldFile);
-    if (!removedPaths.isEmpty())
-        emit filesRemovedFromProject(removedPaths);
 }
 
 QStringList QmlProject::convertToAbsoluteFiles(const QStringList &paths) const
@@ -188,9 +179,11 @@ void QmlProject::refreshProjectFile()
     refresh(QmlProject::ProjectFile | Files);
 }
 
-void QmlProject::refreshFiles()
+void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString> &removed)
 {
     refresh(Files);
+    if (!removed.isEmpty())
+        m_modelManager->removeFiles(removed.toList());
 }
 
 void QmlProject::refreshImportPaths()
diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h
index bab39524c42..132622e27ff 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.h
+++ b/src/plugins/qmlprojectmanager/qmlproject.h
@@ -101,12 +101,9 @@ public:
 
     bool addFiles(const QStringList &filePaths);
 
-signals:
-    void filesRemovedFromProject(const QStringList removedPaths);
-
 private slots:
     void refreshProjectFile();
-    void refreshFiles();
+    void refreshFiles(const QSet<QString> &added, const QSet<QString> &removed);
     void refreshImportPaths();
 
 protected:
diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp b/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp
index a1d3092bdb9..cd8cc19f3ac 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp
@@ -79,14 +79,8 @@ ProjectExplorer::Project *Manager::openProject(const QString &fileName)
         }
     }
 
-    if (fileInfo.isFile()) {
-        QmlProject *project = new QmlProject(this, fileName);
-        QmlTaskManager *taskManager = QmlTaskManager::instance();
-        if (taskManager)
-            connect(project, SIGNAL(filesRemovedFromProject(QStringList)),
-                    taskManager, SLOT(documentsRemoved(const QStringList)));
-        return project;
-    }
+    if (fileInfo.isFile())
+        return new QmlProject(this, fileName);
 
     return 0;
 }
diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
index f58d3ecb5e5..144d5d00880 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
@@ -103,6 +103,8 @@ void QmlProjectPlugin::extensionsInitialized()
     Q_ASSERT(modelManager);
     connect(modelManager, SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)),
             m_qmlTaskManager, SLOT(documentChangedOnDisk(QmlJS::Document::Ptr)));
+    connect(modelManager, SIGNAL(aboutToRemoveFiles(QStringList)),
+            m_qmlTaskManager, SLOT(documentsRemoved(QStringList)));
 }
 
 } // namespace Internal
-- 
GitLab