ProjectExplorer: Make priorities available on more nodes

Make priority available on all FolderNodes. Make the sort order
of all kinds of FolderNodes check the priority.

This allows no reorder e.g. ProjectNodes as needed.

Change-Id: I369edd28807ab9f89fb646b0001e1b3eb1a19d7e
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Tobias Hunger
2016-11-10 16:56:15 +01:00
parent 3af1372395
commit 49f5d98871
5 changed files with 54 additions and 132 deletions

View File

@@ -50,119 +50,20 @@ namespace {
bool sortNodes(Node *n1, Node *n2) bool sortNodes(Node *n1, Node *n2)
{ {
// Ordering is: project files, project, folder, file if (n1->priority() > n2->priority())
const NodeType n1Type = n1->nodeType();
const NodeType n2Type = n2->nodeType();
// project files
FileNode *file1 = n1->asFileNode();
FileNode *file2 = n2->asFileNode();
if (file1 && file1->fileType() == FileType::Project) {
if (file2 && file2->fileType() == FileType::Project) {
const QString fileName1 = file1->filePath().fileName();
const QString fileName2 = file2->filePath().fileName();
int result = caseFriendlyCompare(fileName1, fileName2);
if (result != 0)
return result < 0;
else
return file1 < file2;
} else {
return true; // project file is before everything else
}
} else {
if (file2 && file2->fileType() == FileType::Project)
return false;
}
// projects
if (n1Type == NodeType::Project) {
if (n2Type == NodeType::Project) {
auto project1 = static_cast<ProjectNode*>(n1);
auto project2 = static_cast<ProjectNode*>(n2);
int result = caseFriendlyCompare(project1->displayName(), project2->displayName());
if (result != 0)
return result < 0;
result = caseFriendlyCompare(project1->filePath().toString(),
project2->filePath().toString());
if (result != 0)
return result < 0;
return project1 < project2; // sort by pointer value
} else {
return true; // project is before folder & file
}
}
if (n2Type == NodeType::Project)
return false;
if (n1Type == NodeType::VirtualFolder) {
if (n2Type == NodeType::VirtualFolder) {
auto folder1 = static_cast<VirtualFolderNode *>(n1);
auto folder2 = static_cast<VirtualFolderNode *>(n2);
if (folder1->priority() > folder2->priority())
return true; return true;
if (folder1->priority() < folder2->priority()) if (n1->priority() < n2->priority())
return false;
int result = caseFriendlyCompare(folder1->filePath().toString(),
folder2->filePath().toString());
if (result != 0)
return result < 0;
else
return folder1 < folder2;
} else {
return true; // virtual folder is before folder
}
}
if (n2Type == NodeType::VirtualFolder)
return false; return false;
const int displayNameResult = caseFriendlyCompare(n1->displayName(), n2->displayName());
if (displayNameResult != 0)
return displayNameResult < 0;
if (n1Type == NodeType::Folder) { const int filePathResult = caseFriendlyCompare(n1->filePath().toString(),
if (n2Type == NodeType::Folder) { n2->filePath().toString());
auto folder1 = static_cast<FolderNode*>(n1); if (filePathResult != 0)
auto folder2 = static_cast<FolderNode*>(n2); return filePathResult < 0;
int result = caseFriendlyCompare(folder1->filePath().toString(),
folder2->filePath().toString());
if (result != 0)
return result < 0;
else
return folder1 < folder2;
} else {
return true; // folder is before file
}
}
if (n2Type == NodeType::Folder)
return false;
// must be file nodes
int result = caseFriendlyCompare(n1->displayName(), n2->displayName());
if (result != 0)
return result < 0;
const QString filePath1 = n1->filePath().toString();
const QString filePath2 = n2->filePath().toString();
const QString fileName1 = n1->filePath().fileName();
const QString fileName2 = n2->filePath().fileName();
result = caseFriendlyCompare(fileName1, fileName2);
if (result != 0) {
return result < 0; // sort by filename
} else {
result = caseFriendlyCompare(filePath1, filePath2);
if (result != 0)
return result < 0; // sort by filepath
if (n1->line() != n2->line())
return n1->line() < n2->line(); // sort by line numbers
return n1 < n2; // sort by pointer value return n1 < n2; // sort by pointer value
}
} }
} // namespace anon } // namespace anon

View File

