Designer: Fix look-up of resources for UI files

Commit 81a643ec99, fixing QTCREATORBUG-22412, was too restrictive: UI
files in applications have access to resources of library dependencies,
so we must consider those. We now only exclude resources from other
applications.
Note that this will potentially list non-applicable resources, e.g.
those from libraries to which our product does not have access. This
cannot be reasonably prevented, because not all build systems provide
this information. It's also not as bad as missing resources.

Fixes: QTCREATORBUG-22909
Fixes: QTCREATORBUG-22962
Change-Id: I51a87402b43c156618982813c408060f300e4e58
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2019-09-24 14:39:50 +02:00
parent 85fcd10f90
commit 736eef24ca
5 changed files with 45 additions and 17 deletions

View File

@@ -173,7 +173,7 @@ CMakeTargetNode::CMakeTargetNode(const Utils::FilePath &directory, const QString
setPriority(Node::DefaultProjectPriority + 900); setPriority(Node::DefaultProjectPriority + 900);
setIcon(QIcon(":/projectexplorer/images/build.png")); // TODO: Use proper icon! setIcon(QIcon(":/projectexplorer/images/build.png")); // TODO: Use proper icon!
setListInProject(false); setListInProject(false);
setIsProduct(); setProductType(ProductType::Other);
} }
QString CMakeTargetNode::generateId(const Utils::FilePath &directory, const QString &target) QString CMakeTargetNode::generateId(const Utils::FilePath &directory, const QString &target)

View File

@@ -99,26 +99,37 @@ void ResourceHandler::updateResourcesHelper(bool updateProjectResources)
// Find the (sub-)project the file belongs to. We don't want to find resources // Find the (sub-)project the file belongs to. We don't want to find resources
// from other parts of the project tree, e.g. via a qmake subdirs project. // from other parts of the project tree, e.g. via a qmake subdirs project.
ProjectNode *projectNode = project->rootProjectNode(); Node * const fileNode = project->rootProjectNode()->findNode([&fileName](const Node *n) {
Node * const fileNode = projectNode->findNode([&fileName](const Node *n) {
return n->filePath().toString() == fileName; return n->filePath().toString() == fileName;
}); });
ProjectNode *projectNodeForUiFile = nullptr;
if (fileNode) { if (fileNode) {
// We do not want qbs groups or qmake .pri files here, as they contain only a subset // We do not want qbs groups or qmake .pri files here, as they contain only a subset
// of the relevant files. // of the relevant files.
projectNode = fileNode->parentProjectNode(); projectNodeForUiFile = fileNode->parentProjectNode();
while (projectNode && !projectNode->isProduct()) while (projectNodeForUiFile && !projectNodeForUiFile->isProduct())
projectNode = projectNode->parentProjectNode(); projectNodeForUiFile = projectNodeForUiFile->parentProjectNode();
} }
if (!projectNode) if (!projectNodeForUiFile)
projectNode = project->rootProjectNode(); projectNodeForUiFile = project->rootProjectNode();
const auto useQrcFile = [projectNodeForUiFile, project](const Node *qrcNode) {
if (projectNodeForUiFile == project->rootProjectNode())
return true;
ProjectNode *projectNodeForQrcFile = qrcNode->parentProjectNode();
while (projectNodeForQrcFile && !projectNodeForQrcFile->isProduct())
projectNodeForQrcFile = projectNodeForQrcFile->parentProjectNode();
return !projectNodeForQrcFile
|| projectNodeForQrcFile == projectNodeForUiFile
|| projectNodeForQrcFile->productType() != ProductType::App;
};
QStringList projectQrcFiles; QStringList projectQrcFiles;
projectNode->forEachNode([&](FileNode *node) { project->rootProjectNode()->forEachNode([&](FileNode *node) {
if (node->fileType() == FileType::Resource) if (node->fileType() == FileType::Resource && useQrcFile(node))
projectQrcFiles.append(node->filePath().toString()); projectQrcFiles.append(node->filePath().toString());
}, [&](FolderNode *node) { }, [&](FolderNode *node) {
if (dynamic_cast<ResourceEditor::ResourceTopLevelNode *>(node)) if (dynamic_cast<ResourceEditor::ResourceTopLevelNode *>(node) && useQrcFile(node))
projectQrcFiles.append(node->filePath().toString()); projectQrcFiles.append(node->filePath().toString());
}); });
// Check if the user has chosen to update the lacking resource inside designer // Check if the user has chosen to update the lacking resource inside designer
@@ -130,7 +141,7 @@ void ResourceHandler::updateResourcesHelper(bool updateProjectResources)
} }
if (!qrcPathsToBeAdded.isEmpty()) { if (!qrcPathsToBeAdded.isEmpty()) {
m_handlingResources = true; m_handlingResources = true;
projectNode->addFiles(qrcPathsToBeAdded); projectNodeForUiFile->addFiles(qrcPathsToBeAdded);
m_handlingResources = false; m_handlingResources = false;
projectQrcFiles += qrcPathsToBeAdded; projectQrcFiles += qrcPathsToBeAdded;
} }

