ProjectExplorer: Fix enabling state of main project nodes

Since the rootProjectNode() containing the parsed files is now nested
under a new project node the main node needs to delegate enable/disable
decisions.

Task-number: QTCREATORBUG-17922
Change-Id: Ie7bb6d6802072a2127b32c0fe51fb25fc1c9c6cc
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2017-03-27 17:51:19 +02:00
parent 7f5b37ed14
commit 2ee7967750
7 changed files with 79 additions and 43 deletions

View File

@@ -84,38 +84,6 @@ const char PLUGIN_SETTINGS_KEY[] = "ProjectExplorer.Project.PluginSettings";
namespace ProjectExplorer { namespace ProjectExplorer {
class ContainerNode : public ProjectNode
{
public:
ContainerNode(Project *project)
: ProjectNode(Utils::FileName()),
m_project(project)
{}
QString displayName() const final
{
QString name = m_project->displayName();
const QFileInfo fi = m_project->projectFilePath().toFileInfo();
const QString dir = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
if (Core::IVersionControl *vc = Core::VcsManager::findVersionControlForDirectory(dir)) {
QString vcsTopic = vc->vcsTopic(dir);
if (!vcsTopic.isEmpty())
name += " [" + vcsTopic + ']';
}
return name;
}
QList<ProjectAction> supportedActions(Node *) const final
{
return {};
}
private:
Project *m_project;
};
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Project // Project
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@@ -601,7 +569,7 @@ ProjectNode *Project::rootProjectNode() const
return d->m_rootProjectNode; return d->m_rootProjectNode;
} }
ProjectNode *Project::containerNode() const ContainerNode *Project::containerNode() const
{ {
return &d->m_containerNode; return &d->m_containerNode;
} }

View File