@@ -63,6 +63,11 @@ Node::Node(NodeType nodeType, const Utils::FileName &filePath, int line) :
m_filePath(filePath), m_line(line), m_nodeType(nodeType) m_filePath(filePath), m_line(line), m_nodeType(nodeType)
{ } { }
void Node::setPriority(int p)
{
m_priority = p;
}
void Node::emitNodeSortKeyAboutToChange() void Node::emitNodeSortKeyAboutToChange()
{ {
if (parentFolderNode()) if (parentFolderNode())
@@ -92,6 +97,11 @@ NodeType Node::nodeType() const
return m_nodeType; return m_nodeType;
} }
int Node::priority() const
{
return m_priority;
}
/*! /*!
The project that owns and manages the node. It is the first project in the list The project that owns and manages the node. It is the first project in the list
of ancestors. of ancestors.
@@ -209,7 +219,12 @@ FileNode::FileNode(const Utils::FileName &filePath,
bool generated, int line) : Node(NodeType::File, filePath, line), bool generated, int line) : Node(NodeType::File, filePath, line),
m_fileType(fileType), m_fileType(fileType),
m_generated(generated) m_generated(generated)
{ } {
if (fileType == FileType::Project)
setPriority(DefaultProjectFilePriority);
else
setPriority(DefaultFilePriority);
}
FileType FileNode::fileType() const FileType FileNode::fileType() const
{ {
@@ -287,9 +302,10 @@ QList<FileNode *> FileNode::scanForFiles(const Utils::FileName &directory,
\sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode \sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode
*/ */
FolderNode::FolderNode(const Utils::FileName &folderPath, NodeType nodeType, const QString &displayName) : FolderNode::FolderNode(const Utils::FileName &folderPath, NodeType nodeType, const QString &displayName) :
Node(nodeType, folderPath), Node(nodeType, folderPath, -1),
m_displayName(displayName) m_displayName(displayName)
{ {
setPriority(DefaultFolderPriority);
if (m_displayName.isEmpty()) if (m_displayName.isEmpty())
m_displayName = folderPath.toUserOutput(); m_displayName = folderPath.toUserOutput();
} }
@@ -712,13 +728,9 @@ bool FolderNode::showInSimpleTree() const
\sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode \sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode
*/ */
VirtualFolderNode::VirtualFolderNode(const Utils::FileName &folderPath, int priority) : VirtualFolderNode::VirtualFolderNode(const Utils::FileName &folderPath, int priority) :
FolderNode(folderPath, NodeType::VirtualFolder), FolderNode(folderPath, NodeType::VirtualFolder, QString())
m_priority(priority)
{ }
int VirtualFolderNode::priority() const
{ {
return m_priority; setPriority(priority);
} }
/*! /*!
@@ -737,6 +749,7 @@ int VirtualFolderNode::priority() const
ProjectNode::ProjectNode(const Utils::FileName &projectFilePath) : ProjectNode::ProjectNode(const Utils::FileName &projectFilePath) :
FolderNode(projectFilePath, NodeType::Project) FolderNode(projectFilePath, NodeType::Project)
{ {
setPriority(DefaultProjectPriority);
setDisplayName(projectFilePath.fileName()); setDisplayName(projectFilePath.fileName());
} }

View File

@@ -107,8 +107,18 @@ class SessionManager;
class PROJECTEXPLORER_EXPORT Node class PROJECTEXPLORER_EXPORT Node
{ {
public: public:
enum PriorityLevel {
DefaultPriority = 0,
DefaultFilePriority = 100000,
DefaultFolderPriority = 200000,
DefaultVirtualFolderPriority = 300000,
DefaultProjectPriority = 400000,
DefaultProjectFilePriority = 500000
};
virtual ~Node() = default; virtual ~Node() = default;
NodeType nodeType() const; NodeType nodeType() const;
int priority() const;
ProjectNode *parentProjectNode() const; // parent project, will be nullptr for the top-level project ProjectNode *parentProjectNode() const; // parent project, will be nullptr for the top-level project
FolderNode *parentFolderNode() const; // parent folder or project FolderNode *parentFolderNode() const; // parent folder or project
@@ -148,6 +158,7 @@ public:
protected: protected:
Node(NodeType nodeType, const Utils::FileName &filePath, int line = -1); Node(NodeType nodeType, const Utils::FileName &filePath, int line = -1);
void setPriority(int priority);
void setParentFolderNode(FolderNode *parentFolder); void setParentFolderNode(FolderNode *parentFolder);
void emitNodeSortKeyAboutToChange(); void emitNodeSortKeyAboutToChange();
@@ -156,7 +167,8 @@ protected:
private: private:
FolderNode *m_parentFolderNode = nullptr; FolderNode *m_parentFolderNode = nullptr;
Utils::FileName m_filePath; Utils::FileName m_filePath;
int m_line; int m_line = -1;
int m_priority = DefaultPriority;
const NodeType m_nodeType; const NodeType m_nodeType;
bool m_isEnabled = true; bool m_isEnabled = true;
}; };
@@ -251,21 +263,17 @@ protected:
QList<FileNode*> m_fileNodes; QList<FileNode*> m_fileNodes;
private: private:
// managed by ProjectNode
friend class ProjectNode;
QString m_displayName; QString m_displayName;
mutable QIcon m_icon; mutable QIcon m_icon;
// managed by ProjectNode
friend class ProjectNode;
}; };
class PROJECTEXPLORER_EXPORT VirtualFolderNode : public FolderNode class PROJECTEXPLORER_EXPORT VirtualFolderNode : public FolderNode
{ {
public: public:
explicit VirtualFolderNode(const Utils::FileName &folderPath, int priority); explicit VirtualFolderNode(const Utils::FileName &folderPath, int priority);
int priority() const;
private:
int m_priority;
}; };
// Documentation inside. // Documentation inside.

View File

@@ -322,7 +322,7 @@ struct InternalNode
QMap<QString, InternalNode *> subnodes; QMap<QString, InternalNode *> subnodes;
FileNameList files; FileNameList files;
FileType type = FileType::Unknown; FileType type = FileType::Unknown;
int priority = 0; int priority = Node::DefaultVirtualFolderPriority;
QString displayName; QString displayName;
QString typeName; QString typeName;
QString addFileFilter; QString addFileFilter;
@@ -739,7 +739,7 @@ void QmakePriFileNode::update(const Internal::PriFileEvalResult &result)
subfolder->fullPath = m_projectDir; subfolder->fullPath = m_projectDir;
subfolder->typeName = fileTypes.at(i).typeName; subfolder->typeName = fileTypes.at(i).typeName;
subfolder->addFileFilter = fileTypes.at(i).addFileFilter; subfolder->addFileFilter = fileTypes.at(i).addFileFilter;
subfolder->priority = -i; subfolder->priority = Node::DefaultVirtualFolderPriority - i;
subfolder->displayName = fileTypes.at(i).typeName; subfolder->displayName = fileTypes.at(i).typeName;
contents.virtualfolders.append(subfolder); contents.virtualfolders.append(subfolder);
// create the hierarchy with subdirectories // create the hierarchy with subdirectories
@@ -816,7 +816,7 @@ bool QmakePriFileNode::folderChanged(const QString &changedFolder, const QSet<Fi
subfolder->icon = fileTypes.at(i).icon; subfolder->icon = fileTypes.at(i).icon;
subfolder->fullPath = m_projectDir; subfolder->fullPath = m_projectDir;
subfolder->typeName = fileTypes.at(i).typeName; subfolder->typeName = fileTypes.at(i).typeName;
subfolder->priority = -i; subfolder->priority = Node::DefaultVirtualFolderPriority - i;
subfolder->displayName = fileTypes.at(i).typeName; subfolder->displayName = fileTypes.at(i).typeName;
contents.virtualfolders.append(subfolder); contents.virtualfolders.append(subfolder);
// create the hierarchy with subdirectories // create the hierarchy with subdirectories

View File

@@ -44,7 +44,7 @@
using namespace ResourceEditor; using namespace ResourceEditor;
using namespace ResourceEditor::Internal; using namespace ResourceEditor::Internal;
static bool priority(const QStringList &files) static bool hasPriority(const QStringList &files)
{ {
if (files.isEmpty()) if (files.isEmpty())
return false; return false;
@@ -341,7 +341,7 @@ ProjectExplorer::FolderNode::AddNewInformation ResourceTopLevelNode::addNewInfor
.arg(QLatin1Char('/')); .arg(QLatin1Char('/'));
int p = -1; int p = -1;
if (priority(files)) { // images/* and qml/js mimetypes if (hasPriority(files)) { // images/* and qml/js mimetypes
p = 110; p = 110;
if (context == this) if (context == this)
p = 120; p = 120;
@@ -497,7 +497,7 @@ ProjectExplorer::FolderNode::AddNewInformation ResourceFolderNode::addNewInforma
.arg(displayName()); .arg(displayName());
int p = -1; // never the default int p = -1; // never the default
if (priority(files)) { // image/* and qml/js mimetypes if (hasPriority(files)) { // image/* and qml/js mimetypes
p = 105; // prefer against .pro and .pri files p = 105; // prefer against .pro and .pri files
if (context == this) if (context == this)
p = 120; p = 120;