ProjectExplorer: Introduce some FolderNode convenience functions

... and use them.

Change-Id: I9f5237e5eac30715c2effbd3301dd2a70516d2a9
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
hjk
2017-01-26 17:02:16 +01:00
parent 8427932a0e
commit 87304b3ce0
8 changed files with 117 additions and 139 deletions

View File

@@ -281,13 +281,12 @@ void BuildDirManager::generateProjectTree(CMakeListsNode *root, const QList<cons
const Utils::FileName projectFile = m_buildConfiguration->target()->project()->projectFilePath();
root->makeEmpty();
m_reader->generateProjectTree(root, allFiles);
// Make sure the top level CMakeLists.txt is always visible:
if (root->fileNodes().isEmpty()
&& root->folderNodes().isEmpty()
&& root->projectNodes().isEmpty())
root->addFileNodes({ new FileNode(projectFile, FileType::Project, false) });
if (root->isEmpty())
root->addFileNode(new FileNode(projectFile, FileType::Project, false));
}
QSet<Core::Id> BuildDirManager::updateCodeModel(CppTools::ProjectPartBuilder &ppBuilder)

View File

@@ -217,9 +217,6 @@ void CMakeBuildConfiguration::generateProjectTree(CMakeListsNode *root,
if (!m_buildDirManager || m_buildDirManager->isParsing())
return;
root->removeProjectNodes();
root->setFolderNodes({});
root->setFileNodes({});
m_buildDirManager->generateProjectTree(root, allFiles);
}

View File