@@ -48,6 +48,7 @@ namespace Utils { class MacroExpander; }
namespace ProjectExplorer { namespace ProjectExplorer {
class BuildInfo; class BuildInfo;
class ContainerNode;
class EditorConfiguration; class EditorConfiguration;
class FileNode; class FileNode;
class NamedWidget; class NamedWidget;
@@ -84,7 +85,7 @@ public:
static Utils::FileName projectDirectory(const Utils::FileName &top); static Utils::FileName projectDirectory(const Utils::FileName &top);
virtual ProjectNode *rootProjectNode() const; virtual ProjectNode *rootProjectNode() const;
ProjectNode *containerNode() const; ContainerNode *containerNode() const;
bool hasActiveBuildSettings() const; bool hasActiveBuildSettings() const;

View File

@@ -2913,7 +2913,13 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
if (currentNode && currentNode->managingProject()) { if (currentNode && currentNode->managingProject()) {
QList<ProjectAction> actions = currentNode->supportedActions(currentNode); QList<ProjectAction> actions = currentNode->supportedActions(currentNode);
if (ProjectNode *pn = currentNode->asProjectNode()) { ProjectNode *pn;
if (ContainerNode *cn = currentNode->asContainerNode())
pn = cn->rootProjectNode();
else
pn = currentNode->asProjectNode();
if (pn) {
if (ProjectTree::currentProject() && pn == ProjectTree::currentProject()->rootProjectNode()) { if (ProjectTree::currentProject() && pn == ProjectTree::currentProject()->rootProjectNode()) {
m_runActionContextMenu->setVisible(true); m_runActionContextMenu->setVisible(true);
} else { } else {

View File

@@ -25,6 +25,7 @@
#include "projectnodes.h" #include "projectnodes.h"
#include "project.h"
#include "projectexplorerconstants.h" #include "projectexplorerconstants.h"
#include "projecttree.h" #include "projecttree.h"
@@ -171,8 +172,9 @@ FolderNode *Node::parentFolderNode() const
ProjectNode *Node::managingProject() ProjectNode *Node::managingProject()
{ {
if (!m_parentFolderNode) if (asContainerNode())
return nullptr; return asContainerNode()->rootProjectNode();
QTC_ASSERT(m_parentFolderNode, return nullptr);
ProjectNode *pn = parentProjectNode(); ProjectNode *pn = parentProjectNode();
return pn ? pn : asProjectNode(); // projects manage themselves... return pn ? pn : asProjectNode(); // projects manage themselves...
} }
@@ -790,4 +792,35 @@ bool FolderNode::isEmpty() const
return m_nodes.isEmpty(); return m_nodes.isEmpty();
} }
ContainerNode::ContainerNode(Project *project)
: FolderNode(Utils::FileName(), NodeType::Project), m_project(project)
{}
QString ContainerNode::displayName() const
{
QString name = m_project->displayName();
const QFileInfo fi = m_project->projectFilePath().toFileInfo();
const QString dir = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
if (Core::IVersionControl *vc = Core::VcsManager::findVersionControlForDirectory(dir)) {
QString vcsTopic = vc->vcsTopic(dir);
if (!vcsTopic.isEmpty())
name += " [" + vcsTopic + ']';
}
return name;
}
QList<ProjectAction> ContainerNode::supportedActions(Node *node) const
{
if (Node *rootNode = m_project->rootProjectNode())
return rootNode->supportedActions(node);
return {};
}
ProjectNode *ContainerNode::rootProjectNode() const
{
return m_project->rootProjectNode();
}
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -39,6 +39,8 @@
namespace Utils { class MimeType; } namespace Utils { class MimeType; }
namespace ProjectExplorer { namespace ProjectExplorer {
class Project;
class RunConfiguration; class RunConfiguration;
enum class NodeType : quint16 { enum class NodeType : quint16 {
@@ -92,6 +94,7 @@ enum ProjectAction {
class FileNode; class FileNode;
class FolderNode; class FolderNode;
class ProjectNode; class ProjectNode;
class ContainerNode;
// Documentation inside. // Documentation inside.
class PROJECTEXPLORER_EXPORT Node : public QObject class PROJECTEXPLORER_EXPORT Node : public QObject
@@ -115,8 +118,9 @@ public:
FolderNode *parentFolderNode() const; // parent folder or project FolderNode *parentFolderNode() const; // parent folder or project
ProjectNode *managingProject(); // project managing this node. ProjectNode *managingProject(); // project managing this node.
// result is nullptr if node is the SessionNode // result is the container's rootProject node if this is a project container node
// or node if node is a ProjectNode directly below SessionNode // (i.e. possibly null)
// or node if node is a top-level ProjectNode directly below a container
// or node->parentProjectNode() for all other cases. // or node->parentProjectNode() for all other cases.
const ProjectNode *managingProject() const; // see above. const ProjectNode *managingProject() const; // see above.
@@ -137,6 +141,8 @@ public:
virtual const FolderNode *asFolderNode() const { return nullptr; } virtual const FolderNode *asFolderNode() const { return nullptr; }
virtual ProjectNode *asProjectNode() { return nullptr; } virtual ProjectNode *asProjectNode() { return nullptr; }
virtual const ProjectNode *asProjectNode() const { return nullptr; } virtual const ProjectNode *asProjectNode() const { return nullptr; }
virtual ContainerNode *asContainerNode() { return nullptr; }
virtual const ContainerNode *asContainerNode() const { return nullptr; }
static bool sortByPath(const Node *a, const Node *b); static bool sortByPath(const Node *a, const Node *b);
void setParentFolderNode(FolderNode *parentFolder); void setParentFolderNode(FolderNode *parentFolder);
@@ -297,6 +303,24 @@ protected:
explicit ProjectNode(const Utils::FileName &projectFilePath); explicit ProjectNode(const Utils::FileName &projectFilePath);
}; };
class PROJECTEXPLORER_EXPORT ContainerNode : public FolderNode
{
public:
ContainerNode(Project *project);
QString displayName() const final;
QList<ProjectAction> supportedActions(Node *node) const final;
ContainerNode *asContainerNode() final { return this; }
const ContainerNode *asContainerNode() const final { return this; }
ProjectNode *rootProjectNode() const;
private:
Project *m_project;
QList<Node *> m_nodes;
};
} // namespace ProjectExplorer } // namespace ProjectExplorer
Q_DECLARE_METATYPE(ProjectExplorer::Node *) Q_DECLARE_METATYPE(ProjectExplorer::Node *)

View File

@@ -322,12 +322,14 @@ void ProjectTree::showContextMenu(ProjectTreeWidget *focus, const QPoint &global
contextMenu = Core::ActionManager::actionContainer(Constants::M_SESSIONCONTEXT)->menu(); contextMenu = Core::ActionManager::actionContainer(Constants::M_SESSIONCONTEXT)->menu();
} else { } else {
switch (node->nodeType()) { switch (node->nodeType()) {
case NodeType::Project: case NodeType::Project: {
if (!node->parentFolderNode()) if ((node->parentFolderNode() && node->parentFolderNode()->asContainerNode())
|| node->asContainerNode())
contextMenu = Core::ActionManager::actionContainer(Constants::M_PROJECTCONTEXT)->menu(); contextMenu = Core::ActionManager::actionContainer(Constants::M_PROJECTCONTEXT)->menu();
else else
contextMenu = Core::ActionManager::actionContainer(Constants::M_SUBPROJECTCONTEXT)->menu(); contextMenu = Core::ActionManager::actionContainer(Constants::M_SUBPROJECTCONTEXT)->menu();
break; break;
}
case NodeType::VirtualFolder: case NodeType::VirtualFolder:
case NodeType::Folder: case NodeType::Folder:
contextMenu = Core::ActionManager::actionContainer(Constants::M_FOLDERCONTEXT)->menu(); contextMenu = Core::ActionManager::actionContainer(Constants::M_FOLDERCONTEXT)->menu();

View File

@@ -318,9 +318,11 @@ void QmakeProjectManagerPlugin::updateContextActions()
{ {
Node *node = ProjectTree::currentNode(); Node *node = ProjectTree::currentNode();
Project *project = ProjectTree::currentProject(); Project *project = ProjectTree::currentProject();
m_addLibraryActionContextMenu->setEnabled(dynamic_cast<QmakeProFileNode *>(node));
auto proFileNode = dynamic_cast<QmakeProFileNode *>(node); ContainerNode *containerNode = node ? node->asContainerNode() : nullptr;
ProjectNode *proFileNode = containerNode ? containerNode->rootProjectNode() : dynamic_cast<QmakeProFileNode *>(node);
m_addLibraryActionContextMenu->setEnabled(proFileNode);
QmakeProject *qmakeProject = qobject_cast<QmakeProject *>(QmakeManager::contextProject()); QmakeProject *qmakeProject = qobject_cast<QmakeProject *>(QmakeManager::contextProject());
QmakeProFileNode *subProjectNode = nullptr; QmakeProFileNode *subProjectNode = nullptr;
if (node) { if (node) {