Files
qt-creator/src/plugins/genericprojectmanager/genericproject.cpp

493 lines
16 KiB
C++
Raw Normal View History

/****************************************************************************
2009-03-10 14:20:07 +01:00
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
2009-03-10 14:20:07 +01:00
**
** This file is part of Qt Creator.
2009-03-10 14:20:07 +01:00
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
2009-03-10 14:20:07 +01:00
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
2010-12-17 16:01:08 +01:00
**
****************************************************************************/
2009-03-10 14:20:07 +01:00
#include "genericproject.h"
#include "genericbuildconfiguration.h"
#include "genericmakestep.h"
#include "genericprojectconstants.h"
2009-03-10 14:20:07 +01:00
#include <coreplugin/documentmanager.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <cpptools/cpptoolsconstants.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/projectinfo.h>
CppTools/ProjectManagers: Reduce ui blocking when loading projects ${AnyProject}::updateCppCodeModel() did two potentially not that cheap operations in the ui thread: (1) Querying the MimeDatabase for the mime type for the source files of the project. In 99.9% of the cases no files need to be read for this as the file extension will resolve the type. The expensiveness comes from the sheer number of files that can occur. (2) Calling compilers with the "(sub)project's compiler command line" to determine the macros. While the caches avoid redundant calls, the number of the unique compiler calls makes this still a ui-freezing experience. These two operations are moved into a worker thread. For this, the expensive compiler calls are encapsulated in thread safe lambdas ("runners") in order to keep the "mutexed" data minimal. The original API calls of the toolchains are implemented in terms of the runners. While adapting the project managers, remove also the calls to setProjectLanguage(). These are redundant because all of the project managers already set a proper value in the constructor. Also, currently there is no need (client) to report back detection of C sources in project parts. This also keeps CppProjectUpdater simple. There is still room for improvement: * Run the compiler calls in parallel instead of sequence. * Ensure that the mime type for a file is determined exactly once. Change-Id: I2efc4e132ee88e3c8f264012ec8fafe3d86c404f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-02-06 16:59:53 +01:00
#include <cpptools/cppprojectupdater.h>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/customexecutablerunconfiguration.h>
2011-02-28 16:50:14 +01:00
#include <projectexplorer/headerpath.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
2009-03-10 14:20:07 +01:00
#include <projectexplorer/projectexplorerconstants.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
2009-03-10 14:20:07 +01:00
#include <QDir>
2009-03-10 14:20:07 +01:00
using namespace Core;
using namespace ProjectExplorer;
2009-03-10 14:20:07 +01:00
namespace GenericProjectManager {
namespace Internal {
////////////////////////////////////////////////////////////////////////////////////
//
// GenericProject
//
////////////////////////////////////////////////////////////////////////////////////
GenericProject::GenericProject(const QString &fileName)
CppTools/ProjectManagers: Reduce ui blocking when loading projects ${AnyProject}::updateCppCodeModel() did two potentially not that cheap operations in the ui thread: (1) Querying the MimeDatabase for the mime type for the source files of the project. In 99.9% of the cases no files need to be read for this as the file extension will resolve the type. The expensiveness comes from the sheer number of files that can occur. (2) Calling compilers with the "(sub)project's compiler command line" to determine the macros. While the caches avoid redundant calls, the number of the unique compiler calls makes this still a ui-freezing experience. These two operations are moved into a worker thread. For this, the expensive compiler calls are encapsulated in thread safe lambdas ("runners") in order to keep the "mutexed" data minimal. The original API calls of the toolchains are implemented in terms of the runners. While adapting the project managers, remove also the calls to setProjectLanguage(). These are redundant because all of the project managers already set a proper value in the constructor. Also, currently there is no need (client) to report back detection of C sources in project parts. This also keeps CppProjectUpdater simple. There is still room for improvement: * Run the compiler calls in parallel instead of sequence. * Ensure that the mime type for a file is determined exactly once. Change-Id: I2efc4e132ee88e3c8f264012ec8fafe3d86c404f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-02-06 16:59:53 +01:00
: m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this))
2009-03-10 14:20:07 +01:00
{
setId(Constants::GENERICPROJECT_ID);
setDocument(new GenericProjectFile(this, fileName, GenericProject::Everything));
setRootProjectNode(new GenericProjectNode(this));
setProjectContext(Context(GenericProjectManager::Constants::PROJECTCONTEXT));
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
const QFileInfo fileInfo = projectFilePath().toFileInfo();
const QDir dir = fileInfo.dir();
2009-03-16 11:49:57 +01:00
m_projectName = fileInfo.completeBaseName();
m_filesFileName = QFileInfo(dir, m_projectName + ".files").absoluteFilePath();
m_includesFileName = QFileInfo(dir, m_projectName + ".includes").absoluteFilePath();
m_configFileName = QFileInfo(dir, m_projectName + ".config").absoluteFilePath();
2009-03-16 11:49:57 +01:00
m_filesIDocument = new GenericProjectFile(this, m_filesFileName, GenericProject::Files);
m_includesIDocument = new GenericProjectFile(this, m_includesFileName, GenericProject::Configuration);
m_configIDocument = new GenericProjectFile(this, m_configFileName, GenericProject::Configuration);
DocumentManager::addDocument(document());
DocumentManager::addDocument(m_filesIDocument);
DocumentManager::addDocument(m_includesIDocument);
DocumentManager::addDocument(m_configIDocument);
2009-03-10 14:20:07 +01:00
}
GenericProject::~GenericProject()
{
CppTools/ProjectManagers: Reduce ui blocking when loading projects ${AnyProject}::updateCppCodeModel() did two potentially not that cheap operations in the ui thread: (1) Querying the MimeDatabase for the mime type for the source files of the project. In 99.9% of the cases no files need to be read for this as the file extension will resolve the type. The expensiveness comes from the sheer number of files that can occur. (2) Calling compilers with the "(sub)project's compiler command line" to determine the macros. While the caches avoid redundant calls, the number of the unique compiler calls makes this still a ui-freezing experience. These two operations are moved into a worker thread. For this, the expensive compiler calls are encapsulated in thread safe lambdas ("runners") in order to keep the "mutexed" data minimal. The original API calls of the toolchains are implemented in terms of the runners. While adapting the project managers, remove also the calls to setProjectLanguage(). These are redundant because all of the project managers already set a proper value in the constructor. Also, currently there is no need (client) to report back detection of C sources in project parts. This also keeps CppProjectUpdater simple. There is still room for improvement: * Run the compiler calls in parallel instead of sequence. * Ensure that the mime type for a file is determined exactly once. Change-Id: I2efc4e132ee88e3c8f264012ec8fafe3d86c404f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-02-06 16:59:53 +01:00
delete m_cppCodeModelUpdater;
}
2009-03-16 11:49:57 +01:00
QString GenericProject::filesFileName() const
2011-04-12 08:20:54 +02:00
{
return m_filesFileName;
}
2009-03-16 11:49:57 +01:00
QString GenericProject::includesFileName() const
2011-04-12 08:20:54 +02:00
{
return m_includesFileName;
}
2009-03-16 11:49:57 +01:00
QString GenericProject::configFileName() const
2011-04-12 08:20:54 +02:00
{
return m_configFileName;
}
2009-03-16 11:49:57 +01:00
static QStringList readLines(const QString &absoluteFileName)
{
QStringList lines;
QFile file(absoluteFileName);
if (file.open(QFile::ReadOnly)) {
QTextStream stream(&file);
for (;;) {
const QString line = stream.readLine();
if (line.isNull())
break;
lines.append(line);
}
}
return lines;
}
bool GenericProject::saveRawFileList(const QStringList &rawFileList)
{
bool result = saveRawList(rawFileList, filesFileName());
refresh(GenericProject::Files);
return result;
}
bool GenericProject::saveRawList(const QStringList &rawList, const QString &fileName)
{
FileChangeBlocker changeGuard(fileName);
// Make sure we can open the file for writing
Utils::FileSaver saver(fileName, QIODevice::Text);
if (!saver.hasError()) {
QTextStream stream(saver.file());
for (const QString &filePath : rawList)
stream << filePath << '\n';
saver.setResult(&stream);
}
bool result = saver.finalize(ICore::mainWindow());
return result;
}
static void insertSorted(QStringList *list, const QString &value)
{
int pos = Utils::indexOf(*list, [value](const QString &s) { return s > value; });
list->insert(pos, value);
}
bool GenericProject::addFiles(const QStringList &filePaths)
{
QStringList newList = m_rawFileList;
const QDir baseDir(projectDirectory().toString());
for (const QString &filePath : filePaths)
insertSorted(&newList, baseDir.relativeFilePath(filePath));
const QSet<QString> includes = projectIncludePaths().toSet();
QSet<QString> toAdd;
for (const QString &filePath : filePaths) {
const QString directory = QFileInfo(filePath).absolutePath();
if (!includes.contains(directory))
toAdd << directory;
}
const QDir dir(projectDirectory().toString());
const auto candidates = toAdd;
for (const QString &path : candidates) {
QString relative = dir.relativeFilePath(path);
if (relative.isEmpty())
relative = '.';
m_rawProjectIncludePaths.append(relative);
}
bool result = saveRawList(newList, filesFileName());
result &= saveRawList(m_rawProjectIncludePaths, includesFileName());
refresh(GenericProject::Everything);
return result;
}
bool GenericProject::removeFiles(const QStringList &filePaths)
{
QStringList newList = m_rawFileList;
for (const QString &filePath : filePaths) {
QHash<QString, QString>::iterator i = m_rawListEntries.find(filePath);
if (i != m_rawListEntries.end())
newList.removeOne(i.value());
}
return saveRawFileList(newList);
}
bool GenericProject::setFiles(const QStringList &filePaths)
{
QStringList newList;
QDir baseDir(projectDirectory().toString());
for (const QString &filePath : filePaths)
newList.append(baseDir.relativeFilePath(filePath));
Utils::sort(newList);
return saveRawFileList(newList);
}
bool GenericProject::renameFile(const QString &filePath, const QString &newFilePath)
{
QStringList newList = m_rawFileList;
QHash<QString, QString>::iterator i = m_rawListEntries.find(filePath);
if (i != m_rawListEntries.end()) {
int index = newList.indexOf(i.value());
if (index != -1) {
QDir baseDir(projectDirectory().toString());
newList.removeAt(index);
insertSorted(&newList, baseDir.relativeFilePath(newFilePath));
}
}
return saveRawFileList(newList);
}
void GenericProject::parseProject(RefreshOptions options)
2009-03-12 15:07:54 +01:00
{
if (options & Files) {
m_rawListEntries.clear();
m_rawFileList = readLines(filesFileName());
m_files = processEntries(m_rawFileList, &m_rawListEntries);
}
2009-03-16 11:49:57 +01:00
if (options & Configuration) {
m_rawProjectIncludePaths = readLines(includesFileName());
m_projectIncludePaths = processEntries(m_rawProjectIncludePaths);
// TODO: Possibly load some configuration from the project file
//QSettings projectInfo(m_fileName, QSettings::IniFormat);
}
if (options & Files)
emit fileListChanged();
2009-03-12 15:07:54 +01:00
}
void GenericProject::refresh(RefreshOptions options)
2009-03-10 14:20:07 +01:00
{
parseProject(options);
if (options & Files) {
QList<FileNode *> fileNodes = Utils::transform(files(), [](const QString &f) {
FileType fileType = FileType::Source; // ### FIXME
if (f.endsWith(".qrc"))
fileType = FileType::Resource;
return new FileNode(Utils::FileName::fromString(f), fileType, false);
});
auto projectFilesNode = new FileNode(Utils::FileName::fromString(m_filesFileName),
FileType::Project,
/* generated = */ false);
auto projectIncludesNode = new FileNode(Utils::FileName::fromString(m_includesFileName),
FileType::Project,
/* generated = */ false);
auto projectConfigNode = new FileNode(Utils::FileName::fromString(m_configFileName),
FileType::Project,
/* generated = */ false);
fileNodes << projectFilesNode << projectIncludesNode << projectConfigNode;
rootProjectNode()->makeEmpty();
rootProjectNode()->buildTree(fileNodes);
}
2009-03-10 14:20:07 +01:00
refreshCppCodeModel();
emit parsingFinished();
2009-03-10 14:20:07 +01:00
}
/**
* Expands environment variables and converts the path from relative to the
* project to an absolute path.
*
* The \a map variable is an optional argument that will map the returned
* absolute paths back to their original \a entries.
*/
QStringList GenericProject::processEntries(const QStringList &paths,
QHash<QString, QString> *map) const
2009-03-12 15:07:54 +01:00
{
const BuildConfiguration *const buildConfig = activeTarget() ? activeTarget()->activeBuildConfiguration()
: nullptr;
const Utils::Environment buildEnv = buildConfig ? buildConfig->environment()
: Utils::Environment::systemEnvironment();
const Utils::MacroExpander *expander = macroExpander();
if (buildConfig)
expander = buildConfig->macroExpander();
else if (activeTarget())
expander = activeTarget()->macroExpander();
const QDir projectDir(projectDirectory().toString());
QFileInfo fileInfo;
2009-03-12 15:07:54 +01:00
QStringList absolutePaths;
for (const QString &path : paths) {
QString trimmedPath = path.trimmed();
if (trimmedPath.isEmpty())
continue;
trimmedPath = buildEnv.expandVariables(trimmedPath);
trimmedPath = expander->expand(trimmedPath);
trimmedPath = Utils::FileName::fromUserInput(trimmedPath).toString();
fileInfo.setFile(projectDir, trimmedPath);
if (fileInfo.exists()) {
const QString absPath = fileInfo.absoluteFilePath();
absolutePaths.append(absPath);
if (map)
map->insert(absPath, trimmedPath);
}
2009-03-12 15:07:54 +01:00
}
absolutePaths.removeDuplicates();
return absolutePaths;
}
void GenericProject::refreshCppCodeModel()
{
CppTools/ProjectManagers: Reduce ui blocking when loading projects ${AnyProject}::updateCppCodeModel() did two potentially not that cheap operations in the ui thread: (1) Querying the MimeDatabase for the mime type for the source files of the project. In 99.9% of the cases no files need to be read for this as the file extension will resolve the type. The expensiveness comes from the sheer number of files that can occur. (2) Calling compilers with the "(sub)project's compiler command line" to determine the macros. While the caches avoid redundant calls, the number of the unique compiler calls makes this still a ui-freezing experience. These two operations are moved into a worker thread. For this, the expensive compiler calls are encapsulated in thread safe lambdas ("runners") in order to keep the "mutexed" data minimal. The original API calls of the toolchains are implemented in terms of the runners. While adapting the project managers, remove also the calls to setProjectLanguage(). These are redundant because all of the project managers already set a proper value in the constructor. Also, currently there is no need (client) to report back detection of C sources in project parts. This also keeps CppProjectUpdater simple. There is still room for improvement: * Run the compiler calls in parallel instead of sequence. * Ensure that the mime type for a file is determined exactly once. Change-Id: I2efc4e132ee88e3c8f264012ec8fafe3d86c404f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-02-06 16:59:53 +01:00
const Kit *k = nullptr;
if (Target *target = activeTarget())
k = target->kit();
else
k = KitManager::defaultKit();
QTC_ASSERT(k, return);
CppTools/ProjectManagers: Reduce ui blocking when loading projects ${AnyProject}::updateCppCodeModel() did two potentially not that cheap operations in the ui thread: (1) Querying the MimeDatabase for the mime type for the source files of the project. In 99.9% of the cases no files need to be read for this as the file extension will resolve the type. The expensiveness comes from the sheer number of files that can occur. (2) Calling compilers with the "(sub)project's compiler command line" to determine the macros. While the caches avoid redundant calls, the number of the unique compiler calls makes this still a ui-freezing experience. These two operations are moved into a worker thread. For this, the expensive compiler calls are encapsulated in thread safe lambdas ("runners") in order to keep the "mutexed" data minimal. The original API calls of the toolchains are implemented in terms of the runners. While adapting the project managers, remove also the calls to setProjectLanguage(). These are redundant because all of the project managers already set a proper value in the constructor. Also, currently there is no need (client) to report back detection of C sources in project parts. This also keeps CppProjectUpdater simple. There is still room for improvement: * Run the compiler calls in parallel instead of sequence. * Ensure that the mime type for a file is determined exactly once. Change-Id: I2efc4e132ee88e3c8f264012ec8fafe3d86c404f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-02-06 16:59:53 +01:00
ToolChain *cToolChain
= ToolChainKitInformation::toolChain(k, ProjectExplorer::Constants::C_LANGUAGE_ID);
ToolChain *cxxToolChain
= ToolChainKitInformation::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
CppTools/ProjectManagers: Reduce ui blocking when loading projects ${AnyProject}::updateCppCodeModel() did two potentially not that cheap operations in the ui thread: (1) Querying the MimeDatabase for the mime type for the source files of the project. In 99.9% of the cases no files need to be read for this as the file extension will resolve the type. The expensiveness comes from the sheer number of files that can occur. (2) Calling compilers with the "(sub)project's compiler command line" to determine the macros. While the caches avoid redundant calls, the number of the unique compiler calls makes this still a ui-freezing experience. These two operations are moved into a worker thread. For this, the expensive compiler calls are encapsulated in thread safe lambdas ("runners") in order to keep the "mutexed" data minimal. The original API calls of the toolchains are implemented in terms of the runners. While adapting the project managers, remove also the calls to setProjectLanguage(). These are redundant because all of the project managers already set a proper value in the constructor. Also, currently there is no need (client) to report back detection of C sources in project parts. This also keeps CppProjectUpdater simple. There is still room for improvement: * Run the compiler calls in parallel instead of sequence. * Ensure that the mime type for a file is determined exactly once. Change-Id: I2efc4e132ee88e3c8f264012ec8fafe3d86c404f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-02-06 16:59:53 +01:00
m_cppCodeModelUpdater->cancel();
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
if (QtSupport::BaseQtVersion *qtVersion =
QtSupport::QtKitInformation::qtVersion(activeTarget()->kit())) {
if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
activeQtVersion = CppTools::ProjectPart::Qt4;
else
activeQtVersion = CppTools::ProjectPart::Qt5;
}
CppTools/ProjectManagers: Reduce ui blocking when loading projects ${AnyProject}::updateCppCodeModel() did two potentially not that cheap operations in the ui thread: (1) Querying the MimeDatabase for the mime type for the source files of the project. In 99.9% of the cases no files need to be read for this as the file extension will resolve the type. The expensiveness comes from the sheer number of files that can occur. (2) Calling compilers with the "(sub)project's compiler command line" to determine the macros. While the caches avoid redundant calls, the number of the unique compiler calls makes this still a ui-freezing experience. These two operations are moved into a worker thread. For this, the expensive compiler calls are encapsulated in thread safe lambdas ("runners") in order to keep the "mutexed" data minimal. The original API calls of the toolchains are implemented in terms of the runners. While adapting the project managers, remove also the calls to setProjectLanguage(). These are redundant because all of the project managers already set a proper value in the constructor. Also, currently there is no need (client) to report back detection of C sources in project parts. This also keeps CppProjectUpdater simple. There is still room for improvement: * Run the compiler calls in parallel instead of sequence. * Ensure that the mime type for a file is determined exactly once. Change-Id: I2efc4e132ee88e3c8f264012ec8fafe3d86c404f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-02-06 16:59:53 +01:00
CppTools::RawProjectPart rpp;
rpp.setDisplayName(displayName());
CppTools/ProjectManagers: Reduce ui blocking when loading projects ${AnyProject}::updateCppCodeModel() did two potentially not that cheap operations in the ui thread: (1) Querying the MimeDatabase for the mime type for the source files of the project. In 99.9% of the cases no files need to be read for this as the file extension will resolve the type. The expensiveness comes from the sheer number of files that can occur. (2) Calling compilers with the "(sub)project's compiler command line" to determine the macros. While the caches avoid redundant calls, the number of the unique compiler calls makes this still a ui-freezing experience. These two operations are moved into a worker thread. For this, the expensive compiler calls are encapsulated in thread safe lambdas ("runners") in order to keep the "mutexed" data minimal. The original API calls of the toolchains are implemented in terms of the runners. While adapting the project managers, remove also the calls to setProjectLanguage(). These are redundant because all of the project managers already set a proper value in the constructor. Also, currently there is no need (client) to report back detection of C sources in project parts. This also keeps CppProjectUpdater simple. There is still room for improvement: * Run the compiler calls in parallel instead of sequence. * Ensure that the mime type for a file is determined exactly once. Change-Id: I2efc4e132ee88e3c8f264012ec8fafe3d86c404f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-02-06 16:59:53 +01:00
rpp.setProjectFile(projectFilePath().toString());
rpp.setQtVersion(activeQtVersion);
rpp.setIncludePaths(projectIncludePaths());
rpp.setConfigFileName(configFileName());
rpp.setFiles(files());
CppTools/ProjectManagers: Reduce ui blocking when loading projects ${AnyProject}::updateCppCodeModel() did two potentially not that cheap operations in the ui thread: (1) Querying the MimeDatabase for the mime type for the source files of the project. In 99.9% of the cases no files need to be read for this as the file extension will resolve the type. The expensiveness comes from the sheer number of files that can occur. (2) Calling compilers with the "(sub)project's compiler command line" to determine the macros. While the caches avoid redundant calls, the number of the unique compiler calls makes this still a ui-freezing experience. These two operations are moved into a worker thread. For this, the expensive compiler calls are encapsulated in thread safe lambdas ("runners") in order to keep the "mutexed" data minimal. The original API calls of the toolchains are implemented in terms of the runners. While adapting the project managers, remove also the calls to setProjectLanguage(). These are redundant because all of the project managers already set a proper value in the constructor. Also, currently there is no need (client) to report back detection of C sources in project parts. This also keeps CppProjectUpdater simple. There is still room for improvement: * Run the compiler calls in parallel instead of sequence. * Ensure that the mime type for a file is determined exactly once. Change-Id: I2efc4e132ee88e3c8f264012ec8fafe3d86c404f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
2017-02-06 16:59:53 +01:00
const CppTools::ProjectUpdateInfo projectInfoUpdate(this, cToolChain, cxxToolChain, k, {rpp});
m_cppCodeModelUpdater->update(projectInfoUpdate);
}
void GenericProject::activeTargetWasChanged()
{
if (m_activeTarget) {
disconnect(m_activeTarget, &Target::activeBuildConfigurationChanged,
this, &GenericProject::activeBuildConfigurationWasChanged);
}
m_activeTarget = activeTarget();
if (!m_activeTarget)
return;
connect(m_activeTarget, &Target::activeBuildConfigurationChanged,
this, &GenericProject::activeBuildConfigurationWasChanged);
refresh(Everything);
}
void GenericProject::activeBuildConfigurationWasChanged()
{
refresh(Everything);
}
2009-03-13 15:12:54 +01:00
QStringList GenericProject::projectIncludePaths() const
2011-04-12 08:20:54 +02:00
{
return m_projectIncludePaths;
}
2009-03-13 15:12:54 +01:00
2009-03-12 15:07:54 +01:00
QStringList GenericProject::files() const
2011-04-12 08:20:54 +02:00
{
return m_files;
}
2009-03-12 15:07:54 +01:00
QString GenericProject::displayName() const
2009-03-10 14:20:07 +01:00
{
return m_projectName;
2009-03-10 14:20:07 +01:00
}
QStringList GenericProject::files(FilesMode fileMode) const
{
Q_UNUSED(fileMode);
return m_files;
2009-03-10 14:20:07 +01:00
}
QStringList GenericProject::buildTargets() const
2009-03-10 14:20:07 +01:00
{
const QStringList targets = { "all", "clean" };
2009-03-10 14:20:07 +01:00
return targets;
}
Project::RestoreResult GenericProject::fromMap(const QVariantMap &map, QString *errorMessage)
{
const RestoreResult result = Project::fromMap(map, errorMessage);
if (result != RestoreResult::Ok)
return result;
2009-03-10 14:20:07 +01:00
Kit *defaultKit = KitManager::defaultKit();
if (!activeTarget() && defaultKit)
addTarget(createTarget(defaultKit));
// Sanity check: We need both a buildconfiguration and a runconfiguration!
const QList<Target *> targetList = targets();
if (targetList.isEmpty())
return RestoreResult::Error;
for (Target *t : targetList) {
if (!t->activeBuildConfiguration()) {
removeTarget(t);
continue;
}
if (!t->activeRunConfiguration())
t->addRunConfiguration(new CustomExecutableRunConfiguration(t));
}
m_activeTarget = activeTarget();
if (m_activeTarget) {
connect(m_activeTarget, &Target::activeBuildConfigurationChanged,
this, &GenericProject::activeBuildConfigurationWasChanged);
}
connect(this, &Project::activeTargetChanged,
this, &GenericProject::activeTargetWasChanged);
refresh(Everything);
return RestoreResult::Ok;
}
2009-03-10 14:20:07 +01:00
////////////////////////////////////////////////////////////////////////////////////
//
2009-03-10 14:20:07 +01:00
// GenericProjectFile
//
2009-03-10 14:20:07 +01:00
////////////////////////////////////////////////////////////////////////////////////
GenericProjectFile::GenericProjectFile(GenericProject *parent, QString fileName,
GenericProject::RefreshOptions options) :
m_project(parent),
m_options(options)
2009-03-10 14:20:07 +01:00
{
setId("Generic.ProjectFile");
setMimeType(Constants::GENERICMIMETYPE);
setFilePath(Utils::FileName::fromString(fileName));
2009-03-10 14:20:07 +01:00
}
IDocument::ReloadBehavior GenericProjectFile::reloadBehavior(ChangeTrigger state, ChangeType type) const
2009-03-10 14:20:07 +01:00
{
Q_UNUSED(state);
Q_UNUSED(type);
return BehaviorSilent;
}
bool GenericProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType type)
{
Q_UNUSED(errorString);
Q_UNUSED(flag);
if (type == TypePermissions)
return true;
m_project->refresh(m_options);
return true;
2009-03-10 14:20:07 +01:00
}
} // namespace Internal
} // namespace GenericProjectManager