Commit ebae6426 authored by hjk's avatar hjk
Browse files

ProjectManager: Remove SessionNode



Instead, get root project nodes directly from the project.

Change-Id: I5cf95a7dce1fa29c1adc26013ad03cc017f38a6d
Reviewed-by: Tobias Hunger's avatarTobias Hunger <tobias.hunger@qt.io>
parent 312784a9
......@@ -198,8 +198,6 @@ void PxNodeController::addExplorerNode(const ProjectExplorer::Node *node,
menu->popup(QCursor::pos());
break;
}
case ProjectExplorer::NodeType::Session:
break;
}
}
......
......@@ -80,9 +80,6 @@ QString PxNodeUtilities::calcRelativePath(const ProjectExplorer::Node *node,
case ProjectExplorer::NodeType::Project:
nodePath = node->filePath().toString();
break;
case ProjectExplorer::NodeType::Session:
QTC_ASSERT(false, return QString());
break;
}
return qmt::NameController::calcRelativePath(nodePath, anchorFolder);
......
......@@ -39,6 +39,9 @@
#include <coreplugin/idocument.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <coreplugin/iversioncontrol.h>
#include <coreplugin/vcsmanager.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projecttree.h>
......@@ -80,18 +83,52 @@ const char PLUGIN_SETTINGS_KEY[] = "ProjectExplorer.Project.PluginSettings";
} // namespace
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
// -------------------------------------------------------------------------
class ProjectPrivate
{
public:
ProjectPrivate(Project *owner) : m_containerNode(owner) {}
~ProjectPrivate();
Core::Id m_id;
Core::IDocument *m_document = nullptr;
ProjectNode *m_rootProjectNode = nullptr;
ContainerNode m_containerNode;
QList<Target *> m_targets;
Target *m_activeTarget = nullptr;
EditorConfiguration m_editorConfiguration;
......@@ -117,7 +154,7 @@ ProjectPrivate::~ProjectPrivate()
delete m_accessor;
}
Project::Project() : d(new ProjectPrivate)
Project::Project() : d(new ProjectPrivate(this))
{
d->m_macroExpander.setDisplayName(tr("Project"));
d->m_macroExpander.registerVariable("Project:Name", tr("Project Name"),
......@@ -427,8 +464,11 @@ void Project::setRootProjectNode(ProjectNode *root)
ProjectTree::applyTreeManager(root);
d->m_rootProjectNode = root;
emit projectTreeChanged(this, QPrivateSignal());
// Do not delete oldNode! The ProjectTree owns that!
if (root)
d->m_rootProjectNode->setParentFolderNode(&d->m_containerNode);
ProjectTree::emitSubtreeChanged(d->m_rootProjectNode);
delete d->m_rootProjectNode;
}
Target *Project::restoreTarget(const QVariantMap &data)
......@@ -532,6 +572,11 @@ ProjectNode *Project::rootProjectNode() const
return d->m_rootProjectNode;
}
ProjectNode *Project::containerNode() const
{
return &d->m_containerNode;
}
Project::RestoreResult Project::fromMap(const QVariantMap &map, QString *errorMessage)
{
Q_UNUSED(errorMessage);
......
......@@ -81,6 +81,7 @@ public:
static Utils::FileName projectDirectory(const Utils::FileName &top);
virtual ProjectNode *rootProjectNode() const;
ProjectNode *containerNode() const;
bool hasActiveBuildSettings() const;
......@@ -142,7 +143,6 @@ public:
Utils::MacroExpander *macroExpander() const;
signals:
void projectTreeChanged(Project *project, QPrivateSignal);
void displayNameChanged();
void fileListChanged();
......
......@@ -71,7 +71,7 @@ static bool sortWrapperNodes(const WrapperNode *w1, const WrapperNode *w2)
}
FlatModel::FlatModel(QObject *parent)
: TreeModel<WrapperNode, WrapperNode>(new WrapperNode(SessionManager::sessionNode()), parent)
: TreeModel<WrapperNode, WrapperNode>(new WrapperNode(nullptr), parent)
{
ProjectTree *tree = ProjectTree::instance();
connect(tree, &ProjectTree::subtreeChanged, this, &FlatModel::update);
......@@ -93,17 +93,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
FolderNode *folderNode = node->asFolderNode();
switch (role) {
case Qt::DisplayRole: {
QString name = node->displayName();
if (node->nodeType() == NodeType::Project
&& node->parentFolderNode()
&& node->parentFolderNode()->nodeType() == NodeType::Session) {
const QString vcsTopic = static_cast<ProjectNode *>(node)->vcsTopic();
if (!vcsTopic.isEmpty())
name += QLatin1String(" [") + vcsTopic + QLatin1Char(']');
}
result = name;
result = node->displayName();
break;
}
case Qt::EditRole: {
......@@ -124,7 +114,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
case Qt::FontRole: {
QFont font;
if (Project *project = SessionManager::startupProject()) {
if (node == SessionManager::nodeForProject(project))
if (node == project->containerNode())
font.setBold(true);
}
result = font;
......@@ -187,23 +177,44 @@ void FlatModel::update()
void FlatModel::rebuildModel()
{
QList<Project *> projects = SessionManager::projects();
Utils::sort(projects, [](Project *p1, Project *p2) {
const int displayNameResult = caseFriendlyCompare(p1->displayName(), p2->displayName());
if (displayNameResult != 0)
return displayNameResult < 0;
return p1 < p2; // sort by pointer value
});
QSet<Node *> seen;
rootItem()->removeChildren();
for (Node *node : SessionManager::sessionNode()->nodes()) {
if (ProjectNode *projectNode = node->asProjectNode()) {
if (!seen.contains(projectNode))
addProjectNode(rootItem(), projectNode, &seen);
for (Project *project : projects) {
WrapperNode *container = new WrapperNode(project->containerNode());
ProjectNode *projectNode = project->rootProjectNode();
if (projectNode) {
addFolderNode(container, projectNode, &seen);
} else {
FileNode *projectFileNode = new FileNode(project->projectFilePath(), FileType::Project, false);
seen.insert(projectFileNode);
container->appendChild(new WrapperNode(projectFileNode));
}
container->sortChildren(&sortWrapperNodes);
rootItem()->appendChild(container);
}
rootItem()->sortChildren(&sortWrapperNodes);
forAllItems([this](WrapperNode *node) {
const QString path = node->m_node->filePath().toString();
const QString displayName = node->m_node->displayName();
ExpandData ed(path, displayName);
if (m_toExpand.contains(ed))
if (node->m_node) {
const QString path = node->m_node->filePath().toString();
const QString displayName = node->m_node->displayName();
ExpandData ed(path, displayName);
if (m_toExpand.contains(ed))
emit requestExpansion(node->index());
} else {
emit requestExpansion(node->index());
}
});
}
......@@ -227,7 +238,7 @@ ExpandData FlatModel::expandDataForNode(const Node *node) const
void FlatModel::handleProjectAdded(Project *project)
{
Node *node = SessionManager::nodeForProject(project);
Node *node = project->rootProjectNode();
m_toExpand.insert(expandDataForNode(node));
if (WrapperNode *wrapper = wrapperForNode(node)) {
wrapper->forFirstLevelChildren([this](WrapperNode *child) {
......@@ -251,21 +262,6 @@ void FlatModel::saveExpandData()
SessionManager::setValue(QLatin1String("ProjectTree.ExpandData"), data);
}
void FlatModel::addProjectNode(WrapperNode *parent, ProjectNode *projectNode, QSet<Node *> *seen)
{
seen->insert(projectNode);
auto node = new WrapperNode(projectNode);
parent->appendChild(node);
addFolderNode(node, projectNode, seen);
for (Node *subNode : projectNode->nodes()) {
if (ProjectNode *subProjectNode = subNode->asProjectNode()) {
if (!seen->contains(subProjectNode))
addProjectNode(node, subProjectNode, seen);
}
}
node->sortChildren(&sortWrapperNodes);
}
void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen)
{
const QList<FolderNode *> subFolderNodes = folderNode->folderNodes();
......@@ -374,16 +370,6 @@ const QLoggingCategory &FlatModel::logger()
return logger;
}
bool isSorted(const QList<Node *> &nodes)
{
int size = nodes.size();
for (int i = 0; i < size -1; ++i) {
if (!sortNodes(nodes.at(i), nodes.at(i+1)))
return false;
}
return true;
}
namespace Internal {
int caseFriendlyCompare(const QString &a, const QString &b)
......
......@@ -94,7 +94,6 @@ private:
void update();
void rebuildModel();
void addProjectNode(WrapperNode *parent, ProjectNode *projectNode, QSet<Node *> *seen);
void addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen);
ExpandData expandDataForNode(const Node *node) const;
......
......@@ -214,9 +214,12 @@ bool Node::isEnabled() const
QList<ProjectAction> Node::supportedActions(Node *node) const
{
QList<ProjectAction> list = parentFolderNode()->supportedActions(node);
list.append(InheritedFromParent);
return list;
if (FolderNode *folder = parentFolderNode()) {
QList<ProjectAction> list = folder->supportedActions(node);
list.append(InheritedFromParent);
return list;
}
return {};
}
void Node::setEnabled(bool enabled)
......@@ -702,18 +705,6 @@ ProjectNode::ProjectNode(const Utils::FileName &projectFilePath) :
setDisplayName(projectFilePath.fileName());
}
QString ProjectNode::vcsTopic() const
{
const QFileInfo fi = filePath().toFileInfo();
const QString dir = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
if (Core::IVersionControl *const vc =
Core::VcsManager::findVersionControlForDirectory(dir))
return vc->vcsTopic(dir);
return QString();
}
bool ProjectNode::canAddSubProject(const QString &proFilePath) const
{
Q_UNUSED(proFilePath)
......@@ -797,28 +788,4 @@ bool FolderNode::isEmpty() const
return m_nodes.isEmpty();
}
/*!
\class ProjectExplorer::SessionNode
*/
SessionNode::SessionNode() :
FolderNode(Utils::FileName::fromString("session"), NodeType::Session)
{ }
QList<ProjectAction> SessionNode::supportedActions(Node *node) const
{
Q_UNUSED(node)
return QList<ProjectAction>();
}
bool SessionNode::showInSimpleTree() const
{
return true;
}
QString SessionNode::addFileFilter() const
{
return QString::fromLatin1("*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++; *.h; *.hh; *.hpp; *.hxx;");
}
} // namespace ProjectExplorer
......@@ -40,14 +40,12 @@ namespace Utils { class MimeType; }
namespace ProjectExplorer {
class RunConfiguration;
class SessionManager;
enum class NodeType : quint16 {
File = 1,
Folder,
VirtualFolder,
Project,
Session
Project
};
// File types common for qt projects
......@@ -275,8 +273,6 @@ private:
class PROJECTEXPLORER_EXPORT ProjectNode : public FolderNode
{
public:
QString vcsTopic() const;
virtual bool canAddSubProject(const QString &proFilePath) const;
virtual bool addSubProject(const QString &proFile);
virtual bool removeSubProject(const QString &proFilePath);
......@@ -298,24 +294,7 @@ public:
const ProjectNode *asProjectNode() const final { return this; }
protected:
// this is just the in-memory representation, a subclass
// will add the persistent stuff
explicit ProjectNode(const Utils::FileName &projectFilePath);
friend class SessionManager;
};
// Documentation inside.
class PROJECTEXPLORER_EXPORT SessionNode : public FolderNode
{
public:
SessionNode();
private:
QList<ProjectAction> supportedActions(Node *node) const final;
QString addFileFilter() const final;
bool showInSimpleTree() const final;
};
} // namespace ProjectExplorer
......
......@@ -261,9 +261,6 @@ void ProjectTree::updateContext()
void ProjectTree::emitSubtreeChanged(FolderNode *node)
{
if (!SessionManager::sessionNode()->isAncesterOf(node))
return;
emit s_instance->subtreeChanged(node);
}
......@@ -318,16 +315,15 @@ bool ProjectTree::hasFocus(ProjectTreeWidget *widget)
void ProjectTree::showContextMenu(ProjectTreeWidget *focus, const QPoint &globalPos, Node *node)
{
QMenu *contextMenu = nullptr;
Project *project = SessionManager::projectForNode(node);
emit s_instance->aboutToShowContextMenu(project, node);
if (!node)
node = SessionManager::sessionNode();
if (node->nodeType() != NodeType::Session) {
Project *project = SessionManager::projectForNode(node);
emit s_instance->aboutToShowContextMenu(project, node);
if (!node) {
contextMenu = Core::ActionManager::actionContainer(Constants::M_SESSIONCONTEXT)->menu();
} else {
switch (node->nodeType()) {
case NodeType::Project:
if (node->parentFolderNode() == SessionManager::sessionNode())
if (node->parentFolderNode())
contextMenu = Core::ActionManager::actionContainer(Constants::M_PROJECTCONTEXT)->menu();
else
contextMenu = Core::ActionManager::actionContainer(Constants::M_SUBPROJECTCONTEXT)->menu();
......@@ -342,10 +338,6 @@ void ProjectTree::showContextMenu(ProjectTreeWidget *focus, const QPoint &global
default:
qWarning("ProjectExplorerPlugin::showContextMenu - Missing handler for node type");
}
} else { // session item
emit s_instance->aboutToShowContextMenu(nullptr, node);
contextMenu = Core::ActionManager::actionContainer(Constants::M_SESSIONCONTEXT)->menu();
}
if (contextMenu && contextMenu->actions().count() > 0) {
......
......@@ -70,6 +70,9 @@ public:
void collapseAll();
// for nodes to emit signals, do not call unless you are a node
static void emitSubtreeChanged(FolderNode *node);
signals:
void currentProjectChanged(ProjectExplorer::Project *project);
void currentNodeChanged();
......@@ -80,9 +83,6 @@ signals:
void aboutToShowContextMenu(ProjectExplorer::Project *project,
ProjectExplorer::Node *node);
public: // for nodes to emit signals, do not call unless you are a node
static void emitSubtreeChanged(FolderNode *node);
private:
void sessionChanged();
void focusChanged();
......
......@@ -275,23 +275,27 @@ Node *ProjectTreeWidget::nodeForFile(const Utils::FileName &fileName)
Node *bestNode = nullptr;
int bestNodeExpandCount = INT_MAX;
SessionManager::sessionNode()->forEachGenericNode([&](Node *node) {
if (node->filePath() == fileName) {
if (!bestNode) {
bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} else if (node->nodeType() < bestNode->nodeType()) {
bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} else if (node->nodeType() == bestNode->nodeType()) {
int nodeExpandCount = ProjectTreeWidget::expandedCount(node);
if (nodeExpandCount < bestNodeExpandCount) {
bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
for (Project *project : SessionManager::projects()) {
if (ProjectNode *projectNode = project->rootProjectNode()) {
projectNode->forEachGenericNode([&](Node *node) {
if (node->filePath() == fileName) {
if (!bestNode) {
bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} else if (node->nodeType() < bestNode->nodeType()) {
bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} else if (node->nodeType() == bestNode->nodeType()) {
int nodeExpandCount = ProjectTreeWidget::expandedCount(node);
if (nodeExpandCount < bestNodeExpandCount) {
bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
}
}
}
}
});
}
});
}
return bestNode;
}
......
......@@ -26,6 +26,7 @@
#include "projectwizardpage.h"
#include "ui_projectwizardpage.h"
#include "project.h"
#include "projectexplorer.h"
#include "session.h"
......@@ -300,18 +301,14 @@ ProjectWizardPage::~ProjectWizardPage()
{
disconnect(m_ui->projectComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &ProjectWizardPage::projectChanged);
delete m_model;
delete m_ui;
}
void ProjectWizardPage::setModel(Utils::TreeModel<> *model)
{
delete m_model;
m_model = model;
// TODO see OverViewCombo and OverView for click event filter
m_ui->projectComboBox->setModel(model);
bool enabled = m_model->rowCount(QModelIndex()) > 1;
bool enabled = m_model.rowCount(QModelIndex()) > 1;
m_ui->projectComboBox->setEnabled(enabled);
expandTree(QModelIndex());
......@@ -324,9 +321,9 @@ bool ProjectWizardPage::expandTree(const QModelIndex &root)
expand = true;
// Check children
int count = m_model->rowCount(root);
int count = m_model.rowCount(root);
for (int i = 0; i < count; ++i) {
if (expandTree(m_model->index(i, 0, root)))
if (expandTree(m_model.index(i, 0, root)))
expand = true;
}
......@@ -346,7 +343,7 @@ bool ProjectWizardPage::expandTree(const QModelIndex &root)
void ProjectWizardPage::setBestNode(AddNewTree *tree)
{
QModelIndex index = tree ? m_model->indexForItem(tree) : QModelIndex();
QModelIndex index = tree ? m_model.indexForItem(tree) : QModelIndex();
m_ui->projectComboBox->setCurrentIndex(index);
while (index.isValid()) {
......@@ -454,28 +451,22 @@ void ProjectWizardPage::initializeProjectTree(Node *context, const QStringList &
{
BestNodeSelector selector(m_commonDirectory, paths);
AddNewTree *tree;
SessionNode *root = SessionManager::sessionNode();
QList<AddNewTree *> children;
for (Node *node : root->nodes()) {
if (ProjectNode *pn = node->asProjectNode()) {
TreeItem *root = m_model.rootItem();
root->removeChildren();
for (Project *project : SessionManager::projects()) {
if (ProjectNode *pn = project->rootProjectNode()) {
if (kind == IWizardFactory::ProjectWizard) {
if (AddNewTree *child = buildAddProjectTree(pn, paths.first(), context, &selector))
children.append(child);
root->appendChild(child);
} else {
if (AddNewTree *child = buildAddFilesTree(pn, paths, context, &selector))
children.append(child);
root->appendChild(child);
}
}
}
children.prepend(createNoneNode(&selector));
tree = new AddNewTree(root, children, root->displayName());
root->prependChild(createNoneNode(&selector));
setAdditionalInfo(selector.deployingProjects());
setModel(new TreeModel<>(tree));
setBestNode(selector.bestChoice());
setAddingSubProject(action == AddSubProject);
}
......
......@@ -95,7 +95,7 @@ private:
Ui::WizardPage *m_ui;
QStringList m_projectToolTips;
Utils::TreeModel<> *m_model = nullptr;
Utils::TreeModel<> m_model;
QList<Core::IVersionControl*> m_activeVersionControls;
QString m_commonDirectory;
......