@@ -231,7 +231,7 @@ FolderNode *setupCMakeVFolder(FolderNode *base, const Utils::FileName &basePath,
if (!folder) {
folder = new VirtualFolderNode(basePath, priority);
folder->setDisplayName(displayName);
base->addFolderNodes({ folder });
base->addFolderNode(folder);
}
folder->buildTree(files);
return folder;
@@ -583,7 +583,7 @@ void ServerModeReader::updateCMakeLists(CMakeListsNode *root, const QList<FileNo
FileNode *cmFn = cmln->fileNode(fn->filePath());
if (!cmFn) {
cmFn = fn;
cmln->addFileNodes({ cmFn });
cmln->addFileNode(cmFn);
}
// Update displayName of CMakeListsNode:
const QString dn = prefix.isEmpty() ? k : k.mid(prefix.count() + 1);

View File

@@ -412,7 +412,7 @@ FolderNode *FolderNode::recursiveFindOrCreateFolderNode(const QString &directory
// No FolderNode yet, so create it
auto tmp = new ProjectExplorer::FolderNode(path);
tmp->setDisplayName(part);
parent->addFolderNodes(QList<ProjectExplorer::FolderNode *>({ tmp }));
parent->addFolderNode(tmp);
next = tmp;
}
parent = next;
@@ -431,7 +431,7 @@ void FolderNode::buildTree(QList<FileNode *> &files, const Utils::FileName &over
// Get relative path to rootNode
QString parentDir = fn->filePath().toFileInfo().absolutePath();
ProjectExplorer::FolderNode *folder = recursiveFindOrCreateFolderNode(parentDir, overrideBaseDir);
folder->addFileNodes({ fn });
folder->addFileNode(fn);
}
}
@@ -514,30 +514,29 @@ FolderNode::AddNewInformation FolderNode::addNewInformation(const QStringList &f
addFiles.
*/
void FolderNode::addFileNodes(const QList<FileNode *> &files)
void FolderNode::addFileNode(FileNode *file)
{
Q_ASSERT(managingProject());
if (files.isEmpty())
return;
QTC_ASSERT(!file->parentFolderNode(),
qDebug("File node has already a parent folder"));
foreach (FileNode *file, files) {
QTC_ASSERT(!file->parentFolderNode(),
qDebug("File node has already a parent folder"));
file->setParentFolderNode(this);
// Now find the correct place to insert file
if (m_fileNodes.count() == 0
|| m_fileNodes.last() < file) {
// empty list or greater then last node
m_fileNodes.append(file);
} else {
auto it = std::lower_bound(m_fileNodes.begin(), m_fileNodes.end(), file);
m_fileNodes.insert(it, file);
}
file->setParentFolderNode(this);
// Now find the correct place to insert file
if (m_fileNodes.count() == 0
|| m_fileNodes.last() < file) {
// empty list or greater then last node
m_fileNodes.append(file);
} else {
auto it = std::lower_bound(m_fileNodes.begin(), m_fileNodes.end(), file);
m_fileNodes.insert(it, file);
}
}
ProjectTree::emitDataChanged();
void FolderNode::addFileNodes(const QList<FileNode *> &files)
{
foreach (FileNode *file, files)
addFileNode(file);
}
/*!
@@ -548,29 +547,24 @@ void FolderNode::addFileNodes(const QList<FileNode *> &files)
removeFiles.
*/
void FolderNode::removeFileNodes()
{
qDeleteAll(m_fileNodes);
m_fileNodes.clear();
ProjectTree::emitDataChanged();
}
void FolderNode::removeFileNodes(const QList<FileNode *> &files)
{
for (FileNode *file : files)
removeFileNode(file);
}
void FolderNode::removeFileNode(FileNode *file)
{
Q_ASSERT(managingProject());
if (files.isEmpty())
return;
QList<FileNode*> toRemove = files;
Utils::sort(toRemove);
auto toRemoveIter = toRemove.constBegin();
auto filesIter = m_fileNodes.begin();
for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) {
while (*filesIter != *toRemoveIter) {
++filesIter;
QTC_ASSERT(filesIter != m_fileNodes.end(),
qDebug("File to remove is not part of specified folder!"));
}
delete *filesIter;
filesIter = m_fileNodes.erase(filesIter);
}
ProjectTree::emitDataChanged();
m_fileNodes.removeAll(file);
delete file;
}
void FolderNode::setFileNodes(const QList<FileNode *> &files)
@@ -586,35 +580,30 @@ void FolderNode::setFileNodes(const QList<FileNode *> &files)
Adds folder nodes specified by \a subFolders to the node hierarchy below
\a parentFolder and emits the corresponding signals.
*/
void FolderNode::addFolderNodes(const QList<FolderNode*> &subFolders)
void FolderNode::addFolderNode(FolderNode *folder)
{
Q_ASSERT(managingProject());
if (subFolders.isEmpty())
return;
QTC_ASSERT(!folder->parentFolderNode(),
qDebug("Project node has already a parent folder"));
folder->setParentFolderNode(this);
foreach (FolderNode *folder, subFolders) {
QTC_ASSERT(!folder->parentFolderNode(),
qDebug("Project node has already a parent folder"));
folder->setParentFolderNode(this);
// Find the correct place to insert
if (m_folderNodes.count() == 0
|| m_folderNodes.last() < folder) {
// empty list or greater then last node
m_folderNodes.append(folder);
} else {
// Binary Search for insertion point
auto it = std::lower_bound(m_folderNodes.begin(), m_folderNodes.end(), folder);
m_folderNodes.insert(it, folder);
}
// project nodes have to be added via addProjectNodes
QTC_ASSERT(folder->nodeType() != NodeType::Project,
qDebug("project nodes have to be added via addProjectNodes"));
// Find the correct place to insert
if (m_folderNodes.count() == 0
|| m_folderNodes.last() < folder) {
// empty list or greater then last node
m_folderNodes.append(folder);
} else {
// Binary Search for insertion point
auto it = std::lower_bound(m_folderNodes.begin(), m_folderNodes.end(), folder);
m_folderNodes.insert(it, folder);
}
}
ProjectTree::emitDataChanged();
void FolderNode::addFolderNodes(const QList<FolderNode*> &subFolders)
{
for (FolderNode *folder : subFolders)
addFolderNode(folder);
}
/*!
@@ -623,30 +612,25 @@ void FolderNode::addFolderNodes(const QList<FolderNode*> &subFolders)
All objects in the \a subFolders list are deleted.
*/
void FolderNode::removeFolderNodes()
{
qDeleteAll(m_folderNodes);
m_folderNodes.clear();
ProjectTree::emitDataChanged();
}
void FolderNode::removeFolderNodes(const QList<FolderNode*> &subFolders)
{
Q_ASSERT(managingProject());
for (FolderNode *folder : subFolders)
removeFolderNode(folder);
}
if (subFolders.isEmpty())
return;
QList<FolderNode*> toRemove = subFolders;
Utils::sort(toRemove);
auto toRemoveIter = toRemove.constBegin();
auto folderIter = m_folderNodes.begin();
for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) {
QTC_ASSERT((*toRemoveIter)->nodeType() != NodeType::Project,
qDebug("project nodes have to be removed via removeProjectNodes"));
while (*folderIter != *toRemoveIter) {
++folderIter;
QTC_ASSERT(folderIter != m_folderNodes.end(),
qDebug("Folder to remove is not part of specified folder!"));
}
delete *folderIter;
folderIter = m_folderNodes.erase(folderIter);
}
void FolderNode::removeFolderNode(FolderNode *folder)
{
Q_ASSERT(managingProject());
m_folderNodes.removeAll(folder);
delete folder;
ProjectTree::emitDataChanged();
}
@@ -841,6 +825,18 @@ void ProjectNode::removeProjectNode(ProjectNode *subProject)
delete subProject;
}
void ProjectNode::makeEmpty()
{
removeProjectNodes();
setFolderNodes({});
setFileNodes({});
}
bool ProjectNode::isEmpty() const
{
return m_fileNodes.isEmpty() && m_folderNodes.isEmpty() && m_projectNodes.isEmpty();
}
/*!
\class ProjectExplorer::SessionNode
*/

View File

@@ -245,14 +245,23 @@ public:
// determines if node will be shown in the flat view, by default folder and projects aren't shown
virtual bool showInSimpleTree() const;
void addFileNode(FileNode *file);
void removeFileNodes();
void removeFileNode(FileNode *file);
void addFileNodes(const QList<FileNode*> &files);
void removeFileNodes(const QList<FileNode*> &files);
void setFileNodes(const QList<FileNode*> &files);
void addFolderNode(FolderNode *subFolder);
void removeFolderNodes();
void removeFolderNode(FolderNode *subFolder);
void addFolderNodes(const QList<FolderNode*> &subFolders);
void removeFolderNodes(const QList<FolderNode*> &subFolders);
void setFolderNodes(const QList<FolderNode*> &folders);
void makeEmpty();
bool isEmpty() const;
FolderNode *asFolderNode() override { return this; }
const FolderNode *asFolderNode() const override { return this; }
@@ -304,6 +313,9 @@ public:
void removeProjectNodes();
void removeProjectNode(ProjectNode *subProject);
void makeEmpty();
bool isEmpty() const;
ProjectNode *asProjectNode() final { return this; }
const ProjectNode *asProjectNode() const final { return this; }

View File

@@ -322,10 +322,9 @@ QbsGroupNode::QbsGroupNode(const qbs::GroupData &grp, const QString &productPath
setIcon(m_groupIcon);
QbsFileNode *idx = new QbsFileNode(Utils::FileName::fromString(grp.location().filePath()),
ProjectExplorer::FileType::Project, false,
grp.location().line());
addFileNodes(QList<ProjectExplorer::FileNode *>() << idx);
addFileNode(new QbsFileNode(Utils::FileName::fromString(grp.location().filePath()),
ProjectExplorer::FileType::Project, false,
grp.location().line()));
updateQbsGroupData(grp, productPath, true, true);
}
@@ -583,11 +582,10 @@ QbsProductNode::QbsProductNode(const qbs::Project &project, const qbs::ProductDa
setIcon(m_productIcon);
addFolderNodes(QList<ProjectExplorer::FolderNode *>() << m_generatedFilesNode);
auto idx = new QbsFileNode(Utils::FileName::fromString(prd.location().filePath()),
ProjectExplorer::FileType::Project, false,
prd.location().line());
addFileNodes(QList<ProjectExplorer::FileNode *>() << idx);
addFolderNode(m_generatedFilesNode);
addFileNode(new QbsFileNode(Utils::FileName::fromString(prd.location().filePath()),
ProjectExplorer::FileType::Project, false,
prd.location().line()));
setQbsProductData(project, prd);
}
@@ -760,38 +758,23 @@ QbsProjectNode::~QbsProjectNode()
void QbsProjectNode::update(const qbs::Project &qbsProject, const qbs::ProjectData &prjData)
{
QList<ProjectExplorer::ProjectNode *> toRemove = projectNodes();
QTC_ASSERT(isEmpty(), makeEmpty());
foreach (const qbs::ProjectData &subData, prjData.subProjects()) {
QbsProjectNode *qn = findProjectNode(subData.name());
if (!qn) {
auto subProject =
new QbsProjectNode(Utils::FileName::fromString(subData.location().filePath()));
subProject->update(qbsProject, subData);
addProjectNode(subProject);
} else {
qn->update(qbsProject, subData);
toRemove.removeOne(qn);
}
auto subProject =
new QbsProjectNode(Utils::FileName::fromString(subData.location().filePath()));
subProject->update(qbsProject, subData);
addProjectNode(subProject);
}
foreach (const qbs::ProductData &prd, prjData.products()) {
QbsProductNode *qn = findProductNode(QbsProject::uniqueProductName(prd));
if (!qn) {
addProjectNode(new QbsProductNode(qbsProject, prd));
} else {
qn->setQbsProductData(qbsProject, prd);
toRemove.removeOne(qn);
}
}
foreach (const qbs::ProductData &prd, prjData.products())
addProjectNode(new QbsProductNode(qbsProject, prd));
if (!prjData.name().isEmpty())
setDisplayName(prjData.name());
else
setDisplayName(project()->displayName());
foreach (ProjectNode *node, toRemove)
removeProjectNode(node);
m_projectData = prjData;
}
@@ -816,8 +799,7 @@ void QbsProjectNode::ctor()
m_projectIcon = generateIcon(QString::fromLatin1(ProjectExplorer::Constants::FILEOVERLAY_QT));
setIcon(m_projectIcon);
addFileNodes(QList<ProjectExplorer::FileNode *>()
<< new ProjectExplorer::FileNode(filePath(), ProjectExplorer::FileType::Project, false));
addFileNode(new ProjectExplorer::FileNode(filePath(), ProjectExplorer::FileType::Project, false));
}
QbsProductNode *QbsProjectNode::findProductNode(const QString &uniqueName)
@@ -851,7 +833,7 @@ QbsRootProjectNode::QbsRootProjectNode(QbsProject *project) :
ProjectExplorer::NodeType::Folder,
QCoreApplication::translate("QbsRootProjectNode", "Qbs files")))
{
addFolderNodes(QList<FolderNode *>() << m_buildSystemFiles);
addFolderNode(m_buildSystemFiles);
}
void QbsRootProjectNode::update()

