ProjectNodes: Handle supported actions one-by-one

Getting the full list for a node can get quite expensive e.g. in
cases of recursive calls of QMakeProjectManager::findPriFile.

However, the FlatModel needs to decide quickly on whether an item
is editable to potentially allow renaming.

So split up QList<Actions> supportedActions() into individual
bool supportsAction(action) calls and make sure Rename is not
on the critical path.

Task-number: QTCREATORBUG-17953
Change-Id: I31841847f8aa7d7b94c63d76ce71efb1c930fa69
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
hjk
2017-03-15 15:46:48 +01:00
parent 8410c0bbad
commit bd5e2faa75
24 changed files with 162 additions and 211 deletions

View File

@@ -74,9 +74,13 @@ QmakeProFileNode *QmakePriFileNode::proFileNode() const
return m_qmakeProFileNode;
}
QList<ProjectAction> QmakePriFileNode::supportedActions(Node *node) const
bool QmakePriFileNode::supportsAction(ProjectAction action, Node *node) const
{
QList<ProjectAction> actions;
if (action == Rename || action == DuplicateFile) {
FileNode *fileNode = node->asFileNode();
return (fileNode && fileNode->fileType() != FileType::Project)
|| dynamic_cast<ResourceEditor::ResourceTopLevelNode *>(node);
}
const FolderNode *folderNode = this;
const QmakeProFileNode *proFileNode;
@@ -93,12 +97,12 @@ QList<ProjectAction> QmakePriFileNode::supportedActions(Node *node) const
// TODO: Some of the file types don't make much sense for aux
// projects (e.g. cpp). It'd be nice if the "add" action could
// work on a subset of the file types according to project type.
actions << AddNewFile;
if (pro && pro->knowsFile(node->filePath()))
actions << EraseFile;
else
actions << RemoveFile;
if (action == AddNewFile)
return true;
if (action == EraseFile)
return pro && pro->knowsFile(node->filePath());
if (action == RemoveFile)
return !(pro && pro->knowsFile(node->filePath()));
bool addExistingFiles = true;
if (node->nodeType() == NodeType::VirtualFolder) {
@@ -115,31 +119,26 @@ QList<ProjectAction> QmakePriFileNode::supportedActions(Node *node) const
addExistingFiles = addExistingFiles && !deploysFolder(node->filePath().toString());
if (addExistingFiles)
actions << AddExistingFile << AddExistingDirectory;
if (action == AddExistingFile || action == AddExistingDirectory)
return addExistingFiles;
break;
}
case ProjectType::SubDirsTemplate:
actions << AddSubProject << RemoveSubProject;
if (action == AddSubProject || action == RemoveSubProject)
return true;
break;
default:
break;
}
FileNode *fileNode = node->asFileNode();
if ((fileNode && fileNode->fileType() != FileType::Project)
|| dynamic_cast<ResourceEditor::ResourceTopLevelNode *>(node)) {
actions << Rename;
actions << DuplicateFile;
if (action == HasSubProjectRunConfigurations) {
Target *target = m_project->activeTarget();
QmakeRunConfigurationFactory *factory = QmakeRunConfigurationFactory::find(target);
return factory && !factory->runConfigurationsForNode(target, node).isEmpty();
}
Target *target = m_project->activeTarget();
QmakeRunConfigurationFactory *factory = QmakeRunConfigurationFactory::find(target);
if (factory && !factory->runConfigurationsForNode(target, node).isEmpty())
actions << HasSubProjectRunConfigurations;
return actions;
return false;
}
bool QmakePriFileNode::canAddSubProject(const QString &proFilePath) const