diff options
author | con <qtc-committer@nokia.com> | 2009-08-17 17:59:57 +0200 |
---|---|---|
committer | con <qtc-committer@nokia.com> | 2009-08-21 14:53:25 +0200 |
commit | 7ebea974d69e0ca750ca77ea437e901936a7e8f5 (patch) | |
tree | 30ddd124a69310e554505eb3e2f4b46afb53cc95 /src/plugins | |
parent | f888f5df2d8bb510ca97a3d54ce45ff367594c56 (diff) | |
download | qt-creator-7ebea974d69e0ca750ca77ea437e901936a7e8f5.tar.gz |
Show pro file's subdirectory structure in project tree in non-simple mode.
Also adding category folders for the different file types
(source files, header files, resource files, form files, other files).
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/projectexplorer/projectmodels.cpp | 10 | ||||
-rw-r--r-- | src/plugins/projectexplorer/projectnodes.cpp | 15 | ||||
-rw-r--r-- | src/plugins/projectexplorer/projectnodes.h | 3 | ||||
-rw-r--r-- | src/plugins/qt4projectmanager/images/forms.png | bin | 0 -> 311 bytes | |||
-rw-r--r-- | src/plugins/qt4projectmanager/images/headers.png | bin | 0 -> 223 bytes | |||
-rw-r--r-- | src/plugins/qt4projectmanager/images/qt_qrc.png | bin | 0 -> 676 bytes | |||
-rw-r--r-- | src/plugins/qt4projectmanager/images/sources.png | bin | 0 -> 208 bytes | |||
-rw-r--r-- | src/plugins/qt4projectmanager/images/unknown.png | bin | 0 -> 267 bytes | |||
-rw-r--r-- | src/plugins/qt4projectmanager/qt4nodes.cpp | 290 | ||||
-rw-r--r-- | src/plugins/qt4projectmanager/qt4nodes.h | 3 | ||||
-rw-r--r-- | src/plugins/qt4projectmanager/qt4projectmanager.qrc | 7 |
11 files changed, 279 insertions, 49 deletions
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index dcde9968e5..da793af74a 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -961,11 +961,15 @@ FolderNode *FlatModel::visibleFolderNode(FolderNode *node) const bool FlatModel::filter(Node *node) const { bool isHidden = false; - if (ProjectNode *projectNode = qobject_cast<ProjectNode*>(node)) { + if (node->nodeType() == SessionNodeType) { + isHidden = false; + } else if (ProjectNode *projectNode = qobject_cast<ProjectNode*>(node)) { if (m_filterProjects && projectNode->parentFolderNode() != m_rootNode) isHidden = !projectNode->hasTargets(); - } - if (FileNode *fileNode = qobject_cast<FileNode*>(node)) { + } else if (node->nodeType() == FolderNodeType) { + if (m_filterProjects) + isHidden = true; + } else if (FileNode *fileNode = qobject_cast<FileNode*>(node)) { if (m_filterGeneratedFiles) isHidden = fileNode->isGenerated(); } diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 6bd2205908..7b7b54cf38 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -153,7 +153,11 @@ FolderNode::FolderNode(const QString &folderPath) : Node(FolderNodeType, folderPath), m_folderName(folderPath) { - m_icon = QApplication::style()->standardIcon(QStyle::SP_DirIcon); + static QIcon dirIcon; + if (dirIcon.isNull()) { + dirIcon = QApplication::style()->standardIcon(QStyle::SP_DirIcon); + } + m_icon = dirIcon; } FolderNode::~FolderNode() @@ -549,8 +553,13 @@ void ProjectNode::watcherDestroyed(QObject *watcher) /*! Sort pointers to FileNodes */ -bool ProjectNode::sortNodesByPath(Node *f1, Node *f2) { - return f1->path() < f2->path(); +bool ProjectNode::sortNodesByPath(Node *n1, Node *n2) { + return n1->path() < n2->path(); +} + +bool ProjectNode::sortFolderNodesByName(FolderNode *f1, FolderNode *f2) +{ + return f1->name() < f2->name(); } /*! diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index 958d524b04..cfd0d7ca49 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -136,10 +136,10 @@ public: virtual void accept(NodesVisitor *visitor); -protected: void setFolderName(const QString &name); void setIcon(const QIcon &icon); +protected: QList<FolderNode*> m_subFolderNodes; QList<FileNode*> m_fileNodes; @@ -193,6 +193,7 @@ public: void accept(NodesVisitor *visitor); static bool sortNodesByPath(Node *n1, Node *n2); + static bool sortFolderNodesByName(FolderNode *f1, FolderNode *f2); protected: // this is just the in-memory representation, a subclass diff --git a/src/plugins/qt4projectmanager/images/forms.png b/src/plugins/qt4projectmanager/images/forms.png Binary files differnew file mode 100644 index 0000000000..04059d99f0 --- /dev/null +++ b/src/plugins/qt4projectmanager/images/forms.png diff --git a/src/plugins/qt4projectmanager/images/headers.png b/src/plugins/qt4projectmanager/images/headers.png Binary files differnew file mode 100644 index 0000000000..ff7797fa91 --- /dev/null +++ b/src/plugins/qt4projectmanager/images/headers.png diff --git a/src/plugins/qt4projectmanager/images/qt_qrc.png b/src/plugins/qt4projectmanager/images/qt_qrc.png Binary files differnew file mode 100644 index 0000000000..3643f37e1a --- /dev/null +++ b/src/plugins/qt4projectmanager/images/qt_qrc.png diff --git a/src/plugins/qt4projectmanager/images/sources.png b/src/plugins/qt4projectmanager/images/sources.png Binary files differnew file mode 100644 index 0000000000..60dc177b86 --- /dev/null +++ b/src/plugins/qt4projectmanager/images/sources.png diff --git a/src/plugins/qt4projectmanager/images/unknown.png b/src/plugins/qt4projectmanager/images/unknown.png Binary files differnew file mode 100644 index 0000000000..0f2ad1818e --- /dev/null +++ b/src/plugins/qt4projectmanager/images/unknown.png diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index 1b7f1ea222..a47f43001e 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -116,6 +116,217 @@ void Qt4PriFileNode::scheduleUpdate() m_qt4ProFileNode->scheduleUpdate(); } +namespace Qt4ProjectManager { +namespace Internal { + struct InternalNode + { + QMap<QString, InternalNode*> subnodes; + QStringList files; + ProjectExplorer::FileType type; + QString fullName; + QIcon icon; + + ~InternalNode() + { + qDeleteAll(subnodes); + } + + // Creates a tree structure from a list of absolute file paths. + // Empty directories are compressed into a single entry with a longer path. + // * project + // * /absolute/path + // * file1 + // * relative + // * path1 + // * file1 + // * file2 + // * path2 + // * file1 + void create(const QString &projectDir, const QStringList &newFilePaths, ProjectExplorer::FileType type) + { + static const QChar separator = QChar('/'); + const QString projectDirWithSeparator = projectDir + separator; + int projectDirWithSeparatorLength = projectDirWithSeparator.length(); + foreach (const QString &file, newFilePaths) { + QString fileWithoutPrefix; + bool isRelative; + if (file.startsWith(projectDirWithSeparator)) { + isRelative = true; + fileWithoutPrefix = file.mid(projectDirWithSeparatorLength); + } else { + isRelative = false; + fileWithoutPrefix = file; + } + QStringList parts = fileWithoutPrefix.split(separator, QString::SkipEmptyParts); + if (!isRelative && parts.count() > 0) + parts[0].prepend(separator); + QStringListIterator it(parts); + InternalNode *currentNode = this; + QString path = (isRelative ? projectDir : ""); + while (it.hasNext()) { + const QString &key = it.next(); + path += separator + key; + if (it.hasNext()) { // key is directory + if (!currentNode->subnodes.contains(key)) { + InternalNode *val = new InternalNode; + val->type = type; + val->fullName = path; + currentNode->subnodes.insert(key, val); + currentNode = val; + } else { + currentNode = currentNode->subnodes.value(key); + } + } else { // key is filename + currentNode->files.append(file); + } + } + } + this->compress(); + } + + // Removes folder nodes with only a single sub folder in it + void compress() + { + static const QChar separator = QChar('/'); + QMap<QString, InternalNode*> newSubnodes; + QMapIterator<QString, InternalNode*> i(subnodes); + while (i.hasNext()) { + i.next(); + i.value()->compress(); + if (i.value()->files.isEmpty() && i.value()->subnodes.size() == 1) { + QString key = i.value()->subnodes.keys().at(0); + newSubnodes.insert(i.key()+separator+key, i.value()->subnodes.value(key)); + i.value()->subnodes.clear(); + delete i.value(); + } else { + newSubnodes.insert(i.key(), i.value()); + } + } + subnodes = newSubnodes; + } + + // Makes the projectNode's subtree below the given folder match this internal node's subtree + void updateSubFolders(Qt4PriFileNode *projectNode, ProjectExplorer::FolderNode *folder) + { + updateFiles(projectNode, folder, type); + + // update folders + QList<FolderNode *> existingFolderNodes; + foreach (FolderNode *node, folder->subFolderNodes()) { + if (node->nodeType() != ProjectNodeType) + existingFolderNodes << node; + } + + QList<FolderNode *> foldersToRemove; + QList<FolderNode *> foldersToAdd; + QList<InternalNode *> internalNodesToUpdate; + QList<FolderNode *> folderNodesToUpdate; + + // newFolders is already sorted + qSort(existingFolderNodes.begin(), existingFolderNodes.end(), ProjectNode::sortFolderNodesByName); + + QList<FolderNode*>::const_iterator existingNodeIter = existingFolderNodes.constBegin(); + QMap<QString, InternalNode*>::const_iterator newNodeIter = subnodes.constBegin();; + while (existingNodeIter != existingFolderNodes.constEnd() + && newNodeIter != subnodes.constEnd()) { + if ((*existingNodeIter)->name() < newNodeIter.key()) { + foldersToRemove << *existingNodeIter; + ++existingNodeIter; + } else if ((*existingNodeIter)->name() > newNodeIter.key()) { + FolderNode *newNode = new FolderNode(newNodeIter.value()->fullName); + newNode->setFolderName(newNodeIter.key()); + if (!newNodeIter.value()->icon.isNull()) + newNode->setIcon(newNodeIter.value()->icon); + foldersToAdd << newNode; + internalNodesToUpdate << newNodeIter.value(); + folderNodesToUpdate << newNode; + ++newNodeIter; + } else { // *existingNodeIter->path() == *newPathIter + internalNodesToUpdate << newNodeIter.value(); + folderNodesToUpdate << *existingNodeIter; + ++existingNodeIter; + ++newNodeIter; + } + } + + while (existingNodeIter != existingFolderNodes.constEnd()) { + foldersToRemove << *existingNodeIter; + ++existingNodeIter; + } + while (newNodeIter != subnodes.constEnd()) { + FolderNode *newNode = new FolderNode(newNodeIter.value()->fullName); + newNode->setFolderName(newNodeIter.key()); + if (!newNodeIter.value()->icon.isNull()) + newNode->setIcon(newNodeIter.value()->icon); + foldersToAdd << newNode; + internalNodesToUpdate << newNodeIter.value(); + folderNodesToUpdate << newNode; + ++newNodeIter; + } + + if (!foldersToRemove.isEmpty()) + projectNode->removeFolderNodes(foldersToRemove, folder); + if (!foldersToAdd.isEmpty()) + projectNode->addFolderNodes(foldersToAdd, folder); + + QList<FolderNode *>::const_iterator folderIt = folderNodesToUpdate.constBegin(); + QList<InternalNode *>::const_iterator iNodeIt = internalNodesToUpdate.constBegin(); + while (folderIt != folderNodesToUpdate.constEnd() + && iNodeIt != internalNodesToUpdate.constEnd()) { + (*iNodeIt)->updateSubFolders(projectNode, *folderIt); + ++folderIt; + ++iNodeIt; + } + } + + // Makes the folder's files match this internal node's file list + void updateFiles(Qt4PriFileNode *projectNode, FolderNode *folder, FileType type) + { + QList<FileNode*> existingFileNodes; + foreach (FileNode *fileNode, folder->fileNodes()) { + if (fileNode->fileType() == type && !fileNode->isGenerated()) + existingFileNodes << fileNode; + } + + QList<FileNode*> filesToRemove; + QList<FileNode*> filesToAdd; + + qSort(files); + qSort(existingFileNodes.begin(), existingFileNodes.end(), ProjectNode::sortNodesByPath); + + QList<FileNode*>::const_iterator existingNodeIter = existingFileNodes.constBegin(); + QList<QString>::const_iterator newPathIter = files.constBegin(); + while (existingNodeIter != existingFileNodes.constEnd() + && newPathIter != files.constEnd()) { + if ((*existingNodeIter)->path() < *newPathIter) { + filesToRemove << *existingNodeIter; + ++existingNodeIter; + } else if ((*existingNodeIter)->path() > *newPathIter) { + filesToAdd << new FileNode(*newPathIter, type, false); + ++newPathIter; + } else { // *existingNodeIter->path() == *newPathIter + ++existingNodeIter; + ++newPathIter; + } + } + while (existingNodeIter != existingFileNodes.constEnd()) { + filesToRemove << *existingNodeIter; + ++existingNodeIter; + } + while (newPathIter != files.constEnd()) { + filesToAdd << new FileNode(*newPathIter, type, false); + ++newPathIter; + } + + if (!filesToRemove.isEmpty()) + projectNode->removeFileNodes(filesToRemove, folder); + if (!filesToAdd.isEmpty()) + projectNode->addFileNodes(filesToAdd, folder); + } + }; +} // Internal namespace +} // namespace + void Qt4PriFileNode::update(ProFile *includeFile, ProFileReader *reader) { Q_ASSERT(includeFile); @@ -131,6 +342,30 @@ void Qt4PriFileNode::update(ProFile *includeFile, ProFileReader *reader) << ProjectExplorer::FormType << ProjectExplorer::ResourceType << ProjectExplorer::UnknownFileType); + static QStringList fileTypeNames = + QStringList() << tr("Headers") + << tr("Sources") + << tr("Forms") + << tr("Resources") + << tr("Other files"); + static QList<QIcon> fileTypeIcons; + if (fileTypeIcons.isEmpty()) { + QStringList iconPaths; + iconPaths << ":/qt4projectmanager/images/headers.png" + << ":/qt4projectmanager/images/sources.png" + << ":/qt4projectmanager/images/forms.png" + << ":/qt4projectmanager/images/qt_qrc.png" + << ":/qt4projectmanager/images/unknown.png"; + foreach (const QString &iconPath, iconPaths) { + QIcon dirIcon; + Core::FileIconProvider *iconProvider = Core::FileIconProvider::instance(); + QPixmap dirIconPixmap = iconProvider->overlayIcon(QStyle::SP_DirIcon, + QIcon(iconPath), + QSize(16, 16)); + dirIcon.addPixmap(dirIconPixmap); + fileTypeIcons.append(dirIcon); + } + } const QString &projectDir = m_qt4ProFileNode->m_projectDir; @@ -140,8 +375,11 @@ void Qt4PriFileNode::update(ProFile *includeFile, ProFileReader *reader) baseVPaths += reader->absolutePathValues("DEPENDPATH", projectDir); baseVPaths.removeDuplicates(); + InternalNode contents; + // update files - foreach (FileType type, fileTypes) { + for (int i = 0; i < fileTypes.size(); ++i) { + FileType type = fileTypes.at(i); const QStringList qmakeVariables = varNames(type); QStringList newFilePaths; @@ -157,47 +395,17 @@ void Qt4PriFileNode::update(ProFile *includeFile, ProFileReader *reader) } newFilePaths.removeDuplicates(); - QList<FileNode*> existingFileNodes; - foreach (FileNode *fileNode, fileNodes()) { - if (fileNode->fileType() == type && !fileNode->isGenerated()) - existingFileNodes << fileNode; - } - - QList<FileNode*> toRemove; - QList<FileNode*> toAdd; - - qSort(newFilePaths); - qSort(existingFileNodes.begin(), existingFileNodes.end(), ProjectNode::sortNodesByPath); - - QList<FileNode*>::const_iterator existingNodeIter = existingFileNodes.constBegin(); - QList<QString>::const_iterator newPathIter = newFilePaths.constBegin(); - while (existingNodeIter != existingFileNodes.constEnd() - && newPathIter != newFilePaths.constEnd()) { - if ((*existingNodeIter)->path() < *newPathIter) { - toRemove << *existingNodeIter; - ++existingNodeIter; - } else if ((*existingNodeIter)->path() > *newPathIter) { - toAdd << new FileNode(*newPathIter, type, false); - ++newPathIter; - } else { // *existingNodeIter->path() == *newPathIter - ++existingNodeIter; - ++newPathIter; - } - } - while (existingNodeIter != existingFileNodes.constEnd()) { - toRemove << *existingNodeIter; - ++existingNodeIter; - } - while (newPathIter != newFilePaths.constEnd()) { - toAdd << new FileNode(*newPathIter, type, false); - ++newPathIter; + if (!newFilePaths.isEmpty()) { + InternalNode *subfolder = new InternalNode; + subfolder->type = type; + subfolder->icon = fileTypeIcons.at(i); + subfolder->fullName = m_projectDir; + contents.subnodes.insert(fileTypeNames.at(i), subfolder); + // create the hierarchy with subdirectories + subfolder->create(m_projectDir, newFilePaths, type); } - - if (!toRemove.isEmpty()) - removeFileNodes(toRemove, this); - if (!toAdd.isEmpty()) - addFileNodes(toAdd, this); } + contents.updateSubFolders(this, this); } QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions() const @@ -1084,7 +1292,7 @@ void Qt4ProFileNode::createUiCodeModelSupport() foreach (FileNode *uiFile, uiFiles) { QString uiHeaderFilePath = QString("%1/ui_%2.h").arg(uiDir, QFileInfo(uiFile->path()).completeBaseName()); - uiHeaderFilePath = QDir::cleanPath(uiHeaderFilePath); + uiHeaderFilePath = QDir::cleanPath(uiHeaderFilePath); // qDebug()<<"code model support for "<<uiFile->path()<<" "<<uiHeaderFilePath; QMap<QString, Qt4UiCodeModelSupport *>::iterator it = oldCodeModelSupport.find(uiFile->path()); diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h index 6a491dc6e4..f1240e7cdd 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.h +++ b/src/plugins/qt4projectmanager/qt4nodes.h @@ -104,6 +104,7 @@ enum Qt4Variable { class Qt4PriFileNode; class Qt4ProFileNode; +struct InternalNode; // Implements ProjectNode for qt4 pro files class Qt4PriFileNode : public ProjectExplorer::ProjectNode @@ -175,6 +176,8 @@ private: // managed by Qt4ProFileNode friend class Qt4ProFileNode; + // internal temporary subtree representation + friend class InternalNode; }; // Implements ProjectNode for qt4 pro files diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.qrc b/src/plugins/qt4projectmanager/qt4projectmanager.qrc index f733770e2f..6b17ee4244 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager.qrc +++ b/src/plugins/qt4projectmanager/qt4projectmanager.qrc @@ -1,9 +1,14 @@ <RCC> - <qresource prefix="/qt4projectmanager" > + <qresource prefix="/qt4projectmanager"> <file>images/window.png</file> <file>images/run_qmake.png</file> <file>images/run_qmake_small.png</file> <file>images/qt_project.png</file> <file>Qt4ProjectManager.mimetypes.xml</file> + <file>images/forms.png</file> + <file>images/headers.png</file> + <file>images/qt_qrc.png</file> + <file>images/sources.png</file> + <file>images/unknown.png</file> </qresource> </RCC> |