ProjectExplorer: Use unique_ptr to hold ProjectNodes

Change-Id: Iaa5bea221686564de24138a99b5fe0d09521c118
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Tobias Hunger
2018-04-26 11:00:59 +02:00
parent dc982a1326
commit 1f55ba9012
4 changed files with 55 additions and 41 deletions

View File

@@ -907,7 +907,7 @@ void ServerModeReader::addHeaderNodes(ProjectNode *root, const QList<FileNode *>
}
}
if (headerNode->nodes().isEmpty())
if (headerNode->isEmpty())
delete headerNode; // No Headers, do not show this Folder.
else
root->addNode(headerNode);

View File

@@ -496,7 +496,7 @@ void Project::setRootProjectNode(ProjectNode *root)
if (d->m_rootProjectNode.get() == root)
return;
if (root && root->nodes().isEmpty()) {
if (root && root->isEmpty()) {
// Something went wrong with parsing: At least the project file needs to be
// shown so that the user can fix the breakage.
// Do not leak root and use default project tree in this case.

View File

@@ -39,6 +39,7 @@
#include <utils/hostosinfo.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/mimetypes/mimetype.h>
#include <utils/pointeralgorithm.h>
#include <utils/qtcassert.h>
#include <QFileInfo>
@@ -53,9 +54,8 @@ namespace ProjectExplorer {
static FolderNode *folderNode(const FolderNode *folder, const Utils::FileName &directory)
{
return static_cast<FolderNode *>(Utils::findOrDefault(folder->nodes(),
[&directory](const Node *n) {
const FolderNode *fn = n->asFolderNode();
return static_cast<FolderNode *>(Utils::findOrDefault(folder->folderNodes(),
[&directory](const FolderNode *fn) {
return fn && fn->filePath() == directory;
}));
}
@@ -428,11 +428,6 @@ FolderNode::FolderNode(const Utils::FileName &folderPath, NodeType nodeType,
m_displayName = folderPath.toUserOutput();
}
FolderNode::~FolderNode()
{
qDeleteAll(m_nodes);
}
/*!
Contains the display name that should be used in a view.
\sa setFolderName()
@@ -461,9 +456,9 @@ Node *FolderNode::findNode(const std::function<bool(Node *)> &filter)
if (filter(this))
return this;
for (Node *n : m_nodes) {
if (n->asFileNode() && filter(n)) {
return n;
for (const std::unique_ptr<Node> &n : m_nodes) {
if (n->asFileNode() && filter(n.get())) {
return n.get();
} else if (FolderNode *folder = n->asFolderNode()) {
Node *result = folder->findNode(filter);
if (result)
@@ -478,9 +473,9 @@ QList<Node *> FolderNode::findNodes(const std::function<bool(Node *)> &filter)
QList<Node *> result;
if (filter(this))
result.append(this);
for (Node *n : m_nodes) {
if (n->asFileNode() && filter(n))
result.append(n);
for (const std::unique_ptr<Node> &n : m_nodes) {
if (n->asFileNode() && filter(n.get()))
result.append(n.get());
else if (FolderNode *folder = n->asFolderNode())
result.append(folder->findNode(filter));
}
@@ -496,12 +491,12 @@ void FolderNode::forEachNode(const std::function<void(FileNode *)> &fileTask,
return;
}
if (fileTask) {
for (Node *n : m_nodes) {
for (const std::unique_ptr<Node> &n : m_nodes) {
if (FileNode *fn = n->asFileNode())
fileTask(fn);
}
}
for (Node *n : m_nodes) {
for (const std::unique_ptr<Node> &n : m_nodes) {
if (FolderNode *fn = n->asFolderNode()) {
if (folderTask)
folderTask(fn);
@@ -512,17 +507,22 @@ void FolderNode::forEachNode(const std::function<void(FileNode *)> &fileTask,
void FolderNode::forEachGenericNode(const std::function<void(Node *)> &genericTask) const
{
for (Node *n : m_nodes) {
genericTask(n);
for (const std::unique_ptr<Node> &n : m_nodes) {
genericTask(n.get());
if (FolderNode *fn = n->asFolderNode())
fn->forEachGenericNode(genericTask);
}
}
const QList<Node *> FolderNode::nodes() const
{
return Utils::toRawPointer<QList>(m_nodes);
}
QList<FileNode*> FolderNode::fileNodes() const
{
QList<FileNode *> result;
for (Node *n : m_nodes) {
for (const std::unique_ptr<Node> &n : m_nodes) {
if (FileNode *fn = n->asFileNode())
result.append(fn);
}
@@ -531,7 +531,8 @@ QList<FileNode*> FolderNode::fileNodes() const
FileNode *FolderNode::fileNode(const Utils::FileName &file) const
{
return static_cast<FileNode *>(Utils::findOrDefault(m_nodes, [&file](const Node *n) {
return static_cast<FileNode *>(Utils::findOrDefault(m_nodes,
[&file](const std::unique_ptr<Node> &n) {
const FileNode *fn = n->asFileNode();
return fn && fn->filePath() == file;
}));
@@ -540,7 +541,7 @@ FileNode *FolderNode::fileNode(const Utils::FileName &file) const
QList<FolderNode*> FolderNode::folderNodes() const
{
QList<FolderNode *> result;
for (Node *n : m_nodes) {
for (const std::unique_ptr<Node> &n : m_nodes) {
if (FolderNode *fn = n->asFolderNode())
result.append(fn);
}
@@ -570,21 +571,19 @@ void FolderNode::addNestedNodes(const QList<FileNode *> &files, const Utils::Fil
// files.
void FolderNode::compress()
{
QList<Node *> children = nodes();
if (auto subFolder = children.count() == 1 ? children.at(0)->asFolderNode() : nullptr) {
if (auto subFolder = m_nodes.size() == 1 ? m_nodes.at(0)->asFolderNode() : nullptr) {
if (subFolder->nodeType() != nodeType())
return;
// Only one subfolder: Compress!
setDisplayName(QDir::toNativeSeparators(displayName() + "/" + subFolder->displayName()));
for (Node *n : subFolder->nodes()) {
subFolder->removeNode(n);
n->setParentFolderNode(nullptr);
addNode(n);
std::unique_ptr<Node> toMove = subFolder->takeNode(n);
toMove->setParentFolderNode(nullptr);
addNode(std::move(toMove));
}
setAbsoluteFilePathAndLine(subFolder->filePath(), -1);
removeNode(subFolder);
delete subFolder;
compress();
} else {
@@ -610,11 +609,13 @@ bool FolderNode::replaceSubtree(Node *oldNode, Node *newNode)
addNode(nn.release()); // Happens e.g. when a project is registered
} else {
auto it = std::find_if(m_nodes.begin(), m_nodes.end(),
[oldNode](const Node *n) { return oldNode == n; });
[oldNode](const std::unique_ptr<Node> &n) {
return oldNode == n.get();
});
QTC_ASSERT(it != m_nodes.end(), return false);
if (nn) {
nn->setParentFolderNode(this);
*it = nn.release();
*it = std::move(nn);
} else {
removeNode(oldNode); // Happens e.g. when project is shutting down
}
@@ -713,9 +714,17 @@ FolderNode::AddNewInformation FolderNode::addNewInformation(const QStringList &f
void FolderNode::addNode(Node *node)
{
QTC_ASSERT(node, return);
QTC_ASSERT(!node->parentFolderNode(), qDebug("File node has already a parent folder"));
QTC_ASSERT(!node->parentFolderNode(), qDebug("Node has already a parent folder"));
node->setParentFolderNode(this);
m_nodes.append(node);
m_nodes.emplace_back(std::unique_ptr<Node>(node));
}
void FolderNode::addNode(std::unique_ptr<Node> &&node)
{
QTC_ASSERT(node, return);
QTC_ASSERT(!node->parentFolderNode(), qDebug("Node has already a parent folder"));
node->setParentFolderNode(this);
m_nodes.emplace_back(std::move(node));
}
/*!
@@ -725,7 +734,12 @@ void FolderNode::addNode(Node *node)
void FolderNode::removeNode(Node *node)
{
m_nodes.removeOne(node);
takeNode(node);
}
std::unique_ptr<Node> FolderNode::takeNode(Node *node)
{
return Utils::takeOrDefault(m_nodes, node);
}
bool FolderNode::showInSimpleTree() const
@@ -848,8 +862,8 @@ bool ProjectNode::deploysFolder(const QString &folder) const
ProjectNode *ProjectNode::projectNode(const Utils::FileName &file) const
{
for (Node *node : m_nodes) {
if (ProjectNode *pnode = node->asProjectNode())
for (const std::unique_ptr<Node> &n: m_nodes) {
if (ProjectNode *pnode = n->asProjectNode())
if (pnode->filePath() == file)
return pnode;
}
@@ -858,7 +872,7 @@ ProjectNode *ProjectNode::projectNode(const Utils::FileName &file) const
bool FolderNode::isEmpty() const
{
return m_nodes.isEmpty();
return m_nodes.size() == 0;
}
void FolderNode::handleSubTreeChanged(FolderNode *node)
@@ -899,7 +913,6 @@ ProjectNode *ContainerNode::rootProjectNode() const
void ContainerNode::removeAllChildren()
{
qDeleteAll(m_nodes);
m_nodes.clear();
}

View File

@@ -206,7 +206,6 @@ class PROJECTEXPLORER_EXPORT FolderNode : public Node
public:
explicit FolderNode(const Utils::FileName &folderPath, NodeType nodeType = NodeType::Folder,
const QString &displayName = QString(), const QByteArray &id = {});
~FolderNode() override;
QString displayName() const override;
QIcon icon() const;
@@ -218,7 +217,7 @@ public:
const std::function<void(FolderNode *)> &folderTask = {},
const std::function<bool(const FolderNode *)> &folderFilterTask = {}) const;
void forEachGenericNode(const std::function<void(Node *)> &genericTask) const;
const QList<Node *> nodes() const { return m_nodes; }
const QList<Node *> nodes() const;
QList<FileNode *> fileNodes() const;
FileNode *fileNode(const Utils::FileName &file) const;
QList<FolderNode *> folderNodes() const;
@@ -279,7 +278,9 @@ public:
virtual bool showWhenEmpty() const;
void addNode(Node *node);
void addNode(std::unique_ptr<Node> &&node);
void removeNode(Node *node);
std::unique_ptr<Node> takeNode(Node *node);
bool isEmpty() const;
@@ -289,7 +290,7 @@ public:
protected:
virtual void handleSubTreeChanged(FolderNode *node);
QList<Node *> m_nodes;
std::vector<std::unique_ptr<Node>> m_nodes;
QList<LocationInfo> m_locations;
private: