2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02: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
|
2016-01-15 14:57:40 +01:00
|
|
|
** 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.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +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
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2008-12-02 16:19:05 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "project.h"
|
2008-12-02 16:19:05 +01:00
|
|
|
|
2013-07-22 15:53:57 +02:00
|
|
|
#include "buildinfo.h"
|
2012-04-24 15:49:09 +02:00
|
|
|
#include "buildconfiguration.h"
|
2015-11-16 16:52:36 +01:00
|
|
|
#include "deployconfiguration.h"
|
2010-02-08 15:50:06 +01:00
|
|
|
#include "editorconfiguration.h"
|
2015-11-16 16:52:36 +01:00
|
|
|
#include "kit.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "projectexplorer.h"
|
2016-01-08 12:49:00 +01:00
|
|
|
#include "projectnodes.h"
|
2010-02-08 15:50:06 +01:00
|
|
|
#include "target.h"
|
2015-07-28 18:29:52 +02:00
|
|
|
#include "session.h"
|
2011-09-16 12:57:37 +02:00
|
|
|
#include "settingsaccessor.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-02-14 16:43:51 +01:00
|
|
|
#include <coreplugin/idocument.h>
|
2017-03-29 11:11:49 +02:00
|
|
|
#include <coreplugin/documentmanager.h>
|
2011-04-12 12:17:19 +02:00
|
|
|
#include <coreplugin/icontext.h>
|
2014-02-25 18:10:42 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2017-03-17 12:26:00 +01:00
|
|
|
#include <coreplugin/iversioncontrol.h>
|
|
|
|
|
#include <coreplugin/vcsmanager.h>
|
|
|
|
|
|
2011-10-24 13:10:38 +00:00
|
|
|
#include <projectexplorer/buildmanager.h>
|
2012-09-03 18:31:44 +02:00
|
|
|
#include <projectexplorer/kitmanager.h>
|
2017-03-10 10:20:53 +01:00
|
|
|
#include <projectexplorer/projecttree.h>
|
2014-11-15 20:16:53 +01:00
|
|
|
|
2014-06-06 13:12:47 +02:00
|
|
|
#include <utils/algorithm.h>
|
2014-11-15 20:16:53 +01:00
|
|
|
#include <utils/macroexpander.h>
|
|
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
|
|
|
|
#include <limits>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
|
|
|
|
\class ProjectExplorer::Project
|
|
|
|
|
|
2013-06-05 14:29:24 +02:00
|
|
|
\brief The Project class implements a project node in the project explorer.
|
2011-04-14 12:58:14 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\fn void ProjectExplorer::Project::environmentChanged()
|
|
|
|
|
|
2013-09-10 17:16:10 +02:00
|
|
|
A convenience signal emitted if activeBuildConfiguration emits
|
|
|
|
|
environmentChanged or if the active build configuration changes
|
|
|
|
|
(including due to the active target changing).
|
2011-04-14 12:58:14 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\fn void ProjectExplorer::Project::buildConfigurationEnabledChanged()
|
|
|
|
|
|
2013-09-10 17:16:10 +02:00
|
|
|
A convenience signal emitted if activeBuildConfiguration emits
|
|
|
|
|
isEnabledChanged() or if the active build configuration changes
|
|
|
|
|
(including due to the active target changing).
|
2011-04-14 12:58:14 +02:00
|
|
|
*/
|
|
|
|
|
|
2010-01-14 19:08:43 +01:00
|
|
|
namespace {
|
2012-06-28 17:17:43 +02:00
|
|
|
const char ACTIVE_TARGET_KEY[] = "ProjectExplorer.Project.ActiveTarget";
|
|
|
|
|
const char TARGET_KEY_PREFIX[] = "ProjectExplorer.Project.Target.";
|
|
|
|
|
const char TARGET_COUNT_KEY[] = "ProjectExplorer.Project.TargetCount";
|
|
|
|
|
const char EDITOR_SETTINGS_KEY[] = "ProjectExplorer.Project.EditorSettings";
|
|
|
|
|
const char PLUGIN_SETTINGS_KEY[] = "ProjectExplorer.Project.PluginSettings";
|
2010-01-14 19:08:43 +01:00
|
|
|
} // namespace
|
|
|
|
|
|
2010-09-21 09:17:37 +02:00
|
|
|
namespace ProjectExplorer {
|
2017-03-17 12:26:00 +01:00
|
|
|
|
2017-03-29 11:11:49 +02:00
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
// ProjectDocument:
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ProjectDocument::ProjectDocument(const QString &mimeType, const Utils::FileName &fileName,
|
|
|
|
|
const ProjectDocument::ProjectCallback &callback) :
|
|
|
|
|
m_callback(callback)
|
|
|
|
|
{
|
|
|
|
|
setFilePath(fileName);
|
|
|
|
|
setMimeType(mimeType);
|
|
|
|
|
if (m_callback)
|
|
|
|
|
Core::DocumentManager::addDocument(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Core::IDocument::ReloadBehavior
|
|
|
|
|
ProjectDocument::reloadBehavior(Core::IDocument::ChangeTrigger state,
|
|
|
|
|
Core::IDocument::ChangeType type) const
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(state);
|
|
|
|
|
Q_UNUSED(type);
|
|
|
|
|
return BehaviorSilent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag flag,
|
|
|
|
|
Core::IDocument::ChangeType type)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(errorString);
|
|
|
|
|
Q_UNUSED(flag);
|
|
|
|
|
Q_UNUSED(type);
|
|
|
|
|
|
|
|
|
|
if (m_callback)
|
|
|
|
|
m_callback();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-14 19:08:43 +01:00
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
// Project
|
|
|
|
|
// -------------------------------------------------------------------------
|
2011-04-12 12:17:19 +02:00
|
|
|
class ProjectPrivate
|
|
|
|
|
{
|
2010-09-21 09:17:37 +02:00
|
|
|
public:
|
2017-03-29 11:29:48 +02:00
|
|
|
ProjectPrivate(Core::IDocument *document) : m_document(document) { }
|
2012-08-17 13:18:31 +02:00
|
|
|
~ProjectPrivate();
|
|
|
|
|
|
2013-09-27 16:30:20 +02:00
|
|
|
Core::Id m_id;
|
2016-04-13 15:52:14 +02:00
|
|
|
Core::IDocument *m_document = nullptr;
|
|
|
|
|
ProjectNode *m_rootProjectNode = nullptr;
|
2017-03-29 11:29:48 +02:00
|
|
|
ContainerNode *m_containerNode = nullptr;
|
2010-09-21 09:17:37 +02:00
|
|
|
QList<Target *> m_targets;
|
2016-04-13 15:52:14 +02:00
|
|
|
Target *m_activeTarget = nullptr;
|
2014-11-06 15:49:52 +01:00
|
|
|
EditorConfiguration m_editorConfiguration;
|
2011-04-12 12:17:19 +02:00
|
|
|
Core::Context m_projectContext;
|
2012-11-21 16:18:53 +01:00
|
|
|
Core::Context m_projectLanguages;
|
2011-08-01 13:21:01 +00:00
|
|
|
QVariantMap m_pluginSettings;
|
2016-04-13 15:52:14 +02:00
|
|
|
Internal::UserFileAccessor *m_accessor = nullptr;
|
2014-07-23 09:09:20 +02:00
|
|
|
|
2017-01-11 17:25:58 +01:00
|
|
|
Kit::Predicate m_requiredKitPredicate;
|
|
|
|
|
Kit::Predicate m_preferredKitPredicate;
|
2014-11-15 20:16:53 +01:00
|
|
|
|
|
|
|
|
Utils::MacroExpander m_macroExpander;
|
2010-09-21 09:17:37 +02:00
|
|
|
};
|
|
|
|
|
|
2012-08-17 13:18:31 +02:00
|
|
|
ProjectPrivate::~ProjectPrivate()
|
2016-01-08 11:09:37 +01:00
|
|
|
{
|
2016-04-13 15:52:14 +02:00
|
|
|
// Make sure our root node is null when deleting
|
2016-01-08 12:49:00 +01:00
|
|
|
ProjectNode *oldNode = m_rootProjectNode;
|
2016-04-13 15:52:14 +02:00
|
|
|
m_rootProjectNode = nullptr;
|
2016-01-08 12:49:00 +01:00
|
|
|
delete oldNode;
|
|
|
|
|
|
2017-03-29 11:29:48 +02:00
|
|
|
delete m_containerNode;
|
|
|
|
|
|
2016-01-08 11:09:37 +01:00
|
|
|
delete m_document;
|
2016-01-08 12:49:00 +01:00
|
|
|
delete m_accessor;
|
2016-01-08 11:09:37 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2017-03-29 11:25:01 +02:00
|
|
|
Project::Project(const QString &mimeType, const Utils::FileName &fileName,
|
|
|
|
|
const ProjectDocument::ProjectCallback &callback) :
|
2017-03-29 11:29:48 +02:00
|
|
|
d(new ProjectPrivate(new ProjectDocument(mimeType, fileName, callback)))
|
2014-11-15 20:16:53 +01:00
|
|
|
{
|
|
|
|
|
d->m_macroExpander.setDisplayName(tr("Project"));
|
|
|
|
|
d->m_macroExpander.registerVariable("Project:Name", tr("Project Name"),
|
|
|
|
|
[this] { return displayName(); });
|
2017-03-29 11:29:48 +02:00
|
|
|
|
|
|
|
|
// Only set up containernode after d is set so that it will find the project directory!
|
|
|
|
|
d->m_containerNode = new ContainerNode(this);
|
2014-11-15 20:16:53 +01:00
|
|
|
}
|
2010-09-21 09:17:37 +02:00
|
|
|
|
2009-01-16 16:30:22 +01:00
|
|
|
Project::~Project()
|
|
|
|
|
{
|
2010-09-21 09:17:37 +02:00
|
|
|
qDeleteAll(d->m_targets);
|
2011-09-16 15:00:41 +02:00
|
|
|
delete d;
|
2009-01-16 16:30:22 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-27 16:30:20 +02:00
|
|
|
Core::Id Project::id() const
|
|
|
|
|
{
|
|
|
|
|
QTC_CHECK(d->m_id.isValid());
|
|
|
|
|
return d->m_id;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-08 11:09:37 +01:00
|
|
|
Core::IDocument *Project::document() const
|
|
|
|
|
{
|
|
|
|
|
QTC_CHECK(d->m_document);
|
|
|
|
|
return d->m_document;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-02 12:22:58 +02:00
|
|
|
Utils::FileName Project::projectFilePath() const
|
2013-07-23 12:30:17 +02:00
|
|
|
{
|
2016-01-08 11:09:37 +01:00
|
|
|
QTC_ASSERT(document(), return Utils::FileName());
|
2014-12-21 21:54:30 +02:00
|
|
|
return document()->filePath();
|
2013-07-23 12:30:17 +02:00
|
|
|
}
|
|
|
|
|
|
2010-02-08 15:50:06 +01:00
|
|
|
bool Project::hasActiveBuildSettings() const
|
|
|
|
|
{
|
2012-04-24 15:49:09 +02:00
|
|
|
return activeTarget() && IBuildConfigurationFactory::find(activeTarget());
|
2010-02-08 15:50:06 +01:00
|
|
|
}
|
|
|
|
|
|
2010-01-14 19:08:43 +01:00
|
|
|
QString Project::makeUnique(const QString &preferredName, const QStringList &usedNames)
|
2009-10-07 13:18:26 +02:00
|
|
|
{
|
2010-01-14 19:08:43 +01:00
|
|
|
if (!usedNames.contains(preferredName))
|
|
|
|
|
return preferredName;
|
2009-10-07 13:18:26 +02:00
|
|
|
int i = 2;
|
2010-01-14 19:08:43 +01:00
|
|
|
QString tryName = preferredName + QString::number(i);
|
2009-10-07 13:18:26 +02:00
|
|
|
while (usedNames.contains(tryName))
|
2010-01-14 19:08:43 +01:00
|
|
|
tryName = preferredName + QString::number(++i);
|
2009-10-07 13:18:26 +02:00
|
|
|
return tryName;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-08 15:50:06 +01:00
|
|
|
void Project::changeEnvironment()
|
|
|
|
|
{
|
2016-04-13 15:52:14 +02:00
|
|
|
auto t = qobject_cast<Target *>(sender());
|
2010-02-08 15:50:06 +01:00
|
|
|
if (t == activeTarget())
|
|
|
|
|
emit environmentChanged();
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-19 15:46:01 +01:00
|
|
|
void Project::changeBuildConfigurationEnabled()
|
|
|
|
|
{
|
2016-04-13 15:52:14 +02:00
|
|
|
auto t = qobject_cast<Target *>(sender());
|
2011-01-19 15:46:01 +01:00
|
|
|
if (t == activeTarget())
|
|
|
|
|
emit buildConfigurationEnabledChanged();
|
|
|
|
|
}
|
2010-02-08 15:50:06 +01:00
|
|
|
|
|
|
|
|
void Project::addTarget(Target *t)
|
|
|
|
|
{
|
2010-09-21 09:17:37 +02:00
|
|
|
QTC_ASSERT(t && !d->m_targets.contains(t), return);
|
2012-09-03 18:31:44 +02:00
|
|
|
QTC_ASSERT(!target(t->kit()), return);
|
2010-02-08 15:50:06 +01:00
|
|
|
Q_ASSERT(t->project() == this);
|
2010-01-15 10:54:29 +01:00
|
|
|
|
2012-09-25 11:11:02 +02:00
|
|
|
t->setDefaultDisplayName(t->displayName());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-09-24 16:02:02 +02:00
|
|
|
// add it
|
2010-09-21 09:17:37 +02:00
|
|
|
d->m_targets.push_back(t);
|
2016-01-07 17:33:21 +01:00
|
|
|
connect(t, &Target::environmentChanged, this, &Project::changeEnvironment);
|
|
|
|
|
connect(t, &Target::buildConfigurationEnabledChanged,
|
|
|
|
|
this, &Project::changeBuildConfigurationEnabled);
|
|
|
|
|
connect(t, &Target::buildDirectoryChanged, this, &Project::onBuildDirectoryChanged);
|
2010-02-08 15:50:06 +01:00
|
|
|
emit addedTarget(t);
|
|
|
|
|
|
|
|
|
|
// check activeTarget:
|
2016-04-13 15:52:14 +02:00
|
|
|
if (!activeTarget())
|
2010-02-08 15:50:06 +01:00
|
|
|
setActiveTarget(t);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-10-24 13:10:38 +00:00
|
|
|
bool Project::removeTarget(Target *target)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2016-02-02 12:43:57 +01:00
|
|
|
QTC_ASSERT(target && d->m_targets.contains(target), return false);
|
2011-10-24 13:10:38 +00:00
|
|
|
|
2013-09-05 14:36:20 +02:00
|
|
|
if (BuildManager::isBuilding(target))
|
2011-10-24 13:10:38 +00:00
|
|
|
return false;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-02-08 15:50:06 +01:00
|
|
|
if (target == activeTarget()) {
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (d->m_targets.size() == 1)
|
2016-04-13 15:52:14 +02:00
|
|
|
SessionManager::setActiveTarget(this, nullptr, SetActive::Cascade);
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
else if (d->m_targets.first() == target)
|
2015-07-28 18:29:52 +02:00
|
|
|
SessionManager::setActiveTarget(this, d->m_targets.at(1), SetActive::Cascade);
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
else
|
2015-07-28 18:29:52 +02:00
|
|
|
SessionManager::setActiveTarget(this, d->m_targets.at(0), SetActive::Cascade);
|
2010-02-08 15:50:06 +01:00
|
|
|
}
|
2011-12-06 15:13:50 +01:00
|
|
|
|
|
|
|
|
emit aboutToRemoveTarget(target);
|
|
|
|
|
d->m_targets.removeOne(target);
|
|
|
|
|
emit removedTarget(target);
|
|
|
|
|
|
2010-02-08 15:50:06 +01:00
|
|
|
delete target;
|
2011-11-03 14:13:23 +01:00
|
|
|
return true;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-02-08 15:50:06 +01:00
|
|
|
QList<Target *> Project::targets() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-09-21 09:17:37 +02:00
|
|
|
return d->m_targets;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-02-08 15:50:06 +01:00
|
|
|
Target *Project::activeTarget() const
|
2010-01-19 16:33:44 +01:00
|
|
|
{
|
2010-09-21 09:17:37 +02:00
|
|
|
return d->m_activeTarget;
|
2010-01-19 16:33:44 +01:00
|
|
|
}
|
|
|
|
|
|
2010-02-08 15:50:06 +01:00
|
|
|
void Project::setActiveTarget(Target *target)
|
2010-01-19 16:33:44 +01:00
|
|
|
{
|
2010-09-21 09:17:37 +02:00
|
|
|
if ((!target && !d->m_targets.isEmpty()) ||
|
|
|
|
|
(target && d->m_targets.contains(target) && d->m_activeTarget != target)) {
|
|
|
|
|
d->m_activeTarget = target;
|
|
|
|
|
emit activeTargetChanged(d->m_activeTarget);
|
2010-02-08 15:50:06 +01:00
|
|
|
emit environmentChanged();
|
2011-01-19 15:46:01 +01:00
|
|
|
emit buildConfigurationEnabledChanged();
|
2010-02-08 15:50:06 +01:00
|
|
|
}
|
2010-01-19 16:33:44 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-01 11:08:26 +02:00
|
|
|
Target *Project::target(Core::Id id) const
|
2009-05-06 16:33:43 +02:00
|
|
|
{
|
2014-07-10 12:57:06 +02:00
|
|
|
return Utils::findOrDefault(d->m_targets, Utils::equal(&Target::id, id));
|
2009-05-06 16:33:43 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-03 18:31:44 +02:00
|
|
|
Target *Project::target(Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2014-07-10 12:57:06 +02:00
|
|
|
return Utils::findOrDefault(d->m_targets, Utils::equal(&Target::kit, k));
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2012-09-20 11:16:47 +02:00
|
|
|
bool Project::supportsKit(Kit *k, QString *errorMessage) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2012-09-03 18:31:44 +02:00
|
|
|
Q_UNUSED(k);
|
2012-09-20 11:16:47 +02:00
|
|
|
Q_UNUSED(errorMessage);
|
2012-04-24 15:49:09 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-03 18:31:44 +02:00
|
|
|
Target *Project::createTarget(Kit *k)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2012-09-03 18:31:44 +02:00
|
|
|
if (!k || target(k))
|
2016-04-13 15:52:14 +02:00
|
|
|
return nullptr;
|
2012-04-24 15:49:09 +02:00
|
|
|
|
2016-04-13 15:52:14 +02:00
|
|
|
auto t = new Target(this, k);
|
2012-10-02 17:46:19 +02:00
|
|
|
if (!setupTarget(t)) {
|
|
|
|
|
delete t;
|
2016-04-13 15:52:14 +02:00
|
|
|
return nullptr;
|
2012-10-02 17:46:19 +02:00
|
|
|
}
|
2012-04-24 15:49:09 +02:00
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-22 15:53:01 +02:00
|
|
|
bool Project::copySteps(Target *sourceTarget, Target *newTarget)
|
2015-11-16 16:52:36 +01:00
|
|
|
{
|
2017-01-19 10:22:38 +01:00
|
|
|
QTC_ASSERT(newTarget, return false);
|
2016-07-22 15:53:01 +02:00
|
|
|
bool fatalError = false;
|
2015-11-16 16:52:36 +01:00
|
|
|
QStringList buildconfigurationError;
|
|
|
|
|
QStringList deployconfigurationError;
|
|
|
|
|
QStringList runconfigurationError;
|
|
|
|
|
|
|
|
|
|
foreach (BuildConfiguration *sourceBc, sourceTarget->buildConfigurations()) {
|
|
|
|
|
IBuildConfigurationFactory *factory = IBuildConfigurationFactory::find(newTarget, sourceBc);
|
|
|
|
|
if (!factory) {
|
|
|
|
|
buildconfigurationError << sourceBc->displayName();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
BuildConfiguration *newBc = factory->clone(newTarget, sourceBc);
|
|
|
|
|
if (!newBc) {
|
|
|
|
|
buildconfigurationError << sourceBc->displayName();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
newBc->setDisplayName(sourceBc->displayName());
|
|
|
|
|
newTarget->addBuildConfiguration(newBc);
|
|
|
|
|
if (sourceTarget->activeBuildConfiguration() == sourceBc)
|
|
|
|
|
SessionManager::setActiveBuildConfiguration(newTarget, newBc, SetActive::NoCascade);
|
|
|
|
|
}
|
|
|
|
|
if (!newTarget->activeBuildConfiguration()) {
|
|
|
|
|
QList<BuildConfiguration *> bcs = newTarget->buildConfigurations();
|
|
|
|
|
if (!bcs.isEmpty())
|
|
|
|
|
SessionManager::setActiveBuildConfiguration(newTarget, bcs.first(), SetActive::NoCascade);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (DeployConfiguration *sourceDc, sourceTarget->deployConfigurations()) {
|
|
|
|
|
DeployConfigurationFactory *factory = DeployConfigurationFactory::find(newTarget, sourceDc);
|
|
|
|
|
if (!factory) {
|
|
|
|
|
deployconfigurationError << sourceDc->displayName();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
DeployConfiguration *newDc = factory->clone(newTarget, sourceDc);
|
|
|
|
|
if (!newDc) {
|
|
|
|
|
deployconfigurationError << sourceDc->displayName();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
newDc->setDisplayName(sourceDc->displayName());
|
|
|
|
|
newTarget->addDeployConfiguration(newDc);
|
|
|
|
|
if (sourceTarget->activeDeployConfiguration() == sourceDc)
|
|
|
|
|
SessionManager::setActiveDeployConfiguration(newTarget, newDc, SetActive::NoCascade);
|
|
|
|
|
}
|
|
|
|
|
if (!newTarget->activeBuildConfiguration()) {
|
|
|
|
|
QList<DeployConfiguration *> dcs = newTarget->deployConfigurations();
|
|
|
|
|
if (!dcs.isEmpty())
|
|
|
|
|
SessionManager::setActiveDeployConfiguration(newTarget, dcs.first(), SetActive::NoCascade);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (RunConfiguration *sourceRc, sourceTarget->runConfigurations()) {
|
|
|
|
|
IRunConfigurationFactory *factory = IRunConfigurationFactory::find(newTarget, sourceRc);
|
|
|
|
|
if (!factory) {
|
|
|
|
|
runconfigurationError << sourceRc->displayName();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
RunConfiguration *newRc = factory->clone(newTarget, sourceRc);
|
|
|
|
|
if (!newRc) {
|
|
|
|
|
runconfigurationError << sourceRc->displayName();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
newRc->setDisplayName(sourceRc->displayName());
|
|
|
|
|
newTarget->addRunConfiguration(newRc);
|
|
|
|
|
if (sourceTarget->activeRunConfiguration() == sourceRc)
|
|
|
|
|
newTarget->setActiveRunConfiguration(newRc);
|
|
|
|
|
}
|
|
|
|
|
if (!newTarget->activeRunConfiguration()) {
|
|
|
|
|
QList<RunConfiguration *> rcs = newTarget->runConfigurations();
|
|
|
|
|
if (!rcs.isEmpty())
|
|
|
|
|
newTarget->setActiveRunConfiguration(rcs.first());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (buildconfigurationError.count() == sourceTarget->buildConfigurations().count())
|
|
|
|
|
fatalError = true;
|
|
|
|
|
|
|
|
|
|
if (deployconfigurationError.count() == sourceTarget->deployConfigurations().count())
|
|
|
|
|
fatalError = true;
|
|
|
|
|
|
|
|
|
|
if (runconfigurationError.count() == sourceTarget->runConfigurations().count())
|
|
|
|
|
fatalError = true;
|
|
|
|
|
|
|
|
|
|
if (fatalError) {
|
|
|
|
|
// That could be a more granular error message
|
|
|
|
|
QMessageBox::critical(Core::ICore::mainWindow(),
|
|
|
|
|
tr("Incompatible Kit"),
|
|
|
|
|
tr("Kit %1 is incompatible with kit %2.")
|
|
|
|
|
.arg(sourceTarget->kit()->displayName())
|
2016-07-22 15:53:01 +02:00
|
|
|
.arg(newTarget->kit()->displayName()));
|
2015-11-16 16:52:36 +01:00
|
|
|
} else if (!buildconfigurationError.isEmpty()
|
|
|
|
|
|| !deployconfigurationError.isEmpty()
|
|
|
|
|
|| ! runconfigurationError.isEmpty()) {
|
|
|
|
|
|
|
|
|
|
QString error;
|
|
|
|
|
if (!buildconfigurationError.isEmpty())
|
|
|
|
|
error += tr("Build configurations:") + QLatin1Char('\n')
|
|
|
|
|
+ buildconfigurationError.join(QLatin1Char('\n'));
|
|
|
|
|
|
|
|
|
|
if (!deployconfigurationError.isEmpty()) {
|
|
|
|
|
if (!error.isEmpty())
|
|
|
|
|
error.append(QLatin1Char('\n'));
|
|
|
|
|
error += tr("Deploy configurations:") + QLatin1Char('\n')
|
|
|
|
|
+ deployconfigurationError.join(QLatin1Char('\n'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!runconfigurationError.isEmpty()) {
|
|
|
|
|
if (!error.isEmpty())
|
|
|
|
|
error.append(QLatin1Char('\n'));
|
|
|
|
|
error += tr("Run configurations:") + QLatin1Char('\n')
|
|
|
|
|
+ runconfigurationError.join(QLatin1Char('\n'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QMessageBox msgBox(Core::ICore::mainWindow());
|
|
|
|
|
msgBox.setIcon(QMessageBox::Warning);
|
|
|
|
|
msgBox.setWindowTitle(tr("Partially Incompatible Kit"));
|
|
|
|
|
msgBox.setText(tr("Some configurations could not be copied."));
|
|
|
|
|
msgBox.setDetailedText(error);
|
|
|
|
|
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
2016-07-22 15:53:01 +02:00
|
|
|
fatalError = msgBox.exec() != QDialog::Accepted;
|
2015-11-16 16:52:36 +01:00
|
|
|
}
|
|
|
|
|
|
2016-07-22 15:53:01 +02:00
|
|
|
return !fatalError;
|
2015-11-16 16:52:36 +01:00
|
|
|
}
|
|
|
|
|
|
2012-10-02 17:46:19 +02:00
|
|
|
bool Project::setupTarget(Target *t)
|
|
|
|
|
{
|
|
|
|
|
t->updateDefaultBuildConfigurations();
|
|
|
|
|
t->updateDefaultDeployConfigurations();
|
|
|
|
|
t->updateDefaultRunConfigurations();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-27 16:30:20 +02:00
|
|
|
void Project::setId(Core::Id id)
|
|
|
|
|
{
|
|
|
|
|
d->m_id = id;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-08 12:49:00 +01:00
|
|
|
void Project::setRootProjectNode(ProjectNode *root)
|
|
|
|
|
{
|
2017-03-03 14:40:02 +01:00
|
|
|
if (d->m_rootProjectNode == root)
|
2017-03-03 14:14:09 +01:00
|
|
|
return;
|
|
|
|
|
|
2017-03-24 11:06:26 +01:00
|
|
|
if (root && root->nodes().isEmpty()) {
|
|
|
|
|
// Something went wrong with parsing: At least the project file needs to be
|
|
|
|
|
// shown so that the user can fix the breakage.
|
|
|
|
|
// Do not leak root and use default project tree in this case.
|
|
|
|
|
delete root;
|
|
|
|
|
root = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-10 10:20:53 +01:00
|
|
|
ProjectTree::applyTreeManager(root);
|
|
|
|
|
|
2017-03-21 14:42:24 +01:00
|
|
|
ProjectNode *oldNode = d->m_rootProjectNode;
|
2016-01-08 12:49:00 +01:00
|
|
|
d->m_rootProjectNode = root;
|
2017-04-04 14:36:03 +02:00
|
|
|
if (root) {
|
2017-03-29 11:29:48 +02:00
|
|
|
root->setParentFolderNode(d->m_containerNode);
|
2017-04-04 14:36:03 +02:00
|
|
|
// Only announce non-null root, null is only used when project is destroyed.
|
|
|
|
|
// In that case SessionManager::projectRemoved() triggers the update.
|
|
|
|
|
ProjectTree::emitSubtreeChanged(root);
|
|
|
|
|
emit fileListChanged();
|
|
|
|
|
}
|
2017-03-17 12:26:00 +01:00
|
|
|
|
2017-03-21 14:42:24 +01:00
|
|
|
delete oldNode;
|
2016-01-08 12:49:00 +01:00
|
|
|
}
|
|
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
Target *Project::restoreTarget(const QVariantMap &data)
|
|
|
|
|
{
|
|
|
|
|
Core::Id id = idFromMap(data);
|
|
|
|
|
if (target(id)) {
|
|
|
|
|
qWarning("Warning: Duplicated target id found, not restoring second target with id '%s'. Continuing.",
|
|
|
|
|
qPrintable(id.toString()));
|
2016-04-13 15:52:14 +02:00
|
|
|
return nullptr;
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-11 17:25:58 +01:00
|
|
|
Kit *k = KitManager::kit(id);
|
2012-09-03 18:31:44 +02:00
|
|
|
if (!k) {
|
2012-09-27 22:30:29 +02:00
|
|
|
qWarning("Warning: No kit '%s' found. Continuing.", qPrintable(id.toString()));
|
2016-04-13 15:52:14 +02:00
|
|
|
return nullptr;
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2016-04-13 15:52:14 +02:00
|
|
|
auto t = new Target(this, k);
|
2012-04-24 15:49:09 +02:00
|
|
|
if (!t->fromMap(data)) {
|
|
|
|
|
delete t;
|
2016-04-13 15:52:14 +02:00
|
|
|
return nullptr;
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
2013-08-13 10:52:57 +02:00
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void Project::saveSettings()
|
|
|
|
|
{
|
2011-08-01 13:21:01 +00:00
|
|
|
emit aboutToSaveSettings();
|
2012-08-17 13:18:31 +02:00
|
|
|
if (!d->m_accessor)
|
2014-02-25 17:49:57 +01:00
|
|
|
d->m_accessor = new Internal::UserFileAccessor(this);
|
2014-06-18 13:02:41 +02:00
|
|
|
if (!targets().isEmpty())
|
|
|
|
|
d->m_accessor->saveSettings(toMap(), Core::ICore::mainWindow());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2015-05-18 16:57:29 +02:00
|
|
|
Project::RestoreResult Project::restoreSettings(QString *errorMessage)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2012-08-17 13:18:31 +02:00
|
|
|
if (!d->m_accessor)
|
2014-02-25 17:49:57 +01:00
|
|
|
d->m_accessor = new Internal::UserFileAccessor(this);
|
2014-02-27 12:02:02 +01:00
|
|
|
QVariantMap map(d->m_accessor->restoreSettings(Core::ICore::mainWindow()));
|
2015-05-18 16:57:29 +02:00
|
|
|
RestoreResult result = fromMap(map, errorMessage);
|
|
|
|
|
if (result == RestoreResult::Ok)
|
2011-08-01 13:21:01 +00:00
|
|
|
emit settingsLoaded();
|
2015-05-18 16:57:29 +02:00
|
|
|
return result;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2017-03-27 12:12:38 +02:00
|
|
|
QStringList Project::files(Project::FilesMode fileMode,
|
|
|
|
|
const std::function<bool (const FileNode *)> &filter) const
|
|
|
|
|
{
|
|
|
|
|
QStringList result;
|
|
|
|
|
|
|
|
|
|
if (!rootProjectNode())
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
rootProjectNode()->forEachNode([&](const FileNode *fn) {
|
|
|
|
|
if (filter && !filter(fn))
|
|
|
|
|
return;
|
|
|
|
|
if ((fileMode == AllFiles)
|
|
|
|
|
|| (fileMode == SourceFiles && !fn->isGenerated())
|
|
|
|
|
|| (fileMode == GeneratedFiles && fn->isGenerated()))
|
|
|
|
|
result.append(fn->filePath().toString());
|
|
|
|
|
});
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
2013-09-10 17:16:10 +02:00
|
|
|
Serializes all data into a QVariantMap.
|
2011-04-14 12:58:14 +02:00
|
|
|
|
|
|
|
|
This map is then saved in the .user file of the project.
|
|
|
|
|
Just put all your data into the map.
|
|
|
|
|
|
2013-10-07 13:34:40 +02:00
|
|
|
\note Do not forget to call your base class' toMap function.
|
2011-04-14 12:58:14 +02:00
|
|
|
\note Do not forget to call setActiveBuildConfiguration when
|
2013-09-10 17:16:10 +02:00
|
|
|
creating new build configurations.
|
2011-04-14 12:58:14 +02:00
|
|
|
*/
|
|
|
|
|
|
2010-01-19 16:33:44 +01:00
|
|
|
QVariantMap Project::toMap() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-02-08 15:50:06 +01:00
|
|
|
const QList<Target *> ts = targets();
|
2009-11-24 15:36:31 +01:00
|
|
|
|
2010-01-19 16:33:44 +01:00
|
|
|
QVariantMap map;
|
2010-09-21 09:17:37 +02:00
|
|
|
map.insert(QLatin1String(ACTIVE_TARGET_KEY), ts.indexOf(d->m_activeTarget));
|
2010-02-08 15:50:06 +01:00
|
|
|
map.insert(QLatin1String(TARGET_COUNT_KEY), ts.size());
|
|
|
|
|
for (int i = 0; i < ts.size(); ++i)
|
|
|
|
|
map.insert(QString::fromLatin1(TARGET_KEY_PREFIX) + QString::number(i), ts.at(i)->toMap());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2014-11-06 15:49:52 +01:00
|
|
|
map.insert(QLatin1String(EDITOR_SETTINGS_KEY), d->m_editorConfiguration.toMap());
|
2011-08-01 13:21:01 +00:00
|
|
|
map.insert(QLatin1String(PLUGIN_SETTINGS_KEY), d->m_pluginSettings);
|
2010-01-19 16:33:44 +01:00
|
|
|
|
|
|
|
|
return map;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-02-24 11:38:11 +01:00
|
|
|
/*!
|
|
|
|
|
Returns the directory that contains the project.
|
|
|
|
|
|
|
|
|
|
This includes the absolute path.
|
|
|
|
|
*/
|
|
|
|
|
|
2014-05-02 12:53:36 +02:00
|
|
|
Utils::FileName Project::projectDirectory() const
|
2010-03-25 13:19:27 +01:00
|
|
|
{
|
2014-05-02 12:53:36 +02:00
|
|
|
return projectDirectory(projectFilePath());
|
2010-06-08 14:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
2016-02-24 11:38:11 +01:00
|
|
|
/*!
|
|
|
|
|
Returns the directory that contains the file \a top.
|
|
|
|
|
|
|
|
|
|
This includes the absolute path.
|
|
|
|
|
*/
|
|
|
|
|
|
2014-05-02 12:53:36 +02:00
|
|
|
Utils::FileName Project::projectDirectory(const Utils::FileName &top)
|
2010-06-08 14:19:05 +02:00
|
|
|
{
|
2012-09-03 18:31:44 +02:00
|
|
|
if (top.isEmpty())
|
2014-05-02 12:53:36 +02:00
|
|
|
return Utils::FileName();
|
|
|
|
|
return Utils::FileName::fromString(top.toFileInfo().absoluteDir().path());
|
2010-03-25 13:19:27 +01:00
|
|
|
}
|
|
|
|
|
|
2016-01-08 12:49:00 +01:00
|
|
|
ProjectNode *Project::rootProjectNode() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_rootProjectNode;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-27 17:51:19 +02:00
|
|
|
ContainerNode *Project::containerNode() const
|
2017-03-17 12:26:00 +01:00
|
|
|
{
|
2017-03-29 11:29:48 +02:00
|
|
|
return d->m_containerNode;
|
2017-03-17 12:26:00 +01:00
|
|
|
}
|
|
|
|
|
|
2015-05-18 16:57:29 +02:00
|
|
|
Project::RestoreResult Project::fromMap(const QVariantMap &map, QString *errorMessage)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2015-09-01 17:02:48 +02:00
|
|
|
Q_UNUSED(errorMessage);
|
2010-01-19 16:33:44 +01:00
|
|
|
if (map.contains(QLatin1String(EDITOR_SETTINGS_KEY))) {
|
|
|
|
|
QVariantMap values(map.value(QLatin1String(EDITOR_SETTINGS_KEY)).toMap());
|
2014-11-06 15:49:52 +01:00
|
|
|
d->m_editorConfiguration.fromMap(values);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-08-01 13:21:01 +00:00
|
|
|
if (map.contains(QLatin1String(PLUGIN_SETTINGS_KEY)))
|
|
|
|
|
d->m_pluginSettings = map.value(QLatin1String(PLUGIN_SETTINGS_KEY)).toMap();
|
|
|
|
|
|
2010-01-19 16:33:44 +01:00
|
|
|
bool ok;
|
2010-02-08 15:50:06 +01:00
|
|
|
int maxI(map.value(QLatin1String(TARGET_COUNT_KEY), 0).toInt(&ok));
|
2010-01-19 16:33:44 +01:00
|
|
|
if (!ok || maxI < 0)
|
|
|
|
|
maxI = 0;
|
2010-02-08 15:50:06 +01:00
|
|
|
int active(map.value(QLatin1String(ACTIVE_TARGET_KEY), 0).toInt(&ok));
|
2012-08-07 14:01:52 +02:00
|
|
|
if (!ok || active < 0 || active >= maxI)
|
2010-02-08 15:50:06 +01:00
|
|
|
active = 0;
|
2010-01-19 16:33:44 +01:00
|
|
|
|
|
|
|
|
for (int i = 0; i < maxI; ++i) {
|
2010-02-08 15:50:06 +01:00
|
|
|
const QString key(QString::fromLatin1(TARGET_KEY_PREFIX) + QString::number(i));
|
2015-09-01 12:57:51 +02:00
|
|
|
if (!map.contains(key))
|
2015-08-19 15:59:35 +03:00
|
|
|
continue;
|
2010-12-10 19:02:19 +01:00
|
|
|
QVariantMap targetMap = map.value(key).toMap();
|
2010-12-06 16:15:41 +01:00
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
Target *t = restoreTarget(targetMap);
|
|
|
|
|
if (!t)
|
|
|
|
|
continue;
|
2010-12-10 19:02:19 +01:00
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
addTarget(t);
|
|
|
|
|
if (i == active)
|
|
|
|
|
setActiveTarget(t);
|
2009-11-30 13:58:06 +01:00
|
|
|
}
|
2012-04-24 15:49:09 +02:00
|
|
|
|
2015-05-18 16:57:29 +02:00
|
|
|
return RestoreResult::Ok;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EditorConfiguration *Project::editorConfiguration() const
|
|
|
|
|
{
|
2014-11-06 15:49:52 +01:00
|
|
|
return &d->m_editorConfiguration;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-01-15 16:12:54 +01:00
|
|
|
QStringList Project::filesGeneratedFrom(const QString &file) const
|
2009-12-03 16:23:15 +01:00
|
|
|
{
|
2016-01-15 16:12:54 +01:00
|
|
|
Q_UNUSED(file);
|
|
|
|
|
return QStringList();
|
2009-12-03 16:23:15 +01:00
|
|
|
}
|
2010-09-21 09:17:37 +02:00
|
|
|
|
2011-04-12 12:17:19 +02:00
|
|
|
void Project::setProjectContext(Core::Context context)
|
|
|
|
|
{
|
2013-04-09 15:30:20 +02:00
|
|
|
if (d->m_projectContext == context)
|
|
|
|
|
return;
|
2011-04-12 12:17:19 +02:00
|
|
|
d->m_projectContext = context;
|
2013-04-09 15:30:20 +02:00
|
|
|
emit projectContextUpdated();
|
2011-04-12 12:17:19 +02:00
|
|
|
}
|
|
|
|
|
|
2012-11-21 16:18:53 +01:00
|
|
|
void Project::setProjectLanguages(Core::Context language)
|
2011-04-12 12:17:19 +02:00
|
|
|
{
|
2013-04-09 15:30:20 +02:00
|
|
|
if (d->m_projectLanguages == language)
|
|
|
|
|
return;
|
2012-11-21 16:18:53 +01:00
|
|
|
d->m_projectLanguages = language;
|
2013-04-09 15:30:20 +02:00
|
|
|
emit projectLanguagesUpdated();
|
2011-04-12 12:17:19 +02:00
|
|
|
}
|
|
|
|
|
|
2013-04-10 14:45:47 +02:00
|
|
|
void Project::addProjectLanguage(Core::Id id)
|
|
|
|
|
{
|
|
|
|
|
Core::Context lang = projectLanguages();
|
|
|
|
|
int pos = lang.indexOf(id);
|
|
|
|
|
if (pos < 0)
|
|
|
|
|
lang.add(id);
|
|
|
|
|
setProjectLanguages(lang);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Project::removeProjectLanguage(Core::Id id)
|
|
|
|
|
{
|
|
|
|
|
Core::Context lang = projectLanguages();
|
|
|
|
|
int pos = lang.indexOf(id);
|
|
|
|
|
if (pos >= 0)
|
|
|
|
|
lang.removeAt(pos);
|
|
|
|
|
setProjectLanguages(lang);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Project::setProjectLanguage(Core::Id id, bool enabled)
|
|
|
|
|
{
|
|
|
|
|
if (enabled)
|
|
|
|
|
addProjectLanguage(id);
|
|
|
|
|
else
|
|
|
|
|
removeProjectLanguage(id);
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-02 10:20:43 +02:00
|
|
|
void Project::projectLoaded()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-12 12:17:19 +02:00
|
|
|
Core::Context Project::projectContext() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_projectContext;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-21 16:18:53 +01:00
|
|
|
Core::Context Project::projectLanguages() const
|
2011-04-12 12:17:19 +02:00
|
|
|
{
|
2012-11-21 16:18:53 +01:00
|
|
|
return d->m_projectLanguages;
|
2011-04-12 12:17:19 +02:00
|
|
|
}
|
|
|
|
|
|
2011-08-01 13:21:01 +00:00
|
|
|
QVariant Project::namedSettings(const QString &name) const
|
|
|
|
|
{
|
|
|
|
|
return d->m_pluginSettings.value(name);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-24 16:23:13 +02:00
|
|
|
void Project::setNamedSettings(const QString &name, const QVariant &value)
|
2011-08-01 13:21:01 +00:00
|
|
|
{
|
2012-04-24 15:49:09 +02:00
|
|
|
if (value.isNull())
|
|
|
|
|
d->m_pluginSettings.remove(name);
|
|
|
|
|
else
|
|
|
|
|
d->m_pluginSettings.insert(name, value);
|
2011-08-01 13:21:01 +00:00
|
|
|
}
|
|
|
|
|
|
2011-10-28 10:15:04 +00:00
|
|
|
bool Project::needsConfiguration() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-27 16:14:14 +01:00
|
|
|
void Project::configureAsExampleProject(const QSet<Core::Id> &platforms)
|
2012-03-06 13:14:42 +01:00
|
|
|
{
|
2012-03-12 17:16:16 +01:00
|
|
|
Q_UNUSED(platforms);
|
2012-03-06 13:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-11 12:04:30 +02:00
|
|
|
bool Project::requiresTargetPanel() const
|
2012-09-06 16:19:14 +02:00
|
|
|
{
|
2014-07-11 12:04:30 +02:00
|
|
|
return true;
|
2012-09-06 16:19:14 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-06 11:14:27 +02:00
|
|
|
bool Project::needsSpecialDeployment() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-01 16:19:55 +02:00
|
|
|
bool Project::knowsAllBuildExecutables() const
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-22 15:53:57 +02:00
|
|
|
void Project::setup(QList<const BuildInfo *> infoList)
|
|
|
|
|
{
|
|
|
|
|
QList<Target *> toRegister;
|
|
|
|
|
foreach (const BuildInfo *info, infoList) {
|
2017-01-11 17:25:58 +01:00
|
|
|
Kit *k = KitManager::kit(info->kitId);
|
2013-07-22 15:53:57 +02:00
|
|
|
if (!k)
|
|
|
|
|
continue;
|
|
|
|
|
Target *t = target(k);
|
|
|
|
|
if (!t) {
|
2014-07-10 12:57:06 +02:00
|
|
|
t = Utils::findOrDefault(toRegister, Utils::equal(&Target::kit, k));
|
2013-07-22 15:53:57 +02:00
|
|
|
}
|
|
|
|
|
if (!t) {
|
|
|
|
|
t = new Target(this, k);
|
|
|
|
|
toRegister << t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BuildConfiguration *bc = info->factory()->create(t, info);
|
|
|
|
|
if (!bc)
|
|
|
|
|
continue;
|
|
|
|
|
t->addBuildConfiguration(bc);
|
|
|
|
|
}
|
2013-08-13 10:52:57 +02:00
|
|
|
foreach (Target *t, toRegister) {
|
|
|
|
|
t->updateDefaultDeployConfigurations();
|
|
|
|
|
t->updateDefaultRunConfigurations();
|
2013-07-22 15:53:57 +02:00
|
|
|
addTarget(t);
|
2013-08-13 10:52:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-15 20:16:53 +01:00
|
|
|
Utils::MacroExpander *Project::macroExpander() const
|
|
|
|
|
{
|
|
|
|
|
return &d->m_macroExpander;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-05 08:31:16 +02:00
|
|
|
ProjectImporter *Project::projectImporter() const
|
2013-08-13 10:52:57 +02:00
|
|
|
{
|
2016-04-13 15:52:14 +02:00
|
|
|
return nullptr;
|
2013-07-22 15:53:57 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-11 17:25:58 +01:00
|
|
|
Kit::Predicate Project::requiredKitPredicate() const
|
2014-07-23 09:09:20 +02:00
|
|
|
{
|
2017-01-11 17:25:58 +01:00
|
|
|
return d->m_requiredKitPredicate;
|
2014-07-23 09:09:20 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-11 17:25:58 +01:00
|
|
|
void Project::setRequiredKitPredicate(const Kit::Predicate &predicate)
|
2014-07-23 09:09:20 +02:00
|
|
|
{
|
2017-01-11 17:25:58 +01:00
|
|
|
d->m_requiredKitPredicate = predicate;
|
2014-07-23 09:09:20 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-11 17:25:58 +01:00
|
|
|
Kit::Predicate Project::preferredKitPredicate() const
|
2014-07-23 09:09:20 +02:00
|
|
|
{
|
2017-01-11 17:25:58 +01:00
|
|
|
return d->m_preferredKitPredicate;
|
2014-07-23 09:09:20 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-11 17:25:58 +01:00
|
|
|
void Project::setPreferredKitPredicate(const Kit::Predicate &predicate)
|
2014-07-23 09:09:20 +02:00
|
|
|
{
|
2017-01-11 17:25:58 +01:00
|
|
|
d->m_preferredKitPredicate = predicate;
|
2014-07-23 09:09:20 +02:00
|
|
|
}
|
|
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
void Project::onBuildDirectoryChanged()
|
|
|
|
|
{
|
2016-04-13 15:52:14 +02:00
|
|
|
auto target = qobject_cast<Target *>(sender());
|
2012-04-24 15:49:09 +02:00
|
|
|
if (target && target == activeTarget())
|
|
|
|
|
emit buildDirectoryChanged();
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-21 09:17:37 +02:00
|
|
|
} // namespace ProjectExplorer
|