summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorcon <qtc-committer@nokia.com>2009-08-17 17:59:57 +0200
committercon <qtc-committer@nokia.com>2009-08-21 14:53:25 +0200
commit7ebea974d69e0ca750ca77ea437e901936a7e8f5 (patch)
tree30ddd124a69310e554505eb3e2f4b46afb53cc95 /src/plugins
parentf888f5df2d8bb510ca97a3d54ce45ff367594c56 (diff)
downloadqt-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.cpp10
-rw-r--r--src/plugins/projectexplorer/projectnodes.cpp15
-rw-r--r--src/plugins/projectexplorer/projectnodes.h3
-rw-r--r--src/plugins/qt4projectmanager/images/forms.pngbin0 -> 311 bytes
-rw-r--r--src/plugins/qt4projectmanager/images/headers.pngbin0 -> 223 bytes
-rw-r--r--src/plugins/qt4projectmanager/images/qt_qrc.pngbin0 -> 676 bytes
-rw-r--r--src/plugins/qt4projectmanager/images/sources.pngbin0 -> 208 bytes
-rw-r--r--src/plugins/qt4projectmanager/images/unknown.pngbin0 -> 267 bytes
-rw-r--r--src/plugins/qt4projectmanager/qt4nodes.cpp290
-rw-r--r--src/plugins/qt4projectmanager/qt4nodes.h3
-rw-r--r--src/plugins/qt4projectmanager/qt4projectmanager.qrc7
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
new file mode 100644
index 0000000000..04059d99f0
--- /dev/null
+++ b/src/plugins/qt4projectmanager/images/forms.png
Binary files differ
diff --git a/src/plugins/qt4projectmanager/images/headers.png b/src/plugins/qt4projectmanager/images/headers.png
new file mode 100644
index 0000000000..ff7797fa91
--- /dev/null
+++ b/src/plugins/qt4projectmanager/images/headers.png
Binary files differ
diff --git a/src/plugins/qt4projectmanager/images/qt_qrc.png b/src/plugins/qt4projectmanager/images/qt_qrc.png
new file mode 100644
index 0000000000..3643f37e1a
--- /dev/null
+++ b/src/plugins/qt4projectmanager/images/qt_qrc.png
Binary files differ
diff --git a/src/plugins/qt4projectmanager/images/sources.png b/src/plugins/qt4projectmanager/images/sources.png
new file mode 100644
index 0000000000..60dc177b86
--- /dev/null
+++ b/src/plugins/qt4projectmanager/images/sources.png
Binary files differ
diff --git a/src/plugins/qt4projectmanager/images/unknown.png b/src/plugins/qt4projectmanager/images/unknown.png
new file mode 100644
index 0000000000..0f2ad1818e
--- /dev/null
+++ b/src/plugins/qt4projectmanager/images/unknown.png
Binary files differ
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>