From e8ee898864dee2b7e7fef7656ea030ab9d85332b Mon Sep 17 00:00:00 2001 From: Daniel Teske <daniel.teske@nokia.com> Date: Fri, 4 May 2012 11:49:37 +0200 Subject: [PATCH] ProjectExplorer: Remove hack for virtual folders Previously virtual folders, that is the "Sources", "Headers" folders used a hack. This patch removes that hack, by introducing the following changes - The FlatModel and the ProjectExplorer::Nodes now don't require path() to be unique. Thus allowing the virtual folders to all return the same for path(). [1] - Introducing a new node type "VirtualFolder" which is sorted according to a priority. - Introducing a few new virtuals for displayName and toolip(), which can be overriden. [1] Note that all the project managers do require path() to be unique for some types of nodes. That also fixes: Task-number: QTCREATORBUG-7100 Change-Id: I76b730f4c4254e2894467603bbe9a30e356a0bcc Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com> Reviewed-by: Daniel Teske <daniel.teske@nokia.com> --- .../cmakeprojectmanager/cmakeproject.cpp | 9 +- .../projectexplorer/projectexplorer.cpp | 5 +- src/plugins/projectexplorer/projectmodels.cpp | 30 +++- src/plugins/projectexplorer/projectnodes.cpp | 113 ++++++++----- src/plugins/projectexplorer/projectnodes.h | 19 ++- src/plugins/qt4projectmanager/qt4nodes.cpp | 157 ++++++++++++------ src/plugins/qt4projectmanager/qt4nodes.h | 23 +++ 7 files changed, 247 insertions(+), 109 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index b7fa77ee746..2845b74ed00 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -376,13 +376,18 @@ void CMakeProject::gatherFileNodes(ProjectExplorer::FolderNode *parent, QList<Pr list.append(file); } +bool sortNodesByPath(Node *a, Node *b) +{ + return a->path() < b->path(); +} + void CMakeProject::buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> newList) { // Gather old list QList<ProjectExplorer::FileNode *> oldList; gatherFileNodes(rootNode, oldList); - qSort(oldList.begin(), oldList.end(), ProjectExplorer::ProjectNode::sortNodesByPath); - qSort(newList.begin(), newList.end(), ProjectExplorer::ProjectNode::sortNodesByPath); + qSort(oldList.begin(), oldList.end(), sortNodesByPath); + qSort(newList.begin(), newList.end(), sortNodesByPath); // generate added and deleted list QList<ProjectExplorer::FileNode *>::const_iterator oldIt = oldList.constBegin(); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index a4f4553b05f..92f46f15e1b 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2567,12 +2567,11 @@ QString pathOrDirectoryFor(Node *node, bool dir) QString path = node->path(); QString location; FolderNode *folder = qobject_cast<FolderNode *>(node); - const int hashPos = path.indexOf(QLatin1Char('#')); - if (hashPos >= 0 && folder) { + if (node->nodeType() == ProjectExplorer::VirtualFolderNodeType && folder) { // Virtual Folder case // If there are files directly below or no subfolders, take the folder path if (!folder->fileNodes().isEmpty() || folder->subFolderNodes().isEmpty()) { - location = path.left(hashPos); + location = path; } else { // Otherwise we figure out a commonPath from the subfolders QStringList list; diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index 9eeb72aecad..aaf65d113af 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -101,6 +101,29 @@ bool sortNodes(Node *n1, Node *n2) if (n2Type == ProjectNodeType) return false; + if (n1Type == VirtualFolderNodeType) { + if (n2Type == VirtualFolderNodeType) { + VirtualFolderNode *folder1 = static_cast<VirtualFolderNode *>(n1); + VirtualFolderNode *folder2 = static_cast<VirtualFolderNode *>(n2); + + if (folder1->priority() > folder2->priority()) + return true; + if (folder1->priority() < folder2->priority()) + return false; + int result = caseFriendlyCompare(folder1->path(), folder2->path()); + if (result != 0) + return result < 0; + else + return folder1 < folder2; + } else { + return true; // virtual folder is before folder + } + } + + if (n2Type == VirtualFolderNodeType) + return false; + + if (n1Type == FolderNodeType) { if (n2Type == FolderNodeType) { FolderNode *folder1 = static_cast<FolderNode*>(n1); @@ -240,14 +263,11 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const switch (role) { case Qt::DisplayRole: case Qt::EditRole: { - if (folderNode) - result = folderNode->displayName(); - else - result = QFileInfo(node->path()).fileName(); //TODO cache that? + result = node->displayName(); break; } case Qt::ToolTipRole: { - result = QDir::toNativeSeparators(node->path()); + result = node->tooltip(); break; } case Qt::DecorationRole: { diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 2d971dc6746..6620b439673 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -102,6 +102,16 @@ QString Node::path() const return m_path; } +QString Node::displayName() const +{ + return QFileInfo(path()).fileName(); +} + +QString Node::tooltip() const +{ + return QDir::toNativeSeparators(path()); +} + void Node::setNodeType(NodeType type) { m_nodeType = type; @@ -154,8 +164,8 @@ bool FileNode::isGenerated() const \sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode */ -FolderNode::FolderNode(const QString &folderPath) : - Node(FolderNodeType, folderPath), +FolderNode::FolderNode(const QString &folderPath, NodeType nodeType) : + Node(nodeType, folderPath), m_displayName(QDir::toNativeSeparators(folderPath)) { } @@ -215,6 +225,31 @@ void FolderNode::setIcon(const QIcon &icon) m_icon = icon; } +/*! + \class ProjectExplorer::VirtualFolderNode + + In-memory presentation of a virtual folder. + Note that the node itself + all children (files and folders) are "managed" by the owning project. + A virtual folder does not correspond to a actual folder on the file system. See for example the + sources, headers and forms folder the qt4projectmanager creates + VirtualFolderNodes are always sorted before FolderNodes and are sorted according to their priority. + + \sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode +*/ +VirtualFolderNode::VirtualFolderNode(const QString &folderPath, int priority) + : FolderNode(folderPath, VirtualFolderNodeType), m_priority(priority) +{ +} + +VirtualFolderNode::~VirtualFolderNode() +{ +} + +int VirtualFolderNode::priority() const +{ + return m_priority; +} + /*! \class ProjectExplorer::ProjectNode @@ -344,10 +379,8 @@ void ProjectNode::addProjectNodes(const QList<ProjectNode*> &subProjects) m_subFolderNodes.append(project); m_subProjectNodes.append(project); } - qSort(m_subFolderNodes.begin(), m_subFolderNodes.end(), - sortNodesByPath); - qSort(m_subProjectNodes.begin(), m_subProjectNodes.end(), - sortNodesByPath); + qSort(m_subFolderNodes.begin(), m_subFolderNodes.end()); + qSort(m_subProjectNodes.begin(), m_subProjectNodes.end()); foreach (NodesWatcher *watcher, m_watchers) emit watcher->foldersAdded(); @@ -366,7 +399,7 @@ void ProjectNode::removeProjectNodes(const QList<ProjectNode*> &subProjects) QList<FolderNode*> toRemove; foreach (ProjectNode *projectNode, subProjects) toRemove << projectNode; - qSort(toRemove.begin(), toRemove.end(), sortNodesByPath); + qSort(toRemove.begin(), toRemove.end()); foreach (NodesWatcher *watcher, m_watchers) emit watcher->foldersAboutToBeRemoved(this, toRemove); @@ -375,12 +408,12 @@ void ProjectNode::removeProjectNodes(const QList<ProjectNode*> &subProjects) QList<FolderNode*>::iterator folderIter = m_subFolderNodes.begin(); QList<ProjectNode*>::iterator projectIter = m_subProjectNodes.begin(); for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) { - while ((*projectIter)->path() != (*toRemoveIter)->path()) { + while (*projectIter != *toRemoveIter) { ++projectIter; QTC_ASSERT(projectIter != m_subProjectNodes.end(), qDebug("Project to remove is not part of specified folder!")); } - while ((*folderIter)->path() != (*toRemoveIter)->path()) { + while (*folderIter != *toRemoveIter) { ++folderIter; QTC_ASSERT(folderIter != m_subFolderNodes.end(), qDebug("Project to remove is not part of specified folder!")); @@ -416,22 +449,17 @@ void ProjectNode::addFolderNodes(const QList<FolderNode*> &subFolders, FolderNod folder->setProjectNode(this); // Find the correct place to insert - if (parentFolder->m_subFolderNodes.count() == 0 || sortNodesByPath(parentFolder->m_subFolderNodes.last(), folder)) { + if (parentFolder->m_subFolderNodes.count() == 0 + || parentFolder->m_subFolderNodes.last() < folder) { // empty list or greater then last node parentFolder->m_subFolderNodes.append(folder); } else { // Binary Search for insertion point - int l = 0; - int r = parentFolder->m_subFolderNodes.count(); - while (l != r) { - int i = (l + r) / 2; - if (sortNodesByPath(folder, parentFolder->m_subFolderNodes.at(i))) { - r = i; - } else { - l = i + 1; - } - } - parentFolder->m_subFolderNodes.insert(l, folder); + QList<FolderNode*>::iterator it + = qLowerBound(parentFolder->m_subFolderNodes.begin(), + parentFolder->m_subFolderNodes.end(), + folder); + parentFolder->m_subFolderNodes.insert(it, folder); } // project nodes have to be added via addProjectNodes @@ -459,7 +487,7 @@ void ProjectNode::removeFolderNodes(const QList<FolderNode*> &subFolders, const bool emitSignals = (parentFolder->projectNode() == this); QList<FolderNode*> toRemove = subFolders; - qSort(toRemove.begin(), toRemove.end(), sortNodesByPath); + qSort(toRemove.begin(), toRemove.end()); if (emitSignals) foreach (NodesWatcher *watcher, m_watchers) @@ -470,7 +498,7 @@ void ProjectNode::removeFolderNodes(const QList<FolderNode*> &subFolders, for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) { QTC_ASSERT((*toRemoveIter)->nodeType() != ProjectNodeType, qDebug("project nodes have to be removed via removeProjectNodes")); - while ((*folderIter)->path() != (*toRemoveIter)->path()) { + while (*folderIter != *toRemoveIter) { ++folderIter; QTC_ASSERT(folderIter != parentFolder->m_subFolderNodes.end(), qDebug("Folder to remove is not part of specified folder!")); @@ -509,22 +537,16 @@ void ProjectNode::addFileNodes(const QList<FileNode*> &files, FolderNode *folder file->setParentFolderNode(folder); file->setProjectNode(this); // Now find the correct place to insert file - if (folder->m_fileNodes.count() == 0 || sortNodesByPath(folder->m_fileNodes.last(), file)) { + if (folder->m_fileNodes.count() == 0 + || folder->m_fileNodes.last() < file) { // empty list or greater then last node folder->m_fileNodes.append(file); } else { - // Binary Search for insertion point - int l = 0; - int r = folder->m_fileNodes.count(); - while (l != r) { - int i = (l + r) / 2; - if (sortNodesByPath(file, folder->m_fileNodes.at(i))) { - r = i; - } else { - l = i + 1; - } - } - folder->m_fileNodes.insert(l, file); + QList<FileNode *>::iterator it + = qLowerBound(folder->m_fileNodes.begin(), + folder->m_fileNodes.end(), + file); + folder->m_fileNodes.insert(it, file); } } @@ -549,7 +571,7 @@ void ProjectNode::removeFileNodes(const QList<FileNode*> &files, FolderNode *fol const bool emitSignals = (folder->projectNode() == this); QList<FileNode*> toRemove = files; - qSort(toRemove.begin(), toRemove.end(), sortNodesByPath); + qSort(toRemove.begin(), toRemove.end()); if (emitSignals) foreach (NodesWatcher *watcher, m_watchers) @@ -558,7 +580,7 @@ void ProjectNode::removeFileNodes(const QList<FileNode*> &files, FolderNode *fol QList<FileNode*>::const_iterator toRemoveIter = toRemove.constBegin(); QList<FileNode*>::iterator filesIter = folder->m_fileNodes.begin(); for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) { - while ((*filesIter)->path() != (*toRemoveIter)->path()) { + while (*filesIter != *toRemoveIter) { ++filesIter; QTC_ASSERT(filesIter != folder->m_fileNodes.end(), qDebug("File to remove is not part of specified folder!")); @@ -579,12 +601,6 @@ void ProjectNode::watcherDestroyed(QObject *watcher) unregisterWatcher(static_cast<NodesWatcher*>(watcher)); } -/*! - \brief Sort pointers to FileNodes -*/ -bool ProjectNode::sortNodesByPath(Node *n1, Node *n2) { - return n1->path() < n2->path(); -} /*! \class ProjectExplorer::SessionNode @@ -663,6 +679,9 @@ void SessionNode::addProjectNodes(const QList<ProjectNode*> &projectNodes) m_projectNodes.append(project); } + qSort(m_subFolderNodes); + qSort(m_projectNodes); + foreach (NodesWatcher *watcher, m_watchers) emit watcher->foldersAdded(); } @@ -675,6 +694,8 @@ void SessionNode::removeProjectNodes(const QList<ProjectNode*> &projectNodes) foreach (ProjectNode *projectNode, projectNodes) toRemove << projectNode; + qSort(toRemove); + foreach (NodesWatcher *watcher, m_watchers) emit watcher->foldersAboutToBeRemoved(this, toRemove); @@ -682,12 +703,12 @@ void SessionNode::removeProjectNodes(const QList<ProjectNode*> &projectNodes) QList<FolderNode*>::iterator folderIter = m_subFolderNodes.begin(); QList<ProjectNode*>::iterator projectIter = m_projectNodes.begin(); for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) { - while ((*projectIter)->path() != (*toRemoveIter)->path()) { + while (*projectIter != *toRemoveIter) { ++projectIter; QTC_ASSERT(projectIter != m_projectNodes.end(), qDebug("Project to remove is not part of specified folder!")); } - while ((*folderIter)->path() != (*toRemoveIter)->path()) { + while (*folderIter != *toRemoveIter) { ++folderIter; QTC_ASSERT(folderIter != m_subFolderNodes.end(), qDebug("Project to remove is not part of specified folder!")); diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index 24440c668e5..c654d2da16a 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -54,6 +54,7 @@ class RunConfiguration; enum NodeType { FileNodeType = 1, FolderNodeType, + VirtualFolderNodeType, ProjectNodeType, SessionNodeType }; @@ -87,6 +88,8 @@ public: ProjectNode *projectNode() const; // managing project FolderNode *parentFolderNode() const; // parent folder or project QString path() const; // file system path + virtual QString displayName() const; + virtual QString tooltip() const; protected: Node(NodeType nodeType, const QString &path); @@ -122,7 +125,7 @@ private: class PROJECTEXPLORER_EXPORT FolderNode : public Node { Q_OBJECT public: - explicit FolderNode(const QString &folderPath); + explicit FolderNode(const QString &folderPath, NodeType nodeType = FolderNodeType); virtual ~FolderNode(); QString displayName() const; @@ -147,6 +150,18 @@ private: mutable QIcon m_icon; }; +class PROJECTEXPLORER_EXPORT VirtualFolderNode : public FolderNode +{ + Q_OBJECT +public: + explicit VirtualFolderNode(const QString &folderPath, int priority); + virtual ~VirtualFolderNode(); + + int priority() const; +private: + int m_priority; +}; + // Documentation inside. class PROJECTEXPLORER_EXPORT ProjectNode : public FolderNode { @@ -213,8 +228,6 @@ public: void accept(NodesVisitor *visitor); - static bool sortNodesByPath(Node *n1, Node *n2); - protected: // this is just the in-memory representation, a subclass // will add the persistent stuff diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index 0aa2b569525..0d69951516d 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -107,6 +107,11 @@ static const FileTypeDataStorage fileTypeDataStorage[] = { ":/qt4projectmanager/images/unknown.png" } }; +bool sortNodesByPath(ProjectExplorer::Node *a, ProjectExplorer::Node *b) +{ + return a->path() < b->path(); +} + class Qt4NodeStaticData { public: class FileTypeData { @@ -278,20 +283,25 @@ void Qt4PriFileNode::scheduleUpdate() namespace Internal { struct InternalNode { - QMap<QString, InternalNode*> subnodes; + QList<InternalNode *> virtualfolders; + QMap<QString, InternalNode *> subnodes; QStringList files; ProjectExplorer::FileType type; QString displayName; + QString typeName; + int priority; QString fullPath; QIcon icon; InternalNode() { type = ProjectExplorer::UnknownFileType; + priority = 0; } ~InternalNode() { + qDeleteAll(virtualfolders); qDeleteAll(subnodes); } @@ -381,62 +391,102 @@ struct InternalNode subnodes = newSubnodes; } + FolderNode *createFolderNode(InternalNode *node) + { + FolderNode *newNode = 0; + if (node->typeName.isEmpty()) + newNode = new FolderNode(node->fullPath); + else + newNode = new ProVirtualFolderNode(node->fullPath, node->priority, node->typeName); + + newNode->setDisplayName(node->displayName); + if (!node->icon.isNull()) + newNode->setIcon(node->icon); + return newNode; + } + // Makes the projectNode's subtree below the given folder match this internal node's subtree void updateSubFolders(Qt4ProjectManager::Qt4PriFileNode *projectNode, ProjectExplorer::FolderNode *folder) { updateFiles(projectNode, folder, type); - // update folders - QList<FolderNode *> existingFolderNodes; - foreach (FolderNode *node, folder->subFolderNodes()) { + // updateFolders + QMultiMap<QString, FolderNode *> existingFolderNodes; + foreach (FolderNode *node, folder->subFolderNodes()) if (node->nodeType() != ProjectNodeType) - existingFolderNodes << node; - } - - qSort(existingFolderNodes.begin(), existingFolderNodes.end(), ProjectNode::sortNodesByPath); + existingFolderNodes.insert(node->path(), node); QList<FolderNode *> foldersToRemove; QList<FolderNode *> foldersToAdd; typedef QPair<InternalNode *, FolderNode *> NodePair; QList<NodePair> nodesToUpdate; - // Both lists should be already sorted... - QList<FolderNode*>::const_iterator existingNodeIter = existingFolderNodes.constBegin(); - QMap<QString, InternalNode*>::const_iterator newNodeIter = subnodes.constBegin();; - while (existingNodeIter != existingFolderNodes.constEnd() - && newNodeIter != subnodes.constEnd()) { - if ((*existingNodeIter)->path() < newNodeIter.value()->fullPath) { - foldersToRemove << *existingNodeIter; - ++existingNodeIter; - } else if ((*existingNodeIter)->path() > newNodeIter.value()->fullPath) { - FolderNode *newNode = new FolderNode(newNodeIter.value()->fullPath); - newNode->setDisplayName(newNodeIter.value()->displayName); - if (!newNodeIter.value()->icon.isNull()) - newNode->setIcon(newNodeIter.value()->icon); - foldersToAdd << newNode; - nodesToUpdate << NodePair(newNodeIter.value(), newNode); - ++newNodeIter; - } else { // *existingNodeIter->path() == *newPathIter - nodesToUpdate << NodePair(newNodeIter.value(), *existingNodeIter); - ++existingNodeIter; - ++newNodeIter; + // Check virtual + { + QList<InternalNode *>::const_iterator it = virtualfolders.constBegin(); + QList<InternalNode *>::const_iterator end = virtualfolders.constEnd(); + for ( ; it != end; ++it) { + bool found = false; + QString path = (*it)->fullPath; + QMultiMap<QString, FolderNode *>::const_iterator oldit + = existingFolderNodes.constFind(path); + while (oldit != existingFolderNodes.end() && oldit.key() == path) { + if (oldit.value()->nodeType() == ProjectExplorer::VirtualFolderNodeType) { + ProjectExplorer::VirtualFolderNode *vfn + = qobject_cast<ProjectExplorer::VirtualFolderNode *>(oldit.value()); + if (vfn->priority() == (*it)->priority) { + found = true; + break; + } + } + ++oldit; + } + if (found) { + nodesToUpdate << NodePair(*it, *oldit); + } else { + FolderNode *newNode = createFolderNode(*it); + foldersToAdd << newNode; + nodesToUpdate << NodePair(*it, newNode); + } } } - - while (existingNodeIter != existingFolderNodes.constEnd()) { - foldersToRemove << *existingNodeIter; - ++existingNodeIter; - } - while (newNodeIter != subnodes.constEnd()) { - FolderNode *newNode = new FolderNode(newNodeIter.value()->fullPath); - newNode->setDisplayName(newNodeIter.value()->displayName); - if (!newNodeIter.value()->icon.isNull()) - newNode->setIcon(newNodeIter.value()->icon); - foldersToAdd << newNode; - nodesToUpdate << NodePair(newNodeIter.value(), newNode); - ++newNodeIter; + // Check subnodes + { + QMap<QString, InternalNode *>::const_iterator it = subnodes.constBegin(); + QMap<QString, InternalNode *>::const_iterator end = subnodes.constEnd(); + + for ( ; it != end; ++it) { + bool found = false; + QString path = it.value()->fullPath; + QMultiMap<QString, FolderNode *>::const_iterator oldit + = existingFolderNodes.constFind(path); + while (oldit != existingFolderNodes.end() && oldit.key() == path) { + if (oldit.value()->nodeType() == ProjectExplorer::FolderNodeType) { + found = true; + break; + } + ++oldit; + } + if (found) { + nodesToUpdate << NodePair(it.value(), *oldit); + } else { + FolderNode *newNode = createFolderNode(it.value()); + foldersToAdd << newNode; + nodesToUpdate << NodePair(it.value(), newNode); + } + } } + QSet<FolderNode *> toKeep; + foreach (const NodePair &np, nodesToUpdate) + toKeep << np.second; + + QMultiMap<QString, FolderNode *>::const_iterator jit = existingFolderNodes.constBegin(); + QMultiMap<QString, FolderNode *>::const_iterator jend = existingFolderNodes.constEnd(); + for ( ; jit != jend; ++jit) + if (!toKeep.contains(jit.value())) + foldersToRemove << jit.value(); + if (!foldersToRemove.isEmpty()) projectNode->removeFolderNodes(foldersToRemove, folder); if (!foldersToAdd.isEmpty()) @@ -459,7 +509,7 @@ struct InternalNode QList<FileNode*> filesToAdd; qSort(files); - qSort(existingFileNodes.begin(), existingFileNodes.end(), ProjectNode::sortNodesByPath); + qSort(existingFileNodes.begin(), existingFileNodes.end(), sortNodesByPath); QList<FileNode*>::const_iterator existingNodeIter = existingFileNodes.constBegin(); QList<QString>::const_iterator newPathIter = files.constBegin(); @@ -647,10 +697,11 @@ void Qt4PriFileNode::update(ProFile *includeFileExact, QtSupport::ProFileReader InternalNode *subfolder = new InternalNode; subfolder->type = type; subfolder->icon = fileTypes.at(i).icon; - subfolder->fullPath = m_projectDir + QLatin1String("/#") - + QString::number(i) + fileTypes.at(i).typeName; + subfolder->fullPath = m_projectDir; + subfolder->typeName = fileTypes.at(i).typeName; + subfolder->priority = -i; subfolder->displayName = fileTypes.at(i).typeName; - contents.subnodes.insert(subfolder->fullPath, subfolder); + contents.virtualfolders.append(subfolder); // create the hierarchy with subdirectories subfolder->create(m_projectDir, newFilePaths, type); } @@ -731,10 +782,11 @@ void Qt4PriFileNode::folderChanged(const QString &folder) InternalNode *subfolder = new InternalNode; subfolder->type = type; subfolder->icon = fileTypes.at(i).icon; - subfolder->fullPath = m_projectDir + QLatin1String("/#") - + QString::number(i) + fileTypes.at(i).typeName; + subfolder->fullPath = m_projectDir; + subfolder->typeName = fileTypes.at(i).typeName; + subfolder->priority = -i; subfolder->displayName = fileTypes.at(i).typeName; - contents.subnodes.insert(subfolder->fullPath, subfolder); + contents.virtualfolders.append(subfolder); // create the hierarchy with subdirectories subfolder->create(m_projectDir, m_files[type], type); } @@ -833,7 +885,7 @@ QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions(Node *node) c } bool addExistingFiles = true; - if (node->path().contains(QLatin1Char('#'))) { + if (node->nodeType() == ProjectExplorer::VirtualFolderNodeType) { // A virtual folder, we do what the projectexplorer does FolderNode *folder = qobject_cast<FolderNode *>(node); if (folder) { @@ -1648,6 +1700,11 @@ void Qt4ProFileNode::applyAsyncEvaluate() m_project->decrementPendingEvaluateFutures(); } +bool sortByNodes(Node *a, Node *b) +{ + return a->path() < b->path(); +} + void Qt4ProFileNode::applyEvaluate(EvalResult evalResult, bool async) { if (!m_readerExact) @@ -1996,7 +2053,7 @@ QStringList Qt4ProFileNode::updateUiFiles() QStringList toUpdate; qSort(newFilePaths); - qSort(existingFileNodes.begin(), existingFileNodes.end(), ProjectNode::sortNodesByPath); + qSort(existingFileNodes.begin(), existingFileNodes.end(), sortNodesByPath); QList<ProjectExplorer::FileNode*>::const_iterator existingNodeIter = existingFileNodes.constBegin(); QList<QString>::const_iterator newPathIter = newFilePaths.constBegin(); diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h index dcef5dbd821..5426d6de7de 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.h +++ b/src/plugins/qt4projectmanager/qt4nodes.h @@ -264,6 +264,29 @@ private: friend class Qt4PriFileNode; }; +class ProVirtualFolderNode : public ProjectExplorer::VirtualFolderNode +{ +public: + explicit ProVirtualFolderNode(const QString &folderPath, int priority, const QString &typeName) + : VirtualFolderNode(folderPath, priority), m_typeName(typeName) + { + + } + + QString displayName() const + { + return m_typeName; + } + + QString tooltip() const + { + return QString(); + } + +private: + QString m_typeName; +}; + } // namespace Internal struct QT4PROJECTMANAGER_EXPORT TargetInformation -- GitLab