ProjectExplorer Nodes: Replace dynamic_cast with as* functions

The OS X linker makes using dynamic_casts across shared object
boundaries fail, so do all casting in the projectexplorer library
and provide functions to do it.

Task-number: QTCREATORBUG-13864
Change-Id: I0e13c0986f8342d83c3b838ffdd2dd7b8312b13c
Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
This commit is contained in:
Daniel Teske
2015-02-18 13:10:40 +01:00
parent d1e0324b22
commit 2ffd0e2d0d
10 changed files with 97 additions and 35 deletions

View File

@@ -2042,7 +2042,7 @@ static QString pathOrDirectoryFor(Node *node, bool dir)
{ {
Utils::FileName path = node->path(); Utils::FileName path = node->path();
QString location; QString location;
FolderNode *folder = dynamic_cast<FolderNode *>(node); FolderNode *folder = node->asFolderNode();
if (node->nodeType() == VirtualFolderNodeType && folder) { if (node->nodeType() == VirtualFolderNodeType && folder) {
// Virtual Folder case // Virtual Folder case
// If there are files directly below or no subfolders, take the folder path // If there are files directly below or no subfolders, take the folder path
@@ -2397,7 +2397,8 @@ void ProjectExplorerPluginPrivate::runProjectWithoutDeploy()
void ProjectExplorerPluginPrivate::runProjectContextMenu() void ProjectExplorerPluginPrivate::runProjectContextMenu()
{ {
ProjectNode *projectNode = dynamic_cast<ProjectNode*>(ProjectTree::currentNode()); Node *node = ProjectTree::currentNode();
ProjectNode *projectNode = node ? node->asProjectNode() : 0;
if (projectNode == ProjectTree::currentProject()->rootProjectNode() || !projectNode) { if (projectNode == ProjectTree::currentProject()->rootProjectNode() || !projectNode) {
m_instance->runProject(ProjectTree::currentProject(), NormalRunMode); m_instance->runProject(ProjectTree::currentProject(), NormalRunMode);
} else { } else {
@@ -2916,7 +2917,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
if (currentNode && currentNode->projectNode()) { if (currentNode && currentNode->projectNode()) {
QList<ProjectAction> actions = currentNode->supportedActions(currentNode); QList<ProjectAction> actions = currentNode->supportedActions(currentNode);
if (ProjectNode *pn = dynamic_cast<ProjectNode *>(currentNode)) { if (ProjectNode *pn = currentNode->asProjectNode()) {
if (ProjectTree::currentProject() && pn == ProjectTree::currentProject()->rootProjectNode()) { if (ProjectTree::currentProject() && pn == ProjectTree::currentProject()->rootProjectNode()) {
m_runActionContextMenu->setVisible(true); m_runActionContextMenu->setVisible(true);
} else { } else {
@@ -2937,7 +2938,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
} }
} }
} }
if (dynamic_cast<FolderNode*>(currentNode)) { if (currentNode->asFolderNode()) {
// Also handles ProjectNode // Also handles ProjectNode
m_addNewFileAction->setEnabled(actions.contains(AddNewFile) m_addNewFileAction->setEnabled(actions.contains(AddNewFile)
&& !ICore::isNewItemDialogRunning()); && !ICore::isNewItemDialogRunning());
@@ -2949,7 +2950,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
m_addExistingFilesAction->setEnabled(actions.contains(AddExistingFile)); m_addExistingFilesAction->setEnabled(actions.contains(AddExistingFile));
m_addExistingDirectoryAction->setEnabled(actions.contains(AddExistingDirectory)); m_addExistingDirectoryAction->setEnabled(actions.contains(AddExistingDirectory));
m_renameFileAction->setEnabled(actions.contains(Rename)); m_renameFileAction->setEnabled(actions.contains(Rename));
} else if (dynamic_cast<FileNode*>(currentNode)) { } else if (currentNode->asFileNode()) {
// Enable and show remove / delete in magic ways: // Enable and show remove / delete in magic ways:
// If both are disabled show Remove // If both are disabled show Remove
// If both are enabled show both (can't happen atm) // If both are enabled show both (can't happen atm)
@@ -3050,7 +3051,8 @@ void ProjectExplorerPluginPrivate::addExistingDirectory()
void ProjectExplorerPlugin::addExistingFiles(const QStringList &filePaths) void ProjectExplorerPlugin::addExistingFiles(const QStringList &filePaths)
{ {
FolderNode *folderNode = dynamic_cast<FolderNode *>(ProjectTree::currentNode()); Node *node = ProjectTree::currentNode();
FolderNode *folderNode = node ? node->asFolderNode() : 0;
addExistingFiles(folderNode, filePaths); addExistingFiles(folderNode, filePaths);
} }
@@ -3079,8 +3081,13 @@ void ProjectExplorerPlugin::addExistingFiles(FolderNode *folderNode, const QStri
void ProjectExplorerPluginPrivate::removeProject() void ProjectExplorerPluginPrivate::removeProject()
{ {
ProjectNode *subProjectNode = dynamic_cast<ProjectNode*>(ProjectTree::currentNode()->projectNode()); Node *node = ProjectTree::currentNode();
ProjectNode *projectNode = dynamic_cast<ProjectNode *>(subProjectNode->parentFolderNode()); if (!node)
return;
ProjectNode *subProjectNode = node->projectNode();
if (!subProjectNode)
return;
ProjectNode *projectNode = subProjectNode->parentFolderNode()->asProjectNode();
if (projectNode) { if (projectNode) {
RemoveFileDialog removeFileDialog(subProjectNode->path().toString(), ICore::mainWindow()); RemoveFileDialog removeFileDialog(subProjectNode->path().toString(), ICore::mainWindow());
removeFileDialog.setDeleteFileVisible(false); removeFileDialog.setDeleteFileVisible(false);
@@ -3118,7 +3125,7 @@ void ProjectExplorerPluginPrivate::removeFile()
Node *currentNode = ProjectTree::currentNode(); Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode && currentNode->nodeType() == FileNodeType, return); QTC_ASSERT(currentNode && currentNode->nodeType() == FileNodeType, return);
FileNode *fileNode = dynamic_cast<FileNode*>(currentNode); FileNode *fileNode = currentNode->asFileNode();
QString filePath = currentNode->path().toString(); QString filePath = currentNode->path().toString();
RemoveFileDialog removeFileDialog(filePath, ICore::mainWindow()); RemoveFileDialog removeFileDialog(filePath, ICore::mainWindow());
@@ -3147,7 +3154,7 @@ void ProjectExplorerPluginPrivate::deleteFile()
Node *currentNode = ProjectTree::currentNode(); Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode && currentNode->nodeType() == FileNodeType, return); QTC_ASSERT(currentNode && currentNode->nodeType() == FileNodeType, return);
FileNode *fileNode = dynamic_cast<FileNode*>(currentNode); FileNode *fileNode = currentNode->asFileNode();
QString filePath = currentNode->path().toString(); QString filePath = currentNode->path().toString();
QMessageBox::StandardButton button = QMessageBox::StandardButton button =

View File

@@ -59,8 +59,8 @@ bool sortNodes(Node *n1, Node *n2)
const NodeType n2Type = n2->nodeType(); const NodeType n2Type = n2->nodeType();
// project files // project files
FileNode *file1 = dynamic_cast<FileNode*>(n1); FileNode *file1 = n1->asFileNode();
FileNode *file2 = dynamic_cast<FileNode*>(n2); FileNode *file2 = n2->asFileNode();
if (file1 && file1->fileType() == ProjectFileType) { if (file1 && file1->fileType() == ProjectFileType) {
if (file2 && file2->fileType() == ProjectFileType) { if (file2 && file2->fileType() == ProjectFileType) {
const QString fileName1 = file1->path().fileName(); const QString fileName1 = file1->path().fileName();
@@ -221,7 +221,7 @@ QModelIndex FlatModel::index(int row, int column, const QModelIndex &parent) con
if (!parent.isValid() && row == 0 && column == 0) { // session if (!parent.isValid() && row == 0 && column == 0) { // session
result = createIndex(0, 0, m_rootNode); result = createIndex(0, 0, m_rootNode);
} else if (parent.isValid() && column == 0) { } else if (parent.isValid() && column == 0) {
FolderNode *parentNode = dynamic_cast<FolderNode*>(nodeForIndex(parent)); FolderNode *parentNode = nodeForIndex(parent)->asFolderNode();
Q_ASSERT(parentNode); Q_ASSERT(parentNode);
QHash<FolderNode*, QList<Node*> >::const_iterator it = m_childNodes.constFind(parentNode); QHash<FolderNode*, QList<Node*> >::const_iterator it = m_childNodes.constFind(parentNode);
if (it == m_childNodes.constEnd()) { if (it == m_childNodes.constEnd()) {
@@ -270,7 +270,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
QVariant result; QVariant result;
if (Node *node = nodeForIndex(index)) { if (Node *node = nodeForIndex(index)) {
FolderNode *folderNode = dynamic_cast<FolderNode*>(node); FolderNode *folderNode = node->asFolderNode();
switch (role) { switch (role) {
case Qt::DisplayRole: { case Qt::DisplayRole: {
QString name = node->displayName(); QString name = node->displayName();
@@ -334,11 +334,11 @@ Qt::ItemFlags FlatModel::flags(const QModelIndex &index) const
if (Node *node = nodeForIndex(index)) { if (Node *node = nodeForIndex(index)) {
if (node == m_rootNode) if (node == m_rootNode)
return 0; // no flags for session node... return 0; // no flags for session node...
if (!dynamic_cast<ProjectNode *>(node)) { if (!node->asProjectNode()) {
// either folder or file node // either folder or file node
if (node->supportedActions(node).contains(Rename)) if (node->supportedActions(node).contains(Rename))
f = f | Qt::ItemIsEditable; f = f | Qt::ItemIsEditable;
if (dynamic_cast<FileNode *>(node)) if (node->asFileNode())
f = f | Qt::ItemIsDragEnabled; f = f | Qt::ItemIsDragEnabled;
} }
} }
@@ -368,7 +368,7 @@ int FlatModel::rowCount(const QModelIndex &parent) const
if (!parent.isValid()) { if (!parent.isValid()) {
rows = 1; rows = 1;
} else { } else {
FolderNode *folderNode = dynamic_cast<FolderNode*>(nodeForIndex(parent)); FolderNode *folderNode = nodeForIndex(parent)->asFolderNode();
if (folderNode && m_childNodes.contains(folderNode)) if (folderNode && m_childNodes.contains(folderNode))
rows = m_childNodes.value(folderNode).size(); rows = m_childNodes.value(folderNode).size();
} }
@@ -385,7 +385,7 @@ bool FlatModel::hasChildren(const QModelIndex &parent) const
if (!parent.isValid()) if (!parent.isValid())
return true; return true;
FolderNode *folderNode = dynamic_cast<FolderNode*>(nodeForIndex(parent)); FolderNode *folderNode = nodeForIndex(parent)->asFolderNode();
if (!folderNode) if (!folderNode)
return false; return false;
@@ -402,7 +402,7 @@ bool FlatModel::canFetchMore(const QModelIndex & parent) const
if (!parent.isValid()) { if (!parent.isValid()) {
return false; return false;
} else { } else {
if (FolderNode *folderNode = dynamic_cast<FolderNode*>(nodeForIndex(parent))) if (FolderNode *folderNode = nodeForIndex(parent)->asFolderNode())
return !m_childNodes.contains(folderNode); return !m_childNodes.contains(folderNode);
else else
return false; return false;
@@ -472,7 +472,7 @@ void FlatModel::fetchMore(FolderNode *folderNode) const
void FlatModel::fetchMore(const QModelIndex &parent) void FlatModel::fetchMore(const QModelIndex &parent)
{ {
FolderNode *folderNode = dynamic_cast<FolderNode*>(nodeForIndex(parent)); FolderNode *folderNode = nodeForIndex(parent)->asFolderNode();
Q_ASSERT(folderNode); Q_ASSERT(folderNode);
fetchMore(folderNode); fetchMore(folderNode);
@@ -513,7 +513,7 @@ QMimeData *FlatModel::mimeData(const QModelIndexList &indexes) const
auto data = new Utils::FileDropMimeData; auto data = new Utils::FileDropMimeData;
foreach (const QModelIndex &index, indexes) { foreach (const QModelIndex &index, indexes) {
Node *node = nodeForIndex(index); Node *node = nodeForIndex(index);
if (dynamic_cast<FileNode *>(node)) if (node->asFileNode())
data->addFile(node->path().toString()); data->addFile(node->path().toString());
} }
return data; return data;
@@ -600,10 +600,10 @@ FolderNode *FlatModel::visibleFolderNode(FolderNode *node) const
bool FlatModel::filter(Node *node) const bool FlatModel::filter(Node *node) const
{ {
bool isHidden = false; bool isHidden = false;
if (FolderNode *folderNode = dynamic_cast<FolderNode*>(node)) { if (FolderNode *folderNode = node->asFolderNode()) {
if (m_filterProjects) if (m_filterProjects)
isHidden = !folderNode->showInSimpleTree(); isHidden = !folderNode->showInSimpleTree();
} else if (FileNode *fileNode = dynamic_cast<FileNode*>(node)) { } else if (FileNode *fileNode = node->asFileNode()) {
if (m_filterGeneratedFiles) if (m_filterGeneratedFiles)
isHidden = fileNode->isGenerated(); isHidden = fileNode->isGenerated();
} }
@@ -802,7 +802,7 @@ void FlatModel::aboutToShowInSimpleTreeChanged(FolderNode* node)
QList<Node *> staleFolders; QList<Node *> staleFolders;
recursiveAddFolderNodesImpl(node, &staleFolders); recursiveAddFolderNodesImpl(node, &staleFolders);
foreach (Node *n, staleFolders) foreach (Node *n, staleFolders)
if (FolderNode *fn = dynamic_cast<FolderNode *>(n)) if (FolderNode *fn = n->asFolderNode())
m_childNodes.remove(fn); m_childNodes.remove(fn);
} }

View File

@@ -198,6 +198,26 @@ void Node::emitNodeUpdated()
ProjectTree::instance()->emitNodeUpdated(this); ProjectTree::instance()->emitNodeUpdated(this);
} }
FileNode *Node::asFileNode()
{
return 0;
}
FolderNode *Node::asFolderNode()
{
return 0;
}
ProjectNode *Node::asProjectNode()
{
return 0;
}
SessionNode *Node::asSessionNode()
{
return 0;
}
void Node::setParentFolderNode(FolderNode *parentFolder) void Node::setParentFolderNode(FolderNode *parentFolder)
{ {
m_folderNode = parentFolder; m_folderNode = parentFolder;
@@ -235,6 +255,11 @@ bool FileNode::isGenerated() const
return m_generated; return m_generated;
} }
FileNode *FileNode::asFileNode()
{
return this;
}
/*! /*!
\class ProjectExplorer::FolderNode \class ProjectExplorer::FolderNode
@@ -494,6 +519,11 @@ void FolderNode::removeFolderNodes(const QList<FolderNode*> &subFolders)
ProjectTree::instance()->emitFoldersRemoved(this); ProjectTree::instance()->emitFoldersRemoved(this);
} }
FolderNode *FolderNode::asFolderNode()
{
return this;
}
bool FolderNode::showInSimpleTree() const bool FolderNode::showInSimpleTree() const
{ {
return false; return false;
@@ -672,6 +702,11 @@ void ProjectNode::removeProjectNodes(const QList<ProjectNode*> &subProjects)
} }
} }
ProjectNode *ProjectNode::asProjectNode()
{
return this;
}
/*! /*!
\class ProjectExplorer::SessionNode \class ProjectExplorer::SessionNode
@@ -707,6 +742,11 @@ void SessionNode::projectDisplayNameChanged(Node *node)
ProjectTree::instance()->emitNodeSortKeyChanged(node); ProjectTree::instance()->emitNodeSortKeyChanged(node);
} }
SessionNode *SessionNode::asSessionNode()
{
return this;
}
QList<ProjectNode*> SessionNode::projectNodes() const QList<ProjectNode*> SessionNode::projectNodes() const
{ {
return m_projectNodes; return m_projectNodes;

View File

@@ -100,6 +100,7 @@ class FileNode;
class FileContainerNode; class FileContainerNode;
class FolderNode; class FolderNode;
class ProjectNode; class ProjectNode;
class SessionNode;
class NodesVisitor; class NodesVisitor;
class SessionManager; class SessionManager;
@@ -124,6 +125,11 @@ public:
void setPathAndLine(const Utils::FileName &path, int line); void setPathAndLine(const Utils::FileName &path, int line);
void emitNodeUpdated(); void emitNodeUpdated();
virtual FileNode *asFileNode();
virtual FolderNode *asFolderNode();
virtual ProjectNode *asProjectNode();
virtual SessionNode *asSessionNode();
protected: protected:
Node(NodeType nodeType, const Utils::FileName &path, int line = -1); Node(NodeType nodeType, const Utils::FileName &path, int line = -1);
@@ -149,6 +155,8 @@ public:
FileType fileType() const; FileType fileType() const;
bool isGenerated() const; bool isGenerated() const;
FileNode *asFileNode();
private: private:
// managed by ProjectNode // managed by ProjectNode
friend class FolderNode; friend class FolderNode;
@@ -204,6 +212,7 @@ public:
void addFolderNodes(const QList<FolderNode*> &subFolders); void addFolderNodes(const QList<FolderNode*> &subFolders);
void removeFolderNodes(const QList<FolderNode*> &subFolders); void removeFolderNodes(const QList<FolderNode*> &subFolders);
FolderNode *asFolderNode();
protected: protected:
QList<FolderNode*> m_subFolderNodes; QList<FolderNode*> m_subFolderNodes;
@@ -256,6 +265,8 @@ public:
void addProjectNodes(const QList<ProjectNode*> &subProjects); void addProjectNodes(const QList<ProjectNode*> &subProjects);
void removeProjectNodes(const QList<ProjectNode*> &subProjects); void removeProjectNodes(const QList<ProjectNode*> &subProjects);
ProjectNode *asProjectNode();
protected: protected:
// this is just the in-memory representation, a subclass // this is just the in-memory representation, a subclass
// will add the persistent stuff // will add the persistent stuff
@@ -285,6 +296,8 @@ public:
bool showInSimpleTree() const; bool showInSimpleTree() const;
void projectDisplayNameChanged(Node *node); void projectDisplayNameChanged(Node *node);
SessionNode *asSessionNode();
protected: protected:
void addProjectNodes(const QList<ProjectNode*> &projectNodes); void addProjectNodes(const QList<ProjectNode*> &projectNodes);
void removeProjectNodes(const QList<ProjectNode*> &projectNodes); void removeProjectNodes(const QList<ProjectNode*> &projectNodes);

View File

@@ -162,7 +162,7 @@ Project *ProjectTree::projectForNode(Node *node)
if (!node) if (!node)
return 0; return 0;
FolderNode *rootProjectNode = dynamic_cast<FolderNode*>(node); FolderNode *rootProjectNode = node->asFolderNode();
if (!rootProjectNode) if (!rootProjectNode)
rootProjectNode = node->parentFolderNode(); rootProjectNode = node->parentFolderNode();
@@ -310,7 +310,7 @@ void ProjectTree::emitFoldersAboutToBeRemoved(FolderNode *parentFolder, const QL
Node *n = ProjectTree::currentNode(); Node *n = ProjectTree::currentNode();
while (n) { while (n) {
if (FolderNode *fn = dynamic_cast<FolderNode *>(n)) { if (FolderNode *fn = n->asFolderNode()) {
if (staleFolders.contains(fn)) { if (staleFolders.contains(fn)) {
ProjectNode *pn = n->projectNode(); ProjectNode *pn = n->projectNode();
// Make sure the node we are switching too isn't going to be removed also // Make sure the node we are switching too isn't going to be removed also
@@ -363,7 +363,8 @@ void ProjectTree::emitFilesAboutToBeRemoved(FolderNode *folder, const QList<File
if (!isInNodeHierarchy(folder)) if (!isInNodeHierarchy(folder))
return; return;
if (FileNode *fileNode = dynamic_cast<FileNode *>(m_currentNode)) if (m_currentNode)
if (FileNode *fileNode = m_currentNode->asFileNode())
if (staleFiles.contains(fileNode)) if (staleFiles.contains(fileNode))
m_resetCurrentNodeFile = true; m_resetCurrentNodeFile = true;

View File

@@ -563,7 +563,7 @@ Project *SessionManager::projectForNode(Node *node)
if (!node) if (!node)
return 0; return 0;
FolderNode *rootProjectNode = dynamic_cast<FolderNode*>(node); FolderNode *rootProjectNode = node->asFolderNode();
if (!rootProjectNode) if (!rootProjectNode)
rootProjectNode = node->parentFolderNode(); rootProjectNode = node->parentFolderNode();

View File

@@ -932,7 +932,7 @@ QList<ProjectAction> QmakePriFileNode::supportedActions(Node *node) const
bool addExistingFiles = true; bool addExistingFiles = true;
if (node->nodeType() == VirtualFolderNodeType) { if (node->nodeType() == VirtualFolderNodeType) {
// A virtual folder, we do what the projectexplorer does // A virtual folder, we do what the projectexplorer does
FolderNode *folder = dynamic_cast<FolderNode *>(node); FolderNode *folder = node->asFolderNode();
if (folder) { if (folder) {
QStringList list; QStringList list;
foreach (FolderNode *f, folder->subFolderNodes()) foreach (FolderNode *f, folder->subFolderNodes())
@@ -956,7 +956,7 @@ QList<ProjectAction> QmakePriFileNode::supportedActions(Node *node) const
break; break;
} }
FileNode *fileNode = dynamic_cast<FileNode *>(node); FileNode *fileNode = node->asFileNode();
if ((fileNode && fileNode->fileType() != ProjectFileType) if ((fileNode && fileNode->fileType() != ProjectFileType)
|| dynamic_cast<ResourceEditor::ResourceTopLevelNode *>(node)) || dynamic_cast<ResourceEditor::ResourceTopLevelNode *>(node))
actions << Rename; actions << Rename;

View File

@@ -232,7 +232,8 @@ void QmakeManager::buildFile()
{ {
if (Core::IDocument *currentDocument= Core::EditorManager::currentDocument()) { if (Core::IDocument *currentDocument= Core::EditorManager::currentDocument()) {
const Utils::FileName file = currentDocument->filePath(); const Utils::FileName file = currentDocument->filePath();
FileNode *node = dynamic_cast<FileNode *>(SessionManager::nodeForFile(file)); Node *n = SessionManager::nodeForFile(file);
FileNode *node = n ? n->asFileNode() : 0;
Project *project = SessionManager::projectForFile(file); Project *project = SessionManager::projectForFile(file);
if (project && node) if (project && node)

View File

@@ -329,7 +329,7 @@ void QmakeProjectManagerPlugin::updateContextActions(ProjectExplorer::Node *node
if (QmakePriFileNode *subPriFileNode = dynamic_cast<QmakePriFileNode *>(node->projectNode())) if (QmakePriFileNode *subPriFileNode = dynamic_cast<QmakePriFileNode *>(node->projectNode()))
subProjectNode = subPriFileNode->proFileNode(); subProjectNode = subPriFileNode->proFileNode();
} }
ProjectExplorer::FileNode *fileNode = dynamic_cast<ProjectExplorer::FileNode *>(node); ProjectExplorer::FileNode *fileNode = node ? node->asFileNode() : 0;
bool buildFilePossible = subProjectNode && fileNode bool buildFilePossible = subProjectNode && fileNode
&& (fileNode->fileType() == ProjectExplorer::SourceType); && (fileNode->fileType() == ProjectExplorer::SourceType);