forked from qt-creator/qt-creator
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:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user