View File

@@ -57,6 +57,8 @@ enum class FileType : quint16 {
FileTypeSize FileTypeSize
}; };
enum class ProductType { App, Lib, Other, None };
enum ProjectAction { enum ProjectAction {
// Special value to indicate that the actions are handled by the parent // Special value to indicate that the actions are handled by the parent
InheritedFromParent, InheritedFromParent,
@@ -357,15 +359,16 @@ public:
virtual QVariant data(Core::Id role) const; virtual QVariant data(Core::Id role) const;
virtual bool setData(Core::Id role, const QVariant &value) const; virtual bool setData(Core::Id role, const QVariant &value) const;
bool isProduct() const { return m_isProduct; } bool isProduct() const { return m_productType != ProductType::None; }
ProductType productType() const { return m_productType; }
protected: protected:
void setIsProduct() { m_isProduct = true; } void setProductType(ProductType type) { m_productType = type; }
QString m_target; QString m_target;
private: private:
bool m_isProduct = false; ProductType m_productType = ProductType::None;
}; };
class PROJECTEXPLORER_EXPORT ContainerNode : public FolderNode class PROJECTEXPLORER_EXPORT ContainerNode : public FolderNode

View File

@@ -320,7 +320,14 @@ QbsProductNode::QbsProductNode(const qbs::ProductData &prd) :
{ {
static QIcon productIcon = Core::FileIconProvider::directoryIcon(Constants::QBS_PRODUCT_OVERLAY_ICON); static QIcon productIcon = Core::FileIconProvider::directoryIcon(Constants::QBS_PRODUCT_OVERLAY_ICON);
setIcon(productIcon); setIcon(productIcon);
setIsProduct(); if (m_qbsProductData.isRunnable()) {
setProductType(ProductType::App);
} else if (m_qbsProductData.type().contains("dynamiclibrary")
|| m_qbsProductData.type().contains("staticlibrary")) {
setProductType(ProductType::Lib);
} else {
setProductType(ProductType::Other);
}
} }
bool QbsProductNode::supportsAction(ProjectAction action, const Node *node) const bool QbsProductNode::supportsAction(ProjectAction action, const Node *node) const

View File

@@ -230,7 +230,14 @@ FolderNode::AddNewInformation QmakePriFileNode::addNewInformation(const QStringL
QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FilePath &filePath, QmakeProFile *pf) : QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FilePath &filePath, QmakeProFile *pf) :
QmakePriFileNode(project, this, filePath, pf) QmakePriFileNode(project, this, filePath, pf)
{ {
setIsProduct(); if (projectType() == ProjectType::ApplicationTemplate) {
setProductType(ProductType::App);
} else if (projectType() == ProjectType::SharedLibraryTemplate
|| projectType() == ProjectType::StaticLibraryTemplate) {
setProductType(ProductType::Lib);
} else if (projectType() != ProjectType::SubDirsTemplate) {
setProductType(ProductType::Other);
}
} }
bool QmakeProFileNode::showInSimpleTree() const bool QmakeProFileNode::showInSimpleTree() const