From 892066cfa664c0e8ec1f970648a5ec3f1fdd89f5 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 16 Apr 2013 16:19:11 +0200 Subject: [PATCH] Qbs: Fix display of project tree Do not display a folder below the Groups if the files are in the same directory as the product definition. The product directory is chosen since the groups can be implemented elsewhere as done in creator for the pluginspec groups. Task-number: QBS-257 (partial) Change-Id: I0e39bbc62f991f2485adb3c4b47dd62dfa72763c Reviewed-by: Tobias Hunger --- src/plugins/qbsprojectmanager/qbsnodes.cpp | 173 ++++++++++++++------- src/plugins/qbsprojectmanager/qbsnodes.h | 20 ++- 2 files changed, 130 insertions(+), 63 deletions(-) diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp index bffda992ce6..c0753eacbef 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp @@ -38,10 +38,6 @@ #include -// -#include -// - // ---------------------------------------------------------------------- // Helpers: // ---------------------------------------------------------------------- @@ -54,9 +50,6 @@ public: FileTreeNode(const QString &n, FileTreeNode *p = 0) : parent(p), name(n) { - // - Q_ASSERT((!name.isEmpty() && p) || (name.isEmpty() && !p)); - // if (p) p->children.append(this); } @@ -77,11 +70,47 @@ public: bool isFile() { return children.isEmpty(); } + // Moves the node pointing to basedir to the root of the tree and deletes any now empty nodes. + static void reorder(FileTreeNode *node, const QString &basedir, FileTreeNode *root) + { + if (node != root && node->path() == basedir) { + // move node to root: + FileTreeNode *parent = node->parent; + if (parent) + parent->children.removeOne(node); + root->children.append(node); + node->parent = root; + if (basedir.startsWith(QLatin1Char('/'))) + node->name = basedir.mid(1); + else + node->name = basedir; + + // clean up now-empty nodes: + while (parent) { + if (parent->children.count() == 0) { + FileTreeNode *current = parent; + parent = current->parent; + parent->children.removeOne(current); + current->parent = 0; + delete current; + } else { + break; + } + } + return; + } + foreach (FileTreeNode *n, node->children) + reorder(n, basedir, root); + } + static void simplify(FileTreeNode *node) { foreach (FileTreeNode *c, node->children) simplify(c); + if (!node->parent) + return; + if (node->children.count() == 1) { FileTreeNode *child = node->children.at(0); if (child->isFile()) @@ -99,11 +128,6 @@ public: child->children.clear(); child->parent = 0; delete child; - - // - Q_ASSERT(!node->name.isEmpty()); - // - return; } } @@ -220,11 +244,11 @@ QList QbsBaseProjectNode::runConfigurations // QbsGroupNode: // -------------------------------------------------------------------- -QbsGroupNode::QbsGroupNode(const qbs::GroupData *grp) : +QbsGroupNode::QbsGroupNode(const qbs::GroupData *grp, const QString &productPath) : QbsBaseProjectNode(QString()), m_group(0) { - setGroup(grp); + setGroup(grp, productPath); } bool QbsGroupNode::isEnabled() const @@ -232,15 +256,18 @@ bool QbsGroupNode::isEnabled() const return static_cast(parentFolderNode())->isEnabled() && group()->isEnabled(); } -void QbsGroupNode::setGroup(const qbs::GroupData *group) +void QbsGroupNode::setGroup(const qbs::GroupData *group, const QString &productPath) { - if (group == m_group) + if (group == m_group && productPath == m_productPath) return; + m_productPath = productPath; + + // Set Product file node used to jump to the product setPath(group->location().fileName); setDisplayName(group->name()); - // Set Product file node used to jump to the product + // set up file node... QbsFileNode *indexFile = 0; if (!m_group) { indexFile = new QbsFileNode(group->location().fileName, @@ -254,6 +281,15 @@ void QbsGroupNode::setGroup(const qbs::GroupData *group) indexFile->emitNodeUpdated(); } + m_group = group; + + setGroup(this, group, productPath, QList() << indexFile); + emitNodeUpdated(); +} + +void QbsGroupNode::setGroup(QbsBaseProjectNode *root, const qbs::GroupData *group, + const QString &productPath, QList keepers) +{ // Build up a tree of nodes: FileTreeNode *tree = new FileTreeNode(QString()); @@ -265,33 +301,32 @@ void QbsGroupNode::setGroup(const qbs::GroupData *group) root = root->addPart(pathSegments.takeFirst()); } + FileTreeNode::reorder(tree, productPath, tree); FileTreeNode::simplify(tree); - setupFolders(this, tree, indexFile); - + setupFolders(root, root, tree, productPath, keepers); delete tree; - - m_group = group; - emitNodeUpdated(); } -void QbsGroupNode::setupFolders(ProjectExplorer::FolderNode *root, FileTreeNode *node, - ProjectExplorer::FileNode *keep) +void QbsGroupNode::setupFolders(QbsBaseProjectNode *topLevel, ProjectExplorer::FolderNode *root, + FileTreeNode *node, const QString &baseDirPath, + QList keepers) { - // insert initial folder: - if (!node->parent && !node->name.isEmpty()) { - ProjectExplorer::FolderNode *fn = root->findSubFolder(node->name); - if (!fn) { - fn = new ProjectExplorer::FolderNode(node->name); - addFolderNodes(QList() << fn, root); - } - root = fn; + QList filesToRemove; + foreach (ProjectExplorer::FileNode *fn, root->fileNodes()) { + ProjectExplorer::Node *n = static_cast(fn); + if (!keepers.contains(n)) + filesToRemove.append(fn); } - QList filesToRemove = root->fileNodes(); - filesToRemove.removeAll(keep); QList filesToAdd; - QList foldersToRemove = root->subFolderNodes(); + QList foldersToKeep = keepers; + QList foldersToRemove; + foreach (ProjectExplorer::FolderNode *fn, root->subFolderNodes()) { + ProjectExplorer::Node *n = static_cast(fn); + if (!keepers.contains(n)) + foldersToRemove.append(fn); + } // insert subfolders foreach (FileTreeNode *c, node->children) { @@ -305,22 +340,31 @@ void QbsGroupNode::setupFolders(ProjectExplorer::FolderNode *root, FileTreeNode fn = new ProjectExplorer::FileNode(path, ProjectExplorer::UnknownFileType, false); filesToAdd.append(fn); } - } else { - ProjectExplorer::FolderNode *fn = root->findSubFolder(path); - path = path.mid(root->path().length() + 1); // remove common prefix - if (fn) { - fn->emitNodeUpdated(); // enabled might have changed - foldersToRemove.removeOne(fn); - } else { - fn = new ProjectExplorer::FolderNode(path); - addFolderNodes(QList() << fn, root); - } - setupFolders(fn, c); + continue; } + + ProjectExplorer::FolderNode *fn = root->findSubFolder(path); + if (path == baseDirPath) { + setupFolders(topLevel, root, c, c->path(), foldersToKeep); + continue; + } + + if (path.startsWith(baseDirPath + QLatin1Char('/'))) + path = path.mid(baseDirPath.length() + 1); // remove common prefix + + if (fn) { + fn->emitNodeUpdated(); // enabled might have changed + foldersToRemove.removeOne(fn); + } else { + fn = new ProjectExplorer::FolderNode(path); + topLevel->addFolderNodes(QList() << fn, root); + } + foldersToKeep.append(fn); + setupFolders(topLevel, fn, c, c->path()); } - addFileNodes(filesToAdd, root); - removeFileNodes(filesToRemove, root); - removeFolderNodes(foldersToRemove, root); + topLevel->removeFileNodes(filesToRemove, root); + topLevel->removeFolderNodes(foldersToRemove, root); + topLevel->addFileNodes(filesToAdd, root); } // -------------------------------------------------------------------- @@ -346,31 +390,42 @@ void QbsProductNode::setProduct(const qbs::ProductData *prd) setDisplayName(prd->name()); setPath(prd->location().fileName); + const QString &productPath = QFileInfo(prd->location().fileName).absolutePath(); // Set Product file node used to jump to the product QList files = fileNodes(); + QList toKeep; if (files.isEmpty()) { - addFileNodes(QList() - << new QbsFileNode(prd->location().fileName, - ProjectExplorer::ProjectFileType, false, - prd->location().line), - this); + QbsFileNode *idx = new QbsFileNode(prd->location().fileName, + ProjectExplorer::ProjectFileType, false, + prd->location().line); + addFileNodes(QList() << idx, this); + toKeep.append(idx); } else { - QbsFileNode *qbsFile = static_cast(files.at(0)); - qbsFile->setPath(prd->location().fileName); - qbsFile->setLine(prd->location().line); + QbsFileNode *idx = static_cast(files.at(0)); + idx->setPath(prd->location().fileName); + idx->setLine(prd->location().line); + toKeep.append(idx); } QList toAdd; QList toRemove = subProjectNodes(); foreach (const qbs::GroupData &grp, prd->groups()) { + if (grp.name() == prd->name() && grp.location() == prd->location()) { + // Set implicit product group right onto this node: + QbsGroupNode::setGroup(this, &grp, productPath, toKeep); + continue; + } QbsGroupNode *qn = findGroupNode(grp.name()); if (qn) { toRemove.removeAll(qn); - qn->setGroup(&grp); + toKeep.append(qn); + qn->setGroup(&grp, productPath); } else { - toAdd << new QbsGroupNode(&grp); + qn = new QbsGroupNode(&grp, productPath); + toAdd.append(qn); + toKeep.append(qn); } } diff --git a/src/plugins/qbsprojectmanager/qbsnodes.h b/src/plugins/qbsprojectmanager/qbsnodes.h index c398d4b7220..6f703cfda56 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.h +++ b/src/plugins/qbsprojectmanager/qbsnodes.h @@ -64,6 +64,8 @@ private: // QbsBaseProjectNode: // --------------------------------------------------------------------------- +class QbsGroupNode; + class QbsBaseProjectNode : public ProjectExplorer::ProjectNode { Q_OBJECT @@ -94,6 +96,9 @@ public: const QString &newFilePath); QList runConfigurationsFor(Node *node); + +private: + friend class QbsGroupNode; }; // -------------------------------------------------------------------- @@ -105,17 +110,24 @@ class QbsGroupNode : public QbsBaseProjectNode Q_OBJECT public: - QbsGroupNode(const qbs::GroupData *grp); + QbsGroupNode(const qbs::GroupData *grp, const QString &productPath); bool isEnabled() const; - void setGroup(const qbs::GroupData *group); + void setGroup(const qbs::GroupData *group, const QString &productPath); const qbs::GroupData *group() const { return m_group; } + QString productPath() const; + + static void setGroup(QbsBaseProjectNode *root, const qbs::GroupData *group, + const QString &productPath, QList keepers); + private: - void setupFolders(ProjectExplorer::FolderNode *root, FileTreeNode *node, - ProjectExplorer::FileNode *keep = 0); + static void setupFolders(QbsBaseProjectNode *topLevel, FolderNode *root, FileTreeNode *node, + const QString &baseDirPath, + QList keepers = QList()); const qbs::GroupData *m_group; + QString m_productPath; }; // --------------------------------------------------------------------