diff options
author | Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> | 2014-12-02 12:11:05 +0100 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> | 2014-12-03 10:53:39 +0100 |
commit | cb0d13692657d171e031d48c2879f8d8ce8e0e6a (patch) | |
tree | 263ef82a51f3d64bdbbe9bbcfdf852db4f7353e3 | |
parent | 9cd552a1656c04c1f3ccc92fefc62e2bd36fad37 (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.cpp | 48 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager.h | 3 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager_test.cpp | 63 | ||||
-rw-r--r-- | src/plugins/cpptools/cpptoolsplugin.h | 1 | ||||
-rw-r--r-- | src/plugins/cpptools/editordocumenthandle.cpp | 11 | ||||
-rw-r--r-- | src/plugins/cpptools/editordocumenthandle.h | 6 |
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 |