View File

@@ -453,7 +453,6 @@ struct InternalNode
existingFolderNodes.insert(node->filePath().toString(), node);
QList<FolderNode *> foldersToRemove;
QList<FolderNode *> foldersToAdd;
typedef QPair<InternalNode *, FolderNode *> NodePair;
QList<NodePair> nodesToUpdate;
@@ -480,7 +479,7 @@ struct InternalNode
nodesToUpdate << NodePair(*it, *oldit);
} else {
FolderNode *newNode = createFolderNode(*it);
foldersToAdd << newNode;
folder->addFolderNode(newNode);
nodesToUpdate << NodePair(*it, newNode);
}
}
@@ -506,7 +505,7 @@ struct InternalNode
nodesToUpdate << NodePair(it.value(), *oldit);
} else {
FolderNode *newNode = createFolderNode(it.value());
foldersToAdd << newNode;
folder->addFolderNode(newNode);
nodesToUpdate << NodePair(it.value(), newNode);
}
}
@@ -524,8 +523,6 @@ struct InternalNode
if (!foldersToRemove.isEmpty())
folder->removeFolderNodes(foldersToRemove);
if (!foldersToAdd.isEmpty())
folder->addFolderNodes(foldersToAdd);
foreach (const NodePair &np, nodesToUpdate)
np.first->updateSubFolders(np.second);
@@ -582,7 +579,7 @@ struct InternalNode
dynamic_cast<ResourceEditor::ResourceTopLevelNode *>(fn)->update();
}
};
}
} // Internal
QStringList QmakePriFileNode::baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir)
{
@@ -701,7 +698,7 @@ void QmakePriFileNode::update(const Internal::PriFileEvalResult &result)
{
// add project file node
if (m_fileNodes.isEmpty())
addFileNodes(QList<FileNode *>() << new FileNode(m_projectFilePath, FileType::Project, false));
addFileNode(new FileNode(m_projectFilePath, FileType::Project, false));
m_recursiveEnumerateFiles = result.recursiveEnumerateFiles;
watchFolders(result.folders.toSet());

View File

@@ -121,7 +121,6 @@ ResourceTopLevelNode::~ResourceTopLevelNode()
void ResourceTopLevelNode::update()
{
QList<ProjectExplorer::FolderNode *> newPrefixList;
QMap<PrefixFolderLang, QList<ProjectExplorer::FileNode *>> filesToAdd;
QMap<PrefixFolderLang, QList<ProjectExplorer::FolderNode *>> foldersToAddToFolders;
QMap<PrefixFolderLang, QList<ProjectExplorer::FolderNode *>> foldersToAddToPrefix;
@@ -139,8 +138,7 @@ void ResourceTopLevelNode::update()
PrefixFolderLang prefixId(prefix, QString(), lang);
if (!prefixNodes.contains(prefixId)) {
ProjectExplorer::FolderNode *fn = new ResourceFolderNode(file.prefix(i), file.lang(i), this);
newPrefixList << fn;
addFolderNode(fn);
prefixNodes.insert(prefixId, fn);
}
ResourceFolderNode *currentPrefixNode = static_cast<ResourceFolderNode*>(prefixNodes[prefixId]);
@@ -208,9 +206,6 @@ void ResourceTopLevelNode::update()
}
}
addFolderNodes(newPrefixList);
foreach (FolderNode *sfn, folderNodes()) {
ResourceFolderNode *srn = static_cast<ResourceFolderNode *>(sfn);
PrefixFolderLang folderId(srn->prefix(), QString(), srn->lang());