forked from qt-creator/qt-creator
CMakeProjectManager: Add File System virtual folder
If a CMake project cannot be parsed by CMake, it is practically unusable in Qt Creator. According to discussion in QTCREATORBUG-24677, a virtual folder with the project's file system view is added to the project manager as a convenience feature. Fixes: QTCREATORBUG-24677 Change-Id: I48775bb89c704d3f7e5bb21ec6481bd5cc0f4b6c Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Kai Koehne <kai.koehne@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -517,11 +517,11 @@ void CMakeBuildSystem::clearCMakeCache()
|
||||
Utils::FileUtils::removeRecursively(cmakeFiles);
|
||||
}
|
||||
|
||||
std::unique_ptr<CMakeProjectNode>
|
||||
CMakeBuildSystem::generateProjectTree(const QList<const FileNode *> &allFiles)
|
||||
std::unique_ptr<CMakeProjectNode> CMakeBuildSystem::generateProjectTree(
|
||||
const QList<const FileNode *> &allFiles, bool includeHeaderNodes)
|
||||
{
|
||||
QString errorMessage;
|
||||
auto root = m_reader.generateProjectTree(allFiles, errorMessage);
|
||||
auto root = m_reader.generateProjectTree(allFiles, errorMessage, includeHeaderNodes);
|
||||
checkAndReportError(errorMessage);
|
||||
return root;
|
||||
}
|
||||
@@ -535,6 +535,8 @@ void CMakeBuildSystem::combineScanAndParse()
|
||||
if (m_combinedScanAndParseResult) {
|
||||
updateProjectData();
|
||||
m_currentGuard.markAsSuccess();
|
||||
} else {
|
||||
updateFallbackProjectData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,7 +592,7 @@ void CMakeBuildSystem::updateProjectData()
|
||||
|
||||
Project *p = project();
|
||||
{
|
||||
auto newRoot = generateProjectTree(m_allFiles);
|
||||
auto newRoot = generateProjectTree(m_allFiles, true);
|
||||
if (newRoot) {
|
||||
setRootProjectNode(std::move(newRoot));
|
||||
CMakeConfigItem settingFileItem;
|
||||
@@ -671,6 +673,18 @@ void CMakeBuildSystem::updateProjectData()
|
||||
qCDebug(cmakeBuildSystemLog) << "All CMake project data up to date.";
|
||||
}
|
||||
|
||||
void CMakeBuildSystem::updateFallbackProjectData()
|
||||
{
|
||||
qCDebug(cmakeBuildSystemLog) << "Updating fallback CMake project data";
|
||||
|
||||
QTC_ASSERT(m_treeScanner.isFinished() && !m_reader.isParsing(), return );
|
||||
|
||||
auto newRoot = generateProjectTree(m_allFiles, false);
|
||||
setRootProjectNode(std::move(newRoot));
|
||||
|
||||
qCDebug(cmakeBuildSystemLog) << "All fallback CMake project data up to date.";
|
||||
}
|
||||
|
||||
void CMakeBuildSystem::handleParsingSucceeded()
|
||||
{
|
||||
if (!cmakeBuildConfiguration()->isActive()) {
|
||||
|
@@ -123,11 +123,11 @@ private:
|
||||
void combineScanAndParse();
|
||||
|
||||
std::unique_ptr<CMakeProjectNode> generateProjectTree(
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles);
|
||||
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles, bool includeHeadersNode);
|
||||
void checkAndReportError(QString &errorMessage);
|
||||
|
||||
void updateProjectData();
|
||||
void updateFallbackProjectData();
|
||||
QList<ProjectExplorer::ExtraCompiler *> findExtraCompilers();
|
||||
void updateQmlJSCodeModel();
|
||||
|
||||
|
@@ -692,5 +692,29 @@ FileApiQtcData extractData(FileApiData &input,
|
||||
return result;
|
||||
}
|
||||
|
||||
FileApiQtcData generateFallbackData(const FilePath &topCmakeFile,
|
||||
const FilePath &sourceDirectory,
|
||||
const FilePath &buildDirectory,
|
||||
QString errorMessage)
|
||||
{
|
||||
FileApiQtcData result;
|
||||
|
||||
result.rootProjectNode.reset(new CMakeProjectNode{sourceDirectory});
|
||||
result.rootProjectNode->setDisplayName(sourceDirectory.fileName());
|
||||
result.errorMessage = errorMessage;
|
||||
|
||||
if (!topCmakeFile.isEmpty()) {
|
||||
auto node = std::make_unique<FileNode>(topCmakeFile, FileType::Project);
|
||||
node->setIsGenerated(false);
|
||||
|
||||
std::vector<std::unique_ptr<FileNode>> fileNodes;
|
||||
fileNodes.emplace_back(std::move(node));
|
||||
|
||||
addCMakeLists(result.rootProjectNode.get(), std::move(fileNodes));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <projectexplorer/rawprojectpart.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/optional.h>
|
||||
|
||||
#include <QList>
|
||||
#include <QSet>
|
||||
@@ -58,6 +59,10 @@ public:
|
||||
FileApiQtcData extractData(FileApiData &data,
|
||||
const Utils::FilePath &sourceDirectory,
|
||||
const Utils::FilePath &buildDirectory);
|
||||
FileApiQtcData generateFallbackData(const Utils::FilePath &topCmakeFile,
|
||||
const Utils::FilePath &sourceDirectory,
|
||||
const Utils::FilePath &buildDirectory,
|
||||
QString errorMessage);
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
|
@@ -193,11 +193,14 @@ CMakeConfig FileApiReader::takeParsedConfiguration(QString &errorMessage)
|
||||
}
|
||||
|
||||
std::unique_ptr<CMakeProjectNode> FileApiReader::generateProjectTree(
|
||||
const QList<const FileNode *> &allFiles, QString &errorMessage)
|
||||
const QList<const FileNode *> &allFiles, QString &errorMessage, bool includeHeaderNodes)
|
||||
{
|
||||
Q_UNUSED(errorMessage)
|
||||
|
||||
if (includeHeaderNodes) {
|
||||
addHeaderNodes(m_rootProjectNode.get(), m_knownHeaders, allFiles);
|
||||
}
|
||||
addFileSystemNodes(m_rootProjectNode.get(), allFiles);
|
||||
return std::move(m_rootProjectNode);
|
||||
}
|
||||
|
||||
@@ -230,19 +233,23 @@ void FileApiReader::endState(const QFileInfo &replyFi)
|
||||
|
||||
const FilePath sourceDirectory = m_parameters.sourceDirectory;
|
||||
const FilePath buildDirectory = m_parameters.workDirectory;
|
||||
const FilePath topCmakeFile = m_cmakeFiles.size() == 1 ? *m_cmakeFiles.begin() : FilePath{};
|
||||
|
||||
m_lastReplyTimestamp = replyFi.lastModified();
|
||||
|
||||
m_future = runAsync(ProjectExplorerPlugin::sharedThreadPool(),
|
||||
[replyFi, sourceDirectory, buildDirectory]() {
|
||||
[replyFi, sourceDirectory, buildDirectory, topCmakeFile]() {
|
||||
auto result = std::make_unique<FileApiQtcData>();
|
||||
FileApiData data = FileApiParser::parseData(replyFi,
|
||||
result->errorMessage);
|
||||
FileApiData data = FileApiParser::parseData(replyFi, result->errorMessage);
|
||||
if (!result->errorMessage.isEmpty()) {
|
||||
qWarning() << result->errorMessage;
|
||||
return result.release();
|
||||
}
|
||||
*result = generateFallbackData(topCmakeFile,
|
||||
sourceDirectory,
|
||||
buildDirectory,
|
||||
result->errorMessage);
|
||||
} else {
|
||||
*result = extractData(data, sourceDirectory, buildDirectory);
|
||||
}
|
||||
if (!result->errorMessage.isEmpty()) {
|
||||
qWarning() << result->errorMessage;
|
||||
}
|
||||
|
@@ -67,7 +67,9 @@ public:
|
||||
QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage);
|
||||
CMakeConfig takeParsedConfiguration(QString &errorMessage);
|
||||
std::unique_ptr<CMakeProjectNode> generateProjectTree(
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles, QString &errorMessage);
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles,
|
||||
QString &errorMessage,
|
||||
bool includeHeaderNodes);
|
||||
ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage);
|
||||
|
||||
signals:
|
||||
|
@@ -208,5 +208,31 @@ void addHeaderNodes(ProjectNode *root,
|
||||
root->addNode(std::move(headerNode));
|
||||
}
|
||||
|
||||
void addFileSystemNodes(ProjectNode *root, const QList<const FileNode *> &allFiles)
|
||||
{
|
||||
QTC_ASSERT(root, return );
|
||||
|
||||
static QIcon fileSystemNodeIcon = Core::FileIconProvider::directoryIcon(
|
||||
ProjectExplorer::Constants::FILEOVERLAY_UNKNOWN);
|
||||
auto fileSystemNode = std::make_unique<VirtualFolderNode>(root->filePath());
|
||||
fileSystemNode->setPriority(Node::DefaultPriority - 6);
|
||||
fileSystemNode->setDisplayName(
|
||||
QCoreApplication::translate("CMakeProjectManager::Internal::ProjectTreeHelper",
|
||||
"<File System>"));
|
||||
fileSystemNode->setIcon(fileSystemNodeIcon);
|
||||
|
||||
for (const FileNode *fn : allFiles) {
|
||||
if (!fn->filePath().isChildOf(root->filePath()))
|
||||
continue;
|
||||
|
||||
std::unique_ptr<FileNode> node(fn->clone());
|
||||
node->setEnabled(false);
|
||||
fileSystemNode->addNestedNode(std::move(node));
|
||||
}
|
||||
|
||||
if (!fileSystemNode->isEmpty())
|
||||
root->addNode(std::move(fileSystemNode));
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
|
@@ -68,5 +68,7 @@ void addHeaderNodes(ProjectExplorer::ProjectNode *root,
|
||||
QSet<Utils::FilePath> &seenHeaders,
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles);
|
||||
|
||||
void addFileSystemNodes(ProjectExplorer::ProjectNode *root,
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles);
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
|
Reference in New Issue
Block a user