From 2ead91358b367eb1379957cdbb2d1d1b86b35dec Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 14 Oct 2024 12:47:56 +0200 Subject: [PATCH] ProjectExplorer: optimize file state highlight in project tree In general file operations are way more expensive on windows compared to linux. The current implementation of the modification state highlight of a file in the project tree tries to get the responsible version control system in the data function. This is called pretty often and the code that tries to detect which version control system is used iterates over a lot of directories. This results in notable hickups when loading and browsing a fully expanded Qt Creator project tree here. Reduce the number of file operations by caching the file state inside the FileNode. Change-Id: I7d7a82b296494f964ae9259c2e10c1da2ae4aa3a Reviewed-by: Orgad Shaneh --- src/plugins/projectexplorer/projectmodels.cpp | 10 +++++++--- src/plugins/projectexplorer/projectnodes.cpp | 19 +++++++++++++------ src/plugins/projectexplorer/projectnodes.h | 2 ++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index 9a47d1d0473..833643197de 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -471,12 +471,16 @@ void FlatModel::handleProjectAdded(Project *project) void FlatModel::updateVCStatusFor(const Utils::FilePath root, const QStringList &files) { std::for_each(std::begin(files), std::end(files), [root, this](const QString &file) { - const Node *node = ProjectTree::nodeForFile(root.pathAppended(file)); - + const FilePath filePath = root.pathAppended(file); + Node *node = ProjectTree::nodeForFile(filePath); if (!node) return; + FileNode *fileNode = node->asFileNode(); + if (!fileNode) + return; - const QModelIndex index = indexForNode(node); + fileNode->resetModificationState(); + const QModelIndex index = indexForNode(fileNode); emit dataChanged(index, index, {Qt::ForegroundRole}); }); } diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 2ac4859eabb..42e1d604741 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -266,12 +266,14 @@ Core::IVersionControl::FileState FileNode::modificationState() const if (isGenerated()) return Core::IVersionControl::FileState::NoModification; - const FilePath file = filePath(); - const FilePath dir = file.absolutePath(); - if (Core::IVersionControl *vc = Core::VcsManager::findVersionControlForDirectory(dir)) - return vc->modificationState(file); - - return Core::IVersionControl::FileState::NoModification; + if (!m_modificationState) { + const FilePath dir = filePath().absolutePath(); + if (Core::IVersionControl *vc = Core::VcsManager::findVersionControlForDirectory(dir)) + m_modificationState = vc->modificationState(filePath()); + else + m_modificationState = Core::IVersionControl::FileState::NoModification; + } + return *m_modificationState; } bool FileNode::useUnavailableMarker() const @@ -284,6 +286,11 @@ void FileNode::setUseUnavailableMarker(bool useUnavailableMarker) m_useUnavailableMarker = useUnavailableMarker; } +void FileNode::resetModificationState() +{ + m_modificationState.reset(); +} + /*! Returns \c true if the file is automatically generated by a compile step. */ diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index 623dea202dc..1e2e0ff4d3f 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -204,6 +204,7 @@ public: void setHasError(const bool error) const; Core::IVersionControl::FileState modificationState() const; + void resetModificationState(); QIcon icon() const; void setIcon(const QIcon icon); @@ -213,6 +214,7 @@ public: private: FileType m_fileType; + mutable std::optional m_modificationState; mutable QIcon m_icon; mutable bool m_hasError = false; bool m_useUnavailableMarker = false;