summaryrefslogtreecommitdiff
path: root/src/plugins/projectexplorer
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/projectexplorer')
-rw-r--r--src/plugins/projectexplorer/abstractmsvctoolchain.cpp15
-rw-r--r--src/plugins/projectexplorer/abstractmsvctoolchain.h3
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.cpp91
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.h31
-rw-r--r--src/plugins/projectexplorer/buildenvironmentwidget.cpp9
-rw-r--r--src/plugins/projectexplorer/buildsettingspropertiespage.cpp50
-rw-r--r--src/plugins/projectexplorer/buildsteplist.cpp2
-rw-r--r--src/plugins/projectexplorer/buildstepspage.cpp38
-rw-r--r--src/plugins/projectexplorer/buildstepspage.h15
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.cpp43
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.h9
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanager.cpp12
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanager.h2
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp12
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanagermodel.h4
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp4
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.cpp94
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.h5
-rw-r--r--src/plugins/projectexplorer/gcctoolchainfactories.h2
-rw-r--r--src/plugins/projectexplorer/miniprojecttargetselector.cpp15
-rw-r--r--src/plugins/projectexplorer/miniprojecttargetselector.h2
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp169
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.h23
-rw-r--r--src/plugins/projectexplorer/profile.cpp307
-rw-r--r--src/plugins/projectexplorer/profile.h109
-rw-r--r--src/plugins/projectexplorer/profileconfigwidget.h67
-rw-r--r--src/plugins/projectexplorer/profileinformation.cpp355
-rw-r--r--src/plugins/projectexplorer/profileinformation.h224
-rw-r--r--src/plugins/projectexplorer/profileinformationconfigwidget.cpp353
-rw-r--r--src/plugins/projectexplorer/profileinformationconfigwidget.h160
-rw-r--r--src/plugins/projectexplorer/profilemanager.cpp471
-rw-r--r--src/plugins/projectexplorer/profilemanager.h171
-rw-r--r--src/plugins/projectexplorer/profilemanagerconfigwidget.cpp132
-rw-r--r--src/plugins/projectexplorer/profilemanagerconfigwidget.h78
-rw-r--r--src/plugins/projectexplorer/profilemodel.cpp521
-rw-r--r--src/plugins/projectexplorer/profilemodel.h124
-rw-r--r--src/plugins/projectexplorer/profileoptionspage.cpp253
-rw-r--r--src/plugins/projectexplorer/profileoptionspage.h104
-rw-r--r--src/plugins/projectexplorer/project.cpp138
-rw-r--r--src/plugins/projectexplorer/project.h28
-rw-r--r--src/plugins/projectexplorer/projectconfiguration.cpp2
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp30
-rw-r--r--src/plugins/projectexplorer/projectexplorer.h1
-rw-r--r--src/plugins/projectexplorer/projectexplorer.pro16
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qbs16
-rw-r--r--src/plugins/projectexplorer/projectexplorerconstants.h1
-rw-r--r--src/plugins/projectexplorer/projectwindow.cpp22
-rw-r--r--src/plugins/projectexplorer/projectwindow.h2
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp122
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h12
-rw-r--r--src/plugins/projectexplorer/runconfigurationmodel.cpp3
-rw-r--r--src/plugins/projectexplorer/runsettingspropertiespage.cpp19
-rw-r--r--src/plugins/projectexplorer/settingsaccessor.cpp334
-rw-r--r--src/plugins/projectexplorer/target.cpp354
-rw-r--r--src/plugins/projectexplorer/target.h68
-rw-r--r--src/plugins/projectexplorer/targetselector.cpp6
-rw-r--r--src/plugins/projectexplorer/targetselector.h1
-rw-r--r--src/plugins/projectexplorer/targetsettingspanel.cpp77
-rw-r--r--src/plugins/projectexplorer/targetsettingspanel.h1
-rw-r--r--src/plugins/projectexplorer/targetsettingswidget.cpp6
-rw-r--r--src/plugins/projectexplorer/targetsettingswidget.h1
-rw-r--r--src/plugins/projectexplorer/toolchain.cpp54
-rw-r--r--src/plugins/projectexplorer/toolchain.h12
-rw-r--r--src/plugins/projectexplorer/toolchainconfigwidget.cpp177
-rw-r--r--src/plugins/projectexplorer/toolchainconfigwidget.h19
-rw-r--r--src/plugins/projectexplorer/toolchainmanager.cpp31
-rw-r--r--src/plugins/projectexplorer/toolchainoptionspage.cpp83
-rw-r--r--src/plugins/projectexplorer/toolchainoptionspage.h16
-rw-r--r--src/plugins/projectexplorer/toolchainoptionspage.ui112
-rw-r--r--src/plugins/projectexplorer/wincetoolchain.cpp21
-rw-r--r--src/plugins/projectexplorer/wincetoolchain.h3
71 files changed, 4640 insertions, 1227 deletions
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
index 4bb17b044e..0017243a5a 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
@@ -132,14 +132,6 @@ QString AbstractMsvcToolChain::makeCommand() const
return QLatin1String("nmake.exe");
}
-void AbstractMsvcToolChain::setDebuggerCommand(const Utils::FileName &d)
-{
- if (m_debuggerCommand == d)
- return;
- m_debuggerCommand = d;
- toolChainUpdated();
-}
-
Utils::FileName AbstractMsvcToolChain::compilerCommand() const
{
Utils::Environment env;
@@ -147,12 +139,6 @@ Utils::FileName AbstractMsvcToolChain::compilerCommand() const
return Utils::FileName::fromString(env.searchInPath("cl.exe"));
}
-Utils::FileName AbstractMsvcToolChain::debuggerCommand() const
-{
- return m_debuggerCommand;
-}
-
-
IOutputParser *AbstractMsvcToolChain::outputParser() const
{
return new MsvcParser;
@@ -296,7 +282,6 @@ bool AbstractMsvcToolChain::operator ==(const ToolChain &other) const
const AbstractMsvcToolChain *msvcTc = static_cast<const AbstractMsvcToolChain *>(&other);
return targetAbi() == msvcTc->targetAbi()
- && m_debuggerCommand == msvcTc->m_debuggerCommand
&& m_vcvarsBat == msvcTc->m_vcvarsBat;
}
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h
index 519785880c..ef26aa401c 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.h
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h
@@ -57,10 +57,7 @@ public:
void addToEnvironment(Utils::Environment &env) const;
QString makeCommand() const;
- void setDebuggerCommand(const Utils::FileName &d);
-
Utils::FileName compilerCommand() const;
- Utils::FileName debuggerCommand() const;
IOutputParser *outputParser() const;
bool canClone() const;
diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp
index df9561db06..e97134952c 100644
--- a/src/plugins/projectexplorer/buildconfiguration.cpp
+++ b/src/plugins/projectexplorer/buildconfiguration.cpp
@@ -32,16 +32,16 @@
#include "buildconfiguration.h"
-#include "toolchain.h"
#include "buildmanager.h"
#include "buildsteplist.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
+#include "profilemanager.h"
#include "target.h"
-#include "toolchainmanager.h"
#include "project.h"
#include <coreplugin/variablemanager.h>
+#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <utils/stringutils.h>
@@ -52,7 +52,6 @@ static const char BUILD_STEP_LIST_COUNT[] = "ProjectExplorer.BuildConfiguration.
static const char BUILD_STEP_LIST_PREFIX[] = "ProjectExplorer.BuildConfiguration.BuildStepList.";
static const char CLEAR_SYSTEM_ENVIRONMENT_KEY[] = "ProjectExplorer.BuildConfiguration.ClearSystemEnvironment";
static const char USER_ENVIRONMENT_CHANGES_KEY[] = "ProjectExplorer.BuildConfiguration.UserEnvironmentChanges";
-static const char TOOLCHAIN_KEY[] = "ProjectExplorer.BuildCOnfiguration.ToolChain";
namespace ProjectExplorer {
namespace Internal {
@@ -83,7 +82,6 @@ bool BuildConfigMacroExpander::resolveMacro(const QString &name, QString *ret)
BuildConfiguration::BuildConfiguration(Target *target, const Core::Id id) :
ProjectConfiguration(target, id),
m_clearSystemEnvironment(false),
- m_toolChain(0),
m_macroExpander(0)
{
Q_ASSERT(target);
@@ -96,19 +94,14 @@ BuildConfiguration::BuildConfiguration(Target *target, const Core::Id id) :
bsl->setDefaultDisplayName(tr("Clean"));
m_stepLists.append(bsl);
- connect(ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
- this, SLOT(handleToolChainRemovals(ProjectExplorer::ToolChain*)));
- connect(ToolChainManager::instance(), SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
- this, SLOT(handleToolChainAddition(ProjectExplorer::ToolChain*)));
- connect(ToolChainManager::instance(), SIGNAL(toolChainUpdated(ProjectExplorer::ToolChain*)),
- this, SLOT(handleToolChainUpdates(ProjectExplorer::ToolChain*)));
+ connect(ProfileManager::instance(), SIGNAL(profileUpdated(ProjectExplorer::Profile*)),
+ this, SLOT(handleProfileUpdate(ProjectExplorer::Profile*)));
}
BuildConfiguration::BuildConfiguration(Target *target, BuildConfiguration *source) :
ProjectConfiguration(target, source),
m_clearSystemEnvironment(source->m_clearSystemEnvironment),
m_userEnvironmentChanges(source->m_userEnvironmentChanges),
- m_toolChain(source->m_toolChain),
m_macroExpander(0)
{
Q_ASSERT(target);
@@ -116,12 +109,8 @@ BuildConfiguration::BuildConfiguration(Target *target, BuildConfiguration *sourc
// otherwise BuildStepFactories might reject to set up a BuildStep for us
// since we are not yet the derived class!
- connect(ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
- this, SLOT(handleToolChainRemovals(ProjectExplorer::ToolChain*)));
- connect(ToolChainManager::instance(), SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
- this, SLOT(handleToolChainAddition(ProjectExplorer::ToolChain*)));
- connect(ToolChainManager::instance(), SIGNAL(toolChainUpdated(ProjectExplorer::ToolChain*)),
- this, SLOT(handleToolChainUpdates(ProjectExplorer::ToolChain*)));
+ connect(ProfileManager::instance(), SIGNAL(profileUpdated(ProjectExplorer::Profile*)),
+ this, SLOT(handleProfileUpdate(ProjectExplorer::Profile*)));
}
BuildConfiguration::~BuildConfiguration()
@@ -162,8 +151,6 @@ QVariantMap BuildConfiguration::toMap() const
for (int i = 0; i < m_stepLists.count(); ++i)
map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QString::number(i), m_stepLists.at(i)->toMap());
- map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChain ? m_toolChain->id() : QLatin1String("INVALID"));
-
return map;
}
@@ -195,10 +182,6 @@ bool BuildConfiguration::fromMap(const QVariantMap &map)
m_stepLists.append(list);
}
- const QString id = map.value(QLatin1String(TOOLCHAIN_KEY)).toString();
- setToolChain(ToolChainManager::instance()->findToolChain(id)); // Do not validate the tool chain as
- // the BC is not completely set up yet!
-
// We currently assume there to be at least a clean and build list!
QTC_CHECK(knownStepLists().contains(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)));
QTC_CHECK(knownStepLists().contains(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)));
@@ -206,52 +189,18 @@ bool BuildConfiguration::fromMap(const QVariantMap &map)
return ProjectConfiguration::fromMap(map);
}
-void BuildConfiguration::handleToolChainRemovals(ProjectExplorer::ToolChain *tc)
-{
- if (m_toolChain != tc)
- return;
- setToolChain(target()->preferredToolChain(this));
-}
-
-void BuildConfiguration::handleToolChainAddition(ProjectExplorer::ToolChain *tc)
-{
- Q_UNUSED(tc);
- if (m_toolChain != 0)
- return;
- setToolChain(target()->preferredToolChain(this));
-}
-
-void BuildConfiguration::handleToolChainUpdates(ProjectExplorer::ToolChain *tc)
+void BuildConfiguration::handleProfileUpdate(ProjectExplorer::Profile *p)
{
- if (tc != m_toolChain)
+ if (p != target()->profile())
return;
- QList<ToolChain *> candidates = target()->possibleToolChains(this);
- if (!candidates.contains(m_toolChain))
- setToolChain(target()->preferredToolChain(this));
- else
- emit toolChainChanged();
+ emit environmentChanged();
}
-
Target *BuildConfiguration::target() const
{
return static_cast<Target *>(parent());
}
-ProjectExplorer::ToolChain *BuildConfiguration::toolChain() const
-{
- return m_toolChain;
-}
-
-void BuildConfiguration::setToolChain(ProjectExplorer::ToolChain *tc)
-{
- if (m_toolChain == tc)
- return;
- m_toolChain = tc;
- emit toolChainChanged();
- emit environmentChanged();
-}
-
Utils::Environment BuildConfiguration::baseEnvironment() const
{
Utils::Environment result;
@@ -333,4 +282,26 @@ IBuildConfigurationFactory::IBuildConfigurationFactory(QObject *parent) :
IBuildConfigurationFactory::~IBuildConfigurationFactory()
{ }
+IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, const QVariantMap &map)
+{
+ QList<IBuildConfigurationFactory *> factories
+ = ExtensionSystem::PluginManager::instance()->getObjects<IBuildConfigurationFactory>();
+ foreach (IBuildConfigurationFactory *factory, factories) {
+ if (factory->canRestore(parent, map))
+ return factory;
+ }
+ return 0;
+}
+
+IBuildConfigurationFactory * IBuildConfigurationFactory::find(Target *parent)
+{
+ QList<IBuildConfigurationFactory *> factories
+ = ExtensionSystem::PluginManager::instance()->getObjects<IBuildConfigurationFactory>();
+ foreach (IBuildConfigurationFactory *factory, factories) {
+ if (!factory->availableCreationIds(parent).isEmpty())
+ return factory;
+ }
+ return 0;
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h
index e2057f4ef4..958692f900 100644
--- a/src/plugins/projectexplorer/buildconfiguration.h
+++ b/src/plugins/projectexplorer/buildconfiguration.h
@@ -47,9 +47,10 @@ class AbstractMacroExpander;
namespace ProjectExplorer {
class BuildConfiguration;
+class BuildConfigWidget;
class BuildStepList;
+class Profile;
class Target;
-class ToolChain;
class IOutputParser;
class PROJECTEXPLORER_EXPORT BuildConfiguration : public ProjectConfiguration
@@ -62,6 +63,8 @@ public:
virtual QString buildDirectory() const = 0;
+ virtual BuildConfigWidget *createConfigWidget() = 0;
+
// Maybe the BuildConfiguration is not the best place for the environment
virtual Utils::Environment baseEnvironment() const;
QString baseEnvironmentText() const;
@@ -90,9 +93,6 @@ public:
Utils::AbstractMacroExpander *macroExpander();
- virtual ProjectExplorer::ToolChain *toolChain() const;
- virtual void setToolChain(ProjectExplorer::ToolChain *tc);
-
enum BuildType {
Unknown,
Debug,
@@ -104,7 +104,10 @@ signals:
void environmentChanged();
void buildDirectoryChanged();
void enabledChanged();
- void toolChainChanged();
+ /// Emitted whenever the build system needs to be (re-) evaluated
+ void requestBuildSystemEvaluation();
+ /// Emitter whenever the build directory was successfully initialized (configured).
+ void buildDirectoryInitialized();
protected:
BuildConfiguration(Target *target, const Core::Id id);
@@ -115,15 +118,12 @@ protected:
virtual bool fromMap(const QVariantMap &map);
private slots:
- void handleToolChainRemovals(ProjectExplorer::ToolChain *tc);
- void handleToolChainAddition(ProjectExplorer::ToolChain *tc);
- void handleToolChainUpdates(ProjectExplorer::ToolChain*);
+ void handleProfileUpdate(ProjectExplorer::Profile *p);
private:
bool m_clearSystemEnvironment;
QList<Utils::EnvironmentItem> m_userEnvironmentChanges;
QList<BuildStepList *> m_stepLists;
- ToolChain *m_toolChain;
Utils::AbstractMacroExpander *m_macroExpander;
};
@@ -137,18 +137,21 @@ public:
virtual ~IBuildConfigurationFactory();
// used to show the list of possible additons to a target, returns a list of types
- virtual QList<Core::Id> availableCreationIds(Target *parent) const = 0;
+ virtual QList<Core::Id> availableCreationIds(const Target *parent) const = 0;
// used to translate the types to names to display to the user
virtual QString displayNameForId(const Core::Id id) const = 0;
- virtual bool canCreate(Target *parent, const Core::Id id) const = 0;
- virtual BuildConfiguration *create(Target *parent, const Core::Id id) = 0;
+ virtual bool canCreate(const Target *parent, const Core::Id id) const = 0;
+ virtual BuildConfiguration *create(Target *parent, const Core::Id id, const QString &name = QString()) = 0;
// used to recreate the runConfigurations when restoring settings
- virtual bool canRestore(Target *parent, const QVariantMap &map) const = 0;
+ virtual bool canRestore(const Target *parent, const QVariantMap &map) const = 0;
virtual BuildConfiguration *restore(Target *parent, const QVariantMap &map) = 0;
- virtual bool canClone(Target *parent, BuildConfiguration *product) const = 0;
+ virtual bool canClone(const Target *parent, BuildConfiguration *product) const = 0;
virtual BuildConfiguration *clone(Target *parent, BuildConfiguration *product) = 0;
+ static IBuildConfigurationFactory *find(Target *parent, const QVariantMap &map);
+ static IBuildConfigurationFactory *find(Target *parent);
+
signals:
void availableCreationIdsChanged();
};
diff --git a/src/plugins/projectexplorer/buildenvironmentwidget.cpp b/src/plugins/projectexplorer/buildenvironmentwidget.cpp
index acafb1eb38..6ce515fb6f 100644
--- a/src/plugins/projectexplorer/buildenvironmentwidget.cpp
+++ b/src/plugins/projectexplorer/buildenvironmentwidget.cpp
@@ -35,6 +35,7 @@
#include "buildconfiguration.h"
#include "environmentwidget.h"
+#include <projectexplorer/target.h>
#include <utils/qtcassert.h>
#include <QVBoxLayout>
@@ -69,17 +70,13 @@ void BuildEnvironmentWidget::init(BuildConfiguration *bc)
Q_ASSERT(bc);
if (m_buildConfiguration) {
- disconnect(m_buildConfiguration, SIGNAL(environmentChanged()),
- this, SLOT(environmentChanged()));
- disconnect(m_buildConfiguration, SIGNAL(toolChainChanged()),
+ disconnect(m_buildConfiguration->target(), SIGNAL(environmentChanged()),
this, SLOT(environmentChanged()));
}
m_buildConfiguration = bc;
- connect(m_buildConfiguration, SIGNAL(environmentChanged()),
- this, SLOT(environmentChanged()));
- connect(m_buildConfiguration, SIGNAL(toolChainChanged()),
+ connect(m_buildConfiguration->target(), SIGNAL(environmentChanged()),
this, SLOT(environmentChanged()));
m_clearSystemEnvironmentCheckBox->setChecked(!m_buildConfiguration->useSystemEnvironment());
diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
index 986f52de15..91a693a561 100644
--- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
@@ -80,7 +80,7 @@ int BuildSettingsPanelFactory::priority() const
bool BuildSettingsPanelFactory::supports(Target *target)
{
- return target->buildConfigurationFactory();
+ return IBuildConfigurationFactory::find(target);
}
PropertiesPanel *BuildSettingsPanelFactory::createPanel(Target *target)
@@ -120,7 +120,7 @@ void BuildSettingsWidget::setupUi()
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->setContentsMargins(0, 0, 0, 0);
- if (!m_target->buildConfigurationFactory()) {
+ if (!IBuildConfigurationFactory::find(m_target)) {
QLabel *noSettingsLabel = new QLabel(this);
noSettingsLabel->setText(tr("No build settings available"));
QFont f = noSettingsLabel->font();
@@ -179,9 +179,7 @@ void BuildSettingsWidget::setupUi()
connect(m_target, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
this, SLOT(updateActiveConfiguration()));
- if (m_target->buildConfigurationFactory())
- connect(m_target->buildConfigurationFactory(), SIGNAL(availableCreationIdsChanged()),
- SLOT(updateAddButtonMenu()));
+ connect(m_target, SIGNAL(profileChanged()), this, SLOT(updateAddButtonMenu()));
}
void BuildSettingsWidget::addSubWidget(BuildConfigWidget *widget)
@@ -227,12 +225,10 @@ void BuildSettingsWidget::updateAddButtonMenu()
m_addButtonMenu->addAction(tr("&Clone Selected"),
this, SLOT(cloneConfiguration()));
}
- IBuildConfigurationFactory *factory = m_target->buildConfigurationFactory();
- if (factory) {
- foreach (Core::Id id, factory->availableCreationIds(m_target)) {
- QAction *action = m_addButtonMenu->addAction(factory->displayNameForId(id), this, SLOT(createConfiguration()));
- action->setData(QVariant::fromValue(id));
- }
+ IBuildConfigurationFactory * factory = IBuildConfigurationFactory::find(m_target);
+ foreach (Core::Id id, factory->availableCreationIds(m_target)) {
+ QAction *action = m_addButtonMenu->addAction(factory->displayNameForId(id), this, SLOT(createConfiguration()));
+ action->setData(QVariant::fromValue(id));
}
}
}
@@ -245,7 +241,7 @@ void BuildSettingsWidget::updateBuildSettings()
m_removeButton->setEnabled(m_target->buildConfigurations().size() > 1);
// Add pages
- BuildConfigWidget *generalConfigWidget = m_target->createConfigWidget();
+ BuildConfigWidget *generalConfigWidget = m_buildConfiguration->createConfigWidget();
addSubWidget(generalConfigWidget);
addSubWidget(new BuildStepsPage(m_target, Core::Id(Constants::BUILDSTEPS_BUILD)));
@@ -285,16 +281,22 @@ void BuildSettingsWidget::updateActiveConfiguration()
void BuildSettingsWidget::createConfiguration()
{
- if (!m_target->buildConfigurationFactory())
- return;
-
QAction *action = qobject_cast<QAction *>(sender());
Core::Id id = action->data().value<Core::Id>();
- BuildConfiguration *bc = m_target->buildConfigurationFactory()->create(m_target, id);
- if (bc) {
- m_target->setActiveBuildConfiguration(bc);
- updateBuildSettings();
- }
+
+ IBuildConfigurationFactory *factory = IBuildConfigurationFactory::find(m_target);
+ if (!factory)
+ return;
+
+ BuildConfiguration *bc = factory->create(m_target, id);
+ if (!bc)
+ return;
+
+ m_target->addBuildConfiguration(bc);
+
+ QTC_CHECK(bc->id() == id);
+ m_target->setActiveBuildConfiguration(bc);
+ updateBuildSettings();
}
void BuildSettingsWidget::cloneConfiguration()
@@ -343,8 +345,10 @@ void BuildSettingsWidget::renameConfiguration()
void BuildSettingsWidget::cloneConfiguration(BuildConfiguration *sourceConfiguration)
{
- if (!sourceConfiguration ||
- !m_target->buildConfigurationFactory())
+ if (!sourceConfiguration)
+ return;
+ IBuildConfigurationFactory *factory = IBuildConfigurationFactory::find(m_target);
+ if (!factory)
return;
//: Title of a the cloned BuildConfiguration window, text of the window
@@ -352,7 +356,7 @@ void BuildSettingsWidget::cloneConfiguration(BuildConfiguration *sourceConfigura
if (name.isEmpty())
return;
- BuildConfiguration * bc(m_target->buildConfigurationFactory()->clone(m_target, sourceConfiguration));
+ BuildConfiguration *bc = factory->clone(m_target, sourceConfiguration);
if (!bc)
return;
diff --git a/src/plugins/projectexplorer/buildsteplist.cpp b/src/plugins/projectexplorer/buildsteplist.cpp
index 2349035d70..666e148f94 100644
--- a/src/plugins/projectexplorer/buildsteplist.cpp
+++ b/src/plugins/projectexplorer/buildsteplist.cpp
@@ -159,7 +159,7 @@ bool BuildStepList::fromMap(const QVariantMap &map)
qWarning() << "No step data found for" << i << "(continuing).";
continue;
}
- IBuildStepFactory *factory(findRestoreFactory(this, bsData));
+ IBuildStepFactory *factory = findRestoreFactory(this, bsData);
if (!factory) {
qWarning() << "No factory for step" << i << "found (continuing).";
continue;
diff --git a/src/plugins/projectexplorer/buildstepspage.cpp b/src/plugins/projectexplorer/buildstepspage.cpp
index 5c292429d9..44e9070487 100644
--- a/src/plugins/projectexplorer/buildstepspage.cpp
+++ b/src/plugins/projectexplorer/buildstepspage.cpp
@@ -65,7 +65,7 @@ ToolWidget::ToolWidget(QWidget *parent)
layout->setMargin(4);
layout->setSpacing(4);
setLayout(layout);
- m_firstWidget = new FadingWidget(this);
+ m_firstWidget = new Utils::FadingWidget(this);
m_firstWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
QHBoxLayout *hbox = new QHBoxLayout();
hbox->setContentsMargins(0, 0, 0, 0);
@@ -86,7 +86,7 @@ ToolWidget::ToolWidget(QWidget *parent)
hbox->addWidget(m_disableButton);
layout->addWidget(m_firstWidget);
- m_secondWidget = new FadingWidget(this);
+ m_secondWidget = new Utils::FadingWidget(this);
m_secondWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
hbox = new QHBoxLayout();
hbox->setMargin(0);
@@ -182,39 +182,6 @@ void ToolWidget::setDownVisible(bool b)
m_downButton->setVisible(b);
}
-FadingWidget::FadingWidget(QWidget *parent) :
- QWidget(parent),
- m_opacityEffect(new QGraphicsOpacityEffect)
-{
- m_opacityEffect->setOpacity(0);
- setGraphicsEffect(m_opacityEffect);
-
- // Workaround for issue with QGraphicsEffect. GraphicsEffect
- // currently clears with Window color. Remove if flickering
- // no longer occurs on fade-in
- QPalette pal;
- pal.setBrush(QPalette::All, QPalette::Window, Qt::transparent);
- setPalette(pal);
-}
-
-void FadingWidget::setOpacity(qreal value)
-{
- m_opacityEffect->setOpacity(value);
-}
-
-void FadingWidget::fadeTo(qreal value)
-{
- QPropertyAnimation *animation = new QPropertyAnimation(m_opacityEffect, "opacity");
- animation->setDuration(200);
- animation->setEndValue(value);
- animation->start(QAbstractAnimation::DeleteWhenStopped);
-}
-
-qreal FadingWidget::opacity()
-{
- return m_opacityEffect->opacity();
-}
-
BuildStepsWidgetData::BuildStepsWidgetData(BuildStep *s) :
step(s), widget(0), detailsWidget(0)
{
@@ -395,6 +362,7 @@ void BuildStepListWidget::triggerAddBuildStep()
if (QAction *action = qobject_cast<QAction *>(sender())) {
QPair<Core::Id, IBuildStepFactory *> pair = m_addBuildStepHash.value(action);
BuildStep *newStep = pair.second->create(m_buildStepList, pair.first);
+ QTC_ASSERT(newStep, return);
int pos = m_buildStepList->count();
m_buildStepList->insertStep(pos, newStep);
}
diff --git a/src/plugins/projectexplorer/buildstepspage.h b/src/plugins/projectexplorer/buildstepspage.h
index 32f6520379..10fe1edb08 100644
--- a/src/plugins/projectexplorer/buildstepspage.h
+++ b/src/plugins/projectexplorer/buildstepspage.h
@@ -57,17 +57,6 @@ class Target;
class BuildConfiguration;
namespace Internal {
-class FadingWidget : public QWidget
-{
- Q_OBJECT
-public:
- FadingWidget(QWidget *parent = 0);
- void fadeTo(qreal value);
- qreal opacity();
- void setOpacity(qreal value);
-protected:
- QGraphicsOpacityEffect *m_opacityEffect;
-};
class ToolWidget : public Utils::FadingPanel
{
@@ -97,8 +86,8 @@ private:
QToolButton *m_removeButton;
bool m_buildStepEnabled;
- FadingWidget *m_firstWidget;
- FadingWidget *m_secondWidget;
+ Utils::FadingWidget *m_firstWidget;
+ Utils::FadingWidget *m_secondWidget;
qreal m_targetOpacity;
};
diff --git a/src/plugins/projectexplorer/deployconfiguration.cpp b/src/plugins/projectexplorer/deployconfiguration.cpp
index f7f0469a41..f5b87e3cd5 100644
--- a/src/plugins/projectexplorer/deployconfiguration.cpp
+++ b/src/plugins/projectexplorer/deployconfiguration.cpp
@@ -35,10 +35,14 @@
#include "buildmanager.h"
#include "buildsteplist.h"
#include "buildstepspage.h"
+#include "profileinformation.h"
+#include "project.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "target.h"
+#include <extensionsystem/pluginmanager.h>
+
#include <QStringList>
using namespace ProjectExplorer;
@@ -59,7 +63,7 @@ DeployConfiguration::DeployConfiguration(Target *target, const Core::Id id) :
//: Display name of the deploy build step list. Used as part of the labels in the project window.
m_stepList->setDefaultDisplayName(tr("Deploy"));
//: Default DeployConfiguration display name
- setDefaultDisplayName(tr("No deployment"));
+ setDefaultDisplayName(tr("Deploy locally"));
}
DeployConfiguration::DeployConfiguration(Target *target, DeployConfiguration *source) :
@@ -153,14 +157,15 @@ void DeployConfiguration::cloneSteps(DeployConfiguration *source)
DeployConfigurationFactory::DeployConfigurationFactory(QObject *parent) :
QObject(parent)
-{ }
+{ setObjectName(QLatin1String("DeployConfigurationFactory")); }
DeployConfigurationFactory::~DeployConfigurationFactory()
{ }
QList<Core::Id> DeployConfigurationFactory::availableCreationIds(Target *parent) const
{
- Q_UNUSED(parent);
+ if (!canHandle(parent))
+ return QList<Core::Id>();
return QList<Core::Id>() << Core::Id(Constants::DEFAULT_DEPLOYCONFIGURATION_ID);
}
@@ -174,7 +179,8 @@ QString DeployConfigurationFactory::displayNameForId(const Core::Id id) const
bool DeployConfigurationFactory::canCreate(Target *parent, const Core::Id id) const
{
- Q_UNUSED(parent);
+ if (!canHandle(parent))
+ return false;
return id == Core::Id(Constants::DEFAULT_DEPLOYCONFIGURATION_ID);
}
@@ -214,6 +220,35 @@ DeployConfiguration *DeployConfigurationFactory::clone(Target *parent, DeployCon
return new DeployConfiguration(parent, product);
}
+DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent, const QVariantMap &map)
+{
+ QList<DeployConfigurationFactory *> factories
+ = ExtensionSystem::PluginManager::instance()->getObjects<DeployConfigurationFactory>();
+ foreach (DeployConfigurationFactory *factory, factories) {
+ if (factory->canRestore(parent, map))
+ return factory;
+ }
+ return 0;
+}
+
+DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent)
+{
+ QList<DeployConfigurationFactory *> factories
+ = ExtensionSystem::PluginManager::instance()->getObjects<DeployConfigurationFactory>();
+ foreach (DeployConfigurationFactory *factory, factories) {
+ if (!factory->availableCreationIds(parent).isEmpty())
+ return factory;
+ }
+ return 0;
+}
+
+bool DeployConfigurationFactory::canHandle(Target *parent) const
+{
+ if (!parent->project()->supportsProfile(parent->profile()))
+ return false;
+ return DeviceTypeProfileInformation::deviceTypeId(parent->profile()) == Core::Id(Constants::DESKTOP_DEVICE_TYPE);
+}
+
///
// DeployConfigurationWidget
///
diff --git a/src/plugins/projectexplorer/deployconfiguration.h b/src/plugins/projectexplorer/deployconfiguration.h
index 878578aece..af30b665db 100644
--- a/src/plugins/projectexplorer/deployconfiguration.h
+++ b/src/plugins/projectexplorer/deployconfiguration.h
@@ -70,6 +70,7 @@ public:
signals:
void enabledChanged();
+ void requestBuildSystemEvaluation();
protected:
DeployConfiguration(Target *target, const Core::Id id);
@@ -77,7 +78,7 @@ protected:
void cloneSteps(DeployConfiguration *source);
- virtual bool fromMap(const QVariantMap &map);
+ bool fromMap(const QVariantMap &map);
private:
friend class DeployConfigurationFactory;
@@ -107,8 +108,14 @@ public:
virtual bool canClone(Target *parent, DeployConfiguration *product) const;
virtual DeployConfiguration *clone(Target *parent, DeployConfiguration *product);
+ static DeployConfigurationFactory *find(Target *parent, const QVariantMap &map);
+ static DeployConfigurationFactory *find(Target *parent);
+
signals:
void availableCreationIdsChanged();
+
+private:
+ bool canHandle(Target *parent) const;
};
class PROJECTEXPLORER_EXPORT DeployConfigurationWidget : public NamedWidget
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
index 6a2086f6ab..2e41051be9 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
@@ -139,13 +139,16 @@ void DeviceManager::save()
{
Utils::PersistentSettingsWriter writer;
writer.saveValue(QLatin1String(DeviceManagerKey), toMap());
- writer.save(settingsFilePath(), QLatin1String("QtCreatorDevices"), Core::ICore::mainWindow());
+ writer.save(settingsFilePath(QLatin1String("/qtcreator/devices.xml")),
+ QLatin1String("QtCreatorDevices"), Core::ICore::mainWindow());
}
void DeviceManager::load()
{
Utils::PersistentSettingsReader reader;
- if (reader.load(settingsFilePath()))
+ if (reader.load(settingsFilePath(QLatin1String("/qtcreator/devices.xml"))))
+ fromMap(reader.restoreValues().value(QLatin1String(DeviceManagerKey)).toMap());
+ else if (reader.load(settingsFilePath(QLatin1String("/devices.xml"))))
fromMap(reader.restoreValues().value(QLatin1String(DeviceManagerKey)).toMap());
else
loadPre2_6();
@@ -220,9 +223,10 @@ QVariantMap DeviceManager::toMap() const
return map;
}
-QString DeviceManager::settingsFilePath()
+QString DeviceManager::settingsFilePath(const QString &extension)
{
- return QFileInfo(ExtensionSystem::PluginManager::settings()->fileName()).absolutePath() + QLatin1String("/devices.xml");
+ ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+ return QFileInfo(pm->settings()->fileName()).absolutePath() + extension;
}
void DeviceManager::addDevice(const IDevice::Ptr &_device)
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.h b/src/plugins/projectexplorer/devicesupport/devicemanager.h
index e9a913ef31..8dc3615816 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanager.h
+++ b/src/plugins/projectexplorer/devicesupport/devicemanager.h
@@ -101,7 +101,7 @@ private:
IDevice::Ptr fromRawPointer(IDevice *device) const;
IDevice::ConstPtr fromRawPointer(const IDevice *device) const;
- static QString settingsFilePath();
+ static QString settingsFilePath(const QString &extension);
static void copy(const DeviceManager *source, DeviceManager *target, bool deep);
Internal::DeviceManagerPrivate * const d;
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp
index 352b4d58e6..bee3fb5929 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp
@@ -46,6 +46,7 @@ class DeviceManagerModelPrivate
public:
const DeviceManager *deviceManager;
QList<IDevice::ConstPtr> devices;
+ QList<Core::Id> filter;
};
} // namespace Internal
@@ -65,6 +66,12 @@ DeviceManagerModel::~DeviceManagerModel()
delete d;
}
+void DeviceManagerModel::setFilter(const QList<Core::Id> filter)
+{
+ d->filter = filter;
+ handleDeviceListChanged();
+}
+
void DeviceManagerModel::updateDevice(Core::Id id)
{
handleDeviceUpdated(id);
@@ -87,6 +94,9 @@ Core::Id DeviceManagerModel::deviceId(int pos) const
int DeviceManagerModel::indexOf(IDevice::ConstPtr dev) const
{
+ if (dev.isNull())
+ return -1;
+
for (int i = 0; i < d->devices.count(); ++i) {
IDevice::ConstPtr current = d->devices.at(i);
if (current->id() == dev->id())
@@ -127,7 +137,7 @@ void DeviceManagerModel::handleDeviceListChanged()
for (int i = 0; i < d->deviceManager->deviceCount(); ++i) {
IDevice::ConstPtr dev = d->deviceManager->deviceAt(i);
- if (dev->id() == Core::Id(Constants::DESKTOP_DEVICE_ID))
+ if (d->filter.contains(dev->id()))
continue;
d->devices << dev;
}
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.h b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.h
index bc4eeb827d..32eaa5052d 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.h
+++ b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.h
@@ -51,7 +51,7 @@ public:
explicit DeviceManagerModel(const DeviceManager *deviceManager, QObject *parent = 0);
~DeviceManagerModel();
- void updateDevice(Core::Id id);
+ void setFilter(const QList<Core::Id> filter);
IDevice::ConstPtr device(int pos) const;
Core::Id deviceId(int pos) const;
@@ -59,6 +59,8 @@ public:
int indexForId(Core::Id id) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ void updateDevice(Core::Id id);
+
private slots:
void handleDeviceAdded(Core::Id id);
void handleDeviceRemoved(Core::Id id);
diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp
index 4df175bacc..dae2671d36 100644
--- a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp
@@ -31,12 +31,14 @@
#include "devicesettingswidget.h"
#include "ui_devicesettingswidget.h"
+#include "projectexplorerconstants.h"
#include "devicefactoryselectiondialog.h"
#include "devicemanager.h"
#include "devicemanagermodel.h"
#include "idevice.h"
#include "idevicefactory.h"
#include "idevicewidget.h"
+#include "projectexplorerconstants.h"
#include <coreplugin/icore.h>
#include <coreplugin/id.h>
@@ -94,7 +96,6 @@ private:
const DeviceManager * const m_deviceManager;
};
-
DeviceSettingsWidget::DeviceSettingsWidget(QWidget *parent)
: QWidget(parent),
m_ui(new Ui::DeviceSettingsWidget),
@@ -105,6 +106,7 @@ DeviceSettingsWidget::DeviceSettingsWidget(QWidget *parent)
m_additionalActionsMapper(new QSignalMapper(this)),
m_configWidget(0)
{
+ m_deviceManagerModel->setFilter(QList<Core::Id>() << Core::Id(Constants::DESKTOP_DEVICE_ID));
initGui();
connect(m_additionalActionsMapper, SIGNAL(mapped(int)),
SLOT(handleAdditionalActionRequest(int)));
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index a6b1d6942e..51fee9020c 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -62,7 +62,6 @@ namespace ProjectExplorer {
static const char compilerCommandKeyC[] = "ProjectExplorer.GccToolChain.Path";
static const char targetAbiKeyC[] = "ProjectExplorer.GccToolChain.TargetAbi";
static const char supportedAbisKeyC[] = "ProjectExplorer.GccToolChain.SupportedAbis";
-static const char debuggerCommandKeyC[] = "ProjectExplorer.GccToolChain.Debugger";
static QByteArray runGcc(const Utils::FileName &gcc, const QStringList &arguments, const QStringList &env)
{
@@ -325,7 +324,6 @@ GccToolChain::GccToolChain(const GccToolChain &tc) :
ToolChain(tc),
m_predefinedMacros(tc.predefinedMacros(QStringList())),
m_compilerCommand(tc.compilerCommand()),
- m_debuggerCommand(tc.debuggerCommand()),
m_targetAbi(tc.m_targetAbi),
m_supportedAbis(tc.m_supportedAbis),
m_headerPaths(tc.m_headerPaths),
@@ -341,15 +339,6 @@ QString GccToolChain::defaultDisplayName() const
ProjectExplorer::Abi::toString(m_targetAbi.wordWidth()));
}
-QString GccToolChain::legacyId() const
-{
- QString i = id();
- i = i.left(i.indexOf(QLatin1Char(':')));
- return QString::fromLatin1("%1:%2.%3.%4")
- .arg(i).arg(m_compilerCommand.toString())
- .arg(m_targetAbi.toString()).arg(m_debuggerCommand.toString());
-}
-
QString GccToolChain::type() const
{
return QLatin1String("gcc");
@@ -428,19 +417,6 @@ void GccToolChain::addToEnvironment(Utils::Environment &env) const
}
}
-void GccToolChain::setDebuggerCommand(const Utils::FileName &d)
-{
- if (m_debuggerCommand == d)
- return;
- m_debuggerCommand = d;
- toolChainUpdated();
-}
-
-Utils::FileName GccToolChain::debuggerCommand() const
-{
- return m_debuggerCommand;
-}
-
QList<Utils::FileName> GccToolChain::suggestedMkspecList() const
{
Abi abi = targetAbi();
@@ -531,7 +507,6 @@ QVariantMap GccToolChain::toMap() const
foreach (const ProjectExplorer::Abi &a, m_supportedAbis)
abiList.append(a.toString());
data.insert(QLatin1String(supportedAbisKeyC), abiList);
- data.insert(QLatin1String(debuggerCommandKeyC), m_debuggerCommand.toString());
return data;
}
@@ -550,7 +525,6 @@ bool GccToolChain::fromMap(const QVariantMap &data)
continue;
m_supportedAbis.append(abi);
}
- m_debuggerCommand = Utils::FileName::fromString(data.value(QLatin1String(debuggerCommandKeyC)).toString());
return true;
}
@@ -560,8 +534,7 @@ bool GccToolChain::operator ==(const ToolChain &other) const
return false;
const GccToolChain *gccTc = static_cast<const GccToolChain *>(&other);
- return m_compilerCommand == gccTc->m_compilerCommand && m_targetAbi == gccTc->m_targetAbi
- && m_debuggerCommand == gccTc->m_debuggerCommand;
+ return m_compilerCommand == gccTc->m_compilerCommand && m_targetAbi == gccTc->m_targetAbi;
}
ToolChainConfigWidget *GccToolChain::configurationWidget()
@@ -615,16 +588,13 @@ ToolChain *Internal::GccToolChainFactory::create()
QList<ToolChain *> Internal::GccToolChainFactory::autoDetect()
{
- QStringList debuggers;
+ QList<ToolChain *> tcs;
#ifdef Q_OS_MAC
- // Fixme Prefer lldb once it is implemented: debuggers.push_back(QLatin1String("lldb"));
-#endif
- debuggers.push_back(QLatin1String("gdb"));
- QList<ToolChain *> tcs = autoDetectToolchains(QLatin1String("g++"), debuggers, Abi::hostAbi());
-
// Old mac compilers needed to support macx-gccXY mkspecs:
- tcs.append(autoDetectToolchains(QLatin1String("g++-4.0"), debuggers, Abi::hostAbi()));
- tcs.append(autoDetectToolchains(QLatin1String("g++-4.2"), debuggers, Abi::hostAbi()));
+ tcs.append(autoDetectToolchains(QLatin1String("g++-4.0"), Abi::hostAbi()));
+ tcs.append(autoDetectToolchains(QLatin1String("g++-4.2"), Abi::hostAbi()));
+#endif
+ tcs.append(autoDetectToolchains(QLatin1String("g++"), Abi::hostAbi()));
return tcs;
}
@@ -651,7 +621,6 @@ GccToolChain *Internal::GccToolChainFactory::createToolChain(bool autoDetect)
}
QList<ToolChain *> Internal::GccToolChainFactory::autoDetectToolchains(const QString &compiler,
- const QStringList &debuggers,
const Abi &requiredAbi)
{
QList<ToolChain *> result;
@@ -669,22 +638,12 @@ QList<ToolChain *> Internal::GccToolChainFactory::autoDetectToolchains(const QSt
return result;
}
- Utils::FileName debuggerPath = ToolChainManager::instance()->defaultDebugger(requiredAbi);
- if (debuggerPath.isEmpty()) {
- foreach (const QString &debugger, debuggers) {
- debuggerPath = Utils::FileName::fromString(systemEnvironment.searchInPath(debugger));
- if (!debuggerPath.isEmpty())
- break;
- }
- }
-
foreach (const Abi &abi, abiList) {
QScopedPointer<GccToolChain> tc(createToolChain(true));
if (tc.isNull())
return result;
tc->setCompilerCommand(compilerPath);
- tc->setDebuggerCommand(debuggerPath);
tc->setTargetAbi(abi);
tc->setDisplayName(tc->defaultDisplayName()); // reset displayname
@@ -715,14 +674,12 @@ Internal::GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) :
layout->addRow(tr("&ABI:"), m_abiWidget);
m_abiWidget->setEnabled(false);
- addDebuggerCommandControls(layout, gnuVersionArgs);
- addMkspecControls(layout);
addErrorLabel(layout);
setFromToolchain();
connect(m_compilerCommand, SIGNAL(changed(QString)), this, SLOT(handleCompilerCommandChange()));
- connect(m_abiWidget, SIGNAL(abiChanged()), this, SLOT(handleAbiChange()));
+ connect(m_abiWidget, SIGNAL(abiChanged()), this, SIGNAL(dirty()));
}
void Internal::GccToolChainConfigWidget::apply()
@@ -736,9 +693,6 @@ void Internal::GccToolChainConfigWidget::apply()
tc->setCompilerCommand(m_compilerCommand->fileName());
tc->setTargetAbi(m_abiWidget->currentAbi());
tc->setDisplayName(displayName); // reset display name
- tc->setDebuggerCommand(debuggerCommand());
- tc->setMkspecList(mkspecList());
- m_autoDebuggerCommand = Utils::FileName::fromString(QLatin1String("<manually set>"));
}
void Internal::GccToolChainConfigWidget::setFromToolchain()
@@ -750,8 +704,6 @@ void Internal::GccToolChainConfigWidget::setFromToolchain()
m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi());
if (!m_isReadOnly && !m_compilerCommand->path().isEmpty())
m_abiWidget->setEnabled(true);
- setDebuggerCommand(tc->debuggerCommand());
- setMkspecList(tc->mkspecList());
blockSignals(blocked);
}
@@ -760,9 +712,7 @@ bool Internal::GccToolChainConfigWidget::isDirty() const
GccToolChain *tc = static_cast<GccToolChain *>(toolChain());
Q_ASSERT(tc);
return m_compilerCommand->fileName() != tc->compilerCommand()
- || m_abiWidget->currentAbi() != tc->targetAbi()
- || debuggerCommand() != tc->debuggerCommand()
- || mkspecList() != tc->mkspecList();
+ || m_abiWidget->currentAbi() != tc->targetAbi();
}
void Internal::GccToolChainConfigWidget::makeReadOnly()
@@ -787,16 +737,6 @@ void Internal::GccToolChainConfigWidget::handleCompilerCommandChange()
m_abiWidget->setEnabled(haveCompiler);
Abi currentAbi = m_abiWidget->currentAbi();
m_abiWidget->setAbis(abiList, abiList.contains(currentAbi) ? currentAbi : Abi());
- handleAbiChange();
-}
-
-void Internal::GccToolChainConfigWidget::handleAbiChange()
-{
- if (m_autoDebuggerCommand == debuggerCommand()) {
- ProjectExplorer::Abi abi = m_abiWidget->currentAbi();
- m_autoDebuggerCommand = ToolChainManager::instance()->defaultDebugger(abi);
- setDebuggerCommand(m_autoDebuggerCommand);
- }
emit dirty();
}
@@ -868,7 +808,7 @@ QString Internal::ClangToolChainFactory::id() const
QList<ToolChain *> Internal::ClangToolChainFactory::autoDetect()
{
Abi ha = Abi::hostAbi();
- return autoDetectToolchains(QLatin1String("clang++"), QStringList(), ha);
+ return autoDetectToolchains(QLatin1String("clang++"), ha);
}
bool Internal::ClangToolChainFactory::canCreate()
@@ -967,18 +907,8 @@ QString Internal::MingwToolChainFactory::id() const
QList<ToolChain *> Internal::MingwToolChainFactory::autoDetect()
{
- // Compatibility to pre-2.2:
- // All Mingw toolchains that exist so far are either installed by the SDK itself (in
- // which case they most likely have debuggers set up) or were created when updating
- // from a previous Qt version. Add debugger in that case.
- foreach (ToolChain *tc, ToolChainManager::instance()->toolChains()) {
- if (tc->debuggerCommand().isEmpty() && tc->id().startsWith(QLatin1String(Constants::MINGW_TOOLCHAIN_ID)))
- static_cast<MingwToolChain *>(tc)
- ->setDebuggerCommand(ToolChainManager::instance()->defaultDebugger(tc->targetAbi()));
- }
-
Abi ha = Abi::hostAbi();
- return autoDetectToolchains(QLatin1String("g++"), QStringList(),
+ return autoDetectToolchains(QLatin1String("g++"),
Abi(ha.architecture(), Abi::WindowsOS, Abi::WindowsMSysFlavor, Abi::PEFormat, ha.wordWidth()));
}
@@ -1062,9 +992,7 @@ QString Internal::LinuxIccToolChainFactory::id() const
QList<ToolChain *> Internal::LinuxIccToolChainFactory::autoDetect()
{
- return autoDetectToolchains(QLatin1String("icpc"),
- QStringList(QLatin1String("gdb")),
- Abi::hostAbi());
+ return autoDetectToolchains(QLatin1String("icpc"), Abi::hostAbi());
}
ToolChain *Internal::LinuxIccToolChainFactory::create()
diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h
index 4a77843c16..c8faf406b2 100644
--- a/src/plugins/projectexplorer/gcctoolchain.h
+++ b/src/plugins/projectexplorer/gcctoolchain.h
@@ -54,8 +54,6 @@ class LinuxIccToolChainFactory;
class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain
{
public:
- QString legacyId() const;
-
QString type() const;
QString typeDisplayName() const;
Abi targetAbi() const;
@@ -71,8 +69,6 @@ public:
QList<HeaderPath> systemHeaderPaths() const;
void addToEnvironment(Utils::Environment &env) const;
QString makeCommand() const;
- void setDebuggerCommand(const Utils::FileName &);
- Utils::FileName debuggerCommand() const;
QList<Utils::FileName> suggestedMkspecList() const;
IOutputParser *outputParser() const;
@@ -107,7 +103,6 @@ private:
void updateSupportedAbis() const;
Utils::FileName m_compilerCommand;
- Utils::FileName m_debuggerCommand;
Abi m_targetAbi;
mutable QList<Abi> m_supportedAbis;
diff --git a/src/plugins/projectexplorer/gcctoolchainfactories.h b/src/plugins/projectexplorer/gcctoolchainfactories.h
index aab545de74..34421d52c2 100644
--- a/src/plugins/projectexplorer/gcctoolchainfactories.h
+++ b/src/plugins/projectexplorer/gcctoolchainfactories.h
@@ -74,7 +74,6 @@ public:
protected:
virtual GccToolChain *createToolChain(bool autoDetect);
QList<ToolChain *> autoDetectToolchains(const QString &compiler,
- const QStringList &debuggers,
const Abi &);
};
@@ -95,7 +94,6 @@ public:
private slots:
void handleCompilerCommandChange();
- void handleAbiChange();
private:
void setFromToolchain();
diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.cpp b/src/plugins/projectexplorer/miniprojecttargetselector.cpp
index 9fdb170f61..8cc1035dde 100644
--- a/src/plugins/projectexplorer/miniprojecttargetselector.cpp
+++ b/src/plugins/projectexplorer/miniprojecttargetselector.cpp
@@ -47,6 +47,7 @@
#include <projectexplorer/project.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/deployconfiguration.h>
+#include <projectexplorer/profilemanager.h>
#include <projectexplorer/projectmodels.h>
#include <projectexplorer/runconfiguration.h>
@@ -590,6 +591,10 @@ MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorActi
connect(m_sessionManager, SIGNAL(projectDisplayNameChanged(ProjectExplorer::Project*)),
this, SLOT(updateActionAndSummary()));
+ // for icon changes:
+ connect(ProjectExplorer::ProfileManager::instance(), SIGNAL(profileUpdated(ProjectExplorer::Profile*)),
+ this, SLOT(profileChanged(ProjectExplorer::Profile*)));
+
connect(m_listWidgets[TARGET], SIGNAL(changeActiveProjectConfiguration(ProjectExplorer::ProjectConfiguration*)),
this, SLOT(setActiveTarget(ProjectExplorer::ProjectConfiguration*)));
connect(m_listWidgets[BUILD], SIGNAL(changeActiveProjectConfiguration(ProjectExplorer::ProjectConfiguration*)),
@@ -869,6 +874,8 @@ void MiniProjectTargetSelector::activeTargetChanged(ProjectExplorer::Target *tar
this, SLOT(updateActionAndSummary()));
disconnect(m_target, SIGNAL(toolTipChanged()),
this, SLOT(updateActionAndSummary()));
+ disconnect(m_target, SIGNAL(iconChanged()),
+ this, SLOT(updateActionAndSummary()));
disconnect(m_target, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
this, SLOT(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)));
disconnect(m_target, SIGNAL(activeDeployConfigurationChanged(ProjectExplorer::DeployConfiguration*)),
@@ -925,6 +932,8 @@ void MiniProjectTargetSelector::activeTargetChanged(ProjectExplorer::Target *tar
this, SLOT(updateActionAndSummary()));
connect(m_target, SIGNAL(toolTipChanged()),
this, SLOT(updateActionAndSummary()));
+ connect(m_target, SIGNAL(iconChanged()),
+ this, SLOT(updateActionAndSummary()));
connect(m_target, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
this, SLOT(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)));
connect(m_target, SIGNAL(activeDeployConfigurationChanged(ProjectExplorer::DeployConfiguration*)),
@@ -942,6 +951,12 @@ void MiniProjectTargetSelector::activeTargetChanged(ProjectExplorer::Target *tar
updateActionAndSummary();
}
+void MiniProjectTargetSelector::profileChanged(Profile *profile)
+{
+ if (m_target && m_target->profile() == profile)
+ updateActionAndSummary();
+}
+
void MiniProjectTargetSelector::activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration *bc)
{
if (m_buildConfiguration)
diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.h b/src/plugins/projectexplorer/miniprojecttargetselector.h
index 51f14622c5..f356610608 100644
--- a/src/plugins/projectexplorer/miniprojecttargetselector.h
+++ b/src/plugins/projectexplorer/miniprojecttargetselector.h
@@ -43,6 +43,7 @@ class QStackedWidget;
QT_END_NAMESPACE
namespace ProjectExplorer {
+class Profile;
class Project;
class Target;
class BuildConfiguration;
@@ -134,6 +135,7 @@ private slots:
void changeStartupProject(ProjectExplorer::Project *project);
void activeTargetChanged(ProjectExplorer::Target *target);
+ void profileChanged(ProjectExplorer::Profile *profile);
void activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration *bc);
void activeDeployConfigurationChanged(ProjectExplorer::DeployConfiguration *dc);
void activeRunConfigurationChanged(ProjectExplorer::RunConfiguration *rc);
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 74e0f1ffae..8e5fa77871 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -53,7 +53,6 @@
#include <QDesktopServices>
#define KEY_ROOT "ProjectExplorer.MsvcToolChain."
-static const char debuggerCommandKeyC[] = KEY_ROOT"Debugger";
static const char varsBatKeyC[] = KEY_ROOT"VarsBat";
static const char varsBatArgKeyC[] = KEY_ROOT"VarsBatArg";
static const char supportedAbiKeyC[] = KEY_ROOT"SupportedAbi";
@@ -332,19 +331,6 @@ MsvcToolChain *MsvcToolChain::readFromMap(const QVariantMap &data)
return 0;
}
-QString MsvcToolChain::legacyId() const
-{
- const QChar colon = QLatin1Char(':');
- QString id = QLatin1String(Constants::MSVC_TOOLCHAIN_ID);
- id += colon;
- id += m_vcvarsBat;
- id += colon;
- id += m_varsBatArg;
- id += colon;
- id += m_debuggerCommand.toString();
- return id;
-}
-
QString MsvcToolChain::type() const
{
return QLatin1String("msvc");
@@ -369,8 +355,6 @@ QList<Utils::FileName> MsvcToolChain::suggestedMkspecList() const
QVariantMap MsvcToolChain::toMap() const
{
QVariantMap data = ToolChain::toMap();
- if (!m_debuggerCommand.isEmpty())
- data.insert(QLatin1String(debuggerCommandKeyC), m_debuggerCommand.toString());
data.insert(QLatin1String(varsBatKeyC), m_vcvarsBat);
if (!m_varsBatArg.isEmpty())
data.insert(QLatin1String(varsBatArgKeyC), m_varsBatArg);
@@ -384,7 +368,6 @@ bool MsvcToolChain::fromMap(const QVariantMap &data)
return false;
m_vcvarsBat = data.value(QLatin1String(varsBatKeyC)).toString();
m_varsBatArg = data.value(QLatin1String(varsBatArgKeyC)).toString();
- m_debuggerCommand = Utils::FileName::fromString(data.value(QLatin1String(debuggerCommandKeyC)).toString());
const QString abiString = data.value(QLatin1String(supportedAbiKeyC)).toString();
m_abi = Abi(abiString);
@@ -403,42 +386,6 @@ ToolChain *MsvcToolChain::clone() const
}
// --------------------------------------------------------------------------
-// MsvcDebuggerConfigLabel
-// --------------------------------------------------------------------------
-
-static const char dgbToolsDownloadLink32C[] = "http://www.microsoft.com/whdc/devtools/debugging/installx86.Mspx";
-static const char dgbToolsDownloadLink64C[] = "http://www.microsoft.com/whdc/devtools/debugging/install64bit.Mspx";
-
-QString MsvcDebuggerConfigLabel::labelText()
-{
-#ifdef Q_OS_WIN
- const bool is64bit = Utils::winIs64BitSystem();
-#else
- const bool is64bit = false;
-#endif
- const QString link = is64bit ? QLatin1String(dgbToolsDownloadLink64C) : QLatin1String(dgbToolsDownloadLink32C);
- //: Label text for path configuration. %2 is "x-bit version".
- return tr(
- "<html><body><p>Specify the path to the "
- "<a href=\"%1\">Windows Console Debugger executable</a>"
- " (%2) here.</p>"
- "</body></html>").arg(link, (is64bit ? tr("64-bit version")
- : tr("32-bit version")));
-}
-
-MsvcDebuggerConfigLabel::MsvcDebuggerConfigLabel(QWidget *parent) :
- QLabel(labelText(), parent)
-{
- connect(this, SIGNAL(linkActivated(QString)), this, SLOT(slotLinkActivated(QString)));
- setTextInteractionFlags(Qt::TextBrowserInteraction);
-}
-
-void MsvcDebuggerConfigLabel::slotLinkActivated(const QString &link)
-{
- QDesktopServices::openUrl(QUrl(link));
-}
-
-// --------------------------------------------------------------------------
// MsvcToolChainConfigWidget
// --------------------------------------------------------------------------
@@ -450,21 +397,12 @@ MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc) :
formLayout->addRow(new QLabel(tc->displayName()));
m_varsBatDisplayLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
formLayout->addRow(tr("Initialization:"), m_varsBatDisplayLabel);
- formLayout->addRow(new MsvcDebuggerConfigLabel);
- addDebuggerCommandControls(formLayout, QStringList(QLatin1String("-version")));
- addDebuggerAutoDetection(this, SLOT(autoDetectDebugger()));
- addMkspecControls(formLayout);
addErrorLabel(formLayout);
setFromToolChain();
}
void MsvcToolChainConfigWidget::apply()
-{
- MsvcToolChain *tc = static_cast<MsvcToolChain *>(toolChain());
- QTC_ASSERT(tc, return; );
- tc->setDebuggerCommand(debuggerCommand());
- tc->setMkspecList(mkspecList());
-}
+{ }
void MsvcToolChainConfigWidget::setFromToolChain()
{
@@ -476,45 +414,11 @@ void MsvcToolChainConfigWidget::setFromToolChain()
varsBatDisplay += tc->varsBatArg();
}
m_varsBatDisplayLabel->setText(varsBatDisplay);
- setDebuggerCommand(tc->debuggerCommand());
- setMkspecList(tc->mkspecList());
}
bool MsvcToolChainConfigWidget::isDirty() const
{
- MsvcToolChain *tc = static_cast<MsvcToolChain *>(toolChain());
- QTC_ASSERT(tc, return false);
- return debuggerCommand() != tc->debuggerCommand()
- || mkspecList() != tc->mkspecList();
-}
-
-void MsvcToolChainConfigWidget::autoDetectDebugger()
-{
- clearErrorMessage();
-
- MsvcToolChain *tc = static_cast<MsvcToolChain *>(toolChain());
- QTC_ASSERT(tc, return);
- ProjectExplorer::Abi abi = tc->targetAbi();
-
- const QPair<Utils::FileName, Utils::FileName> cdbExecutables = MsvcToolChain::autoDetectCdbDebugger();
- Utils::FileName debugger;
- if (abi.wordWidth() == 32) {
- if (cdbExecutables.first.isEmpty()) {
- setErrorMessage(tr("No CDB debugger detected (neither 32bit nor 64bit)."));
- return;
- }
- debugger = cdbExecutables.first;
- } else if (abi.wordWidth() == 64) {
- if (cdbExecutables.second.isEmpty()) {
- setErrorMessage(tr("No 64bit CDB debugger detected."));
- return;
- }
- debugger = cdbExecutables.second;
- }
- if (debugger != debuggerCommand()) {
- setDebuggerCommand(debugger);
- emitDirty();
- }
+ return false;
}
// --------------------------------------------------------------------------
@@ -638,79 +542,10 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect()
vcvarsIA64bat, QString(), true));
}
}
- if (!results.isEmpty()) { // Detect debugger
- const QPair<Utils::FileName, Utils::FileName> cdbDebugger = MsvcToolChain::autoDetectCdbDebugger();
- foreach (ToolChain *tc, results)
- static_cast<MsvcToolChain *>(tc)->setDebuggerCommand(tc->targetAbi().wordWidth() == 32 ? cdbDebugger.first : cdbDebugger.second);
- }
return results;
}
-// Detect CDB, return a pair of <32bit, 64bit> executables.
-QPair<Utils::FileName, Utils::FileName> MsvcToolChain::autoDetectCdbDebugger()
-{
- QPair<Utils::FileName, Utils::FileName> result;
- QList<Utils::FileName> cdbs;
-
- QStringList programDirs;
- programDirs.append(QString::fromLocal8Bit(qgetenv("ProgramFiles")));
- programDirs.append(QString::fromLocal8Bit(qgetenv("ProgramFiles(x86)")));
- programDirs.append(QString::fromLocal8Bit(qgetenv("ProgramW6432")));
-
- foreach (const QString &dirName, programDirs) {
- if (dirName.isEmpty())
- continue;
- QDir dir(dirName);
- // Windows SDK's starting from version 8 live in
- // "ProgramDir\Windows Kits\<version>"
- const QString windowsKitsFolderName = QLatin1String("Windows Kits");
- if (dir.exists(windowsKitsFolderName)) {
- QDir windowKitsFolder = dir;
- if (windowKitsFolder.cd(windowsKitsFolderName)) {
- // Check in reverse order (latest first)
- const QFileInfoList kitFolders =
- windowKitsFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot,
- QDir::Time|QDir::Reversed);
- foreach (const QFileInfo &kitFolderFi, kitFolders) {
- const QString path = kitFolderFi.absoluteFilePath();
- const QFileInfo cdb32(path + QLatin1String("/Debuggers/x86/cdb.exe"));
- if (cdb32.isExecutable())
- cdbs.push_back(Utils::FileName::fromString(cdb32.absoluteFilePath()));
- const QFileInfo cdb64(path + QLatin1String("/Debuggers/x64/cdb.exe"));
- if (cdb64.isExecutable())
- cdbs.push_back(Utils::FileName::fromString(cdb64.absoluteFilePath()));
- } // for Kits
- } // can cd to "Windows Kits"
- } // "Windows Kits" exists
-
- // Pre Windows SDK 8: Check 'Debugging Tools for Windows'
- foreach (const QFileInfo &fi, dir.entryInfoList(QStringList(QLatin1String("Debugging Tools for Windows*")),
- QDir::Dirs | QDir::NoDotAndDotDot)) {
- Utils::FileName filePath(fi);
- filePath.appendPath(QLatin1String("cdb.exe"));
- if (!cdbs.contains(filePath))
- cdbs.append(filePath);
- }
- }
-
- foreach (const Utils::FileName &cdb, cdbs) {
- QList<ProjectExplorer::Abi> abis = ProjectExplorer::Abi::abisOfBinary(cdb);
- if (abis.isEmpty())
- continue;
- if (abis.first().wordWidth() == 32)
- result.first = cdb;
- else if (abis.first().wordWidth() == 64)
- result.second = cdb;
- }
-
- // prefer 64bit debugger, even for 32bit binaries:
- if (!result.second.isEmpty())
- result.first = result.second;
-
- return result;
-}
-
bool MsvcToolChain::operator ==(const ToolChain &other) const
{
if (!AbstractMsvcToolChain::operator ==(other))
diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h
index d7151e1ba4..ed08140641 100644
--- a/src/plugins/projectexplorer/msvctoolchain.h
+++ b/src/plugins/projectexplorer/msvctoolchain.h
@@ -56,7 +56,6 @@ public:
MsvcToolChain(const QString &name, const Abi &abi,
const QString &varsBat, const QString &varsBatArg, bool autodetect = false);
- QString legacyId() const;
QList<Utils::FileName> suggestedMkspecList() const;
static MsvcToolChain *readFromMap(const QVariantMap &data);
@@ -73,8 +72,6 @@ public:
QString varsBatArg() const { return m_varsBatArg; }
- static QPair<Utils::FileName, Utils::FileName> autoDetectCdbDebugger();
-
bool operator == (const ToolChain &) const;
protected:
@@ -110,23 +107,6 @@ public:
};
// --------------------------------------------------------------------------
-// MsvcDebuggerConfigLabel: Label displaying debugging tools download info.
-// --------------------------------------------------------------------------
-
-class MsvcDebuggerConfigLabel : public QLabel
-{
- Q_OBJECT
-public:
- explicit MsvcDebuggerConfigLabel(QWidget *parent = 0);
-
-private slots:
- void slotLinkActivated(const QString &l);
-
-private:
- static QString labelText();
-};
-
-// --------------------------------------------------------------------------
// MsvcToolChainConfigWidget
// --------------------------------------------------------------------------
@@ -141,9 +121,6 @@ public:
void discard() { setFromToolChain(); }
bool isDirty() const;
-private slots:
- void autoDetectDebugger();
-
private:
void setFromToolChain();
diff --git a/src/plugins/projectexplorer/profile.cpp b/src/plugins/projectexplorer/profile.cpp
new file mode 100644
index 0000000000..a183e13d16
--- /dev/null
+++ b/src/plugins/projectexplorer/profile.cpp
@@ -0,0 +1,307 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "profile.h"
+
+#include "devicesupport/devicemanager.h"
+#include "profileinformation.h"
+#include "profilemanager.h"
+#include "toolchainmanager.h"
+
+#include <QApplication>
+#include <QIcon>
+#include <QStyle>
+#include <QTextStream>
+#include <QUuid>
+
+namespace {
+
+const char ID_KEY[] = "PE.Profile.Id";
+const char DISPLAYNAME_KEY[] = "PE.Profile.Name";
+const char AUTODETECTED_KEY[] = "PE.Profile.AutoDetected";
+const char DATA_KEY[] = "PE.Profile.Data";
+const char ICON_KEY[] = "PE.Profile.Icon";
+
+} // namespace
+
+namespace ProjectExplorer {
+
+// -------------------------------------------------------------------------
+// ProfilePrivate
+// -------------------------------------------------------------------------
+
+namespace Internal {
+
+class ProfilePrivate
+{
+public:
+ ProfilePrivate() :
+ m_id(QUuid::createUuid().toString().toLatin1().constData()),
+ m_autodetected(false),
+ m_isValid(true)
+ { }
+
+ QString m_displayName;
+ Core::Id m_id;
+ bool m_autodetected;
+ bool m_isValid;
+ QIcon m_icon;
+ QString m_iconPath;
+
+ QHash<Core::Id, QVariant> m_data;
+};
+
+} // namespace Internal
+
+// -------------------------------------------------------------------------
+// Profile:
+// -------------------------------------------------------------------------
+
+Profile::Profile() :
+ d(new Internal::ProfilePrivate)
+{
+ ProfileManager *stm = ProfileManager::instance();
+ foreach (ProfileInformation *sti, stm->profileInformation())
+ d->m_data.insert(sti->dataId(), sti->defaultValue(this));
+
+ setDisplayName(QCoreApplication::translate("ProjectExplorer::Profile", "Unnamed"));
+ setIconPath(QLatin1String(":///DESKTOP///"));
+}
+
+Profile::Profile(const Profile &other) :
+ d(new Internal::ProfilePrivate)
+{
+ d->m_displayName = QCoreApplication::translate("ProjectExplorer::Profile", "Clone of %1").arg(other.d->m_displayName);
+ d->m_autodetected = false;
+ d->m_data = other.d->m_data;
+ d->m_isValid = other.d->m_isValid;
+ d->m_icon = other.d->m_icon;
+ d->m_iconPath = other.d->m_iconPath;
+}
+
+Profile::~Profile()
+{
+ delete d;
+}
+
+bool Profile::isValid() const
+{
+ return d->m_id.isValid() && d->m_isValid;
+}
+
+QList<Task> Profile::validate()
+{
+ QList<Task> result;
+ QList<ProfileInformation *> infoList = ProfileManager::instance()->profileInformation();
+ foreach (ProfileInformation *i, infoList)
+ result.append(i->validate(this));
+ return result;
+}
+
+QString Profile::displayName() const
+{
+ return d->m_displayName;
+}
+
+void Profile::setDisplayName(const QString &name)
+{
+ if (d->m_displayName == name)
+ return;
+ d->m_displayName = name;
+ profileUpdated();
+}
+
+bool Profile::isAutoDetected() const
+{
+ return d->m_autodetected;
+}
+
+Core::Id Profile::id() const
+{
+ return d->m_id;
+}
+
+QIcon Profile::icon() const
+{
+ return d->m_icon;
+}
+
+QString Profile::iconPath() const
+{
+ return d->m_iconPath;
+}
+
+void Profile::setIconPath(const QString &path)
+{
+ if (d->m_iconPath == path)
+ return;
+ d->m_iconPath = path;
+ if (path.isNull())
+ d->m_icon = QIcon();
+ else if (path == QLatin1String(":///DESKTOP///"))
+ d->m_icon = qApp->style()->standardIcon(QStyle::SP_ComputerIcon);
+ else
+ d->m_icon = QIcon(path);
+ profileUpdated();
+}
+
+QVariant Profile::value(const Core::Id &key, const QVariant &unset) const
+{
+ return d->m_data.value(key, unset);
+}
+
+bool Profile::hasValue(const Core::Id &key) const
+{
+ return d->m_data.contains(key);
+}
+
+void Profile::setValue(const Core::Id &key, const QVariant &value)
+{
+ if (d->m_data.value(key) == value)
+ return;
+ d->m_data.insert(key, value);
+ profileUpdated();
+}
+
+void Profile::removeKey(const Core::Id &key)
+{
+ if (!d->m_data.contains(key))
+ return;
+ d->m_data.remove(key);
+ profileUpdated();
+}
+
+QVariantMap Profile::toMap() const
+{
+ QVariantMap data;
+ data.insert(QLatin1String(ID_KEY), QString::fromLatin1(d->m_id.name()));
+ data.insert(QLatin1String(DISPLAYNAME_KEY), d->m_displayName);
+ data.insert(QLatin1String(AUTODETECTED_KEY), d->m_autodetected);
+ data.insert(QLatin1String(ICON_KEY), d->m_iconPath);
+
+ QVariantMap extra;
+ foreach (const Core::Id &key, d->m_data.keys())
+ extra.insert(QString::fromLatin1(key.name().constData()), d->m_data.value(key));
+ data.insert(QLatin1String(DATA_KEY), extra);
+
+ return data;
+}
+
+bool Profile::operator==(const Profile &other) const
+{
+ return d->m_data == other.d->m_data;
+}
+
+void Profile::addToEnvironment(Utils::Environment &env) const
+{
+ QList<ProfileInformation *> infoList = ProfileManager::instance()->profileInformation();
+ foreach (ProfileInformation *si, infoList)
+ si->addToEnvironment(this, env);
+}
+
+QString Profile::toHtml()
+{
+ QString rc;
+ QTextStream str(&rc);
+ str << "<html><body>";
+ str << "<h3>" << displayName() << "</h3>";
+ str << "<table>";
+
+ if (!isValid()) {
+ QList<Task> issues = validate();
+ str << "<p>";
+ foreach (const Task &t, issues) {
+ str << "<b>";
+ switch (t.type) {
+ case Task::Error:
+ QCoreApplication::translate("ProjectExplorer::Profile", "Error:");
+ break;
+ case Task::Warning:
+ QCoreApplication::translate("ProjectExplorer::Profile", "Warning:");
+ break;
+ case Task::Unknown:
+ default:
+ break;
+ }
+ str << "</b>" << t.description << "<br>";
+ }
+ str << "</p>";
+ }
+
+ QList<ProfileInformation *> infoList = ProfileManager::instance()->profileInformation();
+ foreach (ProfileInformation *i, infoList) {
+ ProfileInformation::ItemList list = i->toUserOutput(this);
+ foreach (const ProfileInformation::Item &j, list)
+ str << "<tr><td><b>" << j.first << ":</b></td><td>" << j.second << "</td></tr>";
+ }
+ str << "</table></body></html>";
+ return rc;
+}
+
+bool Profile::fromMap(const QVariantMap &data)
+{
+ const QString id = data.value(QLatin1String(ID_KEY)).toString();
+ if (id.isEmpty())
+ return false;
+ d->m_id = Core::Id(id);
+ d->m_displayName = data.value(QLatin1String(DISPLAYNAME_KEY)).toString();
+ d->m_autodetected = data.value(QLatin1String(AUTODETECTED_KEY)).toBool();
+ setIconPath(data.value(QLatin1String(ICON_KEY)).toString());
+
+ QVariantMap extra = data.value(QLatin1String(DATA_KEY)).toMap();
+ foreach (const QString &key, extra.keys())
+ d->m_data.insert(Core::Id(key), extra.value(key));
+
+ return true;
+}
+
+void Profile::setAutoDetected(bool detected)
+{
+ d->m_autodetected = detected;
+}
+
+void Profile::setId(const Core::Id &id)
+{
+ d->m_id = id;
+}
+
+void Profile::setValid(bool valid)
+{
+ d->m_isValid = valid;
+}
+
+void Profile::profileUpdated()
+{
+ ProfileManager::instance()->notifyAboutUpdate(this);
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/profile.h b/src/plugins/projectexplorer/profile.h
new file mode 100644
index 0000000000..775100f522
--- /dev/null
+++ b/src/plugins/projectexplorer/profile.h
@@ -0,0 +1,109 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROFILE_H
+#define PROFILE_H
+
+#include "projectexplorer_export.h"
+#include "task.h"
+
+#include <coreplugin/id.h>
+
+#include <QVariant>
+
+namespace Utils { class Environment; }
+
+namespace ProjectExplorer {
+
+namespace Internal {
+class ProfileManagerPrivate;
+class ProfilePrivate;
+} // namespace Internal
+
+/**
+ * @brief The Profile class
+ *
+ * The profile holds a set of values defining a system targeted by the software
+ * under development.
+ */
+class PROJECTEXPLORER_EXPORT Profile
+{
+public:
+ Profile();
+ Profile(const Profile &other);
+ ~Profile();
+
+ bool isValid() const;
+ QList<Task> validate();
+
+ QString displayName() const;
+ void setDisplayName(const QString &name);
+
+ bool isAutoDetected() const;
+ Core::Id id() const;
+
+ QIcon icon() const;
+ QString iconPath() const;
+ void setIconPath(const QString &path);
+
+ QVariant value(const Core::Id &key, const QVariant &unset = QVariant()) const;
+ bool hasValue(const Core::Id &key) const;
+ void setValue(const Core::Id &key, const QVariant &value);
+ void removeKey(const Core::Id &key);
+
+ bool operator==(const Profile &other) const;
+
+ void addToEnvironment(Utils::Environment &env) const;
+
+ QString toHtml();
+
+private:
+ void setAutoDetected(bool detected);
+ void setId(const Core::Id &id);
+ void setValid(bool valid);
+
+ void profileUpdated();
+
+ QVariantMap toMap() const;
+ bool fromMap(const QVariantMap &value);
+
+ Internal::ProfilePrivate *d;
+
+ friend class ProfileManager;
+ friend class Internal::ProfileManagerPrivate;
+};
+
+} // namespace ProjectExplorer
+
+Q_DECLARE_METATYPE(ProjectExplorer::Profile *)
+
+#endif // PROFILE_H
diff --git a/src/plugins/projectexplorer/profileconfigwidget.h b/src/plugins/projectexplorer/profileconfigwidget.h
new file mode 100644
index 0000000000..c98f5cfbc0
--- /dev/null
+++ b/src/plugins/projectexplorer/profileconfigwidget.h
@@ -0,0 +1,67 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROFILECONFIGWIDGET_H
+#define PROFILECONFIGWIDGET_H
+
+#include "projectexplorer_export.h"
+
+#include <QWidget>
+
+namespace ProjectExplorer {
+
+// --------------------------------------------------------------------------
+// ProfileConfigWidget
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT ProfileConfigWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ProfileConfigWidget(QWidget *parent = 0) : QWidget(parent)
+ { }
+
+ virtual QString displayName() const = 0;
+ virtual void makeReadOnly() = 0;
+
+ virtual void apply() = 0;
+ virtual void discard() = 0;
+ virtual bool isDirty() const = 0;
+
+signals:
+ void dirty();
+};
+
+} // namespace ProjectExplorer
+
+#endif // PROFILECONFIGWIDGET_H
diff --git a/src/plugins/projectexplorer/profileinformation.cpp b/src/plugins/projectexplorer/profileinformation.cpp
new file mode 100644
index 0000000000..0dd63e56d3
--- /dev/null
+++ b/src/plugins/projectexplorer/profileinformation.cpp
@@ -0,0 +1,355 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "profileinformation.h"
+
+#include "devicesupport/desktopdevice.h"
+#include "devicesupport/devicemanager.h"
+#include "projectexplorerconstants.h"
+#include "profile.h"
+#include "profileinformationconfigwidget.h"
+#include "toolchain.h"
+#include "toolchainmanager.h"
+
+#include <extensionsystem/pluginmanager.h>
+#include <projectexplorer/abi.h>
+#include <utils/pathchooser.h>
+
+#include <QComboBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QPushButton>
+
+namespace ProjectExplorer {
+
+// --------------------------------------------------------------------------
+// SysRootInformation:
+// --------------------------------------------------------------------------
+
+static const char SYSROOT_INFORMATION[] = "PE.Profile.SysRoot";
+
+SysRootProfileInformation::SysRootProfileInformation()
+{
+ setObjectName(QLatin1String("SysRootInformation"));
+}
+
+Core::Id SysRootProfileInformation::dataId() const
+{
+ static const Core::Id id(SYSROOT_INFORMATION);
+ return id;
+}
+
+unsigned int SysRootProfileInformation::priority() const
+{
+ return 32000;
+}
+
+QVariant SysRootProfileInformation::defaultValue(Profile *p) const
+{
+ Q_UNUSED(p)
+ return QString();
+}
+
+QList<Task> SysRootProfileInformation::validate(Profile *p) const
+{
+ QList<Task> result;
+ const Utils::FileName dir = SysRootProfileInformation::sysRoot(p);
+ if (!dir.toFileInfo().isDir() && SysRootProfileInformation::hasSysRoot(p))
+ result << Task(Task::Error, QObject::tr("Sys Root \"%1\" is not a directory.").arg(dir.toUserOutput()),
+ Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
+ return result;
+}
+
+ProfileConfigWidget *SysRootProfileInformation::createConfigWidget(Profile *p) const
+{
+ Q_ASSERT(p);
+ return new Internal::SysRootInformationConfigWidget(p);
+}
+
+ProfileInformation::ItemList SysRootProfileInformation::toUserOutput(Profile *p) const
+{
+ return ItemList() << qMakePair(tr("Sys Root"), sysRoot(p).toUserOutput());
+}
+
+bool SysRootProfileInformation::hasSysRoot(const Profile *p)
+{
+ return !p->value(Core::Id(SYSROOT_INFORMATION)).isNull();
+}
+
+Utils::FileName SysRootProfileInformation::sysRoot(const Profile *p)
+{
+ if (!p)
+ return Utils::FileName();
+ return Utils::FileName::fromString(p->value(Core::Id(SYSROOT_INFORMATION)).toString());
+}
+
+void SysRootProfileInformation::setSysRoot(Profile *p, const Utils::FileName &v)
+{
+ p->setValue(Core::Id(SYSROOT_INFORMATION), v.toString());
+}
+
+// --------------------------------------------------------------------------
+// ToolChainInformation:
+// --------------------------------------------------------------------------
+
+static const char TOOLCHAIN_INFORMATION[] = "PE.Profile.ToolChain";
+
+ToolChainProfileInformation::ToolChainProfileInformation()
+{
+ setObjectName(QLatin1String("ToolChainInformation"));
+ connect(ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
+ this, SIGNAL(validationNeeded()));
+ connect(ToolChainManager::instance(), SIGNAL(toolChainUpdated(ProjectExplorer::ToolChain*)),
+ this, SIGNAL(validationNeeded()));
+}
+
+Core::Id ToolChainProfileInformation::dataId() const
+{
+ static const Core::Id id(TOOLCHAIN_INFORMATION);
+ return id;
+}
+
+unsigned int ToolChainProfileInformation::priority() const
+{
+ return 30000;
+}
+
+QVariant ToolChainProfileInformation::defaultValue(Profile *p) const
+{
+ Q_UNUSED(p);
+ QList<ToolChain *> tcList = ToolChainManager::instance()->toolChains();
+ if (tcList.isEmpty())
+ return QString();
+
+ ProjectExplorer::Abi abi = ProjectExplorer::Abi::hostAbi();
+
+ foreach (ToolChain *tc, tcList) {
+ if (tc->targetAbi() == abi)
+ return tc->id();
+ }
+
+ return tcList.at(0)->id();
+}
+
+QList<Task> ToolChainProfileInformation::validate(Profile *p) const
+{
+ QList<Task> result;
+ if (!toolChain(p)) {
+ setToolChain(p, 0); // make sure to clear out no longer known tool chains
+ result << Task(Task::Error, QObject::tr("No tool chain set up."),
+ Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
+ }
+ return result;
+}
+
+ProfileConfigWidget *ToolChainProfileInformation::createConfigWidget(Profile *p) const
+{
+ Q_ASSERT(p);
+ return new Internal::ToolChainInformationConfigWidget(p);
+}
+
+ProfileInformation::ItemList ToolChainProfileInformation::toUserOutput(Profile *p) const
+{
+ ToolChain *tc = toolChain(p);
+ return ItemList() << qMakePair(tr("Tool chain"), tc ? tc->displayName() : tr("None"));
+}
+
+void ToolChainProfileInformation::addToEnvironment(const Profile *p, Utils::Environment &env) const
+{
+ ToolChain *tc = toolChain(p);
+ if (tc)
+ tc->addToEnvironment(env);
+}
+
+ToolChain *ToolChainProfileInformation::toolChain(const Profile *p)
+{
+ if (!p)
+ return 0;
+ const QString id = p->value(Core::Id(TOOLCHAIN_INFORMATION)).toString();
+ return ToolChainManager::instance()->findToolChain(id);
+}
+
+void ToolChainProfileInformation::setToolChain(Profile *p, ToolChain *tc)
+{
+ p->setValue(Core::Id(TOOLCHAIN_INFORMATION), tc ? tc->id() : QString());
+}
+
+// --------------------------------------------------------------------------
+// DeviceTypeInformation:
+// --------------------------------------------------------------------------
+
+static const char DEVICETYPE_INFORMATION[] = "PE.Profile.DeviceType";
+
+DeviceTypeProfileInformation::DeviceTypeProfileInformation()
+{
+ setObjectName(QLatin1String("DeviceTypeInformation"));
+}
+
+Core::Id DeviceTypeProfileInformation::dataId() const
+{
+ static const Core::Id id(DEVICETYPE_INFORMATION);
+ return id;
+}
+
+unsigned int DeviceTypeProfileInformation::priority() const
+{
+ return 33000;
+}
+
+QVariant DeviceTypeProfileInformation::defaultValue(Profile *p) const
+{
+ Q_UNUSED(p);
+ return QByteArray(Constants::DESKTOP_DEVICE_TYPE);
+}
+
+QList<Task> DeviceTypeProfileInformation::validate(Profile *p) const
+{
+ IDevice::ConstPtr dev = DeviceProfileInformation::device(p);
+ QList<Task> result;
+ if (!dev.isNull() && dev->type() != DeviceTypeProfileInformation::deviceTypeId(p))
+ result.append(Task(Task::Error, QObject::tr("Device does not match device type."),
+ Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)));
+ return result;
+}
+
+ProfileConfigWidget *DeviceTypeProfileInformation::createConfigWidget(Profile *p) const
+{
+ Q_ASSERT(p);
+ return new Internal::DeviceTypeInformationConfigWidget(p);
+}
+
+ProfileInformation::ItemList DeviceTypeProfileInformation::toUserOutput(Profile *p) const
+{
+ Core::Id type = deviceTypeId(p);
+ QString typeDisplayName = tr("Unknown device type");
+ if (type.isValid()) {
+ QList<IDeviceFactory *> factories
+ = ExtensionSystem::PluginManager::instance()->getObjects<IDeviceFactory>();
+ foreach (IDeviceFactory *factory, factories) {
+ if (factory->availableCreationIds().contains(type)) {
+ typeDisplayName = factory->displayNameForId(type);
+ break;
+ }
+ }
+ }
+ return ItemList() << qMakePair(tr("Device type"), typeDisplayName);
+}
+
+const Core::Id DeviceTypeProfileInformation::deviceTypeId(const Profile *p)
+{
+ if (!p)
+ return Core::Id();
+ return Core::Id(p->value(Core::Id(DEVICETYPE_INFORMATION)).toByteArray().constData());
+}
+
+void DeviceTypeProfileInformation::setDeviceTypeId(Profile *p, Core::Id type)
+{
+ p->setValue(Core::Id(DEVICETYPE_INFORMATION), type.name());
+}
+
+// --------------------------------------------------------------------------
+// DeviceInformation:
+// --------------------------------------------------------------------------
+
+static const char DEVICE_INFORMATION[] = "PE.Profile.Device";
+
+DeviceProfileInformation::DeviceProfileInformation()
+{
+ setObjectName(QLatin1String("DeviceInformation"));
+ connect(DeviceManager::instance(), SIGNAL(deviceRemoved(Core::Id)),
+ this, SIGNAL(validationNeeded()));
+ connect(DeviceManager::instance(), SIGNAL(deviceUpdated(Core::Id)),
+ this, SIGNAL(validationNeeded()));
+}
+
+Core::Id DeviceProfileInformation::dataId() const
+{
+ static const Core::Id id(DEVICE_INFORMATION);
+ return id;
+}
+
+unsigned int DeviceProfileInformation::priority() const
+{
+ return 32000;
+}
+
+QVariant DeviceProfileInformation::defaultValue(Profile *p) const
+{
+ Q_UNUSED(p);
+ return QByteArray(Constants::DESKTOP_DEVICE_ID);
+}
+
+QList<Task> DeviceProfileInformation::validate(Profile *p) const
+{
+ Q_UNUSED(p);
+ QList<Task> result;
+ return result;
+}
+
+ProfileConfigWidget *DeviceProfileInformation::createConfigWidget(Profile *p) const
+{
+ Q_ASSERT(p);
+ return new Internal::DeviceInformationConfigWidget(p);
+}
+
+ProfileInformation::ItemList DeviceProfileInformation::toUserOutput(Profile *p) const
+{
+ IDevice::ConstPtr dev = device(p);
+ return ItemList() << qMakePair(tr("Device"), dev.isNull() ? tr("Unconfigured") : dev->displayName());
+}
+
+IDevice::ConstPtr DeviceProfileInformation::device(const Profile *p)
+{
+ DeviceManager *dm = DeviceManager::instance();
+ return dm ? dm->find(deviceId(p)) : IDevice::ConstPtr();
+}
+
+Core::Id DeviceProfileInformation::deviceId(const Profile *p)
+{
+ if (p) {
+ QByteArray idname = p->value(Core::Id(DEVICE_INFORMATION)).toByteArray();
+ return idname.isEmpty() ? IDevice::invalidId() : Core::Id(idname.constData());
+ }
+ return IDevice::invalidId();
+}
+
+void DeviceProfileInformation::setDevice(Profile *p, IDevice::ConstPtr dev)
+{
+ setDeviceId(p, dev ? dev->id() : IDevice::invalidId());
+}
+
+void DeviceProfileInformation::setDeviceId(Profile *p, const Core::Id id)
+{
+ p->setValue(Core::Id(DEVICE_INFORMATION), id.name());
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/profileinformation.h b/src/plugins/projectexplorer/profileinformation.h
new file mode 100644
index 0000000000..44fd0793fc
--- /dev/null
+++ b/src/plugins/projectexplorer/profileinformation.h
@@ -0,0 +1,224 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROFILEINFORMATION_H
+#define PROFILEINFORMATION_H
+
+#include "profilemanager.h"
+#include "profile.h"
+
+#include "devicesupport/idevice.h"
+#include "toolchain.h"
+
+#include <utils/fileutils.h>
+
+#include <QVariant>
+
+namespace ProjectExplorer {
+
+class ProfileConfigWidget;
+
+// --------------------------------------------------------------------------
+// SysRootInformation:
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT SysRootProfileInformation : public ProfileInformation
+{
+ Q_OBJECT
+
+public:
+ SysRootProfileInformation();
+
+ Core::Id dataId() const;
+ unsigned int priority() const;
+
+ QVariant defaultValue(Profile *p) const;
+
+ QList<Task> validate(Profile *p) const;
+
+ ProfileConfigWidget *createConfigWidget(Profile *p) const;
+
+ ItemList toUserOutput(Profile *p) const;
+
+ static bool hasSysRoot(const Profile *p);
+ static Utils::FileName sysRoot(const Profile *p);
+ static void setSysRoot(Profile *p, const Utils::FileName &v);
+};
+
+class PROJECTEXPLORER_EXPORT SysRootMatcher : public ProfileMatcher
+{
+public:
+ SysRootMatcher(const Utils::FileName &fn) : m_sysroot(fn)
+ { }
+
+ bool matches(const Profile *p) const
+ {
+ return SysRootProfileInformation::sysRoot(p) == m_sysroot;
+ }
+
+private:
+ Utils::FileName m_sysroot;
+};
+
+// --------------------------------------------------------------------------
+// ToolChainInformation:
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT ToolChainProfileInformation : public ProfileInformation
+{
+ Q_OBJECT
+
+public:
+ ToolChainProfileInformation();
+
+ Core::Id dataId() const;
+ unsigned int priority() const;
+
+ QVariant defaultValue(Profile *p) const;
+
+ QList<Task> validate(Profile *p) const;
+
+ ProfileConfigWidget *createConfigWidget(Profile *p) const;
+
+ ItemList toUserOutput(Profile *p) const;
+
+ void addToEnvironment(const Profile *p, Utils::Environment &env) const;
+
+ static ToolChain *toolChain(const Profile *p);
+ static void setToolChain(Profile *p, ToolChain *tc);
+};
+
+class PROJECTEXPLORER_EXPORT ToolChainMatcher : public ProfileMatcher
+{
+public:
+ ToolChainMatcher(const ToolChain *tc) : m_tc(tc)
+ { }
+
+ bool matches(const Profile *p) const
+ {
+ return ToolChainProfileInformation::toolChain(p) == m_tc;
+ }
+
+private:
+ const ToolChain *m_tc;
+};
+
+// --------------------------------------------------------------------------
+// DeviceTypeInformation:
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT DeviceTypeProfileInformation : public ProfileInformation
+{
+ Q_OBJECT
+
+public:
+ DeviceTypeProfileInformation();
+
+ Core::Id dataId() const;
+ unsigned int priority() const;
+
+ QVariant defaultValue(Profile *p) const;
+
+ QList<Task> validate(Profile *p) const;
+
+ ProfileConfigWidget *createConfigWidget(Profile *p) const;
+
+ ItemList toUserOutput(Profile *p) const;
+
+ static const Core::Id deviceTypeId(const Profile *p);
+ static void setDeviceTypeId(Profile *p, Core::Id type);
+};
+
+class PROJECTEXPLORER_EXPORT DeviceTypeMatcher : public ProfileMatcher
+{
+public:
+ DeviceTypeMatcher(const Core::Id t) : m_type(t)
+ { }
+
+ bool matches(const Profile *p) const
+ {
+ Core::Id deviceType = DeviceTypeProfileInformation::deviceTypeId(p);
+ if (!deviceType.isValid())
+ return false;
+ return deviceType == m_type;
+ }
+
+private:
+ const Core::Id m_type;
+};
+
+// --------------------------------------------------------------------------
+// DeviceInformation:
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT DeviceProfileInformation : public ProfileInformation
+{
+ Q_OBJECT
+
+public:
+ DeviceProfileInformation();
+
+ Core::Id dataId() const;
+ unsigned int priority() const;
+
+ QVariant defaultValue(Profile *p) const;
+
+ QList<Task> validate(Profile *p) const;
+
+ ProfileConfigWidget *createConfigWidget(Profile *p) const;
+
+ ItemList toUserOutput(Profile *p) const;
+
+ static IDevice::ConstPtr device(const Profile *p);
+ static Core::Id deviceId(const Profile *p);
+ static void setDevice(Profile *p, IDevice::ConstPtr dev);
+ static void setDeviceId(Profile *p, const Core::Id id);
+};
+
+class PROJECTEXPLORER_EXPORT DeviceMatcher : public ProfileMatcher
+{
+public:
+ DeviceMatcher(Core::Id id) : m_devId(id)
+ { }
+
+ bool matches(const Profile *p) const
+ {
+ return DeviceProfileInformation::deviceId(p) == m_devId;
+ }
+
+private:
+ Core::Id m_devId;
+};
+
+} // namespace ProjectExplorer
+
+#endif // PROFILEINFORMATION_H
diff --git a/src/plugins/projectexplorer/profileinformationconfigwidget.cpp b/src/plugins/projectexplorer/profileinformationconfigwidget.cpp
new file mode 100644
index 0000000000..457bb8369c
--- /dev/null
+++ b/src/plugins/projectexplorer/profileinformationconfigwidget.cpp
@@ -0,0 +1,353 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "profileinformationconfigwidget.h"
+
+#include "devicesupport/devicemanager.h"
+#include "devicesupport/devicemanagermodel.h"
+#include "devicesupport/idevicefactory.h"
+#include "projectexplorerconstants.h"
+#include "profile.h"
+#include "profileinformation.h"
+#include "toolchain.h"
+#include "toolchainmanager.h"
+
+#include <coreplugin/icore.h>
+#include <extensionsystem/pluginmanager.h>
+#include <utils/pathchooser.h>
+
+#include <QComboBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QPushButton>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// SysRootInformationConfigWidget:
+// --------------------------------------------------------------------------
+
+SysRootInformationConfigWidget::SysRootInformationConfigWidget(Profile *p, QWidget *parent) :
+ ProfileConfigWidget(parent),
+ m_profile(p)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ m_chooser = new Utils::PathChooser;
+ m_chooser->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(m_chooser);
+ m_chooser->setExpectedKind(Utils::PathChooser::ExistingDirectory);
+
+ m_chooser->setFileName(SysRootProfileInformation::sysRoot(p));
+
+ connect(m_chooser, SIGNAL(changed(QString)), this, SIGNAL(dirty()));
+}
+
+QString SysRootInformationConfigWidget::displayName() const
+{
+ return tr("Sysroot:");
+}
+
+void SysRootInformationConfigWidget::apply()
+{
+ SysRootProfileInformation::setSysRoot(m_profile, m_chooser->fileName());
+}
+
+void SysRootInformationConfigWidget::discard()
+{
+ m_chooser->setFileName(SysRootProfileInformation::sysRoot(m_profile));
+}
+
+bool SysRootInformationConfigWidget::isDirty() const
+{
+ return SysRootProfileInformation::sysRoot(m_profile) != m_chooser->fileName();
+}
+
+void SysRootInformationConfigWidget::makeReadOnly()
+{
+ m_chooser->setEnabled(false);
+}
+
+// --------------------------------------------------------------------------
+// ToolChainInformationConfigWidget:
+// --------------------------------------------------------------------------
+
+ToolChainInformationConfigWidget::ToolChainInformationConfigWidget(Profile *p, QWidget *parent) :
+ ProfileConfigWidget(parent),
+ m_isReadOnly(false), m_profile(p),
+ m_comboBox(new QComboBox), m_manageButton(new QPushButton)
+{
+ ToolChainManager *tcm = ToolChainManager::instance();
+
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ m_comboBox->setContentsMargins(0, 0, 0, 0);
+ m_comboBox->setEnabled(false);
+ m_comboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+ layout->addWidget(m_comboBox);
+
+ foreach (ToolChain *tc, tcm->toolChains())
+ toolChainAdded(tc);
+
+ updateComboBox();
+
+ discard();
+ connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(dirty()));
+
+ m_manageButton->setContentsMargins(0, 0, 0, 0);
+ m_manageButton->setText(tr("Manage..."));
+ layout->addWidget(m_manageButton);
+ connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageToolChains()));
+
+ connect(tcm, SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
+ this, SLOT(toolChainAdded(ProjectExplorer::ToolChain*)));
+ connect(tcm, SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
+ this, SLOT(toolChainRemoved(ProjectExplorer::ToolChain*)));
+ connect(tcm, SIGNAL(toolChainUpdated(ProjectExplorer::ToolChain*)),
+ this, SLOT(toolChainUpdated(ProjectExplorer::ToolChain*)));
+}
+
+QString ToolChainInformationConfigWidget::displayName() const
+{
+ return tr("Tool chain:");
+}
+
+void ToolChainInformationConfigWidget::apply()
+{
+ const QString id = m_comboBox->itemData(m_comboBox->currentIndex()).toString();
+ ToolChain *tc = ToolChainManager::instance()->findToolChain(id);
+ ToolChainProfileInformation::setToolChain(m_profile, tc);
+}
+
+void ToolChainInformationConfigWidget::discard()
+{
+ m_comboBox->setCurrentIndex(indexOf(ToolChainProfileInformation::toolChain(m_profile)));
+}
+
+bool ToolChainInformationConfigWidget::isDirty() const
+{
+ ToolChain *tc = ToolChainProfileInformation::toolChain(m_profile);
+ return (m_comboBox->itemData(m_comboBox->currentIndex()).toString())
+ == (tc ? tc->id() : QString());
+}
+
+void ToolChainInformationConfigWidget::makeReadOnly()
+{
+ m_comboBox->setEnabled(false);
+}
+
+void ToolChainInformationConfigWidget::toolChainAdded(ProjectExplorer::ToolChain *tc)
+{
+ m_comboBox->addItem(tc->displayName(), tc->id());
+ updateComboBox();
+}
+
+void ToolChainInformationConfigWidget::toolChainRemoved(ProjectExplorer::ToolChain *tc)
+{
+ const int pos = indexOf(tc);
+ if (pos < 0)
+ return;
+ m_comboBox->removeItem(pos);
+ updateComboBox();
+}
+void ToolChainInformationConfigWidget::toolChainUpdated(ProjectExplorer::ToolChain *tc)
+{
+ const int pos = indexOf(tc);
+ if (pos < 0)
+ return;
+ m_comboBox->setItemText(pos, tc->displayName());
+}
+
+void ToolChainInformationConfigWidget::manageToolChains()
+{
+ Core::ICore::showOptionsDialog(QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY),
+ QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_PAGE_ID));
+}
+
+void ToolChainInformationConfigWidget::updateComboBox()
+{
+ // remove unavailable tool chain:
+ int pos = indexOf(0);
+ if (pos >= 0)
+ m_comboBox->removeItem(pos);
+
+ if (m_comboBox->count() == 0) {
+ m_comboBox->addItem(tr("<No tool chain available>"), QString());
+ m_comboBox->setEnabled(false);
+ } else {
+ m_comboBox->setEnabled(!m_isReadOnly);
+ }
+}
+
+int ToolChainInformationConfigWidget::indexOf(const ToolChain *tc)
+{
+ const QString id = tc ? tc->id() : QString();
+ for (int i = 0; i < m_comboBox->count(); ++i) {
+ if (id == m_comboBox->itemData(i).toString())
+ return i;
+ }
+ return -1;
+}
+
+// --------------------------------------------------------------------------
+// DeviceTypeInformationConfigWidget:
+// --------------------------------------------------------------------------
+
+DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Profile *p, QWidget *parent) :
+ ProfileConfigWidget(parent),
+ m_isReadOnly(false), m_profile(p),
+ m_comboBox(new QComboBox)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ m_comboBox->setContentsMargins(0, 0, 0, 0);
+ m_comboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+ layout->addWidget(m_comboBox);
+
+ QList<IDeviceFactory *> factories
+ = ExtensionSystem::PluginManager::instance()->getObjects<IDeviceFactory>();
+ foreach (IDeviceFactory *factory, factories) {
+ foreach (Core::Id id, factory->availableCreationIds()) {
+ m_comboBox->addItem(factory->displayNameForId(id), QVariant::fromValue(id));
+ }
+ }
+
+ discard();
+ connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(dirty()));
+}
+
+QString DeviceTypeInformationConfigWidget::displayName() const
+{
+ return tr("Device Type:");
+}
+
+void DeviceTypeInformationConfigWidget::apply()
+{
+ Core::Id devType;
+ if (m_comboBox->currentIndex() >= 0)
+ devType = m_comboBox->itemData(m_comboBox->currentIndex()).value<Core::Id>();
+ DeviceTypeProfileInformation::setDeviceTypeId(m_profile, devType);
+}
+
+void DeviceTypeInformationConfigWidget::discard()
+{
+ Core::Id devType = DeviceTypeProfileInformation::deviceTypeId(m_profile);
+ if (!devType.isValid())
+ m_comboBox->setCurrentIndex(-1);
+ for (int i = 0; i < m_comboBox->count(); ++i) {
+ if (m_comboBox->itemData(i).value<Core::Id>() == devType) {
+ m_comboBox->setCurrentIndex(i);
+ break;
+ }
+ }
+}
+
+bool DeviceTypeInformationConfigWidget::isDirty() const
+{
+ Core::Id devType;
+ if (m_comboBox->currentIndex() >= 0)
+ devType = m_comboBox->itemData(m_comboBox->currentIndex()).value<Core::Id>();
+ return DeviceTypeProfileInformation::deviceTypeId(m_profile) != devType;
+}
+
+void DeviceTypeInformationConfigWidget::makeReadOnly()
+{
+ m_comboBox->setEnabled(false);
+}
+
+// --------------------------------------------------------------------------
+// DeviceInformationConfigWidget:
+// --------------------------------------------------------------------------
+
+DeviceInformationConfigWidget::DeviceInformationConfigWidget(Profile *p, QWidget *parent) :
+ ProfileConfigWidget(parent),
+ m_isReadOnly(false), m_profile(p),
+ m_comboBox(new QComboBox), m_manageButton(new QPushButton),
+ m_model(new DeviceManagerModel(DeviceManager::instance()))
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ m_comboBox->setContentsMargins(0, 0, 0, 0);
+ m_comboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+ layout->addWidget(m_comboBox);
+
+ m_comboBox->setModel(m_model);
+
+ m_manageButton->setContentsMargins(0, 0, 0, 0);
+ m_manageButton->setText(tr("Manage..."));
+ layout->addWidget(m_manageButton);
+
+ discard();
+ connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(dirty()));
+
+ connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageDevices()));
+}
+
+QString DeviceInformationConfigWidget::displayName() const
+{
+ return tr("Device:");
+}
+
+void DeviceInformationConfigWidget::apply()
+{
+ int idx = m_comboBox->currentIndex();
+ if (idx >= 0)
+ DeviceProfileInformation::setDeviceId(m_profile, m_model->deviceId(idx));
+ else
+ DeviceProfileInformation::setDeviceId(m_profile, IDevice::invalidId());
+}
+
+void DeviceInformationConfigWidget::discard()
+{
+ m_comboBox->setCurrentIndex(m_model->indexOf(DeviceProfileInformation::device(m_profile)));
+}
+
+bool DeviceInformationConfigWidget::isDirty() const
+{
+ Core::Id devId = DeviceProfileInformation::deviceId(m_profile);
+ return devId != m_model->deviceId(m_comboBox->currentIndex());
+}
+
+void DeviceInformationConfigWidget::makeReadOnly()
+{
+ m_comboBox->setEnabled(false);
+}
+
+void DeviceInformationConfigWidget::manageDevices()
+{
+ Core::ICore::showOptionsDialog(QLatin1String(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY),
+ QLatin1String(ProjectExplorer::Constants::DEVICE_SETTINGS_PAGE_ID));
+}
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/profileinformationconfigwidget.h b/src/plugins/projectexplorer/profileinformationconfigwidget.h
new file mode 100644
index 0000000000..59eafd2a4b
--- /dev/null
+++ b/src/plugins/projectexplorer/profileinformationconfigwidget.h
@@ -0,0 +1,160 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROFILEINFORMATIONCONFIGWIDGET_H
+#define PROFILEINFORMATIONCONFIGWIDGET_H
+
+#include "profileconfigwidget.h"
+
+QT_FORWARD_DECLARE_CLASS(QComboBox)
+QT_FORWARD_DECLARE_CLASS(QPushButton)
+
+namespace Utils { class PathChooser; }
+
+namespace ProjectExplorer {
+
+class DeviceManagerModel;
+class Profile;
+class ToolChain;
+
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// SysRootInformationConfigWidget:
+// --------------------------------------------------------------------------
+
+class SysRootInformationConfigWidget : public ProfileConfigWidget
+{
+ Q_OBJECT
+
+public:
+ explicit SysRootInformationConfigWidget(Profile *p, QWidget *parent = 0);
+
+ QString displayName() const;
+ void apply();
+ void discard();
+ bool isDirty() const;
+ void makeReadOnly();
+
+private:
+ Profile *m_profile;
+ Utils::PathChooser *m_chooser;
+};
+
+// --------------------------------------------------------------------------
+// ToolChainInformationConfigWidget:
+// --------------------------------------------------------------------------
+
+class ToolChainInformationConfigWidget : public ProfileConfigWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ToolChainInformationConfigWidget(Profile *p, QWidget *parent = 0);
+
+ QString displayName() const;
+ void apply();
+ void discard();
+ bool isDirty() const;
+ void makeReadOnly();
+
+private slots:
+ void toolChainAdded(ProjectExplorer::ToolChain *tc);
+ void toolChainRemoved(ProjectExplorer::ToolChain *tc);
+ void toolChainUpdated(ProjectExplorer::ToolChain *tc);
+ void manageToolChains();
+
+private:
+ void updateComboBox();
+ int indexOf(const ToolChain *tc);
+
+ bool m_isReadOnly;
+ Profile *m_profile;
+ QComboBox *m_comboBox;
+ QPushButton *m_manageButton;
+};
+
+// --------------------------------------------------------------------------
+// DeviceTypeInformationConfigWidget:
+// --------------------------------------------------------------------------
+
+class DeviceTypeInformationConfigWidget : public ProfileConfigWidget
+{
+ Q_OBJECT
+
+public:
+ explicit DeviceTypeInformationConfigWidget(Profile *p, QWidget *parent = 0);
+
+ QString displayName() const;
+ void apply();
+ void discard();
+ bool isDirty() const;
+ void makeReadOnly();
+
+private:
+ bool m_isReadOnly;
+ Profile *m_profile;
+ QComboBox *m_comboBox;
+};
+
+// --------------------------------------------------------------------------
+// DeviceInformationConfigWidget:
+// --------------------------------------------------------------------------
+
+class DeviceInformationConfigWidget : public ProfileConfigWidget
+{
+ Q_OBJECT
+
+public:
+ explicit DeviceInformationConfigWidget(Profile *p, QWidget *parent = 0);
+
+ QString displayName() const;
+ void apply();
+ void discard();
+ bool isDirty() const;
+ void makeReadOnly();
+
+private slots:
+ void manageDevices();
+
+private:
+ bool m_isReadOnly;
+ Profile *m_profile;
+ QComboBox *m_comboBox;
+ QPushButton *m_manageButton;
+ DeviceManagerModel *m_model;
+};
+
+} // namespace Internal
+} // namespace ProjectExplorer
+
+#endif // PROFILEINFORMATIONCONFIGWIDGET_H
diff --git a/src/plugins/projectexplorer/profilemanager.cpp b/src/plugins/projectexplorer/profilemanager.cpp
new file mode 100644
index 0000000000..add233b20f
--- /dev/null
+++ b/src/plugins/projectexplorer/profilemanager.cpp
@@ -0,0 +1,471 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "profilemanager.h"
+
+#include "profile.h"
+#include "profileconfigwidget.h"
+#include "profilemanagerconfigwidget.h"
+#include "project.h"
+
+#include <coreplugin/icore.h>
+
+#include <extensionsystem/pluginmanager.h>
+
+#include <utils/persistentsettings.h>
+#include <utils/environment.h>
+
+#include <QCoreApplication>
+#include <QDir>
+#include <QSettings>
+
+#include <QFormLayout>
+#include <QLabel>
+#include <QMainWindow>
+
+static const char PROFILE_DATA_KEY[] = "Profile.";
+static const char PROFILE_COUNT_KEY[] = "Profile.Count";
+static const char PROFILE_FILE_VERSION_KEY[] = "Version";
+static const char PROFILE_DEFAULT_KEY[] = "Profile.Default";
+static const char PROFILE_FILENAME[] = "/qtcreator/profiles.xml";
+
+using Utils::PersistentSettingsWriter;
+using Utils::PersistentSettingsReader;
+
+static QString settingsFileName()
+{
+ ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+ QFileInfo settingsLocation(pm->settings()->fileName());
+ return settingsLocation.absolutePath() + QLatin1String(PROFILE_FILENAME);
+}
+
+namespace ProjectExplorer {
+
+ProfileManager *ProfileManager::m_instance = 0;
+
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// ProfileManagerPrivate:
+// --------------------------------------------------------------------------
+
+class ProfileManagerPrivate
+{
+public:
+ ProfileManagerPrivate();
+ ~ProfileManagerPrivate();
+ QList<Task> validateProfile(Profile *p) const;
+
+ Profile *m_defaultProfile;
+ bool m_initialized;
+ QList<ProfileInformation *> m_informationList;
+ QList<Profile *> m_profileList;
+};
+
+ProfileManagerPrivate::ProfileManagerPrivate()
+ : m_defaultProfile(0), m_initialized(false)
+{ }
+
+ProfileManagerPrivate::~ProfileManagerPrivate()
+{
+}
+
+QList<Task> ProfileManagerPrivate::validateProfile(Profile *p) const
+{
+ Q_ASSERT(p);
+ QList<Task> result;
+ bool hasError = false;
+ foreach (ProfileInformation *pi, m_informationList) {
+ QList<Task> tmp = pi->validate(p);
+ foreach (const Task &t, tmp)
+ if (t.type == Task::Error)
+ hasError = true;
+ result << tmp;
+ }
+ p->setValid(!hasError);
+ return result;
+}
+
+} // namespace Internal
+
+// --------------------------------------------------------------------------
+// ProfileManager:
+// --------------------------------------------------------------------------
+
+ProfileManager *ProfileManager::instance()
+{
+ return m_instance;
+}
+
+ProfileManager::ProfileManager(QObject *parent) :
+ QObject(parent),
+ d(new Internal::ProfileManagerPrivate())
+{
+ Q_ASSERT(!m_instance);
+ m_instance = this;
+
+ connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()),
+ this, SLOT(saveProfiles()));
+
+ connect(this, SIGNAL(profileAdded(ProjectExplorer::Profile*)),
+ this, SIGNAL(profilesChanged()));
+ connect(this, SIGNAL(profileRemoved(ProjectExplorer::Profile*)),
+ this, SIGNAL(profilesChanged()));
+ connect(this, SIGNAL(profileUpdated(ProjectExplorer::Profile*)),
+ this, SIGNAL(profilesChanged()));
+}
+
+void ProfileManager::restoreProfiles()
+{
+ QList<Profile *> stsToRegister;
+ QList<Profile *> stsToCheck;
+
+ // read all profiles from SDK
+ QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
+ ProfileList system = restoreProfiles(systemSettingsFile.absolutePath() + QLatin1String(PROFILE_FILENAME));
+ QList<Profile *> readSts = system.profiles;
+ // make sure we mark these as autodetected!
+ foreach (Profile *p, readSts)
+ p->setAutoDetected(true);
+
+ stsToRegister = readSts; // SDK profiles are always considered to be up-to-date, so no need to
+ // recheck them.
+
+ // read all profile chains from user file
+ ProfileList userProfiles = restoreProfiles(settingsFileName());
+ readSts = userProfiles.profiles;
+
+ foreach (Profile *p, readSts) {
+ if (p->isAutoDetected())
+ stsToCheck.append(p);
+ else
+ stsToRegister.append(p);
+ }
+ readSts.clear();
+
+ // Then auto create profiles:
+ QList<Profile *> detectedSts;
+ Profile *defaultProfile = new Profile; // One profile using default values
+ defaultProfile->setDisplayName(tr("Desktop"));
+ defaultProfile->setAutoDetected(true);
+ defaultProfile->setIconPath(QLatin1String(":///DESKTOP///"));
+
+ detectedSts << defaultProfile;
+
+ // Find/update autodetected profiles:
+ Profile *toStore = 0;
+ foreach (Profile *currentDetected, detectedSts) {
+ toStore = currentDetected;
+
+ // Check whether we had this profile stored and prefer the old one with the old id:
+ for (int i = 0; i < stsToCheck.count(); ++i) {
+ if (*(stsToCheck.at(i)) == *currentDetected) {
+ toStore = stsToCheck.at(i);
+ stsToCheck.removeAt(i);
+ delete currentDetected;
+ break;
+ }
+ }
+ addProfile(toStore);
+ }
+
+ // Delete all loaded autodetected profiles that were not rediscovered:
+ qDeleteAll(stsToCheck);
+
+ // Store manual tool chains
+ foreach (Profile *p, stsToRegister)
+ addProfile(p);
+
+ Profile *p = find(userProfiles.defaultProfile);
+ if (p)
+ setDefaultProfile(p);
+}
+
+ProfileManager::~ProfileManager()
+{
+ // Clean out profile information to avoid calling them during deregistration:
+ qDeleteAll(d->m_informationList);
+ qDeleteAll(d->m_profileList);
+ delete d;
+ m_instance = 0;
+}
+
+void ProfileManager::saveProfiles()
+{
+ PersistentSettingsWriter writer;
+ writer.saveValue(QLatin1String(PROFILE_FILE_VERSION_KEY), 1);
+
+ int count = 0;
+ foreach (Profile *p, profiles()) {
+ QVariantMap tmp = p->toMap();
+ if (tmp.isEmpty())
+ continue;
+ writer.saveValue(QString::fromLatin1(PROFILE_DATA_KEY) + QString::number(count), tmp);
+ ++count;
+ }
+ writer.saveValue(QLatin1String(PROFILE_COUNT_KEY), count);
+ writer.saveValue(QLatin1String(PROFILE_DEFAULT_KEY),
+ d->m_defaultProfile ? QString::fromLatin1(d->m_defaultProfile->id().name()) : QString());
+ writer.save(settingsFileName(), QLatin1String("QtCreatorProfiles"), Core::ICore::mainWindow());
+}
+
+bool greaterPriority(ProfileInformation *a, ProfileInformation *b)
+{
+ return a->priority() > b->priority();
+}
+
+void ProfileManager::registerProfileInformation(ProfileInformation *pi)
+{
+ QList<ProfileInformation *>::iterator it
+ = qLowerBound(d->m_informationList.begin(), d->m_informationList.end(), pi, greaterPriority);
+ d->m_informationList.insert(it, pi);
+
+ connect(pi, SIGNAL(validationNeeded()), this, SLOT(validateProfiles()));
+
+ if (!d->m_initialized)
+ return;
+
+ foreach (Profile *p, profiles()) {
+ if (!p->hasValue(pi->dataId()))
+ p->setValue(pi->dataId(), pi->defaultValue(p));
+ }
+
+ return;
+}
+
+void ProfileManager::deregisterProfileInformation(ProfileInformation *pi)
+{
+ Q_ASSERT(d->m_informationList.contains(pi));
+ d->m_informationList.removeAll(pi);
+ delete pi;
+}
+
+ProfileManager::ProfileList ProfileManager::restoreProfiles(const QString &fileName)
+{
+ ProfileList result;
+
+ PersistentSettingsReader reader;
+ if (!reader.load(fileName))
+ return result;
+ QVariantMap data = reader.restoreValues();
+
+ // Check version:
+ int version = data.value(QLatin1String(PROFILE_FILE_VERSION_KEY), 0).toInt();
+ if (version < 1)
+ return result;
+
+ const int count = data.value(QLatin1String(PROFILE_COUNT_KEY), 0).toInt();
+ for (int i = 0; i < count; ++i) {
+ const QString key = QString::fromLatin1(PROFILE_DATA_KEY) + QString::number(i);
+ if (!data.contains(key))
+ break;
+
+ const QVariantMap stMap = data.value(key).toMap();
+
+ Profile *p = new Profile;
+ if (p->fromMap(stMap)) {
+ result.profiles.append(p);
+ } else {
+ delete p;
+ qWarning("Warning: Unable to restore profiles stored in %s at position %d.",
+ qPrintable(QDir::toNativeSeparators(fileName)), i);
+ }
+ }
+ const QString defaultId = data.value(QLatin1String(PROFILE_DEFAULT_KEY)).toString();
+ if (defaultId.isEmpty())
+ return result;
+
+ const Core::Id id = Core::Id(defaultId);
+ foreach (Profile *i, result.profiles) {
+ if (i->id() == id) {
+ result.defaultProfile = id;
+ break;
+ }
+ }
+ return result;
+}
+
+QList<Profile *> ProfileManager::profiles(const ProfileMatcher *m) const
+{
+ if (!d->m_initialized) {
+ d->m_initialized = true;
+ const_cast<ProfileManager *>(this)->restoreProfiles();
+ }
+
+ QList<Profile *> result;
+ foreach (Profile *p, d->m_profileList) {
+ if (!m || m->matches(p))
+ result.append(p);
+ }
+ return result;
+}
+
+Profile *ProfileManager::find(const Core::Id &id) const
+{
+ if (!id.isValid())
+ return 0;
+
+ foreach (Profile *p, profiles()) {
+ if (p->id() == id)
+ return p;
+ }
+ return 0;
+}
+
+Profile *ProfileManager::find(const ProfileMatcher *m) const
+{
+ QList<Profile *> matched = profiles(m);
+ return matched.isEmpty() ? 0 : matched.first();
+}
+
+Profile *ProfileManager::defaultProfile()
+{
+ if (!d->m_initialized) {
+ d->m_initialized = true;
+ restoreProfiles();
+ }
+ return d->m_defaultProfile;
+}
+
+QList<ProfileInformation *> ProfileManager::profileInformation() const
+{
+ return d->m_informationList;
+}
+
+ProfileConfigWidget *ProfileManager::createConfigWidget(Profile *p) const
+{
+ if (!p)
+ return 0;
+
+ Internal::ProfileManagerConfigWidget *result = new Internal::ProfileManagerConfigWidget(p);
+ foreach (ProfileInformation *pi, d->m_informationList)
+ result->addConfigWidget(pi->createConfigWidget(p));
+
+ return result;
+}
+
+void ProfileManager::notifyAboutUpdate(ProjectExplorer::Profile *p)
+{
+ if (!p || !profiles().contains(p))
+ return;
+ d->validateProfile(p);
+ emit profileUpdated(p);
+}
+
+bool ProfileManager::registerProfile(ProjectExplorer::Profile *p)
+{
+ if (!p)
+ return true;
+ foreach (Profile *current, profiles()) {
+ if (p == current || *p == *current)
+ return false;
+ }
+
+ // Make name unique:
+ QStringList names;
+ foreach (Profile *tmp, profiles())
+ names << tmp->displayName();
+ p->setDisplayName(Project::makeUnique(p->displayName(), names));
+
+ // make sure we have all the information in our profiles:
+ foreach (ProfileInformation *pi, d->m_informationList) {
+ if (!p->hasValue(pi->dataId()))
+ p->setValue(pi->dataId(), pi->defaultValue(p));
+ }
+
+ addProfile(p);
+ emit profileAdded(p);
+ return true;
+}
+
+void ProfileManager::deregisterProfile(Profile *p)
+{
+ if (!p || !profiles().contains(p))
+ return;
+ d->m_profileList.removeOne(p);
+ if (d->m_defaultProfile == p) {
+ QList<Profile *> stList = profiles();
+ Profile *newDefault = 0;
+ foreach (Profile *cur, stList) {
+ if (cur->isValid()) {
+ newDefault = cur;
+ break;
+ }
+ }
+ setDefaultProfile(newDefault);
+ }
+ emit profileRemoved(p);
+ delete p;
+}
+
+QList<Task> ProfileManager::validateProfile(Profile *p)
+{
+ QList<Task> result = d->validateProfile(p);
+ qSort(result);
+ return result;
+}
+
+void ProfileManager::setDefaultProfile(Profile *p)
+{
+ if (d->m_defaultProfile == p)
+ return;
+ if (p && !profiles().contains(p))
+ return;
+ d->m_defaultProfile = p;
+ emit defaultProfileChanged();
+}
+
+void ProfileManager::validateProfiles()
+{
+ foreach (Profile *p, profiles())
+ d->validateProfile(p);
+}
+
+void ProfileManager::addProfile(Profile *p)
+{
+ if (!p)
+ return;
+ d->validateProfile(p);
+ d->m_profileList.append(p);
+ if (!d->m_defaultProfile ||
+ (!d->m_defaultProfile->isValid() && p->isValid()))
+ setDefaultProfile(p);
+}
+
+
+void ProfileInformation::addToEnvironment(const Profile *p, Utils::Environment &env) const
+{
+ Q_UNUSED(p);
+ Q_UNUSED(env);
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/profilemanager.h b/src/plugins/projectexplorer/profilemanager.h
new file mode 100644
index 0000000000..e9bac6dc4f
--- /dev/null
+++ b/src/plugins/projectexplorer/profilemanager.h
@@ -0,0 +1,171 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROFILEMANAGER_H
+#define PROFILEMANAGER_H
+
+#include "projectexplorer_export.h"
+
+#include "task.h"
+
+#include <coreplugin/id.h>
+#include <utils/fileutils.h>
+
+#include <QObject>
+#include <QPair>
+
+namespace Utils { class Environment; }
+
+namespace ProjectExplorer {
+class Profile;
+class ProfileConfigWidget;
+
+namespace Internal {
+class ProfileManagerPrivate;
+class ProfileModel;
+} // namespace Internal
+
+/**
+ * @brief The ProfileInformation class
+ *
+ * One piece of information stored in the profile.
+ *
+ * This needs to get registered with the \a ProfileManager.
+ */
+class PROJECTEXPLORER_EXPORT ProfileInformation : public QObject
+{
+ Q_OBJECT
+
+public:
+ typedef QPair<QString, QString> Item;
+ typedef QList<Item> ItemList;
+
+ virtual Core::Id dataId() const = 0;
+
+ virtual unsigned int priority() const = 0; // the higher the closer to the top.
+
+ virtual bool visibleIn(Profile *) { return true; }
+ virtual QVariant defaultValue(Profile *) const = 0;
+
+ virtual QList<Task> validate(Profile *) const = 0;
+
+ virtual ItemList toUserOutput(Profile *p) const = 0;
+
+ virtual ProfileConfigWidget *createConfigWidget(Profile *) const = 0;
+
+ virtual void addToEnvironment(const Profile *p, Utils::Environment &env) const;
+
+signals:
+ void validationNeeded();
+};
+
+class PROJECTEXPLORER_EXPORT ProfileMatcher
+{
+public:
+ virtual ~ProfileMatcher() { }
+ virtual bool matches(const Profile *p) const = 0;
+};
+
+class PROJECTEXPLORER_EXPORT ProfileManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ static ProfileManager *instance();
+ ~ProfileManager();
+
+ QList<Profile *> profiles(const ProfileMatcher *m = 0) const;
+ Profile *find(const Core::Id &id) const;
+ Profile *find(const ProfileMatcher *m) const;
+ Profile *defaultProfile();
+
+ QList<ProfileInformation *> profileInformation() const;
+
+ ProfileConfigWidget *createConfigWidget(Profile *p) const;
+
+public slots:
+ bool registerProfile(ProjectExplorer::Profile *p);
+ void deregisterProfile(ProjectExplorer::Profile *p);
+ QList<Task> validateProfile(ProjectExplorer::Profile *p);
+ void setDefaultProfile(ProjectExplorer::Profile *p);
+
+ void saveProfiles();
+
+ void registerProfileInformation(ProjectExplorer::ProfileInformation *pi);
+ void deregisterProfileInformation(ProjectExplorer::ProfileInformation *pi);
+
+signals:
+ void profileAdded(ProjectExplorer::Profile *);
+ // Profile is still valid when this call happens!
+ void profileRemoved(ProjectExplorer::Profile *);
+ // Profile was updated.
+ void profileUpdated(ProjectExplorer::Profile *);
+ // Default profile was changed.
+ void defaultProfileChanged();
+ // Something changed.
+ void profilesChanged();
+
+private slots:
+ void validateProfiles();
+
+private:
+ explicit ProfileManager(QObject *parent = 0);
+
+ // Make sure the this is only called after all
+ // ProfileInformation are registered!
+ void restoreProfiles();
+ class ProfileList
+ {
+ public:
+ ProfileList()
+ { }
+ Core::Id defaultProfile;
+ QList<Profile *> profiles;
+ };
+ ProfileList restoreProfiles(const QString &fileName);
+
+ void notifyAboutUpdate(ProjectExplorer::Profile *p);
+ void addProfile(Profile *p);
+
+ Internal::ProfileManagerPrivate *const d;
+
+ static ProfileManager *m_instance;
+
+ friend class Internal::ProfileManagerPrivate; // for the restoreToolChains methods
+ friend class ProjectExplorerPlugin; // for constructor
+ friend class Profile;
+ friend class Internal::ProfileModel;
+};
+
+} // namespace ProjectExplorer
+
+#endif // PROFILEMANAGER_H
diff --git a/src/plugins/projectexplorer/profilemanagerconfigwidget.cpp b/src/plugins/projectexplorer/profilemanagerconfigwidget.cpp
new file mode 100644
index 0000000000..04aed656bf
--- /dev/null
+++ b/src/plugins/projectexplorer/profilemanagerconfigwidget.cpp
@@ -0,0 +1,132 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "profilemanagerconfigwidget.h"
+
+#include "profile.h"
+
+#include <QHBoxLayout>
+#include <QFormLayout>
+#include <QPushButton>
+#include <QFileDialog>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+ProfileManagerConfigWidget::ProfileManagerConfigWidget(Profile *p, QWidget *parent) :
+ ProfileConfigWidget(parent),
+ m_layout(new QFormLayout),
+ m_iconButton(new QPushButton),
+ m_profile(p)
+{
+ m_layout->setMargin(0);
+ m_layout->setSpacing(6);
+
+ m_iconButton->setMinimumSize(70, 70);
+ m_iconButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::QSizePolicy::Fixed);
+ QVBoxLayout *iconLayout = new QVBoxLayout;
+ iconLayout->addWidget(m_iconButton);
+ iconLayout->addStretch();
+
+ QHBoxLayout *masterLayout = new QHBoxLayout(this);
+ masterLayout->addLayout(iconLayout);
+ masterLayout->setMargin(0);
+ masterLayout->setSpacing(12);
+ masterLayout->addLayout(m_layout);
+
+ discard();
+
+ connect(m_iconButton, SIGNAL(clicked()), this, SLOT(setIcon()));
+}
+
+QString ProfileManagerConfigWidget::displayName() const
+{
+ return tr("Profiles");
+}
+
+void ProfileManagerConfigWidget::apply()
+{
+ foreach (ProfileConfigWidget *w, m_widgets)
+ w->apply();
+ m_profile->setIconPath(m_iconPath);
+}
+
+void ProfileManagerConfigWidget::discard()
+{
+ foreach (ProfileConfigWidget *w, m_widgets)
+ w->discard();
+ m_iconButton->setIcon(m_profile->icon());
+ m_iconPath = m_profile->iconPath();
+}
+
+bool ProfileManagerConfigWidget::isDirty() const
+{
+ foreach (ProfileConfigWidget *w, m_widgets)
+ if (w->isDirty())
+ return true;
+ return m_profile->iconPath() != m_iconPath;
+}
+
+void ProfileManagerConfigWidget::addConfigWidget(ProjectExplorer::ProfileConfigWidget *widget)
+{
+ Q_ASSERT(widget);
+ Q_ASSERT(!m_widgets.contains(widget));
+
+ connect(widget, SIGNAL(dirty()), this, SIGNAL(dirty()));
+ m_layout->addRow(widget->displayName(), widget);
+ m_widgets.append(widget);
+}
+
+void ProfileManagerConfigWidget::makeReadOnly()
+{
+ foreach (ProfileConfigWidget *w, m_widgets)
+ w->makeReadOnly();
+ m_iconButton->setEnabled(false);
+}
+
+void ProfileManagerConfigWidget::setIcon()
+{
+ const QString path = QFileDialog::getOpenFileName(0, tr("Select Icon"), m_iconPath, tr("Images (*.png *.xpm *.jpg)"));
+ if (path.isEmpty())
+ return;
+
+ const QIcon icon = QIcon(path);
+ if (icon.isNull())
+ return;
+
+ m_iconButton->setIcon(icon);
+ m_iconPath = path;
+ emit dirty();
+}
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/profilemanagerconfigwidget.h b/src/plugins/projectexplorer/profilemanagerconfigwidget.h
new file mode 100644
index 0000000000..0bf7204a29
--- /dev/null
+++ b/src/plugins/projectexplorer/profilemanagerconfigwidget.h
@@ -0,0 +1,78 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROFILEMANAGERWIDGET_H
+#define PROFILEMANAGERWIDGET_H
+
+#include "profileconfigwidget.h"
+
+QT_BEGIN_NAMESPACE
+class QHBoxLayout;
+class QFormLayout;
+class QPushButton;
+QT_END_NAMESPACE
+
+namespace ProjectExplorer {
+class Profile;
+
+namespace Internal {
+
+class ProfileManagerConfigWidget : public ProjectExplorer::ProfileConfigWidget
+{
+ Q_OBJECT
+
+public:
+ ProfileManagerConfigWidget(Profile *p, QWidget *parent = 0);
+
+ QString displayName() const;
+
+ void apply();
+ void discard();
+ bool isDirty() const;
+ void addConfigWidget(ProjectExplorer::ProfileConfigWidget *widget);
+ void makeReadOnly();
+
+private slots:
+ void setIcon();
+
+private:
+ QFormLayout *m_layout;
+ QPushButton *m_iconButton;
+ QList<ProfileConfigWidget *> m_widgets;
+ Profile *m_profile;
+ QString m_iconPath;
+};
+
+} // namespace Internal
+} // namespace ProjectExplorer
+
+#endif // PROFILEMANAGERCONFIGWIDGET_H
diff --git a/src/plugins/projectexplorer/profilemodel.cpp b/src/plugins/projectexplorer/profilemodel.cpp
new file mode 100644
index 0000000000..b4da323a81
--- /dev/null
+++ b/src/plugins/projectexplorer/profilemodel.cpp
@@ -0,0 +1,521 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "profilemodel.h"
+
+#include "profile.h"
+#include "profileconfigwidget.h"
+#include "profilemanager.h"
+
+#include <utils/qtcassert.h>
+
+#include <QApplication>
+#include <QLayout>
+#include <QMessageBox>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+class ProfileNode
+{
+public:
+ explicit ProfileNode(ProfileNode *pn, Profile *p = 0, bool c = false) :
+ parent(pn), profile(p), changed(c)
+ {
+ if (pn)
+ pn->childNodes.append(this);
+ widget = ProfileManager::instance()->createConfigWidget(p);
+ if (widget) {
+ if (p && p->isAutoDetected())
+ widget->makeReadOnly();
+ widget->setVisible(false);
+ }
+ }
+
+ ~ProfileNode()
+ {
+ if (parent)
+ parent->childNodes.removeOne(this);
+
+ // deleting a child removes it from childNodes
+ // so operate on a temporary list
+ QList<ProfileNode *> tmp = childNodes;
+ qDeleteAll(tmp);
+ Q_ASSERT(childNodes.isEmpty());
+ }
+
+ ProfileNode *parent;
+ QString newName;
+ QList<ProfileNode *> childNodes;
+ Profile *profile;
+ ProfileConfigWidget *widget;
+ bool changed;
+};
+
+// --------------------------------------------------------------------------
+// ProfileModel
+// --------------------------------------------------------------------------
+
+ProfileModel::ProfileModel(QBoxLayout *parentLayout, QObject *parent) :
+ QAbstractItemModel(parent),
+ m_parentLayout(parentLayout),
+ m_defaultNode(0)
+{
+ Q_ASSERT(m_parentLayout);
+
+ connect(ProfileManager::instance(), SIGNAL(profileAdded(ProjectExplorer::Profile*)),
+ this, SLOT(addProfile(ProjectExplorer::Profile*)));
+ connect(ProfileManager::instance(), SIGNAL(profileRemoved(ProjectExplorer::Profile*)),
+ this, SLOT(removeProfile(ProjectExplorer::Profile*)));
+ connect(ProfileManager::instance(), SIGNAL(profileUpdated(ProjectExplorer::Profile*)),
+ this, SLOT(updateProfile(ProjectExplorer::Profile*)));
+ connect(ProfileManager::instance(), SIGNAL(defaultProfileChanged()),
+ this, SLOT(changeDefaultProfile()));
+
+ m_root = new ProfileNode(0);
+ m_autoRoot = new ProfileNode(m_root);
+ m_manualRoot = new ProfileNode(m_root);
+
+ foreach (Profile *p, ProfileManager::instance()->profiles())
+ addProfile(p);
+
+ changeDefaultProfile();
+}
+
+ProfileModel::~ProfileModel()
+{
+ delete m_root;
+}
+
+QModelIndex ProfileModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (!parent.isValid()) {
+ if (row >= 0 && row < m_root->childNodes.count())
+ return createIndex(row, column, m_root->childNodes.at(row));
+ }
+ ProfileNode *node = static_cast<ProfileNode *>(parent.internalPointer());
+ if (row < node->childNodes.count() && column == 0)
+ return createIndex(row, column, node->childNodes.at(row));
+ else
+ return QModelIndex();
+}
+
+QModelIndex ProfileModel::parent(const QModelIndex &idx) const
+{
+ if (!idx.isValid())
+ return QModelIndex();
+ ProfileNode *node = static_cast<ProfileNode *>(idx.internalPointer());
+ if (node->parent == m_root)
+ return QModelIndex();
+ return index(node->parent);
+}
+
+int ProfileModel::rowCount(const QModelIndex &parent) const
+{
+ if (!parent.isValid())
+ return m_root->childNodes.count();
+ ProfileNode *node = static_cast<ProfileNode *>(parent.internalPointer());
+ return node->childNodes.count();
+}
+
+int ProfileModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return 1;
+}
+
+QVariant ProfileModel::data(const QModelIndex &index, int role) const
+{
+ static QIcon warningIcon(":/projectexplorer/images/compile_warning.png");
+
+ if (!index.isValid() || index.column() != 0)
+ return QVariant();
+
+ ProfileNode *node = static_cast<ProfileNode *>(index.internalPointer());
+ QTC_ASSERT(node, return QVariant());
+ if (node == m_autoRoot && role == Qt::DisplayRole)
+ return tr("Auto-detected");
+ if (node == m_manualRoot && role == Qt::DisplayRole)
+ return tr("Manual");
+ if (node->profile) {
+ if (role == Qt::FontRole) {
+ QFont f = QApplication::font();
+ if (node->changed)
+ f.setBold(!f.bold());
+ if (node == m_defaultNode)
+ f.setItalic(f.style() != QFont::StyleItalic);
+ return f;
+ } else if (role == Qt::DisplayRole || role == Qt::EditRole) {
+ QString baseName = node->newName.isEmpty() ? node->profile->displayName() : node->newName;
+ if (node == m_defaultNode)
+ //: Mark up a profile as the default one.
+ baseName = tr("%1 (default)").arg(baseName);
+ return baseName;
+ } else if (role == Qt::DecorationRole) {
+ return node->profile->isValid() ? QIcon() : warningIcon;
+ } else if (role == Qt::ToolTipRole) {
+ return node->profile->toHtml();
+ }
+ }
+ return QVariant();
+}
+
+bool ProfileModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid())
+ return false;
+
+ ProfileNode *node = static_cast<ProfileNode *>(index.internalPointer());
+ Q_ASSERT(node);
+ if (index.column() != 0 || !node->profile || role != Qt::EditRole)
+ return false;
+ node->newName = value.toString();
+ if (!node->newName.isEmpty() && node->newName != node->profile->displayName())
+ node->changed = true;
+ return true;
+}
+
+Qt::ItemFlags ProfileModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+
+ ProfileNode *node = static_cast<ProfileNode *>(index.internalPointer());
+ Q_ASSERT(node);
+ if (!node->profile)
+ return Qt::ItemIsEnabled;
+
+ if (node->profile->isAutoDetected())
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
+}
+
+QVariant ProfileModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ Q_UNUSED(section);
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+ return tr("Name");
+ return QVariant();
+}
+
+Profile *ProfileModel::profile(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return 0;
+ ProfileNode *node = static_cast<ProfileNode *>(index.internalPointer());
+ Q_ASSERT(node);
+ return node->profile;
+}
+
+QModelIndex ProfileModel::indexOf(Profile *p) const
+{
+ ProfileNode *n = find(p);
+ return n ? index(n) : QModelIndex();
+}
+
+void ProfileModel::setDefaultProfile(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return;
+ ProfileNode *node = static_cast<ProfileNode *>(index.internalPointer());
+ Q_ASSERT(node);
+ if (node->profile)
+ setDefaultNode(node);
+}
+
+bool ProfileModel::isDefaultProfile(const QModelIndex &index)
+{
+ return m_defaultNode == static_cast<ProfileNode *>(index.internalPointer());
+}
+
+ProfileConfigWidget *ProfileModel::widget(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return 0;
+ ProfileNode *node = static_cast<ProfileNode *>(index.internalPointer());
+ Q_ASSERT(node);
+ return node->widget;
+}
+
+bool ProfileModel::isDirty() const
+{
+ foreach (ProfileNode *n, m_manualRoot->childNodes) {
+ if (n->changed)
+ return true;
+ }
+ return false;
+}
+
+bool ProfileModel::isDirty(Profile *p) const
+{
+ ProfileNode *n = find(p);
+ return n ? !n->changed : false;
+}
+
+void ProfileModel::setDirty()
+{
+ ProfileConfigWidget *w = qobject_cast<ProfileConfigWidget *>(sender());
+ foreach (ProfileNode *n, m_manualRoot->childNodes) {
+ if (n->widget == w) {
+ n->changed = true;
+ emit dataChanged(index(n, 0), index(n, columnCount(QModelIndex())));
+ }
+ }
+}
+
+void ProfileModel::apply()
+{
+ // Remove unused profiles:
+ QList<ProfileNode *> nodes = m_toRemoveList;
+ foreach (ProfileNode *n, nodes) {
+ Q_ASSERT(!n->parent);
+ ProfileManager::instance()->deregisterProfile(n->profile);
+ }
+ Q_ASSERT(m_toRemoveList.isEmpty());
+
+ // Update profiles:
+ foreach (ProfileNode *n, m_manualRoot->childNodes) {
+ Q_ASSERT(n);
+ Q_ASSERT(n->profile);
+ if (n->changed) {
+ ProfileManager::instance()->blockSignals(true);
+ if (!n->newName.isEmpty()) {
+ n->profile->setDisplayName(n->newName);
+ n->newName.clear();
+ }
+ if (n->widget)
+ n->widget->apply();
+ n->changed = false;
+
+ ProfileManager::instance()->blockSignals(false);
+ ProfileManager::instance()->notifyAboutUpdate(n->profile);
+ emit dataChanged(index(n, 0), index(n, columnCount(QModelIndex())));
+ }
+ }
+
+ // Add new (and already updated) profiles
+ QStringList removedSts;
+ nodes = m_toAddList;
+ foreach (ProfileNode *n, nodes) {
+ if (!ProfileManager::instance()->registerProfile(n->profile))
+ removedSts << n->profile->displayName();
+ }
+
+ foreach (ProfileNode *n, m_toAddList)
+ markForRemoval(n->profile);
+
+ if (removedSts.count() == 1) {
+ QMessageBox::warning(0,
+ tr("Duplicate profiles detected"),
+ tr("The following profile was already configured:<br>"
+ "&nbsp;%1<br>"
+ "It was not configured again.")
+ .arg(removedSts.at(0)));
+
+ } else if (!removedSts.isEmpty()) {
+ QMessageBox::warning(0,
+ tr("Duplicate profile detected"),
+ tr("The following profiles were already configured:<br>"
+ "&nbsp;%1<br>"
+ "They were not configured again.")
+ .arg(removedSts.join(QLatin1String(",<br>&nbsp;"))));
+ }
+
+ // Set default profile:
+ if (m_defaultNode)
+ ProfileManager::instance()->setDefaultProfile(m_defaultNode->profile);
+}
+
+void ProfileModel::markForRemoval(Profile *p)
+{
+ ProfileNode *node = find(p);
+ if (!node)
+ return;
+
+ beginRemoveRows(index(m_manualRoot), m_manualRoot->childNodes.indexOf(node), m_manualRoot->childNodes.indexOf(node));
+ m_manualRoot->childNodes.removeOne(node);
+ node->parent = 0;
+ if (m_toAddList.contains(node)) {
+ delete node->profile;
+ node->profile = 0;
+ m_toAddList.removeOne(node);
+ delete node;
+ } else {
+ m_toRemoveList.append(node);
+ }
+ endRemoveRows();
+
+ if (node == m_defaultNode) {
+ ProfileNode *newDefault = 0;
+ if (!m_autoRoot->childNodes.isEmpty())
+ newDefault = m_autoRoot->childNodes.at(0);
+ else if (!m_manualRoot->childNodes.isEmpty())
+ newDefault = m_manualRoot->childNodes.at(0);
+ setDefaultNode(newDefault);
+ }
+}
+
+void ProfileModel::markForAddition(Profile *p)
+{
+ int pos = m_manualRoot->childNodes.size();
+ beginInsertRows(index(m_manualRoot), pos, pos);
+
+ ProfileNode *node = createNode(m_manualRoot, p, true);
+ m_toAddList.append(node);
+
+ if (!m_defaultNode)
+ setDefaultNode(node);
+
+ endInsertRows();
+}
+
+QModelIndex ProfileModel::index(ProfileNode *node, int column) const
+{
+ if (node->parent == 0) // is root (or was marked for deletion)
+ return QModelIndex();
+ else if (node->parent == m_root)
+ return index(m_root->childNodes.indexOf(node), column, QModelIndex());
+ else
+ return index(node->parent->childNodes.indexOf(node), column, index(node->parent));
+}
+
+ProfileNode *ProfileModel::find(Profile *p) const
+{
+ foreach (ProfileNode *n, m_autoRoot->childNodes) {
+ if (n->profile == p)
+ return n;
+ }
+ foreach (ProfileNode *n, m_manualRoot->childNodes) {
+ if (n->profile == p)
+ return n;
+ }
+ return 0;
+}
+
+ProfileNode *ProfileModel::createNode(ProfileNode *parent, Profile *p, bool changed)
+{
+ ProfileNode *node = new ProfileNode(parent, p, changed);
+ if (node->widget) {
+ m_parentLayout->addWidget(node->widget);
+ connect(node->widget, SIGNAL(dirty()),
+ this, SLOT(setDirty()));
+ }
+ return node;
+}
+
+void ProfileModel::setDefaultNode(ProfileNode *node)
+{
+ if (m_defaultNode) {
+ QModelIndex idx = index(m_defaultNode);
+ if (idx.isValid())
+ emit dataChanged(idx, idx);
+ }
+ m_defaultNode = node;
+ if (m_defaultNode) {
+ QModelIndex idx = index(m_defaultNode);
+ if (idx.isValid())
+ emit dataChanged(idx, idx);
+ }
+}
+
+void ProfileModel::addProfile(Profile *p)
+{
+ QList<ProfileNode *> nodes = m_toAddList;
+ foreach (ProfileNode *n, nodes) {
+ if (n->profile == p) {
+ m_toAddList.removeOne(n);
+ // do not delete n: Still used elsewhere!
+ return;
+ }
+ }
+
+ ProfileNode *parent = m_manualRoot;
+ if (p->isAutoDetected())
+ parent = m_autoRoot;
+ int row = parent->childNodes.count();
+
+ beginInsertRows(index(parent), row, row);
+ createNode(parent, p, false);
+ endInsertRows();
+
+ emit profileStateChanged();
+}
+
+void ProfileModel::removeProfile(Profile *p)
+{
+ QList<ProfileNode *> nodes = m_toRemoveList;
+ foreach (ProfileNode *n, nodes) {
+ if (n->profile == p) {
+ m_toRemoveList.removeOne(n);
+ delete n;
+ return;
+ }
+ }
+
+ ProfileNode *parent = m_manualRoot;
+ if (p->isAutoDetected())
+ parent = m_autoRoot;
+ int row = 0;
+ ProfileNode *node = 0;
+ foreach (ProfileNode *current, parent->childNodes) {
+ if (current->profile == p) {
+ node = current;
+ break;
+ }
+ ++row;
+ }
+
+ beginRemoveRows(index(parent), row, row);
+ parent->childNodes.removeAt(row);
+ delete node;
+ endRemoveRows();
+
+ emit profileStateChanged();
+}
+
+void ProfileModel::updateProfile(Profile *p)
+{
+ ProfileNode *n = find(p);
+ if (n->widget)
+ n->widget->discard();
+ QModelIndex idx = index(n);
+ emit dataChanged(idx, idx);
+}
+
+void ProfileModel::changeDefaultProfile()
+{
+ setDefaultNode(find(ProfileManager::instance()->defaultProfile()));
+}
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/profilemodel.h b/src/plugins/projectexplorer/profilemodel.h
new file mode 100644
index 0000000000..edd4af0a3b
--- /dev/null
+++ b/src/plugins/projectexplorer/profilemodel.h
@@ -0,0 +1,124 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROFILEMODEL_H
+#define PROFILEMODEL_H
+
+#include "projectexplorer_export.h"
+
+#include <QAbstractItemModel>
+
+QT_BEGIN_NAMESPACE
+class QTreeWidgetItem;
+class QBoxLayout;
+QT_END_NAMESPACE
+
+namespace ProjectExplorer {
+
+class Profile;
+class ProfileConfigWidget;
+class ProfileFactory;
+class ProfileManager;
+
+namespace Internal {
+
+class ProfileNode;
+
+// --------------------------------------------------------------------------
+// ProfileModel:
+// --------------------------------------------------------------------------
+
+class ProfileModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ explicit ProfileModel(QBoxLayout *parentLayout, QObject *parent = 0);
+ ~ProfileModel();
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &index) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+
+ Profile *profile(const QModelIndex &);
+ QModelIndex indexOf(Profile *p) const;
+
+ void setDefaultProfile(const QModelIndex &index);
+ bool isDefaultProfile(const QModelIndex &index);
+
+ ProfileConfigWidget *widget(const QModelIndex &);
+
+ bool isDirty() const;
+ bool isDirty(Profile *p) const;
+
+ void apply();
+
+ void markForRemoval(Profile *p);
+ void markForAddition(Profile *p);
+
+signals:
+ void profileStateChanged();
+
+private slots:
+ void addProfile(ProjectExplorer::Profile *p);
+ void removeProfile(ProjectExplorer::Profile *p);
+ void updateProfile(ProjectExplorer::Profile *p);
+ void changeDefaultProfile();
+ void setDirty();
+
+private:
+ QModelIndex index(ProfileNode *, int column = 0) const;
+ ProfileNode *find(Profile *) const;
+ ProfileNode *createNode(ProfileNode *parent, Profile *p, bool changed);
+ void setDefaultNode(ProfileNode *node);
+
+ ProfileNode *m_root;
+ ProfileNode *m_autoRoot;
+ ProfileNode *m_manualRoot;
+
+ QList<ProfileNode *> m_toAddList;
+ QList<ProfileNode *> m_toRemoveList;
+
+ QBoxLayout *m_parentLayout;
+ ProfileNode *m_defaultNode;
+};
+
+} // namespace Internal
+} // namespace ProjectExplorer
+
+#endif // PROFILEMODEL_H
diff --git a/src/plugins/projectexplorer/profileoptionspage.cpp b/src/plugins/projectexplorer/profileoptionspage.cpp
new file mode 100644
index 0000000000..7cc7d80a89
--- /dev/null
+++ b/src/plugins/projectexplorer/profileoptionspage.cpp
@@ -0,0 +1,253 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "profileoptionspage.h"
+
+#include "profilemodel.h"
+#include "profile.h"
+#include "projectexplorerconstants.h"
+#include "profileconfigwidget.h"
+#include "profilemanager.h"
+
+#include <coreplugin/icore.h>
+
+#include <utils/qtcassert.h>
+
+#include <QHBoxLayout>
+#include <QHeaderView>
+#include <QItemSelectionModel>
+#include <QPushButton>
+#include <QTreeView>
+#include <QVBoxLayout>
+
+namespace ProjectExplorer {
+
+// --------------------------------------------------------------------------
+// ProfileOptionsPage:
+// --------------------------------------------------------------------------
+
+ProfileOptionsPage::ProfileOptionsPage() :
+ m_model(0), m_selectionModel(0), m_currentWidget(0), m_toShow(0)
+{
+ setId(Constants::PROFILE_SETTINGS_PAGE_ID);
+ setDisplayName(tr("Targets"));
+ setCategory(QLatin1String(Constants::PROJECTEXPLORER_SETTINGS_CATEGORY));
+ setDisplayCategory(QCoreApplication::translate("ProjectExplorer",
+ Constants::PROJECTEXPLORER_SETTINGS_TR_CATEGORY));
+ setCategoryIcon(QLatin1String(Constants::PROJECTEXPLORER_SETTINGS_CATEGORY_ICON));
+}
+
+QWidget *ProfileOptionsPage::createPage(QWidget *parent)
+{
+ m_configWidget = new QWidget(parent);
+
+ m_profilesView = new QTreeView(m_configWidget);
+ m_profilesView->setUniformRowHeights(true);
+ m_profilesView->header()->setStretchLastSection(true);
+
+ m_addButton = new QPushButton(tr("Add"), m_configWidget);
+ m_cloneButton = new QPushButton(tr("Clone"), m_configWidget);
+ m_delButton = new QPushButton(tr("Remove"), m_configWidget);
+ m_makeDefaultButton = new QPushButton(tr("Make Default"), m_configWidget);
+
+ QVBoxLayout *buttonLayout = new QVBoxLayout();
+ buttonLayout->setContentsMargins(0, 0, 0, 0);
+ buttonLayout->addWidget(m_addButton);
+ buttonLayout->addWidget(m_cloneButton);
+ buttonLayout->addWidget(m_delButton);
+ buttonLayout->addWidget(m_makeDefaultButton);
+ buttonLayout->addItem(new QSpacerItem(10, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
+
+ QVBoxLayout *verticalLayout = new QVBoxLayout();
+ verticalLayout->addWidget(m_profilesView);
+
+ QHBoxLayout *horizontalLayout = new QHBoxLayout(m_configWidget);
+ horizontalLayout->addLayout(verticalLayout);
+ horizontalLayout->addLayout(buttonLayout);
+
+ Q_ASSERT(!m_model);
+ m_model = new Internal::ProfileModel(verticalLayout);
+ connect(m_model, SIGNAL(profileStateChanged()), this, SLOT(updateState()));
+
+ m_profilesView->setModel(m_model);
+ m_profilesView->header()->setResizeMode(0, QHeaderView::Stretch);
+ m_profilesView->expandAll();
+
+ m_selectionModel = m_profilesView->selectionModel();
+ connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(profileSelectionChanged()));
+ connect(ProfileManager::instance(), SIGNAL(profileAdded(ProjectExplorer::Profile*)),
+ this, SLOT(profileSelectionChanged()));
+ connect(ProfileManager::instance(), SIGNAL(profileRemoved(ProjectExplorer::Profile*)),
+ this, SLOT(profileSelectionChanged()));
+ connect(ProfileManager::instance(), SIGNAL(profileUpdated(ProjectExplorer::Profile*)),
+ this, SLOT(profileSelectionChanged()));
+
+ // Set up add menu:
+ connect(m_addButton, SIGNAL(clicked()), this, SLOT(addNewProfile()));
+ connect(m_cloneButton, SIGNAL(clicked()), this, SLOT(cloneProfile()));
+ connect(m_delButton, SIGNAL(clicked()), this, SLOT(removeProfile()));
+ connect(m_makeDefaultButton, SIGNAL(clicked()), this, SLOT(makeDefaultProfile()));
+
+ m_searchKeywords = tr("Profiles");
+
+ updateState();
+
+ if (m_toShow)
+ m_selectionModel->select(m_model->indexOf(m_toShow),
+ QItemSelectionModel::Clear
+ | QItemSelectionModel::SelectCurrent
+ | QItemSelectionModel::Rows);
+ m_toShow = 0;
+
+ return m_configWidget;
+}
+
+void ProfileOptionsPage::apply()
+{
+ if (m_model)
+ m_model->apply();
+}
+
+void ProfileOptionsPage::finish()
+{
+ if (m_model) {
+ delete m_model;
+ m_model = 0;
+ }
+
+ m_configWidget = 0; // deleted by settingsdialog
+ m_selectionModel = 0; // child of m_configWidget
+ m_profilesView = 0; // child of m_configWidget
+ m_currentWidget = 0; // deleted by the model
+ m_toShow = 0;
+}
+
+bool ProfileOptionsPage::matches(const QString &s) const
+{
+ return m_searchKeywords.contains(s, Qt::CaseInsensitive);
+}
+
+void ProfileOptionsPage::showProfile(Profile *p)
+{
+ m_toShow = p;
+}
+
+void ProfileOptionsPage::profileSelectionChanged()
+{
+ if (m_currentWidget)
+ m_currentWidget->setVisible(false);
+
+ QModelIndex current = currentIndex();
+ m_currentWidget = current.isValid() ? m_model->widget(current) : 0;
+
+ if (m_currentWidget)
+ m_currentWidget->setVisible(true);
+ updateState();
+}
+
+void ProfileOptionsPage::addNewProfile()
+{
+ Profile *p = new Profile;
+ m_model->markForAddition(p);
+
+ QModelIndex newIdx = m_model->indexOf(p);
+ m_selectionModel->select(newIdx,
+ QItemSelectionModel::Clear
+ | QItemSelectionModel::SelectCurrent
+ | QItemSelectionModel::Rows);
+}
+
+void ProfileOptionsPage::cloneProfile()
+{
+ Profile *clone = m_model->profile(currentIndex());
+ if (!clone)
+ return;
+
+ Profile *p = new Profile(*clone);
+
+ m_model->markForAddition(p);
+
+ QModelIndex newIdx = m_model->indexOf(p);
+ m_selectionModel->select(newIdx,
+ QItemSelectionModel::Clear
+ | QItemSelectionModel::SelectCurrent
+ | QItemSelectionModel::Rows);
+}
+
+void ProfileOptionsPage::removeProfile()
+{
+ Profile *p = m_model->profile(currentIndex());
+ if (!p)
+ return;
+ m_model->markForRemoval(p);
+}
+
+void ProfileOptionsPage::makeDefaultProfile()
+{
+ m_model->setDefaultProfile(currentIndex());
+ updateState();
+}
+
+void ProfileOptionsPage::updateState()
+{
+ if (!m_profilesView)
+ return;
+
+ bool canCopy = false;
+ bool canDelete = false;
+ bool canMakeDefault = false;
+ QModelIndex index = currentIndex();
+ Profile *p = m_model->profile(index);
+ if (p) {
+ canCopy = p->isValid();
+ canDelete = !p->isAutoDetected();
+ canMakeDefault = !m_model->isDefaultProfile(index);
+ }
+
+ m_cloneButton->setEnabled(canCopy);
+ m_delButton->setEnabled(canDelete);
+ m_makeDefaultButton->setEnabled(canMakeDefault);
+}
+
+QModelIndex ProfileOptionsPage::currentIndex() const
+{
+ if (!m_selectionModel)
+ return QModelIndex();
+
+ QModelIndexList idxs = m_selectionModel->selectedRows();
+ if (idxs.count() != 1)
+ return QModelIndex();
+ return idxs.at(0);
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/profileoptionspage.h b/src/plugins/projectexplorer/profileoptionspage.h
new file mode 100644
index 0000000000..ec60543cc4
--- /dev/null
+++ b/src/plugins/projectexplorer/profileoptionspage.h
@@ -0,0 +1,104 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROFILEOPTIONSPAGE_H
+#define PROFILEOPTIONSPAGE_H
+
+#include "projectexplorer_export.h"
+
+#include <coreplugin/dialogs/ioptionspage.h>
+
+#include <QModelIndex>
+
+QT_BEGIN_NAMESPACE
+class QItemSelectionModel;
+class QTreeView;
+class QPushButton;
+QT_END_NAMESPACE
+
+namespace ProjectExplorer {
+
+namespace Internal { class ProfileModel; }
+
+class Profile;
+class ProfileConfigWidget;
+class ProfileFactory;
+class ProfileManager;
+
+// --------------------------------------------------------------------------
+// ProfileOptionsPage:
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT ProfileOptionsPage : public Core::IOptionsPage
+{
+ Q_OBJECT
+
+public:
+ ProfileOptionsPage();
+
+ QWidget *createPage(QWidget *parent);
+ void apply();
+ void finish();
+ bool matches(const QString &) const;
+
+ void showProfile(Profile *p);
+
+private slots:
+ void profileSelectionChanged();
+ void addNewProfile();
+ void cloneProfile();
+ void removeProfile();
+ void makeDefaultProfile();
+ void updateState();
+
+private:
+ QModelIndex currentIndex() const;
+
+ QTreeView *m_profilesView;
+ QPushButton *m_addButton;
+ QPushButton *m_cloneButton;
+ QPushButton *m_delButton;
+ QPushButton *m_makeDefaultButton;
+
+ QWidget *m_configWidget;
+ QString m_searchKeywords;
+
+ Internal::ProfileModel *m_model;
+ QItemSelectionModel *m_selectionModel;
+ ProfileConfigWidget *m_currentWidget;
+
+ Profile *m_toShow;
+};
+
+} // namespace ProjectExplorer
+
+#endif // PROFILEOPTIONSPAGE_H
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index 2f7641ec83..c2ef837aa4 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -32,11 +32,14 @@
#include "project.h"
+#include "buildconfiguration.h"
+#include "deployconfiguration.h"
#include "editorconfiguration.h"
#include "environment.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "projectnodes.h"
+#include "runconfiguration.h"
#include "target.h"
#include "settingsaccessor.h"
@@ -44,6 +47,8 @@
#include <coreplugin/icontext.h>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/buildmanager.h>
+#include <projectexplorer/profile.h>
+#include <projectexplorer/profilemanager.h>
#include <limits>
#include <utils/qtcassert.h>
@@ -112,7 +117,7 @@ Project::~Project()
bool Project::hasActiveBuildSettings() const
{
- return activeTarget() && activeTarget()->buildConfigurationFactory();
+ return activeTarget() && IBuildConfigurationFactory::find(activeTarget());
}
QString Project::makeUnique(const QString &preferredName, const QStringList &usedNames)
@@ -143,7 +148,7 @@ void Project::changeBuildConfigurationEnabled()
void Project::addTarget(Target *t)
{
QTC_ASSERT(t && !d->m_targets.contains(t), return);
- QTC_ASSERT(!target(t->id()), return);
+ QTC_ASSERT(!target(t->profile()), return);
Q_ASSERT(t->project() == this);
// Check that we don't have a configuration with the same displayName
@@ -160,6 +165,10 @@ void Project::addTarget(Target *t)
SLOT(changeEnvironment()));
connect(t, SIGNAL(buildConfigurationEnabledChanged()),
this, SLOT(changeBuildConfigurationEnabled()));
+ connect(t, SIGNAL(requestBuildSystemEvaluation()),
+ this, SLOT(triggerBuildSystemEvaluation()));
+ connect(t, SIGNAL(buildDirectoryChanged()),
+ this, SLOT(onBuildDirectoryChanged()));
emit addedTarget(t);
// check activeTarget:
@@ -216,7 +225,7 @@ void Project::setActiveTarget(Target *target)
}
}
-Target *Project::target(Core::Id id) const
+Target *Project::target(const Core::Id id) const
{
foreach (Target * target, d->m_targets) {
if (target->id() == id)
@@ -225,6 +234,55 @@ Target *Project::target(Core::Id id) const
return 0;
}
+Target *Project::target(Profile *p) const
+{
+ foreach (Target *target, d->m_targets) {
+ if (target->profile() == p)
+ return target;
+ }
+ return 0;
+}
+
+bool Project::supportsProfile(Profile *p) const
+{
+ Q_UNUSED(p);
+ return true;
+}
+
+Target *Project::createTarget(Profile *p)
+{
+ if (target(p))
+ return 0;
+
+ Target *t = new Target(this, p);
+ t->createDefaultSetup();
+
+ return t;
+}
+
+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()));
+ return 0;
+ }
+
+ Profile *p = ProfileManager::instance()->find(id);
+ if (!p) {
+ qWarning("Warning: No profile '%s' found. Continuing.", qPrintable(id.toString()));
+ return 0;
+ }
+
+ Target *t = new Target(this, p);
+ if (!t->fromMap(data)) {
+ delete t;
+ return 0;
+ }
+ return t;
+}
+
void Project::saveSettings()
{
emit aboutToSaveSettings();
@@ -314,32 +372,15 @@ bool Project::fromMap(const QVariantMap &map)
}
QVariantMap targetMap = map.value(key).toMap();
- QList<ITargetFactory *> factories =
- ExtensionSystem::PluginManager::getObjects<ITargetFactory>();
-
- Target *t = 0;
+ Target *t = restoreTarget(targetMap);
+ if (!t)
+ continue;
- Core::Id id = idFromMap(targetMap);
- if (target(id)) {
- qWarning("Warning: Duplicated target id found, not restoring second target with id '%s'. Continuing.",
- qPrintable(id.toString()));
- } else {
- foreach (ITargetFactory *factory, factories) {
- if (factory->canRestore(this, targetMap)) {
- t = factory->restore(this, targetMap);
- break;
- }
- }
-
- if (!t) {
- qWarning("Warning: Unable to restore target '%s'. Continuing.", qPrintable(id.toString()));
- continue;
- }
- addTarget(t);
- if (i == active)
- setActiveTarget(t);
- }
+ addTarget(t);
+ if (i == active)
+ setActiveTarget(t);
}
+
return true;
}
@@ -363,6 +404,9 @@ void Project::setProjectLanguage(Core::Context language)
d->m_projectLanguage = language;
}
+void Project::evaluateBuildSystem()
+{ buildSystemEvaluationFinished(true); }
+
Core::Context Project::projectContext() const
{
return d->m_projectContext;
@@ -380,7 +424,10 @@ QVariant Project::namedSettings(const QString &name) const
void Project::setNamedSettings(const QString &name, QVariant &value)
{
- d->m_pluginSettings.insert(name, value);
+ if (value.isNull())
+ d->m_pluginSettings.remove(name);
+ else
+ d->m_pluginSettings.insert(name, value);
}
bool Project::needsConfiguration() const
@@ -393,4 +440,39 @@ void Project::configureAsExampleProject(const QStringList &platforms)
Q_UNUSED(platforms);
}
+void Project::triggerBuildSystemEvaluation()
+{
+ Target *target = qobject_cast<Target *>(sender());
+ if (target && target != activeTarget())
+ return;
+
+ evaluateBuildSystem();
+}
+
+void Project::buildSystemEvaluationFinished(bool success)
+{
+ if (!success)
+ return;
+
+ // Create new run configurations:
+ foreach (Target *t, targets())
+ t->updateDefaultRunConfigurations();
+
+ emit buildSystemEvaluated();
+}
+
+void Project::onBuildDirectoryInitialized()
+{
+ Target *target = qobject_cast<Target *>(sender());
+ if (target && target == activeTarget())
+ emit buildDirectoryInitialized();
+}
+
+void Project::onBuildDirectoryChanged()
+{
+ Target *target = qobject_cast<Target *>(sender());
+ if (target && target == activeTarget())
+ emit buildDirectoryChanged();
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index 49d0aec07b..20a5f58038 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -52,6 +52,7 @@ class BuildConfigWidget;
class IProjectManager;
class EditorConfiguration;
class ProjectNode;
+class Profile;
class Target;
class ProjectPrivate;
@@ -89,7 +90,12 @@ public:
// Note: activeTarget can be 0 (if no targets are defined).
Target *activeTarget() const;
void setActiveTarget(Target *target);
- Target *target(Core::Id id) const;
+ Target *target(const Core::Id id) const;
+ Target *target(Profile *p) const;
+ virtual bool supportsProfile(Profile *p) const;
+
+ Target *createTarget(Profile *p);
+ Target *restoreTarget(const QVariantMap &data);
void saveSettings();
bool restoreSettings();
@@ -120,6 +126,12 @@ public:
virtual bool needsConfiguration() const;
virtual void configureAsExampleProject(const QStringList &platforms);
+public slots:
+ void triggerBuildSystemEvaluation();
+
+protected slots:
+ void buildSystemEvaluationFinished(bool success);
+
signals:
void displayNameChanged();
void fileListChanged();
@@ -133,6 +145,11 @@ signals:
void environmentChanged();
void buildConfigurationEnabledChanged();
+ // The build directory of the current target/build configuration was successfully
+ // initialized (or configured).
+ void buildDirectoryInitialized();
+ void buildDirectoryChanged();
+ void buildSystemEvaluated();
void settingsLoaded();
void aboutToSaveSettings();
@@ -143,9 +160,18 @@ protected:
virtual void setProjectContext(Core::Context context);
virtual void setProjectLanguage(Core::Context language);
+ // Implement this to (re-)evaluate the build system of the project.
+ //
+ // This method is triggered by one of its active children (active*Configuration
+ // of the activeTarget) whenever some settings that has influence on the build
+ // system parsing is changed.
+ virtual void evaluateBuildSystem();
+
private slots:
void changeEnvironment();
void changeBuildConfigurationEnabled();
+ void onBuildDirectoryInitialized();
+ void onBuildDirectoryChanged();
private:
ProjectPrivate *d;
diff --git a/src/plugins/projectexplorer/projectconfiguration.cpp b/src/plugins/projectexplorer/projectconfiguration.cpp
index 78b3a05a25..bdb4718db7 100644
--- a/src/plugins/projectexplorer/projectconfiguration.cpp
+++ b/src/plugins/projectexplorer/projectconfiguration.cpp
@@ -41,7 +41,7 @@ const char DEFAULT_DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.De
ProjectConfiguration::ProjectConfiguration(QObject *parent, const Core::Id &id) :
QObject(parent),
m_id(id)
-{ }
+{ setObjectName(id.toString()); }
ProjectConfiguration::ProjectConfiguration(QObject *parent, const ProjectConfiguration *source) :
QObject(parent),
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 8d9ed394b4..dbc0fd66cb 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -37,6 +37,8 @@
#include "gcctoolchainfactories.h"
#include "project.h"
#include "projectexplorersettings.h"
+#include "profilemanager.h"
+#include "profileoptionspage.h"
#include "target.h"
#include "targetsettingspanel.h"
#include "toolchainmanager.h"
@@ -63,6 +65,7 @@
#include "processstep.h"
#include "projectexplorerconstants.h"
#include "customwizard.h"
+#include "profileinformation.h"
#include "projectfilewizardextension.h"
#include "projecttreewidget.h"
#include "projectwindow.h"
@@ -247,6 +250,8 @@ struct ProjectExplorerPluginPrivate {
Core::IMode *m_projectsMode;
TaskHub *m_taskHub;
+ ProfileManager *m_profileManager;
+ ToolChainManager *m_toolChainManager;
bool m_shuttingDown;
};
@@ -256,6 +261,8 @@ ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() :
m_delayedRunConfiguration(0),
m_runMode(NoRunMode),
m_projectsMode(0),
+ m_profileManager(0),
+ m_toolChainManager(0),
m_shuttingDown(false)
{
}
@@ -295,6 +302,10 @@ ProjectExplorerPlugin::~ProjectExplorerPlugin()
removeObject(d->m_welcomePage);
delete d->m_welcomePage;
removeObject(this);
+ // Force sequence of deletion:
+ delete d->m_profileManager; // remove all the profile informations
+ delete d->m_toolChainManager;
+
delete d;
}
@@ -334,8 +345,10 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
addAutoReleasedObject(new Internal::DesktopDeviceFactory);
- new ToolChainManager(this);
+ d->m_profileManager = new ProfileManager; // register before ToolChainManager
+ d->m_toolChainManager = new ToolChainManager;
addAutoReleasedObject(new Internal::ToolChainOptionsPage);
+ addAutoReleasedObject(new ProfileOptionsPage);
d->m_taskHub = new TaskHub;
addAutoReleasedObject(d->m_taskHub);
@@ -1095,15 +1108,17 @@ void ProjectExplorerPlugin::extensionsInitialized()
addAutoReleasedObject(pf);
}
d->m_buildManager->extensionsInitialized();
-}
-bool ProjectExplorerPlugin::delayedInitialize()
-{
+ // Register ProfileInformation:
+ // Only do this now to make sure all device factories were properly initialized.
+ ProfileManager::instance()->registerProfileInformation(new SysRootProfileInformation);
+ ProfileManager::instance()->registerProfileInformation(new DeviceProfileInformation);
+ ProfileManager::instance()->registerProfileInformation(new DeviceTypeProfileInformation);
+ ProfileManager::instance()->registerProfileInformation(new ToolChainProfileInformation);
+
DeviceManager *dm = DeviceManager::instance();
if (dm->find(Core::Id(Constants::DESKTOP_DEVICE_ID)).isNull())
DeviceManager::instance()->addDevice(IDevice::Ptr(new DesktopDevice));
-
- return true;
}
void ProjectExplorerPlugin::loadCustomWizards()
@@ -2623,6 +2638,9 @@ void ProjectExplorerPlugin::addExistingFiles(const QStringList &filePaths)
void ProjectExplorerPlugin::addExistingFiles(ProjectNode *projectNode, const QStringList &filePaths)
{
+ if (!projectNode) // can happen when project is not yet parsed
+ return;
+
const QString dir = directoryFor(projectNode);
QStringList fileNames = filePaths;
QHash<FileType, QString> fileTypeToFiles;
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index 489db72b59..2037050f8d 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -105,7 +105,6 @@ public:
//PluginInterface
bool initialize(const QStringList &arguments, QString *errorMessage);
void extensionsInitialized();
- bool delayedInitialize();
ShutdownFlag aboutToShutdown();
void setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes);
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index a9b64a52b8..9f8c632f53 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -20,6 +20,14 @@ HEADERS += projectexplorer.h \
gcctoolchain.h \
projectexplorer_export.h \
projectwindow.h \
+ profile.h \
+ profileconfigwidget.h \
+ profileinformation.h \
+ profileinformationconfigwidget.h \
+ profilemanager.h \
+ profilemanagerconfigwidget.h \
+ profilemodel.h \
+ profileoptionspage.h \
buildmanager.h \
buildsteplist.h \
compileoutputwindow.h \
@@ -122,6 +130,13 @@ SOURCES += projectexplorer.cpp \
clangparser.cpp \
gcctoolchain.cpp \
projectwindow.cpp \
+ profile.cpp \
+ profileinformation.cpp \
+ profileinformationconfigwidget.cpp \
+ profilemanager.cpp \
+ profilemanagerconfigwidget.cpp \
+ profilemodel.cpp \
+ profileoptionspage.cpp \
buildmanager.cpp \
buildsteplist.cpp \
compileoutputwindow.cpp \
@@ -209,7 +224,6 @@ SOURCES += projectexplorer.cpp \
devicesupport/devicesettingspage.cpp
FORMS += processstep.ui \
- toolchainoptionspage.ui \
editorsettingspropertiespage.ui \
sessiondialog.ui \
projectwizardpage.ui \
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index a59814d774..f5684dc478 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -108,6 +108,21 @@ QtcPlugin {
"processparameters.h",
"processstep.cpp",
"processstep.h",
+ "profile.cpp",
+ "profile.h",
+ "profileconfigwidget.h",
+ "profileinformation.cpp",
+ "profileinformation.h",
+ "profileinformationconfigwidget.cpp",
+ "profileinformationconfigwidget.h",
+ "profilemanager.cpp",
+ "profilemanager.h",
+ "profilemanagerconfigwidget.cpp",
+ "profilemanagerconfigwidget.h",
+ "profilemodel.cpp",
+ "profilemodel.h",
+ "profileoptionspage.cpp",
+ "profileoptionspage.h",
"project.cpp",
"project.h",
"projectconfiguration.cpp",
@@ -158,7 +173,6 @@ QtcPlugin {
"toolchainconfigwidget.h",
"toolchainmanager.h",
"toolchainoptionspage.h",
- "toolchainoptionspage.ui",
"vcsannotatetaskhandler.h",
"environmentitemswidget.h",
"abi.cpp",
diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h
index 04fcd6cf17..f7d984a515 100644
--- a/src/plugins/projectexplorer/projectexplorerconstants.h
+++ b/src/plugins/projectexplorer/projectexplorerconstants.h
@@ -182,6 +182,7 @@ const char PROJECTEXPLORER_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("ProjectEx
const char PROJECTEXPLORER_SETTINGS_CATEGORY_ICON[] = ":/core/images/category_buildrun.png";
const char PROJECTEXPLORER_SETTINGS_ID[] = "A.ProjectExplorer.ProjectExplorer";
const char TOOLCHAIN_SETTINGS_PAGE_ID[] = "M.ProjectExplorer.ToolChainOptions";
+const char PROFILE_SETTINGS_PAGE_ID[] = "D.ProjectExplorer.ProfileOptions";
// Device settings page
const char DEVICE_SETTINGS_CATEGORY[] = "X.Devices";
diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp
index 9707b49e13..1ef5d92720 100644
--- a/src/plugins/projectexplorer/projectwindow.cpp
+++ b/src/plugins/projectexplorer/projectwindow.cpp
@@ -34,6 +34,7 @@
#include "doubletabwidget.h"
+#include "profilemanager.h"
#include "project.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
@@ -128,7 +129,7 @@ PanelsWidget::PanelsWidget(QWidget *parent) :
// side of the screen.
m_root->setFixedWidth(900);
m_root->setContentsMargins(0, 0, 40, 0);
-
+
QPalette pal = m_root->palette();
QColor background = Utils::StyleHelper::mergedColors(
palette().window().color(), Qt::white, 85);
@@ -262,9 +263,7 @@ ProjectWindow::~ProjectWindow()
void ProjectWindow::extensionsInitialized()
{
- foreach (ITargetFactory *fac, ExtensionSystem::PluginManager::getObjects<ITargetFactory>())
- connect(fac, SIGNAL(canCreateTargetIdsChanged()),
- this, SLOT(targetFactoriesChanged()));
+ connect(ProfileManager::instance(), SIGNAL(profilesChanged()), this, SLOT(handleProfilesChanges()));
QList<IProjectPanelFactory *> list = ExtensionSystem::PluginManager::getObjects<IProjectPanelFactory>();
qSort(list.begin(), list.end(), &IPanelFactory::prioritySort);
@@ -286,7 +285,7 @@ void ProjectWindow::projectUpdated(Project *p)
m_tabWidget->setCurrentIndex(index);
}
-void ProjectWindow::targetFactoriesChanged()
+void ProjectWindow::handleProfilesChanges()
{
bool changed = false;
int index = m_tabWidget->currentIndex();
@@ -309,13 +308,12 @@ bool ProjectWindow::useTargetPage(ProjectExplorer::Project *project)
if (project->targets().size() > 1)
return true;
int count = 0;
- foreach (ITargetFactory *fac, ExtensionSystem::PluginManager::getObjects<ITargetFactory>()) {
- foreach (Core::Id targetId, fac->supportedTargetIds()) {
- if (fac->canCreate(project, targetId))
- ++count;
- if (count > 1)
- return true;
- }
+ QList<Profile *> profiles = ProfileManager::instance()->profiles();
+ foreach (Profile *p, profiles) {
+ if (project->supportsProfile(p))
+ ++count;
+ if (count > 1)
+ return true;
}
return false;
}
diff --git a/src/plugins/projectexplorer/projectwindow.h b/src/plugins/projectexplorer/projectwindow.h
index 1a15fad6af..5a5ec3385b 100644
--- a/src/plugins/projectexplorer/projectwindow.h
+++ b/src/plugins/projectexplorer/projectwindow.h
@@ -87,7 +87,7 @@ public slots:
void projectUpdated(ProjectExplorer::Project *p);
private slots:
- void targetFactoriesChanged();
+ void handleProfilesChanges();
void showProperties(int index, int subIndex);
void registerProject(ProjectExplorer::Project*);
void deregisterProject(ProjectExplorer::Project*);
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index d445dcb1ec..d4cada4b63 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -38,6 +38,7 @@
#include "abi.h"
#include "buildconfiguration.h"
#include "projectexplorerconstants.h"
+#include "profileinformation.h"
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
@@ -66,91 +67,6 @@ const char USE_QML_DEBUGGER_AUTO_KEY[] = "RunConfiguration.UseQmlDebuggerAuto";
const char QML_DEBUG_SERVER_PORT_KEY[] = "RunConfiguration.QmlDebugServerPort";
const char USE_MULTIPROCESS_KEY[] = "RunConfiguration.UseMultiProcess";
-// Function objects:
-
-class RunConfigurationFactoryMatcher
-{
-public:
- RunConfigurationFactoryMatcher(Target * target) : m_target(target)
- { }
-
- virtual ~RunConfigurationFactoryMatcher() { }
-
- virtual bool operator()(IRunConfigurationFactory *) const = 0;
-
- Target *target() const
- {
- return m_target;
- }
-
-private:
- Target *m_target;
-};
-
-class CreateMatcher : public RunConfigurationFactoryMatcher
-{
-public:
- CreateMatcher(Target *target, const Core::Id id) :
- RunConfigurationFactoryMatcher(target),
- m_id(id)
- { }
-
- bool operator()(IRunConfigurationFactory *factory) const
- {
- return factory->canCreate(target(), m_id);
- }
-
-private:
- const Core::Id m_id;
-};
-
-class CloneMatcher : public RunConfigurationFactoryMatcher
-{
-public:
- CloneMatcher(Target *target, RunConfiguration *source) :
- RunConfigurationFactoryMatcher(target),
- m_source(source)
- { }
-
- bool operator()(IRunConfigurationFactory *factory) const
- {
- return factory->canClone(target(), m_source);
- }
-
-private:
- RunConfiguration *m_source;
-};
-
-class RestoreMatcher : public RunConfigurationFactoryMatcher
-{
-public:
- RestoreMatcher(Target *target, const QVariantMap &map) :
- RunConfigurationFactoryMatcher(target),
- m_map(map)
- { }
-
- bool operator()(IRunConfigurationFactory *factory) const
- {
- return factory->canRestore(target(), m_map);
- }
-
-private:
- QVariantMap m_map;
-};
-
-// Helper methods:
-
-IRunConfigurationFactory *findRunConfigurationFactory(RunConfigurationFactoryMatcher &matcher)
-{
- QList<IRunConfigurationFactory *> factories
- = ExtensionSystem::PluginManager::getObjects<IRunConfigurationFactory>();
- foreach (IRunConfigurationFactory *factory, factories) {
- if (matcher(factory))
- return factory;
- }
- return 0;
-}
-
} // namespace
/*!
@@ -404,6 +320,11 @@ QString RunConfiguration::disabledReason() const
return QString();
}
+bool RunConfiguration::isConfigured() const
+{
+ return true;
+}
+
/*!
\fn virtual QWidget *ProjectExplorer::RunConfiguration::createConfigurationWidget()
@@ -439,7 +360,7 @@ ProjectExplorer::Abi RunConfiguration::abi() const
BuildConfiguration *bc = target()->activeBuildConfiguration();
if (!bc)
return Abi::hostAbi();
- ToolChain *tc = bc->toolChain();
+ ToolChain *tc = ProjectExplorer::ToolChainProfileInformation::toolChain(target()->profile());
if (!tc)
return Abi::hostAbi();
return tc->targetAbi();
@@ -516,22 +437,27 @@ IRunConfigurationFactory::~IRunConfigurationFactory()
{
}
-IRunConfigurationFactory *IRunConfigurationFactory::createFactory(Target *parent, const Core::Id id)
+IRunConfigurationFactory *IRunConfigurationFactory::find(Target *parent, const QVariantMap &map)
{
- CreateMatcher matcher(parent, id);
- return findRunConfigurationFactory(matcher);
-}
-
-IRunConfigurationFactory *IRunConfigurationFactory::cloneFactory(Target *parent, RunConfiguration *source)
-{
- CloneMatcher matcher(parent, source);
- return findRunConfigurationFactory(matcher);
+ QList<IRunConfigurationFactory *> factories
+ = ExtensionSystem::PluginManager::instance()->getObjects<IRunConfigurationFactory>();
+ foreach (IRunConfigurationFactory *factory, factories) {
+ if (factory->canRestore(parent, map))
+ return factory;
+ }
+ return 0;
}
-IRunConfigurationFactory *IRunConfigurationFactory::restoreFactory(Target *parent, const QVariantMap &map)
+QList<IRunConfigurationFactory *> IRunConfigurationFactory::find(Target *parent)
{
- RestoreMatcher matcher(parent, map);
- return findRunConfigurationFactory(matcher);
+ QList<IRunConfigurationFactory *> factories
+ = ExtensionSystem::PluginManager::instance()->getObjects<IRunConfigurationFactory>();
+ QList<IRunConfigurationFactory *> result;
+ foreach (IRunConfigurationFactory *factory, factories) {
+ if (!factory->availableCreationIds(parent).isEmpty())
+ result << factory;
+ }
+ return result;
}
/*!
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index 78a523e4b9..4d145370b7 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -147,18 +147,19 @@ class PROJECTEXPLORER_EXPORT RunConfiguration : public ProjectConfiguration
Q_OBJECT
public:
- virtual ~RunConfiguration();
+ ~RunConfiguration();
virtual bool isEnabled() const;
virtual QString disabledReason() const;
virtual QWidget *createConfigurationWidget() = 0;
+ virtual bool isConfigured() const;
Target *target() const;
virtual Utils::OutputFormatter *createOutputFormatter() const;
- virtual bool fromMap(const QVariantMap &map);
- virtual QVariantMap toMap() const;
+ bool fromMap(const QVariantMap &map);
+ QVariantMap toMap() const;
DebuggerRunConfigurationAspect *debuggerAspect() const { return m_debuggerAspect; }
@@ -212,9 +213,8 @@ public:
virtual bool canClone(Target *parent, RunConfiguration *product) const = 0;
virtual RunConfiguration *clone(Target *parent, RunConfiguration *product) = 0;
- static IRunConfigurationFactory *createFactory(Target *parent, const Core::Id id);
- static IRunConfigurationFactory *cloneFactory(Target *parent, RunConfiguration *source);
- static IRunConfigurationFactory *restoreFactory(Target *parent, const QVariantMap &map);
+ static IRunConfigurationFactory *find(Target *parent, const QVariantMap &map);
+ static QList<IRunConfigurationFactory *> find(Target *parent);
signals:
void availableCreationIdsChanged();
diff --git a/src/plugins/projectexplorer/runconfigurationmodel.cpp b/src/plugins/projectexplorer/runconfigurationmodel.cpp
index 66fc77ec7d..e047451d72 100644
--- a/src/plugins/projectexplorer/runconfigurationmodel.cpp
+++ b/src/plugins/projectexplorer/runconfigurationmodel.cpp
@@ -182,6 +182,9 @@ void RunConfigurationModel::addedRunConfiguration(ProjectExplorer::RunConfigurat
void RunConfigurationModel::removedRunConfiguration(ProjectExplorer::RunConfiguration *rc)
{
int i = m_runConfigurations.indexOf(rc);
+ if (i < 0)
+ return;
+
beginRemoveRows(QModelIndex(), i, i);
m_runConfigurations.removeAt(i);
endRemoveRows();
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
index d0497bfcbf..b9c7b8b4c3 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
@@ -292,6 +292,7 @@ void RunSettingsWidget::addRunConfiguration()
RunConfiguration *newRC = fai.factory->create(m_target, fai.id);
if (!newRC)
return;
+ QTC_CHECK(newRC->id() == fai.id);
m_target->addRunConfiguration(newRC);
m_target->setActiveRunConfiguration(newRC);
m_removeRunToolButton->setEnabled(m_target->runConfigurations().size() > 1);
@@ -370,9 +371,12 @@ void RunSettingsWidget::currentDeployConfigurationChanged(int index)
void RunSettingsWidget::aboutToShowDeployMenu()
{
m_addDeployMenu->clear();
- QList<Core::Id> ids = m_target->availableDeployConfigurationIds();
+ DeployConfigurationFactory *factory = DeployConfigurationFactory::find(m_target);
+ if (!factory)
+ return;
+ QList<Core::Id> ids = factory->availableCreationIds(m_target);
foreach (Core::Id id, ids) {
- QAction *action = m_addDeployMenu->addAction(m_target->displayNameForDeployConfigurationId(id));
+ QAction *action = m_addDeployMenu->addAction(factory->displayNameForId(id));
action->setData(QVariant::fromValue(id));
connect(action, SIGNAL(triggered()),
this, SLOT(addDeployConfiguration()));
@@ -385,9 +389,18 @@ void RunSettingsWidget::addDeployConfiguration()
if (!act)
return;
Core::Id id = act->data().value<Core::Id>();
- DeployConfiguration *newDc = m_target->createDeployConfiguration(id);
+ DeployConfigurationFactory *factory = DeployConfigurationFactory::find(m_target);
+ if (!factory)
+ return;
+ DeployConfiguration *newDc = 0;
+ foreach (Core::Id id, factory->availableCreationIds(m_target)) {
+ if (!factory->canCreate(m_target, id))
+ continue;
+ newDc = factory->create(m_target, id);
+ }
if (!newDc)
return;
+ QTC_CHECK(!newDc || newDc->id() == id);
m_target->addDeployConfiguration(newDc);
m_target->setActiveDeployConfiguration(newDc);
m_removeDeployToolButton->setEnabled(m_target->deployConfigurations().size() > 1);
diff --git a/src/plugins/projectexplorer/settingsaccessor.cpp b/src/plugins/projectexplorer/settingsaccessor.cpp
index d19eadf5f8..f3330fbdde 100644
--- a/src/plugins/projectexplorer/settingsaccessor.cpp
+++ b/src/plugins/projectexplorer/settingsaccessor.cpp
@@ -38,9 +38,12 @@
#include "projectexplorersettings.h"
#include "projectexplorerconstants.h"
#include "target.h"
+#include "profile.h"
+#include "profilemanager.h"
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
+#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/persistentsettings.h>
@@ -341,6 +344,52 @@ public:
QVariantMap update(Project *project, const QVariantMap &map);
};
+// Version 10 introduces disabling buildsteps, and handles upgrading custom process steps
+class Version11Handler : public UserFileVersionHandler
+{
+public:
+ Version11Handler();
+ ~Version11Handler();
+
+ int userFileVersion() const
+ {
+ return 11;
+ }
+
+ QString displayUserFileVersion() const
+ {
+ return QLatin1String("2.6pre1");
+ }
+
+ QVariantMap update(Project *project, const QVariantMap &map);
+
+private:
+ void addBuildConfiguration(const QString &origTarget, Profile *p,
+ bool targetActive,
+ const QVariantMap &bc, bool bcActive);
+ void addOtherConfiguration(const QString &origTarget,
+ const QList<QVariantMap> &dcs, int activeDc,
+ const QList<QVariantMap> &rcs, int activeRc);
+
+ void parseQtversionFile();
+ void parseToolChainFile();
+
+ class ToolChainExtraData {
+ public:
+ explicit ToolChainExtraData(const QString &mks = QString(), const QString &d = QString()) :
+ m_mkspec(mks), m_debugger(d)
+ { }
+
+ QString m_mkspec;
+ QString m_debugger;
+ };
+
+ QHash<QString, ToolChainExtraData> m_toolChainExtras;
+ QHash<int, QString> m_qtVersionExtras;
+
+ QHash<Profile *, QVariantMap> m_targets;
+};
+
} // namespace
//
@@ -429,6 +478,7 @@ SettingsAccessor::SettingsAccessor() :
addVersionHandler(new Version8Handler);
addVersionHandler(new Version9Handler);
addVersionHandler(new Version10Handler);
+ addVersionHandler(new Version11Handler);
}
SettingsAccessor::~SettingsAccessor()
@@ -2277,3 +2327,287 @@ QVariantMap Version10Handler::update(Project *project, const QVariantMap &map)
QLatin1String("ProjectExplorer.BuildStep.Enabled")));
return renameKeys(changes, QVariantMap(map));
}
+
+Version11Handler::Version11Handler()
+{
+ parseQtversionFile();
+ parseToolChainFile();
+}
+
+Version11Handler::~Version11Handler()
+{
+ ProfileManager *pm = ProfileManager::instance();
+ if (!pm) // Can happen during teardown!
+ return;
+ QList<Profile *> knownProfiles = pm->profiles();
+ foreach (Profile *p, m_targets.keys()) {
+ if (!knownProfiles.contains(p))
+ delete p;
+ }
+ m_targets.clear();
+}
+
+QVariantMap Version11Handler::update(Project *project, const QVariantMap &map)
+{
+ Q_UNUSED(project);
+ QVariantMap result;
+ ProfileManager *pm = ProfileManager::instance();
+
+ foreach (Profile *p, pm->profiles())
+ m_targets.insert(p, QVariantMap());
+
+ QMapIterator<QString, QVariant> globalIt(map);
+ int activeTarget = map.value(QLatin1String("ProjectExplorer.Project.ActiveTarget"), 0).toInt();
+
+ while (globalIt.hasNext()) {
+ globalIt.next();
+ const QString &globalKey = globalIt.key();
+ // Keep everything but targets:
+ if (!globalKey.startsWith(QLatin1String("ProjectExplorer.Project.Target."))) {
+ result.insert(globalKey, globalIt.value());
+ continue;
+ }
+
+ // Update Targets:
+ const QVariantMap &target = globalIt.value().toMap();
+ int targetPos = globalKey.mid(globalKey.lastIndexOf(QLatin1Char('.'))).toInt();
+
+ QVariantMap extraTargetData;
+ QList<QVariantMap> bcs;
+ int activeBc = -1;
+ QList<QVariantMap> dcs;
+ int activeDc = -1;
+ QList<QVariantMap> rcs;
+ int activeRc = -1;
+
+ // Read old target:
+ QMapIterator<QString, QVariant> targetIt(target);
+ while (targetIt.hasNext()) {
+ targetIt.next();
+ const QString &targetKey = targetIt.key();
+ QList<QVariantMap> newTargets;
+ // BuildConfigurations:
+ if (targetKey == QLatin1String("ProjectExplorer.Target.ActiveBuildConfiguration"))
+ activeBc = targetIt.value().toInt();
+ else if (targetKey == QLatin1String("ProjectExplorer.Target.BuildConfigurationCount"))
+ continue;
+ else if (targetKey.startsWith(QLatin1String("ProjectExplorer.Target.BuildConfiguration.")))
+ bcs.append(targetIt.value().toMap());
+ else
+
+ // DeployConfigurations:
+ if (targetKey == QLatin1String("ProjectExplorer.Target.ActiveDeployConfiguration"))
+ activeDc = targetIt.value().toInt();
+ else if (targetKey == QLatin1String("ProjectExplorer.Target.DeployConfigurationCount"))
+ continue;
+ else if (targetKey.startsWith(QLatin1String("ProjectExplorer.Target.DeployConfiguration.")))
+ dcs.append(targetIt.value().toMap());
+ else
+
+ // RunConfigurations:
+ if (targetKey == QLatin1String("ProjectExplorer.Target.ActiveRunConfiguration"))
+ activeRc = targetIt.value().toInt();
+ else if (targetKey == QLatin1String("ProjectExplorer.Target.RunConfigurationCount"))
+ continue;
+ else if (targetKey.startsWith(QLatin1String("ProjectExplorer.Target.RunConfiguration.")))
+ rcs.append(targetIt.value().toMap());
+
+ // Rest (the target's ProjectConfiguration QList<QVariantMap> newTargets; related settings only as there is nothing else)
+ else
+ extraTargetData.insert(targetKey, targetIt.value());
+ }
+
+ const QString targetId = extraTargetData.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString();
+ // Check each BCs/DCs and create profiles as needed
+ int bcPos = 0;
+ foreach (const QVariantMap &bc, bcs) {
+ const QString targetId = extraTargetData.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString();
+ Profile *tmp = new Profile;
+ tmp->setDisplayName(extraTargetData.value(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName")).toString());
+
+ if (targetId == QLatin1String("Qt4ProjectManager.Target.AndroidDeviceTarget"))
+ tmp->setIconPath(QLatin1String(":/android/images/QtAndroid.png"));
+ else if (targetId == QLatin1String("Qt4ProjectManager.Target.HarmattanDeviceTarget"))
+ tmp->setIconPath(QLatin1String(":/projectexplorer/images/MaemoDevice.png"));
+ else if (targetId == QLatin1String("Qt4ProjectManager.Target.MaemoDeviceTarget"))
+ tmp->setIconPath(QLatin1String(":/projectexplorer/images/MaemoDevice.png"));
+ else if (targetId == QLatin1String("Qt4ProjectManager.Target.MeegoDeviceTarget"))
+ tmp->setIconPath(QLatin1String(":/projectexplorer/images/MaemoDevice.png"));
+ else if (targetId == QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget"))
+ tmp->setIconPath(QLatin1String(":/projectexplorer/images/SymbianDevice.png"));
+ else if (targetId == QLatin1String("Qt4ProjectManager.Target.QtSimulatorTarget"))
+ tmp->setIconPath(QLatin1String(":/projectexplorer/images/SymbianEmulator.png"));
+ // use default desktop icon
+
+ // Tool chain
+ QString tcId = bc.value(QLatin1String("CMakeProjectManager.CMakeBuildConfiguration.ToolChain")).toString();
+ if (tcId.isEmpty())
+ tcId = bc.value(QLatin1String("ProjectExplorer.BuildCOnfiguration.ToolChain")).toString();
+ tmp->setValue(Core::Id("PE.Profile.ToolChain"), tcId);
+
+ // QtVersion
+ int qtVersionId = bc.value(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId"), -1).toInt();
+ tmp->setValue(Core::Id("QtSupport.QtInformation"), qtVersionId);
+
+ // Debugger + mkspec
+ if (m_toolChainExtras.contains(tcId)) {
+ tmp->setValue(Core::Id("Debugger.Information"), m_toolChainExtras.value(tcId).m_debugger);
+ tmp->setValue(Core::Id("QtPM4.mkSpecInformation"), m_toolChainExtras.value(tcId).m_mkspec);
+ }
+
+ // SysRoot
+ if (m_qtVersionExtras.contains(qtVersionId))
+ tmp->setValue(Core::Id("PE.Profile.SysRoot"), m_qtVersionExtras.value(qtVersionId));
+
+ // Device
+ if (dcs.isEmpty()) {
+ QByteArray devId;
+ if (targetId == QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget"))
+ devId = QByteArray("Symbian Device");
+ else
+ devId = QByteArray("Desktop Device");
+
+ tmp->setValue(Core::Id("PE.Profile.Device"), devId);
+ } else {
+ foreach (const QVariantMap &dc, dcs) {
+ QByteArray devId = dc.value(QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.DeviceId")).toString().toUtf8();
+ if (devId.isEmpty())
+ devId = QByteArray("Desktop Device");
+ tmp->setValue(Core::Id("PE.Profile.Device"), devId);
+ } // dcs
+ }
+
+ addBuildConfiguration(targetId, tmp, activeTarget == targetPos, bc, bcPos == activeBc);
+
+ ++bcPos;
+ } // bcs
+
+ addOtherConfiguration(targetId, dcs, activeDc, rcs, activeRc);
+ }
+
+ int newPos = 0;
+ QList<Profile *> knownProfiles = pm->profiles();
+ // Generate new target data:
+ foreach (Profile *p, m_targets.keys()) {
+ QVariantMap data = m_targets.value(p);
+ if (data.isEmpty())
+ continue;
+
+ if (!knownProfiles.contains(p))
+ pm->registerProfile(p);
+
+ data.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), p->id().name());
+ data.insert(QLatin1String("ProjectExplorer.Target.Profile"), p->id().name());
+ data.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"), p->displayName());
+ data.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DefaultDisplayName"), p->displayName());
+
+ result.insert(QString::fromLatin1("ProjectExplorer.Project.Target.") + QString::number(newPos), data);
+ if (data.value(QLatin1String("IsActive"), false).toBool())
+ result.insert(QLatin1String("ProjectExplorer.Project.ActiveTarget"), newPos);
+ ++newPos;
+ }
+ result.insert(QLatin1String("ProjectExplorer.Project.TargetCount"), newPos);
+
+ return result;
+}
+
+void Version11Handler::addBuildConfiguration(const QString &origTarget, Profile *p, bool targetActive,
+ const QVariantMap &bc, bool bcActive)
+{
+ foreach (Profile *i, m_targets.keys()) {
+ if (*i == *p) {
+ delete p;
+ p = i;
+ }
+ }
+ QVariantMap merged = m_targets.value(p);
+
+ int bcCount = merged.value(QLatin1String("ProjectExplorer.Target.BuildConfigurationCount"), 0).toInt();
+ merged.insert(QString::fromLatin1("ProjectExplorer.Target.BuildConfiguration.") + QString::number(bcCount), bc);
+ if (bcActive)
+ merged.insert(QLatin1String("ProjectExplorer.Target.ActiveBuildConfiguration"), bcCount);
+ merged.insert(QLatin1String("ProjectExplorer.Target.BuildConfigurationCount"), bcCount + 1);
+
+ if (targetActive && bcActive)
+ merged.insert(QLatin1String("Update.IsActive"), true);
+ merged.insert(QLatin1String("Update.OriginalTarget"), origTarget);
+
+ m_targets.insert(p, merged);
+}
+
+void Version11Handler::addOtherConfiguration(const QString &origTarget, const QList<QVariantMap> &dcs, int activeDc, const QList<QVariantMap> &rcs, int activeRc)
+{
+ foreach (Profile *tmp, m_targets.keys()) {
+ QVariantMap data = m_targets.value(tmp);
+ if (data.isEmpty())
+ continue;
+ const QString dataTarget = data.value(QLatin1String("Update.OriginalTarget")).toString();
+ if (dataTarget != origTarget)
+ continue;
+
+ int dcCount = dcs.count();
+ data.insert(QLatin1String("ProjectExplorer.Target.DeployConfigurationCount"), dcCount);
+ for (int i = 0; i < dcCount; ++i)
+ data.insert(QString::fromLatin1("ProjectExplorer.Target.DeployConfiguration.") + QString::number(i), dcs.at(i));
+ data.insert(QLatin1String("ProjectExplorer.Target.ActiveDeployConfiguration"), activeDc);
+
+ int rcCount = rcs.count();
+ data.insert(QLatin1String("ProjectExplorer.Target.RunConfigurationCount"), rcCount);
+ for (int i = 0; i < rcCount; ++i)
+ data.insert(QString::fromLatin1("ProjectExplorer.Target.RunConfiguration.") + QString::number(i), rcs.at(i));
+ data.insert(QLatin1String("ProjectExplorer.Target.ActiveRunConfiguration"), activeRc);
+
+ m_targets.insert(tmp, data);
+ }
+}
+
+void Version11Handler::parseQtversionFile()
+{
+ ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+ QFileInfo settingsLocation(pm->settings()->fileName());
+ QString fileName = settingsLocation.absolutePath() + QLatin1String("/qtversion.xml");
+ Utils::PersistentSettingsReader reader;
+ if (!reader.load(fileName))
+ return;
+ QVariantMap data = reader.restoreValues();
+
+ int count = data.value(QLatin1String("QtVersion.Count"), 0).toInt();
+ for (int i = 0; i < count; ++i) {
+ const QString key = QString::fromLatin1("QtVersion.") + QString::number(i);
+ if (!data.contains(key))
+ continue;
+
+ const QVariantMap qtversionMap = data.value(key).toMap();
+ QString sysRoot = qtversionMap.value(QLatin1String("SystemRoot")).toString();
+ int id = qtversionMap.value(QLatin1String("Id")).toInt();
+ if (id > -1 && !sysRoot.isEmpty())
+ m_qtVersionExtras.insert(id, sysRoot);
+ }
+}
+
+void Version11Handler::parseToolChainFile()
+{
+ ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+ QFileInfo settingsLocation(pm->settings()->fileName());
+ QString fileName = settingsLocation.absolutePath() + QLatin1String("/toolChains.xml");
+ Utils::PersistentSettingsReader reader;
+ if (!reader.load(fileName))
+ return;
+ QVariantMap data = reader.restoreValues();
+ int count = data.value(QLatin1String("ToolChain.Count"), 0).toInt();
+ for (int i = 0; i < count; ++i) {
+ const QString key = QString::fromLatin1("ToolChain.") + QString::number(i);
+ if (!data.contains(key))
+ continue;
+
+ const QVariantMap tcMap = data.value(key).toMap();
+ QString id = tcMap.value(QLatin1String("ProjectExplorer.ToolChain.Id")).toString();
+ if (id.isEmpty())
+ continue;
+ QString mkspec = tcMap.value(QLatin1String("ProjectExplorer.ToolChain.MkSpecOverride")).toString();
+ QString debugger = tcMap.value(QLatin1String("ProjectExplorer.GccToolChain.Debugger")).toString();
+
+ m_toolChainExtras.insert(id, ToolChainExtraData(mkspec, debugger));
+ }
+}
+
diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp
index a3a86af7a1..a35c37aca7 100644
--- a/src/plugins/projectexplorer/target.cpp
+++ b/src/plugins/projectexplorer/target.cpp
@@ -32,13 +32,14 @@
#include "target.h"
-#include "toolchain.h"
+#include "profile.h"
+#include "profileinformation.h"
+#include "profilemanager.h"
#include "buildconfiguration.h"
#include "deployconfiguration.h"
#include "project.h"
#include "projectexplorerconstants.h"
#include "runconfiguration.h"
-#include "toolchainmanager.h"
#include <limits>
#include <coreplugin/coreconstants.h>
@@ -48,6 +49,7 @@
#include <projectexplorer/projectexplorer.h>
#include <utils/qtcassert.h>
+#include <QDebug>
#include <QIcon>
#include <QPainter>
@@ -94,6 +96,8 @@ public:
QPixmap m_connectedPixmap;
QPixmap m_readyToUsePixmap;
QPixmap m_disconnectedPixmap;
+
+ Profile *m_profile;
};
TargetPrivate::TargetPrivate() :
@@ -103,7 +107,8 @@ TargetPrivate::TargetPrivate() :
m_activeRunConfiguration(0),
m_connectedPixmap(QLatin1String(":/projectexplorer/images/DeviceConnected.png")),
m_readyToUsePixmap(QLatin1String(":/projectexplorer/images/DeviceReadyToUse.png")),
- m_disconnectedPixmap(QLatin1String(":/projectexplorer/images/DeviceDisconnected.png"))
+ m_disconnectedPixmap(QLatin1String(":/projectexplorer/images/DeviceDisconnected.png")),
+ m_profile(0)
{
}
@@ -113,16 +118,28 @@ QList<DeployConfigurationFactory *> TargetPrivate::deployFactories() const
}
-Target::Target(Project *project, const Core::Id id) :
- ProjectConfiguration(project, id),
+Target::Target(Project *project, Profile *p) :
+ ProjectConfiguration(project, p->id()),
d(new TargetPrivate)
{
connect(DeviceManager::instance(), SIGNAL(updated()), this, SLOT(updateDeviceState()));
+
+ d->m_profile = p;
+
+ setDisplayName(d->m_profile->displayName());
+ setIcon(d->m_profile->icon());
+
+ ProfileManager *pm = ProfileManager::instance();
+ connect(pm, SIGNAL(profileUpdated(ProjectExplorer::Profile*)),
+ this, SLOT(handleProfileUpdates(ProjectExplorer::Profile*)));
+ connect(pm, SIGNAL(profileRemoved(ProjectExplorer::Profile*)),
+ this, SLOT(handleProfileRemoval(ProjectExplorer::Profile*)));
}
Target::~Target()
{
qDeleteAll(d->m_buildConfigurations);
+ qDeleteAll(d->m_deployConfigurations);
qDeleteAll(d->m_runConfigurations);
delete d;
}
@@ -155,19 +172,47 @@ void Target::changeRunConfigurationEnabled()
emit runConfigurationEnabledChanged();
}
+void Target::onBuildDirectoryChanged()
+{
+ BuildConfiguration *bc = qobject_cast<BuildConfiguration *>(sender());
+ if (bc)
+ emit buildDirectoryChanged();
+}
+
+void Target::handleProfileUpdates(Profile *p)
+{
+ if (p != d->m_profile)
+ return;
+
+ setDisplayName(p->displayName());
+ setIcon(p->icon());
+ updateDefaultDeployConfigurations();
+ emit profileChanged();
+}
+
+void Target::handleProfileRemoval(Profile *p)
+{
+ if (p != d->m_profile)
+ return;
+ d->m_profile = 0;
+ project()->removeTarget(this);
+}
+
Project *Target::project() const
{
return static_cast<Project *>(parent());
}
+Profile *Target::profile() const
+{
+ return d->m_profile;
+}
+
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;
@@ -175,18 +220,12 @@ void Target::addBuildConfiguration(BuildConfiguration *configuration)
displayNames << bc->displayName();
configurationDisplayName = Project::makeUnique(configurationDisplayName, displayNames);
if (configurationDisplayName != configuration->displayName()) {
- if (configuration->usesDefaultDisplayName()) {
+ if (configuration->usesDefaultDisplayName())
configuration->setDefaultDisplayName(configurationDisplayName);
- } else {
+ 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);
@@ -194,9 +233,11 @@ void Target::addBuildConfiguration(BuildConfiguration *configuration)
connect(configuration, SIGNAL(environmentChanged()),
SLOT(changeEnvironment()));
-
connect(configuration, SIGNAL(enabledChanged()),
this, SLOT(changeBuildConfigurationEnabled()));
+ connect(configuration, SIGNAL(requestBuildSystemEvaluation()),
+ this, SLOT(onRequestBuildSystemEvaluation()));
+
if (!activeBuildConfiguration())
setActiveBuildConfiguration(configuration);
@@ -247,6 +288,8 @@ void Target::setActiveBuildConfiguration(BuildConfiguration *configuration)
emit activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
emit environmentChanged();
emit buildConfigurationEnabledChanged();
+ emit buildDirectoryChanged();
+ emit requestBuildSystemEvaluation();
}
}
@@ -270,6 +313,7 @@ void Target::addDeployConfiguration(DeployConfiguration *dc)
d->m_deployConfigurations.push_back(dc);
connect(dc, SIGNAL(enabledChanged()), this, SLOT(changeDeployConfigurationEnabled()));
+ connect(dc, SIGNAL(requestBuildSystemEvaluation()), this, SLOT(onRequestBuildSystemEvaluation()));
emit addedDeployConfiguration(dc);
@@ -322,36 +366,11 @@ void Target::setActiveDeployConfiguration(DeployConfiguration *dc)
d->m_activeDeployConfiguration = dc;
emit activeDeployConfigurationChanged(d->m_activeDeployConfiguration);
emit deployConfigurationEnabledChanged();
+ emit requestBuildSystemEvaluation();
}
updateDeviceState();
}
-QList<Core::Id> Target::availableDeployConfigurationIds()
-{
- QList<Core::Id> ids;
- foreach (const DeployConfigurationFactory * const factory, d->deployFactories())
- ids << factory->availableCreationIds(this);
- return ids;
-}
-
-QString Target::displayNameForDeployConfigurationId(Core::Id &id)
-{
- foreach (const DeployConfigurationFactory * const factory, d->deployFactories()) {
- if (factory->availableCreationIds(this).contains(id))
- return factory->displayNameForId(id);
- }
- return QString();
-}
-
-DeployConfiguration *Target::createDeployConfiguration(Core::Id 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;
@@ -410,6 +429,7 @@ void Target::setActiveRunConfiguration(RunConfiguration* configuration)
d->m_activeRunConfiguration = configuration;
emit activeRunConfigurationChanged(d->m_activeRunConfiguration);
emit runConfigurationEnabledChanged();
+ emit requestBuildSystemEvaluation();
}
updateDeviceState();
}
@@ -452,31 +472,14 @@ void Target::setToolTip(const QString &text)
emit toolTipChanged();
}
-QList<ToolChain *> Target::possibleToolChains(BuildConfiguration *) const
-{
- QList<ToolChain *> tcList = ToolChainManager::instance()->toolChains();
- QList<ToolChain *> result;
- foreach (ToolChain *tc, tcList) {
- QList<Core::Id> 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();
+ if (!d->m_profile) // Profile was deleted, target is only around to be copied.
+ return QVariantMap();
QVariantMap map(ProjectConfiguration::toMap());
+
+ const QList<BuildConfiguration *> bcs = buildConfigurations();
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)
@@ -497,6 +500,153 @@ QVariantMap Target::toMap() const
return map;
}
+void Target::createDefaultSetup()
+{
+ updateDefaultBuildConfigurations();
+ updateDefaultDeployConfigurations();
+ updateDefaultRunConfigurations();
+}
+
+void Target::updateDefaultBuildConfigurations()
+{
+ IBuildConfigurationFactory *bcFactory = IBuildConfigurationFactory::find(this);
+ if (!bcFactory) {
+ qWarning("No build configuration factory found for target id '%s'.", qPrintable(id().toString()));
+ return;
+ }
+ QList<Core::Id> bcIds = bcFactory->availableCreationIds(this);
+ foreach (Core::Id id, bcIds) {
+ if (!bcFactory->canCreate(this, id))
+ continue;
+ BuildConfiguration *bc = bcFactory->create(this, id, tr("Default build"));
+ if (!bc)
+ continue;
+ QTC_CHECK(bc->id() == id);
+ addBuildConfiguration(bc);
+ }
+}
+
+void Target::updateDefaultDeployConfigurations()
+{
+ DeployConfigurationFactory *dcFactory = DeployConfigurationFactory::find(this);
+ if (!dcFactory) {
+ qWarning("No deployment configuration factory found for target id '%s'.", qPrintable(id().toString()));
+ return;
+ }
+ QList<Core::Id> dcIds = dcFactory->availableCreationIds(this);
+ QList<DeployConfiguration *> dcList = deployConfigurations();
+
+ foreach (DeployConfiguration *dc, dcList) {
+ if (dcIds.contains(dc->id()))
+ dcIds.removeOne(dc->id());
+ else
+ removeDeployConfiguration(dc);
+ }
+
+ foreach (Core::Id id, dcIds) {
+ if (!dcFactory->canCreate(this, id))
+ continue;
+ DeployConfiguration *dc = dcFactory->create(this, id);
+ if (dc) {
+ QTC_CHECK(dc->id() == id);
+ addDeployConfiguration(dc);
+ }
+ }
+}
+
+void Target::updateDefaultRunConfigurations()
+{
+ QList<IRunConfigurationFactory *> rcFactories = IRunConfigurationFactory::find(this);
+ if (rcFactories.isEmpty()) {
+ qWarning("No run configuration factory found for target id '%s'.", qPrintable(id().toString()));
+ return;
+ }
+
+ QList<RunConfiguration *> existingConfigured; // Existing configured RCs
+ QList<RunConfiguration *> existingUnconfigured; // Existing unconfigured RCs
+ QList<RunConfiguration *> newConfigured; // NEW configured Rcs
+ QList<RunConfiguration *> newUnconfigured; // NEW unconfigured RCs
+
+
+ // sort existing RCs into configured/unconfigured.
+ foreach (RunConfiguration *rc, runConfigurations()) {
+ if (rc->isConfigured())
+ existingConfigured << rc;
+ else
+ existingUnconfigured << rc;
+ }
+ int configuredCount = existingConfigured.count();
+
+ // find all RC ids that can get created:
+ QList<Core::Id> factoryIds;
+ foreach (IRunConfigurationFactory *rcFactory, rcFactories)
+ factoryIds.append(rcFactory->availableCreationIds(this));
+
+ // Put outdated RCs into toRemove, do not bother with factories
+ // that produce already existing RCs
+ QList<RunConfiguration *> toRemove;
+ foreach (RunConfiguration *rc, existingConfigured) {
+ if (factoryIds.contains(rc->id()))
+ factoryIds.removeOne(rc->id()); // Already there
+ else
+ toRemove << rc;
+ }
+ configuredCount -= toRemove.count();
+
+ // Create new RCs and put them into newConfigured/newUnconfigured
+ foreach (Core::Id id, factoryIds) {
+ IRunConfigurationFactory *factory = 0;
+ foreach (IRunConfigurationFactory *i, rcFactories) {
+ if (i->canCreate(this, id)) {
+ factory = i;
+ break;
+ }
+ }
+ if (!factory)
+ continue;
+
+ RunConfiguration *rc = factory->create(this, id);
+ if (!rc)
+ continue;
+ QTC_CHECK(rc->id() == id);
+ if (!rc->isConfigured())
+ newUnconfigured << rc;
+ else
+ newConfigured << rc;
+ }
+ configuredCount += newConfigured.count();
+
+ // Decide what to do with the different categories:
+ bool removeExistingUnconfigured = false;
+ if (configuredCount > 0) {
+ // new non-Custom Executable RCs were added
+ removeExistingUnconfigured = true;
+ qDeleteAll(newUnconfigured);
+ newUnconfigured.clear();
+ } else {
+ // no new RCs, use old or new CERCs?
+ if (!existingUnconfigured.isEmpty()) {
+ qDeleteAll(newUnconfigured);
+ newUnconfigured.clear();
+ }
+ }
+
+ // Do actual changes:
+ foreach (RunConfiguration *rc, toRemove)
+ removeRunConfiguration(rc);
+
+ if (removeExistingUnconfigured) {
+ foreach (RunConfiguration *rc, existingUnconfigured)
+ removeRunConfiguration(rc);
+ existingUnconfigured.clear();
+ }
+
+ foreach (RunConfiguration *rc, newConfigured)
+ addRunConfiguration(rc);
+ foreach (RunConfiguration *rc, newUnconfigured)
+ addRunConfiguration(rc);
+}
+
static QString formatToolTip(const IDevice::DeviceInfo &input)
{
QStringList lines;
@@ -507,7 +657,7 @@ static QString formatToolTip(const IDevice::DeviceInfo &input)
void Target::updateDeviceState()
{
- IDevice::ConstPtr current = currentDevice();
+ IDevice::ConstPtr current = DeviceProfileInformation::device(profile());
QPixmap overlay;
if (current.isNull()) {
@@ -547,11 +697,6 @@ void Target::updateDeviceState()
setToolTip(current.isNull() ? QString() : formatToolTip(current->deviceInformation()));
}
-ProjectExplorer::IDevice::ConstPtr Target::currentDevice() const
-{
- return DeviceManager::instance()->find(ProjectExplorer::Constants::DESKTOP_DEVICE_ID);
-}
-
void Target::setEnabled(bool enabled)
{
if (enabled == d->m_isEnabled)
@@ -566,6 +711,10 @@ bool Target::fromMap(const QVariantMap &map)
if (!ProjectConfiguration::fromMap(map))
return false;
+ d->m_profile = ProfileManager::instance()->find(id());
+ if (!d->m_profile)
+ return false;
+
bool ok;
int bcCount = map.value(QLatin1String(BC_COUNT_KEY), 0).toInt(&ok);
if (!ok || bcCount < 0)
@@ -580,14 +729,23 @@ bool Target::fromMap(const QVariantMap &map)
const QString key = QString::fromLatin1(BC_KEY_PREFIX) + QString::number(i);
if (!map.contains(key))
return false;
- BuildConfiguration *bc = buildConfigurationFactory()->restore(this, map.value(key).toMap());
- if (!bc)
+ const QVariantMap valueMap = map.value(key).toMap();
+ IBuildConfigurationFactory *factory = IBuildConfigurationFactory::find(this, valueMap);
+ if (!factory) {
+ qWarning("No factory found to restore build configuration!");
+ continue;
+ }
+ BuildConfiguration *bc = factory->restore(this, valueMap);
+ if (!bc) {
+ qWarning("Failed '%s' to restore build configuration!", qPrintable(factory->objectName()));
continue;
+ }
+ QTC_CHECK(bc->id() == ProjectExplorer::idFromMap(valueMap));
addBuildConfiguration(bc);
if (i == activeConfiguration)
setActiveBuildConfiguration(bc);
}
- if (buildConfigurations().isEmpty() && buildConfigurationFactory())
+ if (buildConfigurations().isEmpty() && IBuildConfigurationFactory::find(this))
return false;
int dcCount = map.value(QLatin1String(DC_COUNT_KEY), 0).toInt(&ok);
@@ -603,16 +761,18 @@ bool Target::fromMap(const QVariantMap &map)
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;
- }
+ QVariantMap valueMap = map.value(key).toMap();
+ DeployConfigurationFactory *factory = DeployConfigurationFactory::find(this, valueMap);
+ if (!factory) {
+ qWarning("No factory found to restore deployment configuration!");
+ continue;
}
- if (!dc)
+ DeployConfiguration *dc = factory->restore(this, valueMap);
+ if (!dc) {
+ qWarning("Factory '%s' failed to restore deployment configuration!", qPrintable(factory->objectName()));
continue;
+ }
+ QTC_CHECK(dc->id() == ProjectExplorer::idFromMap(valueMap));
addDeployConfiguration(dc);
if (i == activeConfiguration)
setActiveDeployConfiguration(dc);
@@ -632,32 +792,40 @@ bool Target::fromMap(const QVariantMap &map)
if (!map.contains(key))
return false;
+ // Ignore missing RCs: We will just populate them using the default ones.
QVariantMap valueMap = map.value(key).toMap();
- IRunConfigurationFactory *factory = IRunConfigurationFactory::restoreFactory(this, valueMap);
- if (!factory)
- continue; // Skip RCs we do not know about.)
-
+ IRunConfigurationFactory *factory = IRunConfigurationFactory::find(this, valueMap);
+ if (!factory || !factory->canRestore(this, valueMap))
+ continue;
RunConfiguration *rc = factory->restore(this, valueMap);
if (!rc)
continue;
+ QTC_CHECK(rc->id() == ProjectExplorer::idFromMap(valueMap));
addRunConfiguration(rc);
if (i == activeConfiguration)
setActiveRunConfiguration(rc);
}
- // Ignore missing RCs: We will just populate them using the default ones.
return true;
}
-// -------------------------------------------------------------------------
-// ITargetFactory
-// -------------------------------------------------------------------------
+void Target::onRequestBuildSystemEvaluation()
+{
+ ProjectConfiguration *config = qobject_cast<ProjectConfiguration *>(sender());
+ if (!config)
+ return;
+ if (config == static_cast<ProjectConfiguration *>(activeBuildConfiguration())
+ || config == static_cast<ProjectConfiguration *>(activeDeployConfiguration()))
+ emit requestBuildSystemEvaluation();
+}
-ITargetFactory::ITargetFactory(QObject *parent) :
- QObject(parent)
+void Target::onBuildDirectoryInitialized()
{
- connect(ToolChainManager::instance(), SIGNAL(toolChainsChanged()),
- this, SIGNAL(canCreateTargetIdsChanged()));
+ BuildConfiguration *bc = qobject_cast<BuildConfiguration *>(sender());
+ if (!bc)
+ return;
+ if (bc == activeBuildConfiguration())
+ emit buildDirectoryInitialized();
}
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h
index 1b05c9c07b..69e4fb4459 100644
--- a/src/plugins/projectexplorer/target.h
+++ b/src/plugins/projectexplorer/target.h
@@ -43,12 +43,12 @@ namespace Utils { class Environment; }
namespace ProjectExplorer {
class RunConfiguration;
-class ToolChain;
class BuildConfiguration;
class DeployConfiguration;
class IBuildConfigurationFactory;
class DeployConfigurationFactory;
class IRunConfigurationFactory;
+class Profile;
class Project;
class BuildConfigWidget;
@@ -59,11 +59,14 @@ class PROJECTEXPLORER_EXPORT Target : public ProjectConfiguration
Q_OBJECT
public:
- virtual ~Target();
+ Target(Project *parent, Profile *p);
+ ~Target();
- virtual BuildConfigWidget *createConfigWidget() = 0;
Project *project() const;
+ // Profile:
+ Profile *profile() const;
+
// Build configuration
void addBuildConfiguration(BuildConfiguration *configuration);
bool removeBuildConfiguration(BuildConfiguration *configuration);
@@ -72,8 +75,6 @@ public:
BuildConfiguration *activeBuildConfiguration() const;
void setActiveBuildConfiguration(BuildConfiguration *configuration);
- virtual IBuildConfigurationFactory *buildConfigurationFactory() const = 0;
-
// DeployConfiguration
void addDeployConfiguration(DeployConfiguration *dc);
bool removeDeployConfiguration(DeployConfiguration *dc);
@@ -82,10 +83,6 @@ public:
DeployConfiguration *activeDeployConfiguration() const;
void setActiveDeployConfiguration(DeployConfiguration *configuration);
- QList<Core::Id> availableDeployConfigurationIds();
- QString displayNameForDeployConfigurationId(Core::Id &id);
- DeployConfiguration *createDeployConfiguration(Core::Id id);
-
// Running
QList<RunConfiguration *> runConfigurations() const;
void addRunConfiguration(RunConfiguration *runConfiguration);
@@ -108,10 +105,12 @@ public:
QString toolTip() const;
void setToolTip(const QString &text);
- virtual QList<ToolChain *> possibleToolChains(BuildConfiguration *) const;
- virtual ToolChain *preferredToolChain(BuildConfiguration *) const;
+ QVariantMap toMap() const;
- virtual QVariantMap toMap() const;
+ void createDefaultSetup();
+ void updateDefaultBuildConfigurations();
+ void updateDefaultDeployConfigurations();
+ void updateDefaultRunConfigurations();
signals:
void targetEnabled(bool);
@@ -119,6 +118,8 @@ signals:
void overlayIconChanged();
void toolTipChanged();
+ void profileChanged();
+
// TODO clean up signal names
// might be better to also have aboutToRemove signals
void removedRunConfiguration(ProjectExplorer::RunConfiguration *);
@@ -143,14 +144,23 @@ signals:
void deployConfigurationEnabledChanged();
void runConfigurationEnabledChanged();
-protected:
- Target(Project *parent, const Core::Id id);
+ /// Emitted whenever the project should (re-)evaluate the build system
+ void requestBuildSystemEvaluation();
+ /// Emitted whenever the current build configuration has finished to initialize its build directory.
+ void buildDirectoryInitialized();
+ /// Emitted whenever the current build configuartion changed or the build directory of the current
+ /// build configuration was changed.
+ void buildDirectoryChanged();
- virtual ProjectExplorer::IDevice::ConstPtr currentDevice() const;
+public slots:
+ void onRequestBuildSystemEvaluation();
+ void onBuildDirectoryInitialized();
+ void onBuildDirectoryChanged();
+protected:
void setEnabled(bool);
- virtual bool fromMap(const QVariantMap &map);
+ bool fromMap(const QVariantMap &map);
protected slots:
void updateDeviceState();
@@ -161,31 +171,13 @@ private slots:
void changeDeployConfigurationEnabled();
void changeRunConfigurationEnabled();
+ void handleProfileUpdates(ProjectExplorer::Profile *p);
+ void handleProfileRemoval(ProjectExplorer::Profile *p);
+
private:
TargetPrivate *d;
-};
-class PROJECTEXPLORER_EXPORT ITargetFactory :
- public QObject
-{
- Q_OBJECT
-
-public:
- explicit ITargetFactory(QObject *parent = 0);
-
- virtual QList<Core::Id> supportedTargetIds() const = 0;
- virtual bool supportsTargetId(const Core::Id id) const = 0;
-
- // used to translate the types to names to display to the user
- virtual QString displayNameForId(const Core::Id id) const = 0;
-
- virtual bool canCreate(Project *parent, const Core::Id id) const = 0;
- virtual Target *create(Project *parent, const Core::Id id) = 0;
- virtual bool canRestore(Project *parent, const QVariantMap &map) const = 0;
- virtual Target *restore(Project *parent, const QVariantMap &map) = 0;
-
-signals:
- void canCreateTargetIdsChanged();
+ friend class Project;
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/targetselector.cpp b/src/plugins/projectexplorer/targetselector.cpp
index 707160377d..20a3023187 100644
--- a/src/plugins/projectexplorer/targetselector.cpp
+++ b/src/plugins/projectexplorer/targetselector.cpp
@@ -80,6 +80,12 @@ void TargetSelector::insertTarget(int index, const QString &name)
update();
}
+void TargetSelector::renameTarget(int index, const QString &name)
+{
+ m_targets[index].name = name;
+ update();
+}
+
void TargetSelector::removeTarget(int index)
{
QTC_ASSERT(index >= 0 && index < m_targets.count(), return);
diff --git a/src/plugins/projectexplorer/targetselector.h b/src/plugins/projectexplorer/targetselector.h
index 6aaadf849b..752bb1c14e 100644
--- a/src/plugins/projectexplorer/targetselector.h
+++ b/src/plugins/projectexplorer/targetselector.h
@@ -70,6 +70,7 @@ public:
public:
void insertTarget(int index, const QString &name);
+ void renameTarget(int index, const QString &name);
void removeTarget(int index);
void setCurrentIndex(int index);
void setCurrentSubIndex(int subindex);
diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp
index a94c34fde4..3646d10fa1 100644
--- a/src/plugins/projectexplorer/targetsettingspanel.cpp
+++ b/src/plugins/projectexplorer/targetsettingspanel.cpp
@@ -41,7 +41,10 @@
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/profile.h>
+#include <projectexplorer/profilemanager.h>
#include <projectexplorer/buildmanager.h>
+#include <utils/qtcassert.h>
#include <QCoreApplication>
#include <QLabel>
@@ -84,13 +87,8 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) :
connect(m_project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
this, SLOT(activeTargetChanged(ProjectExplorer::Target*)));
- QList<ITargetFactory *> factories =
- ExtensionSystem::PluginManager::getObjects<ITargetFactory>();
-
- foreach (ITargetFactory *fac, factories) {
- connect(fac, SIGNAL(canCreateTargetIdsChanged()),
- this, SLOT(updateTargetAddAndRemoveButtons()));
- }
+ connect(ProfileManager::instance(), SIGNAL(profilesChanged()),
+ this, SLOT(updateTargetAddAndRemoveButtons()));
}
TargetSettingsPanelWidget::~TargetSettingsPanelWidget()
@@ -213,19 +211,10 @@ void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subInd
void TargetSettingsPanelWidget::addTarget(QAction *action)
{
- Core::Id id = action->data().value<Core::Id>();
- Q_ASSERT(!m_project->target(id));
- QList<ITargetFactory *> factories =
- ExtensionSystem::PluginManager::getObjects<ITargetFactory>();
-
- Target *target = 0;
- foreach (ITargetFactory *fac, factories) {
- if (fac->canCreate(m_project, id)) {
- target = fac->create(m_project, id);
- break;
- }
- }
+ Profile *p = ProfileManager::instance()->find(action->data().value<Core::Id>());
+ QTC_ASSERT(!m_project->target(p), return);
+ Target *target = m_project->createTarget(p);
if (!target)
return;
m_project->addTarget(target);
@@ -278,6 +267,7 @@ void TargetSettingsPanelWidget::targetAdded(ProjectExplorer::Target *target)
}
}
+ connect(target, SIGNAL(displayNameChanged()), this, SLOT(renameTarget()));
updateTargetAddAndRemoveButtons();
}
@@ -312,35 +302,42 @@ void TargetSettingsPanelWidget::updateTargetAddAndRemoveButtons()
m_addMenu->clear();
- QList<ITargetFactory *> factories =
- ExtensionSystem::PluginManager::getObjects<ITargetFactory>();
-
- foreach (ITargetFactory *fac, factories) {
- foreach (Core::Id id, fac->supportedTargetIds()) {
- if (m_project->target(id))
- continue;
- if (!fac->canCreate(m_project, id))
- continue;
- QString displayName = fac->displayNameForId(id);
- QAction *action = new QAction(displayName, m_addMenu);
- action->setData(QVariant::fromValue(id));
- bool added = false;
- foreach (QAction *existing, m_addMenu->actions()) {
- if (existing->text() > action->text()) {
- m_addMenu->insertAction(existing, action);
- added = true;
- }
- }
+ foreach (Profile *p, ProfileManager::instance()->profiles()) {
+ if (m_project->target(p))
+ continue;
+ if (!m_project->supportsProfile(p))
+ continue;
- if (!added)
- m_addMenu->addAction(action);
+ QAction *action = new QAction(p->displayName(), m_addMenu);
+ action->setData(QVariant::fromValue(p->id()));
+
+ bool inserted = false;
+ foreach (QAction *existing, m_addMenu->actions()) {
+ if (existing->text() > action->text()) {
+ m_addMenu->insertAction(existing, action);
+ inserted = true;
+ break;
+ }
}
+ if (!inserted)
+ m_addMenu->addAction(action);
}
m_selector->setAddButtonEnabled(!m_addMenu->actions().isEmpty());
m_selector->setRemoveButtonEnabled(m_project->targets().count() > 1);
}
+void TargetSettingsPanelWidget::renameTarget()
+{
+ Target *t = qobject_cast<Target *>(sender());
+ if (!t)
+ return;
+ const int pos = m_targets.indexOf(t);
+ if (pos < 0)
+ return;
+ m_selector->renameTarget(pos, t->displayName());
+}
+
int TargetSettingsPanelWidget::currentSubIndex() const
{
return m_selector->currentSubIndex();
diff --git a/src/plugins/projectexplorer/targetsettingspanel.h b/src/plugins/projectexplorer/targetsettingspanel.h
index d95c358d1b..5f84c6fe22 100644
--- a/src/plugins/projectexplorer/targetsettingspanel.h
+++ b/src/plugins/projectexplorer/targetsettingspanel.h
@@ -71,6 +71,7 @@ private slots:
void removedTarget(ProjectExplorer::Target *target);
void activeTargetChanged(ProjectExplorer::Target *target);
void updateTargetAddAndRemoveButtons();
+ void renameTarget();
private:
Target *m_currentTarget;
diff --git a/src/plugins/projectexplorer/targetsettingswidget.cpp b/src/plugins/projectexplorer/targetsettingswidget.cpp
index 18d9e06561..f8f8b3c835 100644
--- a/src/plugins/projectexplorer/targetsettingswidget.cpp
+++ b/src/plugins/projectexplorer/targetsettingswidget.cpp
@@ -78,6 +78,12 @@ void TargetSettingsWidget::insertTarget(int index, const QString &name)
updateTargetSelector();
}
+void TargetSettingsWidget::renameTarget(int index, const QString &name)
+{
+ m_targetSelector->renameTarget(index, name);
+ // geometry won't change, so no need to updateTargetSelector()
+}
+
void TargetSettingsWidget::removeTarget(int index)
{
m_targetSelector->removeTarget(index);
diff --git a/src/plugins/projectexplorer/targetsettingswidget.h b/src/plugins/projectexplorer/targetsettingswidget.h
index dedede723f..ebc3c48dd7 100644
--- a/src/plugins/projectexplorer/targetsettingswidget.h
+++ b/src/plugins/projectexplorer/targetsettingswidget.h
@@ -65,6 +65,7 @@ public:
public:
void insertTarget(int index, const QString &name);
+ void renameTarget(int index, const QString &name);
void removeTarget(int index);
void setCurrentIndex(int index);
void setCurrentSubIndex(int index);
diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp
index 75eeb0baea..1c92f3c77b 100644
--- a/src/plugins/projectexplorer/toolchain.cpp
+++ b/src/plugins/projectexplorer/toolchain.cpp
@@ -32,6 +32,7 @@
#include "toolchain.h"
+#include "abi.h"
#include "toolchainmanager.h"
#include <extensionsystem/pluginmanager.h>
@@ -43,30 +44,6 @@
static const char ID_KEY[] = "ProjectExplorer.ToolChain.Id";
static const char DISPLAY_NAME_KEY[] = "ProjectExplorer.ToolChain.DisplayName";
static const char AUTODETECT_KEY[] = "ProjectExplorer.ToolChain.Autodetect";
-static const char MKSPEC_KEY[] = "ProjectExplorer.ToolChain.MkSpecOverride";
-
-namespace {
-
-QString mkspecListToString(const QList<Utils::FileName> &specList)
-{
- QStringList result;
- foreach (const Utils::FileName &spec, specList)
- result.append(spec.toString());
- return result.join(QChar::fromLatin1(';'));
-}
-
-QList<Utils::FileName> mkspecListFromString(const QString &string)
-{
- QList<Utils::FileName> result;
- QStringList partList;
- if (!string.isEmpty())
- partList = string.split(QLatin1Char(';'));
- foreach (const QString &part, partList)
- result.append(Utils::FileName::fromString(part));
- return result;
-}
-
-} // namespace
namespace ProjectExplorer {
namespace Internal {
@@ -94,7 +71,6 @@ public:
QString m_id;
bool m_autodetect;
mutable QString m_displayName;
- QList<Utils::FileName> m_mkspecList;
};
} // namespace Internal
@@ -150,31 +126,9 @@ QString ToolChain::id() const
return d->m_id;
}
-/*!
- \brief Returns a list of target ids that this tool chain is restricted to.
-
- An empty list is shows that the toolchain is compatible with all targets.
-*/
-
-QList<Core::Id> ToolChain::restrictedToTargets() const
-{
- return QList<Core::Id>();
-}
-
-QList<Utils::FileName> ToolChain::mkspecList() const
+Utils::FileName ToolChain::suggestedDebugger()
{
- if (d->m_mkspecList.isEmpty())
- return suggestedMkspecList();
- return d->m_mkspecList;
-}
-
-void ToolChain::setMkspecList(const QList<Utils::FileName> &specList)
-{
- QList<Utils::FileName> oldSpecList = mkspecList();
- d->m_mkspecList = specList;
-
- if (oldSpecList != mkspecList())
- toolChainUpdated();
+ return ToolChainManager::instance()->defaultDebugger(targetAbi());
}
bool ToolChain::canClone() const
@@ -211,7 +165,6 @@ QVariantMap ToolChain::toMap() const
result.insert(QLatin1String(ID_KEY), id());
result.insert(QLatin1String(DISPLAY_NAME_KEY), displayName());
result.insert(QLatin1String(AUTODETECT_KEY), isAutoDetected());
- result.insert(QLatin1String(MKSPEC_KEY), mkspecListToString(d->m_mkspecList));
return result;
}
@@ -241,7 +194,6 @@ bool ToolChain::fromMap(const QVariantMap &data)
// make sure we have new style ids:
d->m_id = data.value(QLatin1String(ID_KEY)).toString();
d->m_autodetect = data.value(QLatin1String(AUTODETECT_KEY), false).toBool();
- d->m_mkspecList = mkspecListFromString(data.value(QLatin1String(MKSPEC_KEY)).toString());
return true;
}
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index 31211acc7d..1ce975d2c6 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -73,8 +73,9 @@ public:
bool isAutoDetected() const;
QString id() const;
- // No need to implement this for new tool chains:
- virtual QString legacyId() const { return QString(); }
+
+ virtual QList<Utils::FileName> suggestedMkspecList() const { return QList<Utils::FileName>(); }
+ Utils::FileName suggestedDebugger();
virtual QString type() const = 0;
virtual QString typeDisplayName() const = 0;
@@ -82,8 +83,6 @@ public:
virtual bool isValid() const = 0;
- virtual QList<Core::Id> restrictedToTargets() const;
-
virtual QByteArray predefinedMacros(const QStringList &cxxflags) const = 0;
enum CompilerFlags {
@@ -95,12 +94,7 @@ public:
virtual void addToEnvironment(Utils::Environment &env) const = 0;
virtual QString makeCommand() const = 0;
- QList<Utils::FileName> mkspecList() const;
- void setMkspecList(const QList<Utils::FileName> &specList);
- virtual QList<Utils::FileName> suggestedMkspecList() const { return QList<Utils::FileName>(); }
-
virtual Utils::FileName compilerCommand() const = 0;
- virtual Utils::FileName debuggerCommand() const = 0;
virtual QString defaultMakeTarget() const;
virtual IOutputParser *outputParser() const = 0;
diff --git a/src/plugins/projectexplorer/toolchainconfigwidget.cpp b/src/plugins/projectexplorer/toolchainconfigwidget.cpp
index 3ad7e4da4c..93ad2f5d49 100644
--- a/src/plugins/projectexplorer/toolchainconfigwidget.cpp
+++ b/src/plugins/projectexplorer/toolchainconfigwidget.cpp
@@ -44,46 +44,6 @@
#include <QLabel>
#include <QPushButton>
-namespace {
-
-const char DEFAULT_MKSPEC[] = "default";
-
-QString mkspecListToString(const QList<Utils::FileName> &specList)
-{
- QStringList specStrings;
- foreach (const Utils::FileName &spec, specList) {
- if (spec.isEmpty())
- specStrings.append(QLatin1String(DEFAULT_MKSPEC));
- else
- specStrings.append(spec.toUserOutput());
- }
- QString specString = specStrings.join(QChar::fromAscii(';'));
- if (specString.isEmpty())
- return QLatin1String(DEFAULT_MKSPEC);
- return specString;
-}
-
-QList<Utils::FileName> mkspecListFromString(const QString &specString)
-{
- QStringList specList = specString.split(QLatin1Char(';'));
- QList<Utils::FileName> result;
- foreach (const QString &spec, specList) {
- QString trimmed = spec.trimmed();
- if (trimmed == QLatin1String(DEFAULT_MKSPEC))
- result.append(Utils::FileName());
- else
- result.append(Utils::FileName::fromUserInput(trimmed));
- }
-
- if (result.size() == 1 && result.at(0).isEmpty())
- return QList<Utils::FileName>();
-
- return result;
-}
-
-
-} // namespace
-
namespace ProjectExplorer {
namespace Internal {
@@ -95,21 +55,13 @@ class ToolChainConfigWidgetPrivate
{
public:
ToolChainConfigWidgetPrivate(ToolChain *tc) :
- m_toolChain(tc), m_debuggerPathChooser(0),
- m_mkspecLayout(0), m_mkspecEdit(0), m_mkspecResetButton(0), m_mkspecEdited(false),
- m_errorLabel(0)
+ m_toolChain(tc), m_errorLabel(0)
{
QTC_CHECK(tc);
}
ToolChain *m_toolChain;
- Utils::PathChooser *m_debuggerPathChooser;
- QHBoxLayout *m_mkspecLayout;
- QLineEdit *m_mkspecEdit;
- QPushButton *m_mkspecResetButton;
- bool m_mkspecEdited;
QLabel *m_errorLabel;
- QList<Utils::FileName> m_suggestedMkspec;
};
} // namespace Internal
@@ -134,132 +86,7 @@ ToolChain *ToolChainConfigWidget::toolChain() const
}
void ToolChainConfigWidget::makeReadOnly()
-{
- if (d->m_debuggerPathChooser)
- d->m_debuggerPathChooser->setEnabled(false);
- if (d->m_mkspecEdit)
- d->m_mkspecEdit->setEnabled(false);
- if (d->m_mkspecResetButton)
- d->m_mkspecResetButton->setEnabled(false);
-}
-
-void ToolChainConfigWidget::emitDirty()
-{
- if (d->m_mkspecEdit)
- d->m_mkspecEdited = (mkspecListFromString(d->m_mkspecEdit->text()) != d->m_suggestedMkspec);
- if (d->m_mkspecResetButton)
- d->m_mkspecResetButton->setEnabled(d->m_mkspecEdited);
- emit dirty();
-}
-
-void ToolChainConfigWidget::resetMkspecList()
-{
- if (!d->m_mkspecEdit || !d->m_mkspecEdited)
- return;
- d->m_mkspecEdit->setText(mkspecListToString(d->m_suggestedMkspec));
- d->m_mkspecEdited = false;
-}
-
-void ToolChainConfigWidget::addDebuggerCommandControls(QFormLayout *lt,
- const QStringList &versionArguments)
-{
- ensureDebuggerPathChooser(versionArguments);
- lt->addRow(tr("&Debugger:"), d->m_debuggerPathChooser);
-}
-
-void ToolChainConfigWidget::addDebuggerCommandControls(QGridLayout *lt,
- int row, int column,
- const QStringList &versionArguments)
-{
- ensureDebuggerPathChooser(versionArguments);
- QLabel *label = new QLabel(tr("&Debugger:"));
- label->setBuddy(d->m_debuggerPathChooser);
- lt->addWidget(label, row, column);
- lt->addWidget(d->m_debuggerPathChooser, row, column + 1);
-}
-
-void ToolChainConfigWidget::ensureDebuggerPathChooser(const QStringList &versionArguments)
-{
- if (d->m_debuggerPathChooser)
- return;
- d->m_debuggerPathChooser = new Utils::PathChooser;
- d->m_debuggerPathChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
- d->m_debuggerPathChooser->setCommandVersionArguments(versionArguments);
- connect(d->m_debuggerPathChooser, SIGNAL(changed(QString)), this, SLOT(emitDirty()));
-}
-
-void ToolChainConfigWidget::addDebuggerAutoDetection(QObject *receiver, const char *autoDetectSlot)
-{
- QTC_ASSERT(d->m_debuggerPathChooser, return);
- d->m_debuggerPathChooser->addButton(tr("Autodetect"), receiver, autoDetectSlot);
-}
-
-Utils::FileName ToolChainConfigWidget::debuggerCommand() const
-{
- QTC_ASSERT(d->m_debuggerPathChooser, return Utils::FileName());
- return d->m_debuggerPathChooser->fileName();
-}
-
-void ToolChainConfigWidget::setDebuggerCommand(const Utils::FileName &debugger)
-{
- QTC_ASSERT(d->m_debuggerPathChooser, return);
- d->m_debuggerPathChooser->setFileName(debugger);
-}
-
-void ToolChainConfigWidget::addMkspecControls(QFormLayout *lt)
-{
- ensureMkspecEdit();
- lt->addRow(tr("mkspec:"), d->m_mkspecLayout);
-}
-
-void ToolChainConfigWidget::addMkspecControls(QGridLayout *lt, int row, int column)
-{
- ensureMkspecEdit();
- QLabel *label = new QLabel(tr("mkspec:"));
- label->setBuddy(d->m_mkspecEdit);
- lt->addWidget(label, row, column);
- lt->addLayout(d->m_mkspecLayout, row, column + 1);
-}
-
-void ToolChainConfigWidget::ensureMkspecEdit()
-{
- if (d->m_mkspecEdit)
- return;
-
- QTC_CHECK(!d->m_mkspecLayout);
- QTC_CHECK(!d->m_mkspecResetButton);
-
- d->m_suggestedMkspec = d->m_toolChain->suggestedMkspecList();
-
- d->m_mkspecLayout = new QHBoxLayout;
- d->m_mkspecLayout->setMargin(0);
-
- d->m_mkspecEdit = new QLineEdit;
- d->m_mkspecEdit->setWhatsThis(tr("All possible mkspecs separated by a semicolon (';')."));
- d->m_mkspecResetButton = new QPushButton(tr("Reset"));
- d->m_mkspecResetButton->setEnabled(d->m_mkspecEdited);
- d->m_mkspecLayout->addWidget(d->m_mkspecEdit);
- d->m_mkspecLayout->addWidget(d->m_mkspecResetButton);
-
- connect(d->m_mkspecEdit, SIGNAL(textChanged(QString)), this, SLOT(emitDirty()));
- connect(d->m_mkspecResetButton, SIGNAL(clicked()), this, SLOT(resetMkspecList()));
-}
-
-QList<Utils::FileName> ToolChainConfigWidget::mkspecList() const
-{
- QTC_ASSERT(d->m_mkspecEdit, return QList<Utils::FileName>());
-
- return mkspecListFromString(d->m_mkspecEdit->text());
-}
-
-void ToolChainConfigWidget::setMkspecList(const QList<Utils::FileName> &specList)
-{
- QTC_ASSERT(d->m_mkspecEdit, return);
-
- d->m_mkspecEdit->setText(mkspecListToString(specList));
-
- emitDirty();
-}
+{ }
void ToolChainConfigWidget::addErrorLabel(QFormLayout *lt)
{
diff --git a/src/plugins/projectexplorer/toolchainconfigwidget.h b/src/plugins/projectexplorer/toolchainconfigwidget.h
index 1bc25b6661..2314df576c 100644
--- a/src/plugins/projectexplorer/toolchainconfigwidget.h
+++ b/src/plugins/projectexplorer/toolchainconfigwidget.h
@@ -74,33 +74,14 @@ signals:
void dirty();
protected slots:
- void emitDirty();
- void resetMkspecList();
void setErrorMessage(const QString &);
void clearErrorMessage();
protected:
- void addDebuggerCommandControls(QFormLayout *lt,
- const QStringList &versionArguments = QStringList());
- void addDebuggerCommandControls(QGridLayout *lt,
- int row = 0, int column = 0,
- const QStringList &versionArguments = QStringList());
- void addDebuggerAutoDetection(QObject *receiver, const char *autoDetectSlot);
- void addMkspecControls(QFormLayout *lt);
- void addMkspecControls(QGridLayout *lt, int row = 0, int column = 0);
void addErrorLabel(QFormLayout *lt);
void addErrorLabel(QGridLayout *lt, int row = 0, int column = 0, int colSpan = 1);
- Utils::FileName debuggerCommand() const;
- void setDebuggerCommand(const Utils::FileName &debugger);
-
- QList<Utils::FileName> mkspecList() const;
- void setMkspecList(const QList<Utils::FileName> &specList);
-
private:
- void ensureDebuggerPathChooser(const QStringList &versionArguments);
- void ensureMkspecEdit();
-
Internal::ToolChainConfigWidgetPrivate *d;
};
diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp
index b87a38f8da..5b76d3f9ca 100644
--- a/src/plugins/projectexplorer/toolchainmanager.cpp
+++ b/src/plugins/projectexplorer/toolchainmanager.cpp
@@ -31,7 +31,9 @@
**************************************************************************/
#include "toolchainmanager.h"
+
#include "abi.h"
+#include "profileinformation.h"
#include "toolchain.h"
#include <coreplugin/icore.h>
@@ -51,15 +53,17 @@ static const char TOOLCHAIN_FILE_VERSION_KEY[] = "Version";
static const char DEFAULT_DEBUGGER_COUNT_KEY[] = "DefaultDebugger.Count";
static const char DEFAULT_DEBUGGER_ABI_KEY[] = "DefaultDebugger.Abi.";
static const char DEFAULT_DEBUGGER_PATH_KEY[] = "DefaultDebugger.Path.";
-static const char TOOLCHAIN_FILENAME[] = "/toolChains.xml";
+static const char TOOLCHAIN_FILENAME[] = "/qtcreator/toolchains.xml";
+static const char LEGACY_TOOLCHAIN_FILENAME[] = "/toolChains.xml";
using Utils::PersistentSettingsWriter;
using Utils::PersistentSettingsReader;
-static QString settingsFileName()
+static QString settingsFileName(const QString &path)
{
- QFileInfo settingsLocation(ExtensionSystem::PluginManager::settings()->fileName());
- return settingsLocation.absolutePath() + QLatin1String(TOOLCHAIN_FILENAME);
+ ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+ QFileInfo settingsLocation(pm->settings()->fileName());
+ return settingsLocation.absolutePath() + path;
}
namespace ProjectExplorer {
@@ -89,8 +93,7 @@ private:
ToolChainManagerPrivate::ToolChainManagerPrivate(ToolChainManager *parent)
: q(parent), m_initialized(false)
-{
-}
+{ }
QList<ToolChain *> &ToolChainManagerPrivate::toolChains()
{
@@ -109,7 +112,6 @@ QList<ToolChain *> &ToolChainManagerPrivate::toolChains()
ToolChainManager *ToolChainManager::instance()
{
- Q_ASSERT(m_instance);
return m_instance;
}
@@ -119,6 +121,7 @@ ToolChainManager::ToolChainManager(QObject *parent) :
{
Q_ASSERT(!m_instance);
m_instance = this;
+
connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()),
this, SLOT(saveToolChains()));
connect(this, SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
@@ -137,7 +140,7 @@ void ToolChainManager::restoreToolChains()
// read all tool chains from SDK
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
QList<ToolChain *> readTcs =
- restoreToolChains(systemSettingsFile.absolutePath() + QLatin1String(TOOLCHAIN_FILENAME));
+ restoreToolChains(systemSettingsFile.absolutePath() + QLatin1String(LEGACY_TOOLCHAIN_FILENAME));
// make sure we mark these as autodetected!
foreach (ToolChain *tc, readTcs)
tc->setAutoDetected(true);
@@ -145,8 +148,12 @@ void ToolChainManager::restoreToolChains()
tcsToRegister = readTcs; // SDK TCs are always considered to be up-to-date, so no need to
// recheck them.
- // read all tool chains from user file
- readTcs = restoreToolChains(settingsFileName());
+ // read all tool chains from user file.
+ // Read legacy settings once and keep them around...
+ QString fileName = settingsFileName(QLatin1String(TOOLCHAIN_FILENAME));
+ if (!QFileInfo(fileName).exists())
+ fileName = settingsFileName(QLatin1String(LEGACY_TOOLCHAIN_FILENAME));
+ readTcs = restoreToolChains(fileName);
foreach (ToolChain *tc, readTcs) {
if (tc->isAutoDetected())
@@ -214,7 +221,7 @@ void ToolChainManager::saveToolChains()
}
}
writer.saveValue(QLatin1String(TOOLCHAIN_COUNT_KEY), count);
- writer.save(settingsFileName(), QLatin1String("QtCreatorToolChains"), Core::ICore::mainWindow());
+ writer.save(settingsFileName(QLatin1String(TOOLCHAIN_FILENAME)), QLatin1String("QtCreatorToolChains"), Core::ICore::mainWindow());
// Do not save default debuggers! Those are set by the SDK!
}
@@ -296,7 +303,7 @@ ToolChain *ToolChainManager::findToolChain(const QString &id) const
return 0;
foreach (ToolChain *tc, d->toolChains()) {
- if (tc->id() == id || (!tc->legacyId().isEmpty() && tc->legacyId() == id))
+ if (tc->id() == id)
return tc;
}
return 0;
diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp
index 1cdbe5bafa..5cd461ef70 100644
--- a/src/plugins/projectexplorer/toolchainoptionspage.cpp
+++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp
@@ -42,13 +42,20 @@
#include <utils/qtcassert.h>
-#include <QSignalMapper>
-#include <QTextStream>
#include <QAction>
+#include <QApplication>
+#include <QHBoxLayout>
+#include <QHeaderView>
#include <QItemSelectionModel>
#include <QLabel>
#include <QMenu>
#include <QMessageBox>
+#include <QPushButton>
+#include <QSignalMapper>
+#include <QSpacerItem>
+#include <QTextStream>
+#include <QTreeView>
+#include <QVBoxLayout>
namespace ProjectExplorer {
namespace Internal {
@@ -92,11 +99,11 @@ public:
// ToolChainModel
// --------------------------------------------------------------------------
-ToolChainModel::ToolChainModel(QWidget *configWidgetParent, QObject *parent) :
+ToolChainModel::ToolChainModel(QBoxLayout *parentLayout, QObject *parent) :
QAbstractItemModel(parent),
- m_configWidgetParent(configWidgetParent)
+ m_parentLayout(parentLayout)
{
- Q_ASSERT(m_configWidgetParent);
+ Q_ASSERT(m_parentLayout);
connect(ToolChainManager::instance(), SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
this, SLOT(addToolChain(ProjectExplorer::ToolChain*)));
@@ -404,9 +411,8 @@ ToolChainNode *ToolChainModel::createNode(ToolChainNode *parent, ToolChain *tc,
{
ToolChainNode *node = new ToolChainNode(parent, tc, changed);
if (node->widget) {
- m_configWidgetParent->layout()->addWidget(node->widget);
- connect(node->widget, SIGNAL(dirty()),
- this, SLOT(setDirty()));
+ m_parentLayout->addWidget(node->widget);
+ connect(node->widget, SIGNAL(dirty()), this, SLOT(setDirty()));
}
return node;
}
@@ -471,7 +477,8 @@ void ToolChainModel::removeToolChain(ToolChain *tc)
// --------------------------------------------------------------------------
ToolChainOptionsPage::ToolChainOptionsPage() :
- m_ui(0), m_model(0), m_selectionModel(0), m_currentTcWidget(0)
+ m_model(0), m_selectionModel(0), m_currentTcWidget(0),
+ m_toolChainView(0), m_addButton(0), m_cloneButton(0), m_delButton(0)
{
setId(QLatin1String(Constants::TOOLCHAIN_SETTINGS_PAGE_ID));
setDisplayName(tr("Tool Chains"));
@@ -488,19 +495,39 @@ QWidget *ToolChainOptionsPage::createPage(QWidget *parent)
m_currentTcWidget = 0;
- m_ui = new Ui::ToolChainOptionsPage;
- m_ui->setupUi(m_configWidget);
+ m_toolChainView = new QTreeView(m_configWidget);
+ m_toolChainView->setUniformRowHeights(true);
+ m_toolChainView->header()->setStretchLastSection(false);
+ m_addButton = new QPushButton(tr("Add"), m_configWidget);
+ m_cloneButton = new QPushButton(tr("Clone"), m_configWidget);
+ m_delButton = new QPushButton(tr("Remove"), m_configWidget);
+
+ QVBoxLayout *buttonLayout = new QVBoxLayout();
+ buttonLayout->setSpacing(6);
+ buttonLayout->setContentsMargins(0, 0, 0, 0);
+ buttonLayout->addWidget(m_addButton);
+ buttonLayout->addWidget(m_cloneButton);
+ buttonLayout->addWidget(m_delButton);
+ buttonLayout->addItem(new QSpacerItem(10, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
+
+ QVBoxLayout *verticalLayout = new QVBoxLayout();
+ verticalLayout->addWidget(m_toolChainView);
+
+ QHBoxLayout *horizontalLayout = new QHBoxLayout(m_configWidget);
+ horizontalLayout->addLayout(verticalLayout);
+ horizontalLayout->addLayout(buttonLayout);
Q_ASSERT(!m_model);
- m_model = new ToolChainModel(m_configWidget);
+ m_model = new ToolChainModel(verticalLayout);
+
connect(m_model, SIGNAL(toolChainStateChanged()), this, SLOT(updateState()));
- m_ui->toolChainView->setModel(m_model);
- m_ui->toolChainView->header()->setResizeMode(0, QHeaderView::ResizeToContents);
- m_ui->toolChainView->header()->setResizeMode(1, QHeaderView::Stretch);
- m_ui->toolChainView->expandAll();
+ m_toolChainView->setModel(m_model);
+ m_toolChainView->header()->setResizeMode(0, QHeaderView::ResizeToContents);
+ m_toolChainView->header()->setResizeMode(1, QHeaderView::Stretch);
+ m_toolChainView->expandAll();
- m_selectionModel = m_ui->toolChainView->selectionModel();
+ m_selectionModel = m_toolChainView->selectionModel();
connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(toolChainSelectionChanged()));
connect(ToolChainManager::instance(), SIGNAL(toolChainsChanged()),
@@ -510,7 +537,7 @@ QWidget *ToolChainOptionsPage::createPage(QWidget *parent)
m_factories = ExtensionSystem::PluginManager::getObjects<ToolChainFactory>();
// Set up add menu:
- QMenu *addMenu = new QMenu(m_ui->addButton);
+ QMenu *addMenu = new QMenu(m_addButton);
QSignalMapper *mapper = new QSignalMapper(addMenu);
connect(mapper, SIGNAL(mapped(QObject*)), this, SLOT(createToolChain(QObject*)));
@@ -524,12 +551,12 @@ QWidget *ToolChainOptionsPage::createPage(QWidget *parent)
addMenu->addAction(action);
}
}
- connect(m_ui->cloneButton, SIGNAL(clicked()), mapper, SLOT(map()));
- mapper->setMapping(m_ui->cloneButton, static_cast<QObject *>(0));
+ connect(m_cloneButton, SIGNAL(clicked()), mapper, SLOT(map()));
+ mapper->setMapping(m_cloneButton, static_cast<QObject *>(0));
- m_ui->addButton->setMenu(addMenu);
+ m_addButton->setMenu(addMenu);
- connect(m_ui->delButton, SIGNAL(clicked()), this, SLOT(removeToolChain()));
+ connect(m_delButton, SIGNAL(clicked()), this, SLOT(removeToolChain()));
// setup keywords:
if (m_searchKeywords.isEmpty()) {
@@ -562,8 +589,12 @@ void ToolChainOptionsPage::finish()
m_configWidget = 0; // deleted by settingsdialog
m_selectionModel = 0; // child of m_configWidget
- m_ui = 0; // child of m_configWidget
m_currentTcWidget = 0; // deleted by the model
+ // childs of m_configWidget
+ m_toolChainView = 0;
+ m_addButton = 0;
+ m_cloneButton = 0;
+ m_delButton = 0;
}
bool ToolChainOptionsPage::matches(const QString &s) const
@@ -619,7 +650,7 @@ void ToolChainOptionsPage::removeToolChain()
void ToolChainOptionsPage::updateState()
{
- if (!m_ui)
+ if (!m_cloneButton)
return;
bool canCopy = false;
@@ -630,8 +661,8 @@ void ToolChainOptionsPage::updateState()
canDelete = !tc->isAutoDetected();
}
- m_ui->cloneButton->setEnabled(canCopy);
- m_ui->delButton->setEnabled(canDelete);
+ m_cloneButton->setEnabled(canCopy);
+ m_delButton->setEnabled(canDelete);
}
QModelIndex ToolChainOptionsPage::currentIndex() const
diff --git a/src/plugins/projectexplorer/toolchainoptionspage.h b/src/plugins/projectexplorer/toolchainoptionspage.h
index 2049154455..9d882b2001 100644
--- a/src/plugins/projectexplorer/toolchainoptionspage.h
+++ b/src/plugins/projectexplorer/toolchainoptionspage.h
@@ -33,15 +33,16 @@
#ifndef TOOLCHAINOPTIONSPAGE_H
#define TOOLCHAINOPTIONSPAGE_H
-#include "ui_toolchainoptionspage.h"
-
#include <coreplugin/dialogs/ioptionspage.h>
#include <QAbstractItemModel>
QT_BEGIN_NAMESPACE
+class QBoxLayout;
+class QItemSelectionModel;
+class QPushButton;
+class QTreeView;
class QTreeWidgetItem;
-class QWidget;
QT_END_NAMESPACE
namespace ProjectExplorer {
@@ -63,7 +64,7 @@ class ToolChainModel : public QAbstractItemModel
Q_OBJECT
public:
- explicit ToolChainModel(QWidget *configWidgetParent, QObject *parent = 0);
+ explicit ToolChainModel(QBoxLayout *parentLayout, QObject *parent = 0);
~ToolChainModel();
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
@@ -109,7 +110,7 @@ private:
QList<ToolChainNode *> m_toAddList;
QList<ToolChainNode *> m_toRemoveList;
- QWidget *m_configWidgetParent;
+ QBoxLayout *m_parentLayout;
};
// --------------------------------------------------------------------------
@@ -137,7 +138,6 @@ private slots:
private:
QModelIndex currentIndex() const;
- Ui::ToolChainOptionsPage *m_ui;
QWidget *m_configWidget;
QString m_searchKeywords;
@@ -145,6 +145,10 @@ private:
QList<ToolChainFactory *> m_factories;
QItemSelectionModel * m_selectionModel;
ToolChainConfigWidget *m_currentTcWidget;
+ QTreeView *m_toolChainView;
+ QPushButton *m_addButton;
+ QPushButton *m_cloneButton;
+ QPushButton *m_delButton;
};
} // namespace Internal
diff --git a/src/plugins/projectexplorer/toolchainoptionspage.ui b/src/plugins/projectexplorer/toolchainoptionspage.ui
deleted file mode 100644
index 8c31359673..0000000000
--- a/src/plugins/projectexplorer/toolchainoptionspage.ui
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ProjectExplorer::Internal::ToolChainOptionsPage</class>
- <widget class="QWidget" name="ProjectExplorer::Internal::ToolChainOptionsPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>398</width>
- <height>296</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QTreeView" name="toolChainView">
- <property name="uniformRowHeights">
- <bool>true</bool>
- </property>
- <attribute name="headerStretchLastSection">
- <bool>false</bool>
- </attribute>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="_2">
- <property name="spacing">
- <number>6</number>
- </property>
- <property name="margin">
- <number>0</number>
- </property>
- <item>
- <widget class="QPushButton" name="addButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>21</width>
- <height>23</height>
- </size>
- </property>
- <property name="text">
- <string>Add</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="cloneButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>21</width>
- <height>23</height>
- </size>
- </property>
- <property name="text">
- <string>Clone</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="delButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>21</width>
- <height>23</height>
- </size>
- </property>
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/projectexplorer/wincetoolchain.cpp b/src/plugins/projectexplorer/wincetoolchain.cpp
index 8108746528..eb08ddba9e 100644
--- a/src/plugins/projectexplorer/wincetoolchain.cpp
+++ b/src/plugins/projectexplorer/wincetoolchain.cpp
@@ -50,7 +50,6 @@
#include <QXmlStreamReader>
#define KEY_ROOT "ProjectExplorer.WinCEToolChain."
-static const char debuggerCommandKeyC[] = KEY_ROOT"Debugger";
static const char msvcVerKeyC[] = KEY_ROOT"MSVCVer";
static const char ceVerKeyC[] = KEY_ROOT"CEVer";
static const char binPathKeyC[] = KEY_ROOT"BinPath";
@@ -278,23 +277,6 @@ WinCEToolChain *WinCEToolChain::readFromMap(const QVariantMap &data)
return 0;
}
-QString WinCEToolChain::legacyId() const
-{
- const QChar colon = QLatin1Char(':');
- QString id = QLatin1String(Constants::WINCE_TOOLCHAIN_ID);
- id += colon;
- id += m_msvcVer;
- id += colon;
- id += m_binPath;
- id += colon;
- id += m_includePath;
- id += colon;
- id += m_libPath;
- id += colon;
- id += m_debuggerCommand.toString();
- return id;
-}
-
QString WinCEToolChain::type() const
{
return QLatin1String("wince");
@@ -330,8 +312,6 @@ QString WinCEToolChain::ceVer() const
QVariantMap WinCEToolChain::toMap() const
{
QVariantMap data = ToolChain::toMap();
- if (!m_debuggerCommand.isEmpty())
- data.insert(QLatin1String(debuggerCommandKeyC), m_debuggerCommand.toString());
data.insert(QLatin1String(msvcVerKeyC), m_msvcVer);
data.insert(QLatin1String(ceVerKeyC), m_ceVer);
@@ -356,7 +336,6 @@ bool WinCEToolChain::fromMap(const QVariantMap &data)
m_libPath = data.value(QLatin1String(libPathKeyC)).toString();
m_vcvarsBat = data.value(QLatin1String(vcVarsKeyC)).toString();
- m_debuggerCommand = Utils::FileName::fromString(data.value(QLatin1String(debuggerCommandKeyC)).toString());
const QString abiString = data.value(QLatin1String(supportedAbiKeyC)).toString();
m_abi = Abi(abiString);
diff --git a/src/plugins/projectexplorer/wincetoolchain.h b/src/plugins/projectexplorer/wincetoolchain.h
index f09a1ded26..2f8e7db30b 100644
--- a/src/plugins/projectexplorer/wincetoolchain.h
+++ b/src/plugins/projectexplorer/wincetoolchain.h
@@ -57,7 +57,6 @@ public:
const QString &libPath,
bool autodetect = false);
- QString legacyId() const;
QList<Utils::FileName> suggestedMkspecList() const;
static WinCEToolChain *readFromMap(const QVariantMap &data);
@@ -65,8 +64,6 @@ public:
QString type() const;
QString typeDisplayName() const;
- Utils::FileName mkspecList() const;
-
QString ceVer() const;
QVariantMap toMap() const;