Commit 45ffa750 authored by Tobias Hunger's avatar Tobias Hunger
Browse files

Qbs: Move root project setup into QbsNodeTreeBuilder



Change-Id: If8ba7fc6e4edf1346e0636d0bbc78efb27cb433e
Reviewed-by: Christian Kandeler's avatarChristian Kandeler <christian.kandeler@qt.io>
parent 8cb57c73
......@@ -48,24 +48,6 @@
// Helpers:
// ----------------------------------------------------------------------
static QString displayNameFromPath(const QString &path, const QString &base)
{
QString dir = base;
if (!base.endsWith(QLatin1Char('/')))
dir.append(QLatin1Char('/'));
QString name = path;
if (name.startsWith(dir)) {
name = name.mid(dir.count());
} else {
QFileInfo fi = QFileInfo(path);
name = QCoreApplication::translate("Qbs::QbsProjectNode", "%1 in %2")
.arg(fi.fileName(), fi.absolutePath());
}
return name;
}
static QIcon generateIcon(const QString &overlay)
{
const QSize desiredSize = QSize(16, 16);
......@@ -389,95 +371,6 @@ bool QbsGroupNode::renameFile(const QString &filePath, const QString &newFilePat
prdNode->qbsProductData(), m_qbsGroupData);
}
void QbsGroupNode::setupFiles(ProjectExplorer::FolderNode *root, const qbs::GroupData &group,
const QStringList &files, const QString &productPath, bool generated)
{
// Build up a tree of nodes:
FileTreeNode tree;
foreach (const QString &path, files) {
QStringList pathSegments = path.split(QLatin1Char('/'), QString::SkipEmptyParts);
FileTreeNode *root = &tree;
while (!pathSegments.isEmpty()) {
bool isFile = pathSegments.count() == 1;
root = root->addPart(pathSegments.takeFirst(), isFile);
}
}
FileTreeNode::reorder(&tree, productPath);
FileTreeNode::simplify(&tree);
QHash<QString, ProjectExplorer::FileType> fileTypeHash;
foreach (const qbs::ArtifactData &sa, group.allSourceArtifacts())
fileTypeHash[sa.filePath()] = Internal::QbsNodeTreeBuilder::fileType(sa);
setupFolder(root, fileTypeHash, &tree, productPath, generated);
}
void QbsGroupNode::setupFolder(ProjectExplorer::FolderNode *root,
const QHash<QString, ProjectExplorer::FileType> &fileTypeHash,
const FileTreeNode *fileTree,
const QString &baseDir,
bool generated)
{
// We only need to care about FileNodes and FolderNodes here. Everything else is
// handled elsewhere.
// QbsGroupNodes are managed by the QbsProductNode.
// The buildsystem file is either managed by QbsProductNode or by updateQbsGroupData(...).
foreach (FileTreeNode *c, fileTree->children) {
Utils::FileName path = Utils::FileName::fromString(c->path());
const ProjectExplorer::FileType newFileType =
fileTypeHash.value(c->path(), ProjectExplorer::FileType::Unknown);
const bool isQrcFile = newFileType == ProjectExplorer::FileType::Resource;
// Handle files:
if (c->isFile() && !isQrcFile) {
ProjectExplorer::FileNode *fn = 0;
foreach (ProjectExplorer::FileNode *f, root->fileNodes()) {
// There can be one match only here!
if (f->filePath() != path || f->fileType() != newFileType)
continue;
fn = f;
break;
}
if (!fn) {
fn = new ProjectExplorer::FileNode(path, newFileType, generated);
root->addNode(fn);
}
continue;
} else {
ProjectExplorer::FolderNode *fn = 0;
foreach (ProjectExplorer::FolderNode *f, root->folderNodes()) {
// There can be one match only here!
if (f->filePath() != path)
continue;
fn = f;
break;
}
using ResourceEditor::ResourceTopLevelNode;
if (!fn) {
if (isQrcFile) {
fn = new ResourceTopLevelNode(Utils::FileName::fromString(c->path()), QString(), root);
} else {
fn = new QbsFolderNode(Utils::FileName::fromString(c->path()),
ProjectExplorer::NodeType::Folder,
displayNameFromPath(c->path(), baseDir), false);
}
root->addNode(fn);
} else {
fn->setDisplayName(displayNameFromPath(c->path(), baseDir));
}
if (isQrcFile)
static_cast<ResourceTopLevelNode *>(fn)->addInternalNodes();
else
setupFolder(fn, fileTypeHash, c, c->path(), generated);
}
}
}
// --------------------------------------------------------------------
// QbsProductNode:
// --------------------------------------------------------------------
......@@ -624,49 +517,8 @@ void QbsProjectNode::setProjectData(const qbs::ProjectData &data)
QbsRootProjectNode::QbsRootProjectNode(QbsProject *project) :
QbsProjectNode(project->projectDirectory()),
m_project(project),
m_buildSystemFiles(new ProjectExplorer::FolderNode(project->projectDirectory(),
ProjectExplorer::NodeType::Folder,
QCoreApplication::translate("QbsRootProjectNode", "Qbs files")))
{
addNode(m_buildSystemFiles);
}
void QbsRootProjectNode::update()
{
QStringList buildSystemFiles = unreferencedBuildSystemFiles(m_project->qbsProject());
QStringList projectBuildSystemFiles;
Utils::FileName base = m_project->projectDirectory();
foreach (const QString &f, buildSystemFiles) {
if (Utils::FileName::fromString(f).isChildOf(base))
projectBuildSystemFiles.append(f);
}
QbsGroupNode::setupFiles(m_buildSystemFiles, qbs::GroupData(), projectBuildSystemFiles,
base.toString(), false);
QbsNodeTreeBuilder::setupProjectNode(this, m_project->qbsProjectData(), m_project->qbsProject());
}
static QSet<QString> referencedBuildSystemFiles(const qbs::ProjectData &data)
{
QSet<QString> result;
result.insert(data.location().filePath());
foreach (const qbs::ProjectData &subProject, data.subProjects())
result.unite(referencedBuildSystemFiles(subProject));
foreach (const qbs::ProductData &product, data.products()) {
result.insert(product.location().filePath());
foreach (const qbs::GroupData &group, product.groups())
result.insert(group.location().filePath());
}
return result;
}
QStringList QbsRootProjectNode::unreferencedBuildSystemFiles(const qbs::Project &p) const
{
return p.buildSystemFiles().subtract(referencedBuildSystemFiles(p.projectData())).toList();
}
m_project(project)
{ }
} // namespace Internal
} // namespace QbsProjectManager
......@@ -102,16 +102,7 @@ public:
QString productPath() const;
// group can be invalid
static void setupFiles(FolderNode *root, const qbs::GroupData &group, const QStringList &files,
const QString &productPath, bool generated);
private:
static void setupFolder(ProjectExplorer::FolderNode *folder,
const QHash<QString, ProjectExplorer::FileType> &fileTypeHash,
const FileTreeNode *subFileTree, const QString &baseDir,
bool generated);
qbs::GroupData m_qbsGroupData;
QString m_productPath;
......@@ -160,9 +151,9 @@ public:
bool showInSimpleTree() const override;
private:
void setProjectData(const qbs::ProjectData &data);
private:
static QIcon m_projectIcon;
qbs::ProjectData m_projectData;
......@@ -178,15 +169,10 @@ class QbsRootProjectNode : public QbsProjectNode
public:
explicit QbsRootProjectNode(QbsProject *project);
void update();
QbsProject *project() const override { return m_project; }
private:
QStringList unreferencedBuildSystemFiles(const qbs::Project &p) const;
QbsProject *const m_project;
ProjectExplorer::FolderNode *m_buildSystemFiles;
};
......
......@@ -32,13 +32,33 @@
namespace {
ProjectExplorer::FileType fileType(const qbs::ArtifactData &artifact)
{
QTC_ASSERT(artifact.isValid(), return ProjectExplorer::FileType::Unknown);
if (artifact.fileTags().contains("c")
|| artifact.fileTags().contains("cpp")
|| artifact.fileTags().contains("objc")
|| artifact.fileTags().contains("objcpp")) {
return ProjectExplorer::FileType::Source;
}
if (artifact.fileTags().contains("hpp"))
return ProjectExplorer::FileType::Header;
if (artifact.fileTags().contains("qrc"))
return ProjectExplorer::FileType::Resource;
if (artifact.fileTags().contains("ui"))
return ProjectExplorer::FileType::Form;
if (artifact.fileTags().contains("scxml"))
return ProjectExplorer::FileType::StateChart;
return ProjectExplorer::FileType::Unknown;
}
void setupArtifacts(ProjectExplorer::FolderNode *root, const QList<qbs::ArtifactData> &artifacts)
{
QList<ProjectExplorer::FileNode *> fileNodes
= Utils::transform(artifacts, [](const qbs::ArtifactData &ad) {
const Utils::FileName path = Utils::FileName::fromString(ad.filePath());
const ProjectExplorer::FileType type =
QbsProjectManager::Internal::QbsNodeTreeBuilder::fileType(ad);
const ProjectExplorer::FileType type = fileType(ad);
const bool isGenerated = ad.isGenerated();
return new ProjectExplorer::FileNode(path, type, isGenerated);
});
......@@ -113,52 +133,13 @@ buildProductNodeTree(const qbs::Project &project, const qbs::ProductData &prd)
return result;
}
} // namespace
namespace QbsProjectManager {
namespace Internal {
ProjectExplorer::FileType QbsNodeTreeBuilder::fileType(const qbs::ArtifactData &artifact)
{
QTC_ASSERT(artifact.isValid(), return ProjectExplorer::FileType::Unknown);
if (artifact.fileTags().contains("c")
|| artifact.fileTags().contains("cpp")
|| artifact.fileTags().contains("objc")
|| artifact.fileTags().contains("objcpp")) {
return ProjectExplorer::FileType::Source;
}
if (artifact.fileTags().contains("hpp"))
return ProjectExplorer::FileType::Header;
if (artifact.fileTags().contains("qrc"))
return ProjectExplorer::FileType::Resource;
if (artifact.fileTags().contains("ui"))
return ProjectExplorer::FileType::Form;
if (artifact.fileTags().contains("scxml"))
return ProjectExplorer::FileType::StateChart;
return ProjectExplorer::FileType::Unknown;
}
QbsProjectNode *QbsNodeTreeBuilder::buildProjectNodeTree(const qbs::Project &qbsProject,
const qbs::ProjectData &prjData)
{
Utils::FileName filePath = Utils::FileName::fromString(prjData.location().filePath());
auto result = new QbsProjectNode(filePath.parentDir());
result->setProjectData(prjData);
result->addNode(new ProjectExplorer::FileNode(filePath, ProjectExplorer::FileType::Project, false));
setupProjectNode(result, prjData, qbsProject);
return result;
}
void QbsNodeTreeBuilder::setupProjectNode(QbsProjectNode *node, const qbs::ProjectData &prjData,
const qbs::Project &qbsProject)
void setupProjectNode(QbsProjectManager::Internal::QbsProjectNode *node, const qbs::ProjectData &prjData,
const qbs::Project &qbsProject)
{
foreach (const qbs::ProjectData &subData, prjData.subProjects()) {
auto subProject =
new QbsProjectNode(Utils::FileName::fromString(subData.location().filePath()).parentDir());
new QbsProjectManager::Internal::QbsProjectNode(
Utils::FileName::fromString(subData.location().filePath()).parentDir());
setupProjectNode(subProject, subData, qbsProject);
node->addNode(subProject);
}
......@@ -172,5 +153,59 @@ void QbsNodeTreeBuilder::setupProjectNode(QbsProjectNode *node, const qbs::Proje
node->setDisplayName(node->project()->displayName());
}
QSet<QString> referencedBuildSystemFiles(const qbs::ProjectData &data)
{
QSet<QString> result;
result.insert(data.location().filePath());
foreach (const qbs::ProjectData &subProject, data.subProjects())
result.unite(referencedBuildSystemFiles(subProject));
foreach (const qbs::ProductData &product, data.products()) {
result.insert(product.location().filePath());
foreach (const qbs::GroupData &group, product.groups())
result.insert(group.location().filePath());
}
return result;
}
QStringList unreferencedBuildSystemFiles(const qbs::Project &p)
{
return p.buildSystemFiles().subtract(referencedBuildSystemFiles(p.projectData())).toList();
}
} // namespace
namespace QbsProjectManager {
namespace Internal {
void QbsNodeTreeBuilder::buildTree(QbsProject *project)
{
QbsRootProjectNode *root = project->rootProjectNode();
QTC_ASSERT(root, return);
root->makeEmpty();
root->addNode(new ProjectExplorer::FileNode(project->projectFilePath(), ProjectExplorer::FileType::Project, false));
auto buildSystemFiles
= new ProjectExplorer::FolderNode(project->projectDirectory(),
ProjectExplorer::NodeType::Folder,
QCoreApplication::translate("QbsRootProjectNode", "Qbs files"));
QList<ProjectExplorer::FileNode *> projectBuildSystemFiles;
Utils::FileName base = project->projectDirectory();
for (const QString &f : unreferencedBuildSystemFiles(project->qbsProject())) {
const Utils::FileName filePath = Utils::FileName::fromString(f);
if (filePath.isChildOf(base))
projectBuildSystemFiles.append(new ProjectExplorer::FileNode(filePath, ProjectExplorer::FileType::Project, false));
}
buildSystemFiles->buildTree(projectBuildSystemFiles);
buildSystemFiles->compress();
root->addNode(buildSystemFiles);
setupProjectNode(root, project->qbsProjectData(), project->qbsProject());
root->emitNodeUpdated();
root->emitTreeChanged();
}
} // namespace Internal
} // namespace QbsProjectManager
......@@ -39,12 +39,7 @@ namespace Internal {
class QbsNodeTreeBuilder
{
public:
static ProjectExplorer::FileType fileType(const qbs::ArtifactData &artifact);
static QbsProjectNode *buildProjectNodeTree(const qbs::Project &qbsProject,
const qbs::ProjectData &prjData);
static void setupProjectNode(QbsProjectNode *node, const qbs::ProjectData &prjData, const qbs::Project &qbsProject);
static void buildTree(QbsProject *project);
};
} // namespace Internal
......
......@@ -32,6 +32,7 @@
#include "qbsprojectparser.h"
#include "qbsprojectmanagerconstants.h"
#include "qbsnodes.h"
#include "qbsnodetreebuilder.h"
#include <coreplugin/documentmanager.h>
#include <coreplugin/icontext.h>
......@@ -131,6 +132,7 @@ QbsProject::QbsProject(const QString &fileName) :
setDocument(new QbsProjectFile(this, fileName));
DocumentManager::addDocument(document());
setRootProjectNode(new QbsRootProjectNode(this));
Internal::QbsNodeTreeBuilder::buildTree(this); // Populate with initial data
setProjectContext(Context(Constants::PROJECT_ID));
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
......@@ -312,7 +314,7 @@ bool QbsProject::addFilesToProduct(const QStringList &filePaths,
}
if (notAdded->count() != filePaths.count()) {
m_projectData = m_qbsProject.projectData();
rootProjectNode()->update();
Internal::QbsNodeTreeBuilder::buildTree(this);
emit fileListChanged();
}
return notAdded->isEmpty();
......@@ -340,7 +342,7 @@ bool QbsProject::removeFilesFromProduct(const QStringList &filePaths,
}
if (notRemoved->count() != filePaths.count()) {
m_projectData = m_qbsProject.projectData();
rootProjectNode()->update();
Internal::QbsNodeTreeBuilder::buildTree(this);
emit fileListChanged();
}
return notRemoved->isEmpty();
......@@ -482,7 +484,7 @@ void QbsProject::updateAfterParse()
void QbsProject::updateProjectNodes()
{
OpTimer opTimer("updateProjectNodes");
rootProjectNode()->update();
Internal::QbsNodeTreeBuilder::buildTree(this);
}
void QbsProject::handleQbsParsingDone(bool success)
......
......@@ -41,7 +41,6 @@ QtcPlugin {
Depends { name: "ProjectExplorer" }
Depends { name: "Core" }
Depends { name: "CppTools" }
Depends { name: "ResourceEditor" }
Depends { name: "QtSupport" }
Depends { name: "QmlJSTools" }
......
......@@ -8,5 +8,4 @@ QTC_PLUGIN_DEPENDS += \
projectexplorer \
cpptools \
qtsupport \
qmljstools \
resourceeditor
qmljstools
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment