Files
qt-creator/src/plugins/projectexplorer/target.cpp

575 lines
18 KiB
C++
Raw Normal View History

/**************************************************************************
**
** This file is part of Qt Creator
**
2011-01-11 16:28:15 +01:00
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
2011-04-13 08:42:33 +02:00
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
2011-04-13 08:42:33 +02:00
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
2010-12-17 16:01:08 +01:00
** In addition, as a special exception, Nokia gives you certain additional
2011-04-13 08:42:33 +02:00
** rights. These rights are described in the Nokia Qt LGPL Exception
2010-12-17 16:01:08 +01:00
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
2011-04-13 08:42:33 +02:00
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
2010-12-17 16:01:08 +01:00
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#include "target.h"
#include "toolchain.h"
#include "buildconfiguration.h"
#include "deployconfiguration.h"
#include "project.h"
#include "projectexplorerconstants.h"
#include "runconfiguration.h"
#include "toolchainmanager.h"
#include <limits>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <utils/qtcassert.h>
#include <QtGui/QIcon>
namespace {
2011-04-21 15:01:48 +02:00
const char * const ACTIVE_BC_KEY = "ProjectExplorer.Target.ActiveBuildConfiguration";
const char * const BC_KEY_PREFIX = "ProjectExplorer.Target.BuildConfiguration.";
const char * const BC_COUNT_KEY = "ProjectExplorer.Target.BuildConfigurationCount";
2011-04-21 15:01:48 +02:00
const char * const ACTIVE_DC_KEY = "ProjectExplorer.Target.ActiveDeployConfiguration";
const char * const DC_KEY_PREFIX = "ProjectExplorer.Target.DeployConfiguration.";
const char * const DC_COUNT_KEY = "ProjectExplorer.Target.DeployConfigurationCount";
2011-04-21 15:01:48 +02:00
const char * const ACTIVE_RC_KEY = "ProjectExplorer.Target.ActiveRunConfiguration";
const char * const RC_KEY_PREFIX = "ProjectExplorer.Target.RunConfiguration.";
const char * const RC_COUNT_KEY = "ProjectExplorer.Target.RunConfigurationCount";
} // namespace
// -------------------------------------------------------------------------
// Target
// -------------------------------------------------------------------------
namespace ProjectExplorer {
2011-04-21 15:01:48 +02:00
class TargetPrivate
{
public:
TargetPrivate();
QList<DeployConfigurationFactory *> deployFactories() const;
bool m_isEnabled;
QIcon m_icon;
QIcon m_overlayIcon;
QString m_toolTip;
QList<BuildConfiguration *> m_buildConfigurations;
BuildConfiguration *m_activeBuildConfiguration;
QList<DeployConfiguration *> m_deployConfigurations;
DeployConfiguration *m_activeDeployConfiguration;
QList<RunConfiguration *> m_runConfigurations;
RunConfiguration* m_activeRunConfiguration;
};
TargetPrivate::TargetPrivate() :
m_isEnabled(true),
m_activeBuildConfiguration(0),
m_activeDeployConfiguration(0),
m_activeRunConfiguration(0)
{
}
QList<DeployConfigurationFactory *> TargetPrivate::deployFactories() const
{
return ExtensionSystem::PluginManager::instance()->getObjects<DeployConfigurationFactory>();
}
Target::Target(Project *project, const QString &id) :
ProjectConfiguration(project, id), d(new TargetPrivate)
{
}
Target::~Target()
{
qDeleteAll(d->m_buildConfigurations);
qDeleteAll(d->m_runConfigurations);
delete d;
}
void Target::changeEnvironment()
{
2011-04-21 15:01:48 +02:00
BuildConfiguration *bc = qobject_cast<BuildConfiguration *>(sender());
if (bc == activeBuildConfiguration())
emit environmentChanged();
}
void Target::changeBuildConfigurationEnabled()
{
2011-04-21 15:01:48 +02:00
BuildConfiguration *bc = qobject_cast<BuildConfiguration *>(sender());
if (bc == activeBuildConfiguration())
emit buildConfigurationEnabledChanged();
}
Project *Target::project() const
{
return static_cast<Project *>(parent());
}
void Target::addBuildConfiguration(BuildConfiguration *configuration)
{
QTC_ASSERT(configuration && !d->m_buildConfigurations.contains(configuration), return);
Q_ASSERT(configuration->target() == this);
if (!buildConfigurationFactory())
return;
// Check that we don't have a configuration with the same displayName
QString configurationDisplayName = configuration->displayName();
QStringList displayNames;
foreach (const BuildConfiguration *bc, d->m_buildConfigurations)
displayNames << bc->displayName();
configurationDisplayName = Project::makeUnique(configurationDisplayName, displayNames);
if (configurationDisplayName != configuration->displayName()) {
if (configuration->usesDefaultDisplayName()) {
configuration->setDefaultDisplayName(configurationDisplayName);
} else {
configuration->setDisplayName(configurationDisplayName);
}
}
// Make sure we have a sane tool chain if at all possible
if (!configuration->toolChain()
|| !possibleToolChains(configuration).contains(configuration->toolChain()))
configuration->setToolChain(preferredToolChain(configuration));
// add it
d->m_buildConfigurations.push_back(configuration);
emit addedBuildConfiguration(configuration);
connect(configuration, SIGNAL(environmentChanged()),
SLOT(changeEnvironment()));
connect(configuration, SIGNAL(enabledChanged()),
this, SLOT(changeBuildConfigurationEnabled()));
if (!activeBuildConfiguration())
setActiveBuildConfiguration(configuration);
}
bool Target::removeBuildConfiguration(BuildConfiguration *configuration)
{
//todo: this might be error prone
if (!d->m_buildConfigurations.contains(configuration))
return false;
ProjectExplorer::BuildManager *bm =
ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager();
if (bm->isBuilding(configuration))
return false;
d->m_buildConfigurations.removeOne(configuration);
emit removedBuildConfiguration(configuration);
if (activeBuildConfiguration() == configuration) {
if (d->m_buildConfigurations.isEmpty())
setActiveBuildConfiguration(0);
else
setActiveBuildConfiguration(d->m_buildConfigurations.at(0));
}
delete configuration;
return true;
}
QList<BuildConfiguration *> Target::buildConfigurations() const
{
return d->m_buildConfigurations;
}
BuildConfiguration *Target::activeBuildConfiguration() const
{
return d->m_activeBuildConfiguration;
}
void Target::setActiveBuildConfiguration(BuildConfiguration *configuration)
{
if ((!configuration && d->m_buildConfigurations.isEmpty()) ||
(configuration && d->m_buildConfigurations.contains(configuration) &&
configuration != d->m_activeBuildConfiguration)) {
d->m_activeBuildConfiguration = configuration;
emit activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
emit environmentChanged();
emit buildConfigurationEnabledChanged();
}
}
void Target::addDeployConfiguration(DeployConfiguration *dc)
{
QTC_ASSERT(dc && !d->m_deployConfigurations.contains(dc), return);
Q_ASSERT(dc->target() == this);
if (d->deployFactories().isEmpty())
return;
// Check that we don't have a configuration with the same displayName
QString configurationDisplayName = dc->displayName();
QStringList displayNames;
foreach (const DeployConfiguration *current, d->m_deployConfigurations)
displayNames << current->displayName();
configurationDisplayName = Project::makeUnique(configurationDisplayName, displayNames);
dc->setDisplayName(configurationDisplayName);
// add it
d->m_deployConfigurations.push_back(dc);
emit addedDeployConfiguration(dc);
if (!d->m_activeDeployConfiguration)
setActiveDeployConfiguration(dc);
Q_ASSERT(activeDeployConfiguration());
}
bool Target::removeDeployConfiguration(DeployConfiguration *dc)
{
//todo: this might be error prone
if (!d->m_deployConfigurations.contains(dc))
return false;
ProjectExplorer::BuildManager *bm =
ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager();
if (bm->isBuilding(dc))
return false;
d->m_deployConfigurations.removeOne(dc);
emit removedDeployConfiguration(dc);
if (activeDeployConfiguration() == dc) {
if (d->m_deployConfigurations.isEmpty())
setActiveDeployConfiguration(0);
else
setActiveDeployConfiguration(d->m_deployConfigurations.at(0));
}
delete dc;
return true;
}
QList<DeployConfiguration *> Target::deployConfigurations() const
{
return d->m_deployConfigurations;
}
DeployConfiguration *Target::activeDeployConfiguration() const
{
return d->m_activeDeployConfiguration;
}
void Target::setActiveDeployConfiguration(DeployConfiguration *dc)
{
if ((!dc && d->m_deployConfigurations.isEmpty()) ||
(dc && d->m_deployConfigurations.contains(dc) &&
dc != d->m_activeDeployConfiguration)) {
d->m_activeDeployConfiguration = dc;
emit activeDeployConfigurationChanged(d->m_activeDeployConfiguration);
}
}
QStringList Target::availableDeployConfigurationIds()
{
QStringList ids;
foreach (const DeployConfigurationFactory * const factory, d->deployFactories())
ids << factory->availableCreationIds(this);
return ids;
}
QString Target::displayNameForDeployConfigurationId(const QString &id)
{
foreach (const DeployConfigurationFactory * const factory, d->deployFactories()) {
if (factory->availableCreationIds(this).contains(id))
return factory->displayNameForId(id);
}
return QString();
}
DeployConfiguration *Target::createDeployConfiguration(const QString &id)
{
foreach (DeployConfigurationFactory * const factory, d->deployFactories()) {
if (factory->canCreate(this, id))
return factory->create(this, id);
}
return 0;
}
QList<RunConfiguration *> Target::runConfigurations() const
{
return d->m_runConfigurations;
}
void Target::addRunConfiguration(RunConfiguration* runConfiguration)
{
QTC_ASSERT(runConfiguration && !d->m_runConfigurations.contains(runConfiguration), return);
Q_ASSERT(runConfiguration->target() == this);
// Check that we don't have a configuration with the same displayName
QString configurationDisplayName = runConfiguration->displayName();
QStringList displayNames;
foreach (const RunConfiguration *rc, d->m_runConfigurations)
displayNames << rc->displayName();
configurationDisplayName = Project::makeUnique(configurationDisplayName, displayNames);
runConfiguration->setDisplayName(configurationDisplayName);
d->m_runConfigurations.push_back(runConfiguration);
emit addedRunConfiguration(runConfiguration);
if (!activeRunConfiguration())
setActiveRunConfiguration(runConfiguration);
}
void Target::removeRunConfiguration(RunConfiguration* runConfiguration)
{
QTC_ASSERT(runConfiguration && d->m_runConfigurations.contains(runConfiguration), return);
d->m_runConfigurations.removeOne(runConfiguration);
if (activeRunConfiguration() == runConfiguration) {
if (d->m_runConfigurations.isEmpty())
setActiveRunConfiguration(0);
else
setActiveRunConfiguration(d->m_runConfigurations.at(0));
}
emit removedRunConfiguration(runConfiguration);
delete runConfiguration;
}
RunConfiguration* Target::activeRunConfiguration() const
{
return d->m_activeRunConfiguration;
}
void Target::setActiveRunConfiguration(RunConfiguration* configuration)
{
if ((!configuration && d->m_runConfigurations.isEmpty()) ||
(configuration && d->m_runConfigurations.contains(configuration) &&
configuration != d->m_activeRunConfiguration)) {
d->m_activeRunConfiguration = configuration;
emit activeRunConfigurationChanged(d->m_activeRunConfiguration);
}
}
bool Target::isEnabled() const
{
return d->m_isEnabled;
}
QIcon Target::icon() const
{
return d->m_icon;
}
void Target::setIcon(QIcon icon)
{
d->m_icon = icon;
emit iconChanged();
}
QIcon Target::overlayIcon() const
{
return d->m_overlayIcon;
}
void Target::setOverlayIcon(QIcon icon)
{
d->m_overlayIcon = icon;
emit overlayIconChanged();
}
QString Target::toolTip() const
{
return d->m_toolTip;
}
void Target::setToolTip(const QString &text)
{
d->m_toolTip = text;
emit toolTipChanged();
}
QList<ToolChain *> Target::possibleToolChains(BuildConfiguration *) const
{
QList<ToolChain *> tcList = ToolChainManager::instance()->toolChains();
QList<ToolChain *> result;
foreach (ToolChain *tc, tcList) {
QStringList restricted = tc->restrictedToTargets();
if (restricted.isEmpty() || restricted.contains(id()))
result.append(tc);
}
return result;
}
ToolChain *Target::preferredToolChain(BuildConfiguration *bc) const
{
QList<ToolChain *> tcs = possibleToolChains(bc);
if (tcs.isEmpty())
return 0;
return tcs.at(0);
}
QVariantMap Target::toMap() const
{
const QList<BuildConfiguration *> bcs = buildConfigurations();
QVariantMap map(ProjectConfiguration::toMap());
map.insert(QLatin1String(ACTIVE_BC_KEY), bcs.indexOf(d->m_activeBuildConfiguration));
map.insert(QLatin1String(BC_COUNT_KEY), bcs.size());
for (int i = 0; i < bcs.size(); ++i)
map.insert(QString::fromLatin1(BC_KEY_PREFIX) + QString::number(i), bcs.at(i)->toMap());
const QList<DeployConfiguration *> dcs = deployConfigurations();
map.insert(QLatin1String(ACTIVE_DC_KEY), dcs.indexOf(d->m_activeDeployConfiguration));
map.insert(QLatin1String(DC_COUNT_KEY), dcs.size());
for (int i = 0; i < dcs.size(); ++i)
map.insert(QString::fromLatin1(DC_KEY_PREFIX) + QString::number(i), dcs.at(i)->toMap());
const QList<RunConfiguration *> rcs = runConfigurations();
map.insert(QLatin1String(ACTIVE_RC_KEY), rcs.indexOf(d->m_activeRunConfiguration));
map.insert(QLatin1String(RC_COUNT_KEY), rcs.size());
for (int i = 0; i < rcs.size(); ++i)
map.insert(QString::fromLatin1(RC_KEY_PREFIX) + QString::number(i), rcs.at(i)->toMap());
return map;
}
void Target::setEnabled(bool enabled)
{
if (enabled == d->m_isEnabled)
return;
d->m_isEnabled = enabled;
emit targetEnabled(d->m_isEnabled);
}
bool Target::fromMap(const QVariantMap &map)
{
if (!ProjectConfiguration::fromMap(map))
return false;
bool ok;
2011-04-21 15:01:48 +02:00
int bcCount = map.value(QLatin1String(BC_COUNT_KEY), 0).toInt(&ok);
if (!ok || bcCount < 0)
bcCount = 0;
2011-04-21 15:01:48 +02:00
int activeConfiguration = map.value(QLatin1String(ACTIVE_BC_KEY), 0).toInt(&ok);
if (!ok || activeConfiguration < 0)
activeConfiguration = 0;
if (0 > activeConfiguration || bcCount < activeConfiguration)
activeConfiguration = 0;
for (int i = 0; i < bcCount; ++i) {
2011-04-21 15:01:48 +02:00
const QString key = QString::fromLatin1(BC_KEY_PREFIX) + QString::number(i);
if (!map.contains(key))
return false;
2011-04-21 15:01:48 +02:00
BuildConfiguration *bc = buildConfigurationFactory()->restore(this, map.value(key).toMap());
if (!bc)
continue;
addBuildConfiguration(bc);
if (i == activeConfiguration)
setActiveBuildConfiguration(bc);
}
if (buildConfigurations().isEmpty() && buildConfigurationFactory())
return false;
2011-04-21 15:01:48 +02:00
int dcCount = map.value(QLatin1String(DC_COUNT_KEY), 0).toInt(&ok);
if (!ok || dcCount < 0)
dcCount = 0;
activeConfiguration = map.value(QLatin1String(ACTIVE_DC_KEY), 0).toInt(&ok);
if (!ok || activeConfiguration < 0)
activeConfiguration = 0;
if (0 > activeConfiguration || dcCount < activeConfiguration)
activeConfiguration = 0;
for (int i = 0; i < dcCount; ++i) {
2011-04-21 15:01:48 +02:00
const QString key = QString::fromLatin1(DC_KEY_PREFIX) + QString::number(i);
if (!map.contains(key))
return false;
DeployConfiguration *dc = 0;
foreach (DeployConfigurationFactory * const factory, d->deployFactories()) {
QVariantMap valueMap = map.value(key).toMap();
if (factory->canRestore(this, valueMap)) {
dc = factory->restore(this, valueMap);
break;
}
}
if (!dc)
continue;
addDeployConfiguration(dc);
if (i == activeConfiguration)
setActiveDeployConfiguration(dc);
}
2011-04-21 15:01:48 +02:00
int rcCount = map.value(QLatin1String(RC_COUNT_KEY), 0).toInt(&ok);
if (!ok || rcCount < 0)
rcCount = 0;
activeConfiguration = map.value(QLatin1String(ACTIVE_RC_KEY), 0).toInt(&ok);
if (!ok || activeConfiguration < 0)
activeConfiguration = 0;
if (0 > activeConfiguration || rcCount < activeConfiguration)
activeConfiguration = 0;
for (int i = 0; i < rcCount; ++i) {
2011-04-21 15:01:48 +02:00
const QString key = QString::fromLatin1(RC_KEY_PREFIX) + QString::number(i);
if (!map.contains(key))
return false;
2011-04-21 15:01:48 +02:00
QVariantMap valueMap = map.value(key).toMap();
IRunConfigurationFactory *factory = IRunConfigurationFactory::restoreFactory(this, valueMap);
if (!factory)
continue; // Skip RCs we do not know about.)
2011-04-21 15:01:48 +02:00
RunConfiguration *rc = factory->restore(this, valueMap);
if (!rc)
continue;
addRunConfiguration(rc);
if (i == activeConfiguration)
setActiveRunConfiguration(rc);
}
2010-02-10 14:44:58 +01:00
// Ignore missing RCs: We will just populate them using the default ones.
return true;
}
// -------------------------------------------------------------------------
// ITargetFactory
// -------------------------------------------------------------------------
ITargetFactory::ITargetFactory(QObject *parent) :
QObject(parent)
{
connect(ToolChainManager::instance(), SIGNAL(toolChainsChanged()),
this, SIGNAL(supportedTargetIdsChanged()));
}
} // namespace ProjectExplorer