aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2014-12-02 12:11:05 +0100
committerNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2014-12-03 10:53:39 +0100
commitcb0d13692657d171e031d48c2879f8d8ce8e0e6a (patch)
tree263ef82a51f3d64bdbbe9bbcfdf852db4f7353e3
parent9cd552a1656c04c1f3ccc92fefc62e2bd36fad37 (diff)
CppTools: Update document on activation
...if the project was updated in the meanwhile. If a project is updated mark invisible editor documents dirty and update them if they get focus. This also fixes document highlighting when restoring a session for documents that the user "switched away" before the project info is pushed to CppModelManager. This completes CppTools: Update visible documents on project update commit c2eb91e053332d010adc8b9e7918d9de28ef4c90 which only takes care of visible documents. Task-number: QTCREATORBUG-13270 Change-Id: Id445e7f509deac5d03194aecc54ce4629b7926ce Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp48
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h3
-rw-r--r--src/plugins/cpptools/cppmodelmanager_test.cpp63
-rw-r--r--src/plugins/cpptools/cpptoolsplugin.h1
-rw-r--r--src/plugins/cpptools/editordocumenthandle.cpp11
-rw-r--r--src/plugins/cpptools/editordocumenthandle.h6
6 files changed, 121 insertions, 11 deletions
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 5540a2f2da..adbb7b8bfa 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -300,6 +300,10 @@ CppModelManager::CppModelManager(QObject *parent)
this, SLOT(onAboutToLoadSession()));
connect(sessionManager, SIGNAL(aboutToUnloadSession(QString)),
this, SLOT(onAboutToUnloadSession()));
+
+ connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
+ this, &CppModelManager::onCurrentEditorChanged);
+
connect(Core::DocumentManager::instance(), &Core::DocumentManager::allDocumentsRenamed,
this, &CppModelManager::renameIncludes);
@@ -687,21 +691,32 @@ void CppModelManager::recalculateFileToProjectParts()
}
}
-void CppModelManager::updateVisibleEditorDocuments() const
+void CppModelManager::updateCppEditorDocuments() const
{
- QSet<QString> visibleDocumentsInEditMode;
+ // Refresh visible documents
+ QSet<Core::IDocument *> visibleCppEditorDocuments;
foreach (Core::IEditor *editor, Core::EditorManager::visibleEditors()) {
- if (const Core::IDocument *document = editor->document()) {
+ if (Core::IDocument *document = editor->document()) {
const QString filePath = document->filePath();
- if (!filePath.isEmpty())
- visibleDocumentsInEditMode.insert(filePath);
+ if (filePath.isEmpty())
+ continue;
+ if (EditorDocumentHandle *editor = editorDocument(filePath)) {
+ visibleCppEditorDocuments.insert(document);
+ editor->processor()->run();
+ }
}
}
- // Re-process these documents
- foreach (const QString &filePath, visibleDocumentsInEditMode) {
- if (EditorDocumentHandle *editor = editorDocument(filePath))
- editor->processor()->run();
+ // Mark invisible documents dirty
+ QSet<Core::IDocument *> invisibleCppEditorDocuments
+ = Core::DocumentModel::openedDocuments().toSet();
+ invisibleCppEditorDocuments.subtract(visibleCppEditorDocuments);
+ foreach (Core::IDocument *document, invisibleCppEditorDocuments) {
+ const QString filePath = document->filePath();
+ if (filePath.isEmpty())
+ continue;
+ if (EditorDocumentHandle *document = editorDocument(filePath))
+ document->setNeedsRefresh(true);
}
}
@@ -784,7 +799,7 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
// However, on e.g. a session restore first the editor documents are created and then the
// project updates come in. That is, there are no reasonable dependency tables based on
// resolved includes that we could rely on.
- updateVisibleEditorDocuments();
+ updateCppEditorDocuments();
// Trigger reindexing
return updateSourceFiles(filesToReindex, ForcedProgressNotification);
@@ -871,6 +886,19 @@ void CppModelManager::onSourceFilesRefreshed() const
}
}
+void CppModelManager::onCurrentEditorChanged(Core::IEditor *editor)
+{
+ if (!editor || !editor->document())
+ return;
+
+ if (EditorDocumentHandle *cppEditorDocument = editorDocument(editor->document()->filePath())) {
+ if (cppEditorDocument->needsRefresh()) {
+ cppEditorDocument->setNeedsRefresh(false);
+ cppEditorDocument->processor()->run();
+ }
+ }
+}
+
void CppModelManager::onAboutToLoadSession()
{
if (d->m_delayedGcTimer.isActive())
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index e196be585e..41acf24325 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -184,12 +184,13 @@ private slots:
void onProjectAdded(ProjectExplorer::Project *project);
void onAboutToRemoveProject(ProjectExplorer::Project *project);
void onSourceFilesRefreshed() const;
+ void onCurrentEditorChanged(Core::IEditor *editor);
void onCoreAboutToClose();
private:
void delayedGC();
void recalculateFileToProjectParts();
- void updateVisibleEditorDocuments() const;
+ void updateCppEditorDocuments() const;
void replaceSnapshot(const CPlusPlus::Snapshot &newSnapshot);
void removeFilesFromSnapshot(const QSet<QString> &removedFiles);
diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp
index b4065f1328..0e7b35f364 100644
--- a/src/plugins/cpptools/cppmodelmanager_test.cpp
+++ b/src/plugins/cpptools/cppmodelmanager_test.cpp
@@ -1037,6 +1037,69 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
}
}
+void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
+{
+ ModelManagerTestHelper helper;
+ CppModelManager *mm = CppModelManager::instance();
+
+ MyTestDataDir testDataDirectory(_("testdata_defines"));
+ const QString fileA = testDataDirectory.file(_("main1.cpp")); // content not relevant
+ const QString fileB = testDataDirectory.file(_("main2.cpp")); // content not relevant
+
+ // Open file A in editor
+ Core::IEditor *editorA = Core::EditorManager::openEditor(fileA);
+ QVERIFY(editorA);
+ EditorCloser closerA(editorA);
+ QCOMPARE(Core::DocumentModel::openedDocuments().size(), 1);
+
+ EditorDocumentHandle *editorDocumentA = mm->editorDocument(fileA);
+ QVERIFY(editorDocumentA);
+ ProjectPart::Ptr documentAProjectPart = editorDocumentA->processor()->parser()->projectPart();
+ QVERIFY(!documentAProjectPart->project);
+
+ // Open file B in editor
+ Core::IEditor *editorB = Core::EditorManager::openEditor(fileB);
+ QVERIFY(editorB);
+ EditorCloser closerB(editorB);
+ QCOMPARE(Core::DocumentModel::openedDocuments().size(), 2);
+
+ EditorDocumentHandle *editorDocumentB = mm->editorDocument(fileB);
+ QVERIFY(editorDocumentB);
+ ProjectPart::Ptr documentBProjectPart = editorDocumentB->processor()->parser()->projectPart();
+ QVERIFY(!documentBProjectPart->project);
+
+ // Switch back to document A
+ Core::EditorManager::activateEditor(editorA);
+
+ // Open/update related project
+ Project *project = helper.createProject(_("test_modelmanager_updateEditorsAfterProjectUpdate"));
+
+ ProjectPart::Ptr part(new ProjectPart);
+ part->project = project;
+ part->files.append(ProjectFile(fileA, ProjectFile::CXXSource));
+ part->files.append(ProjectFile(fileB, ProjectFile::CXXSource));
+ part->languageVersion = ProjectPart::CXX11;
+ part->qtVersion = ProjectPart::NoQt;
+
+ ProjectInfo pi = mm->projectInfo(project);
+ pi.appendProjectPart(part);
+ pi.finish();
+ updateProjectInfo(mm, &helper, pi);
+
+ // ... and check for updated editor document A
+ while (editorDocumentA->processor()->isParserRunning())
+ QCoreApplication::processEvents();
+ documentAProjectPart = editorDocumentA->processor()->parser()->projectPart();
+ QCOMPARE(documentAProjectPart->project, project);
+
+ // Switch back to document B and check if that's updated, too
+ Core::EditorManager::activateEditor(editorB);
+ while (editorDocumentB->processor()->isParserRunning())
+ QCoreApplication::processEvents();
+ documentBProjectPart = editorDocumentB->processor()->parser()->projectPart();
+ QCOMPARE(documentBProjectPart->project, project);
+}
+
void CppToolsPlugin::test_modelmanager_renameIncludes()
{
struct ModelManagerGCHelper {
diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h
index c225a667fc..a4200cc4de 100644
--- a/src/plugins/cpptools/cpptoolsplugin.h
+++ b/src/plugins/cpptools/cpptoolsplugin.h
@@ -151,6 +151,7 @@ private slots:
void test_modelmanager_dont_gc_opened_files();
void test_modelmanager_defines_per_project();
void test_modelmanager_defines_per_editor();
+ void test_modelmanager_updateEditorsAfterProjectUpdate();
void test_modelmanager_precompiled_headers();
void test_modelmanager_renameIncludes();
diff --git a/src/plugins/cpptools/editordocumenthandle.cpp b/src/plugins/cpptools/editordocumenthandle.cpp
index 58d93372ca..9e40aca5b2 100644
--- a/src/plugins/cpptools/editordocumenthandle.cpp
+++ b/src/plugins/cpptools/editordocumenthandle.cpp
@@ -40,6 +40,7 @@ namespace CppTools {
*/
EditorDocumentHandle::EditorDocumentHandle()
+ : m_needsRefresh(false)
{
}
@@ -47,4 +48,14 @@ EditorDocumentHandle::~EditorDocumentHandle()
{
}
+bool EditorDocumentHandle::needsRefresh() const
+{
+ return m_needsRefresh;
+}
+
+void EditorDocumentHandle::setNeedsRefresh(bool needsRefresh)
+{
+ m_needsRefresh = needsRefresh;
+}
+
} // namespace CppTools
diff --git a/src/plugins/cpptools/editordocumenthandle.h b/src/plugins/cpptools/editordocumenthandle.h
index aa265f91be..d40fd0e9ed 100644
--- a/src/plugins/cpptools/editordocumenthandle.h
+++ b/src/plugins/cpptools/editordocumenthandle.h
@@ -42,6 +42,9 @@ public:
EditorDocumentHandle();
virtual ~EditorDocumentHandle();
+ bool needsRefresh() const;
+ void setNeedsRefresh(bool needsRefresh);
+
// For the Working Copy
virtual QString filePath() const = 0;
virtual QByteArray contents() const = 0;
@@ -49,6 +52,9 @@ public:
// For updating if new project info is set
virtual BaseEditorDocumentProcessor *processor() = 0;
+
+private:
+ bool m_needsRefresh;
};
} // namespace CppTools