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. delete headerNode; // No Headers, do not show this Folder.
else else
root->addNode(headerNode); root->addNode(headerNode);

View File

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

View File

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

View File

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