Commit 921f86df authored by Tobias Hunger's avatar Tobias Hunger

TargetSetupPage: Generalize the page

Generalize the target setup page and move it into projectexplorer

Move the qmake specific code into a projectimporter class with
a specialization for qmake projects in the qt4projectmanager.

This change depends heavily on the BuildConfigurationFactory cleanups
done earlier and completes that change in such a way that generic
build configuration factories are now in theory possible. The
remaining problem is how to select the best factory of several that
claim to be able to handle a kit and that is left for the next patch.

Change-Id: I47134cb1938c52adebcdc1ddfe8dbf26abbbbeee
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
parent 95828d46
......@@ -104,6 +104,24 @@ QList<BuildInfo *> AutotoolsBuildConfigurationFactory::availableBuilds(const Tar
return result;
}
bool AutotoolsBuildConfigurationFactory::canSetup(const Kit *k, const QString &projectPath) const
{
return k && Core::MimeDatabase::findByFile(QFileInfo(projectPath))
.matchesType(QLatin1String(Constants::MAKEFILE_MIMETYPE));
}
QList<BuildInfo *> AutotoolsBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const
{
QList<BuildInfo *> result;
QTC_ASSERT(canSetup(k, projectPath), return result);
BuildInfo *info = createBuildInfo(k,
Utils::FileName::fromString(AutotoolsProject::defaultBuildDirectory(projectPath)));
//: The name of the build configuration created by default for a autotools project.
info->displayName = tr("Default");
result << info;
return result;
}
BuildConfiguration *AutotoolsBuildConfigurationFactory::create(Target *parent, const BuildInfo *info) const
{
QTC_ASSERT(parent, return 0);
......@@ -165,6 +183,7 @@ BuildInfo *AutotoolsBuildConfigurationFactory::createBuildInfo(const ProjectExpl
info->typeName = tr("Build");
info->buildDirectory = buildDir;
info->kitId = k->id();
info->supportsShadowBuild = true; // Works sometimes...
return info;
}
......
......@@ -71,6 +71,9 @@ public:
bool canCreate(const ProjectExplorer::Target *parent) const;
QList<ProjectExplorer::BuildInfo *> availableBuilds(const ProjectExplorer::Target *parent) const;
bool canSetup(const ProjectExplorer::Kit *k, const QString &projectPath) const;
QList<ProjectExplorer::BuildInfo *> availableSetups(const ProjectExplorer::Kit *k,
const QString &projectPath) const;
ProjectExplorer::BuildConfiguration *create(ProjectExplorer::Target *parent,
const ProjectExplorer::BuildInfo *info) const;
......
......@@ -132,7 +132,30 @@ QList<ProjectExplorer::BuildInfo *> CMakeBuildConfigurationFactory::availableBui
QList<ProjectExplorer::BuildInfo *> result;
QTC_ASSERT(canCreate(parent), return result);
CMakeBuildInfo *info = createBuildInfo(parent->kit(), parent->project()->projectDirectory());
CMakeBuildInfo *info = createBuildInfo(parent->kit(),
parent->project()->projectDirectory());
result << info;
return result;
}
bool CMakeBuildConfigurationFactory::canSetup(const ProjectExplorer::Kit *k, const QString &projectPath) const
{
return k && Core::MimeDatabase::findByFile(QFileInfo(projectPath))
.matchesType(QLatin1String(Constants::CMAKEMIMETYPE));
}
QList<ProjectExplorer::BuildInfo *> CMakeBuildConfigurationFactory::availableSetups(const ProjectExplorer::Kit *k,
const QString &projectPath) const
{
QList<ProjectExplorer::BuildInfo *> result;
QTC_ASSERT(canSetup(k, projectPath), return result);
CMakeBuildInfo *info = createBuildInfo(k, ProjectExplorer::Project::projectDirectory(projectPath));
//: The name of the build configuration created by default for a cmake project.
info->displayName = tr("Default");
info->buildDirectory
= Utils::FileName::fromString(CMakeProject::shadowBuildDirectory(projectPath, k,
info->displayName));
result << info;
return result;
}
......@@ -234,6 +257,7 @@ CMakeBuildInfo *CMakeBuildConfigurationFactory::createBuildInfo(const ProjectExp
k->addToEnvironment(info->environment);
info->useNinja = false;
info->sourceDirectory = sourceDir;
info->supportsShadowBuild = true;
return info;
}
......
......@@ -87,6 +87,9 @@ public:
bool canCreate(const ProjectExplorer::Target *parent) const;
QList<ProjectExplorer::BuildInfo *> availableBuilds(const ProjectExplorer::Target *parent) const;
bool canSetup(const ProjectExplorer::Kit *k, const QString &projectPath) const;
QList<ProjectExplorer::BuildInfo *> availableSetups(const ProjectExplorer::Kit *k,
const QString &projectPath) const;
ProjectExplorer::BuildConfiguration *create(ProjectExplorer::Target *parent,
const ProjectExplorer::BuildInfo *info) const;
......
......@@ -93,8 +93,8 @@ public:
CMakeBuildTarget buildTargetForTitle(const QString &title);
QString shadowBuildDirectory(const QString &projectFilePath, const ProjectExplorer::Kit *k,
const QString &bcName);
static QString shadowBuildDirectory(const QString &projectFilePath, const ProjectExplorer::Kit *k,
const QString &bcName);
bool isProjectFile(const QString &fileName);
......
......@@ -102,6 +102,23 @@ QList<BuildInfo *> GenericBuildConfigurationFactory::availableBuilds(const Targe
return result;
}
bool GenericBuildConfigurationFactory::canSetup(const Kit *k, const QString &projectPath) const
{
return k && Core::MimeDatabase::findByFile(QFileInfo(projectPath))
.matchesType(QLatin1String(Constants::GENERICMIMETYPE));
}
QList<BuildInfo *> GenericBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const
{
QList<BuildInfo *> result;
QTC_ASSERT(canSetup(k, projectPath), return result);
BuildInfo *info = createBuildInfo(k, Utils::FileName::fromString(ProjectExplorer::Project::projectDirectory(projectPath)));
//: The name of the build configuration created by default for a generic project.
info->displayName = tr("Default");
result << info;
return result;
}
BuildConfiguration *GenericBuildConfigurationFactory::create(Target *parent, const BuildInfo *info) const
{
QTC_ASSERT(canCreate(parent), return 0);
......
......@@ -74,6 +74,9 @@ public:
bool canCreate(const ProjectExplorer::Target *parent) const;
QList<ProjectExplorer::BuildInfo *> availableBuilds(const ProjectExplorer::Target *parent) const;
bool canSetup(const ProjectExplorer::Kit *k, const QString &projectPath) const;
QList<ProjectExplorer::BuildInfo *> availableSetups(const ProjectExplorer::Kit *k,
const QString &projectPath) const;
ProjectExplorer::BuildConfiguration *create(ProjectExplorer::Target *parent,
const ProjectExplorer::BuildInfo *info) const;
......
......@@ -341,6 +341,18 @@ IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, con
return 0;
}
// setup
IBuildConfigurationFactory *IBuildConfigurationFactory::find(Kit *k, const QString &projectPath)
{
QList<IBuildConfigurationFactory *> factories
= ExtensionSystem::PluginManager::instance()->getObjects<IBuildConfigurationFactory>();
foreach (IBuildConfigurationFactory *factory, factories) {
if (factory->canSetup(k, projectPath))
return factory;
}
return 0;
}
// create
IBuildConfigurationFactory * IBuildConfigurationFactory::find(Target *parent)
{
......
......@@ -133,6 +133,13 @@ public:
// List of build information that can be used to create a new build configuration via
// "Add Build Configuration" button.
virtual QList<BuildInfo *> availableBuilds(const Target *parent) const = 0;
// Used to see whether this factory can produce any BuildConfigurations for a kit when
// setting up the given project.
virtual bool canSetup(const Kit *k, const QString &projectPath) const = 0;
// List of build information that can be used to initially set up a new build configuration.
virtual QList<BuildInfo *> availableSetups(const Kit *k, const QString &projectPath) const = 0;
virtual BuildConfiguration *create(Target *parent, const BuildInfo *info) const = 0;
// used to recreate the runConfigurations when restoring settings
......
......@@ -98,7 +98,7 @@ PropertiesPanel *BuildSettingsPanelFactory::createPanel(Target *target)
BuildSettingsWidget::~BuildSettingsWidget()
{
clear();
clearWidgets();
qDeleteAll(m_buildInfoList);
}
......@@ -195,7 +195,7 @@ void BuildSettingsWidget::addSubWidget(NamedWidget *widget)
m_subWidgets.append(widget);
}
void BuildSettingsWidget::clear()
void BuildSettingsWidget::clearWidgets()
{
qDeleteAll(m_subWidgets);
m_subWidgets.clear();
......@@ -232,7 +232,7 @@ void BuildSettingsWidget::updateAddButtonMenu()
void BuildSettingsWidget::updateBuildSettings()
{
clear();
clearWidgets();
// update buttons
m_removeButton->setEnabled(m_target->buildConfigurations().size() > 1);
......
......@@ -72,7 +72,7 @@ public:
BuildSettingsWidget(Target *target);
~BuildSettingsWidget();
void clear();
void clearWidgets();
void addSubWidget(ProjectExplorer::NamedWidget *widget);
QList<ProjectExplorer::NamedWidget *> subWidgets() const;
......
......@@ -35,7 +35,7 @@
#include <QPushButton>
#include <QVBoxLayout>
namespace Qt4ProjectManager {
namespace ProjectExplorer {
namespace Internal {
ImportWidget::ImportWidget(QWidget *parent) :
......@@ -85,4 +85,4 @@ void ImportWidget::handleImportRequest()
}
} // namespace Internal
} // namespace Qt4ProjectManager
} // namespace ProjectExplorer
......@@ -37,7 +37,7 @@ class PathChooser;
class FileName;
} // namespace Utils
namespace Qt4ProjectManager {
namespace ProjectExplorer {
namespace Internal {
class ImportWidget : public QWidget
......@@ -61,6 +61,6 @@ private:
};
} // namespace Internal
} // namespace Qt4ProjectManager
} // namespace ProjectExplorer
#endif // IMPORTWIDGET_H
......@@ -282,6 +282,7 @@ Target *Project::restoreTarget(const QVariantMap &data)
delete t;
return 0;
}
return t;
}
......@@ -505,8 +506,16 @@ void Project::setup(QList<const BuildInfo *> infoList)
continue;
t->addBuildConfiguration(bc);
}
foreach (Target *t, toRegister)
foreach (Target *t, toRegister) {
t->updateDefaultDeployConfigurations();
t->updateDefaultRunConfigurations();
addTarget(t);
}
}
ProjectImporter *Project::createProjectImporter() const
{
return 0;
}
void Project::onBuildDirectoryChanged()
......
......@@ -47,8 +47,10 @@ namespace ProjectExplorer {
class BuildInfo;
class IProjectManager;
class EditorConfiguration;
class ProjectImporter;
class ProjectNode;
class Kit;
class KitMatcher;
class NamedWidget;
class Target;
class ProjectPrivate;
......@@ -125,6 +127,9 @@ public:
virtual void configureAsExampleProject(const QStringList &platforms);
virtual bool supportsNoTargetPanel() const;
virtual ProjectImporter *createProjectImporter() const;
virtual KitMatcher *createRequiredKitMatcher() const { return 0; }
virtual KitMatcher *createPreferredKitMatcher() const { return 0; }
virtual bool needsSpecialDeployment() const;
......
......@@ -37,6 +37,7 @@
#include "projectexplorersettings.h"
#include "projectmacroexpander.h"
#include "removetaskhandler.h"
#include "unconfiguredprojectpanel.h"
#include "kitmanager.h"
#include "kitoptionspage.h"
#include "target.h"
......@@ -429,6 +430,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
addAutoReleasedObject(new DependenciesPanelFactory);
addAutoReleasedObject(new ProcessStepFactory);
addAutoReleasedObject(new UnconfiguredProjectPanel);
addAutoReleasedObject(new AllProjectsFind);
addAutoReleasedObject(new CurrentProjectFind);
......@@ -1653,7 +1655,7 @@ void ProjectExplorerPlugin::buildStateChanged(Project * pro)
{
if (debug) {
qDebug() << "buildStateChanged";
qDebug() << pro->document()->filePath() << "isBuilding()" << BuildManager::isBuilding(pro);
qDebug() << pro->projectFilePath() << "isBuilding()" << BuildManager::isBuilding(pro);
}
Q_UNUSED(pro)
updateActions();
......
......@@ -11,12 +11,17 @@ HEADERS += projectexplorer.h \
environmentaspect.h \
environmentaspectwidget.h \
gcctoolchain.h \
importwidget.h \
localapplicationrunconfiguration.h \
localenvironmentaspect.h \
osparser.h \
projectexplorer_export.h \
projectimporter.h \
projectwindow.h \
removetaskhandler.h \
targetsetuppage.h \
targetsetupwidget.h \
unconfiguredprojectpanel.h \
kit.h \
kitchooser.h \
kitconfigwidget.h \
......@@ -147,11 +152,16 @@ SOURCES += projectexplorer.cpp \
environmentaspect.cpp \
environmentaspectwidget.cpp \
gcctoolchain.cpp \
importwidget.cpp \
localapplicationrunconfiguration.cpp \
localenvironmentaspect.cpp \
osparser.cpp \
projectimporter.cpp \
projectwindow.cpp \
removetaskhandler.cpp \
targetsetuppage.cpp \
targetsetupwidget.cpp \
unconfiguredprojectpanel.cpp \
kit.cpp \
kitchooser.cpp \
kitconfigwidget.cpp \
......
......@@ -72,6 +72,7 @@ QtcPlugin {
"gcctoolchainfactories.h",
"gnumakeparser.cpp", "gnumakeparser.h",
"headerpath.h",
"importwidget.cpp", "importwidget.h",
"ioutputparser.cpp", "ioutputparser.h",
"iprojectmanager.h",
"iprojectproperties.h",
......@@ -108,6 +109,7 @@ QtcPlugin {
"projectexplorersettings.h",
"projectexplorersettingspage.cpp", "projectexplorersettingspage.h", "projectexplorersettingspage.ui",
"projectfilewizardextension.cpp", "projectfilewizardextension.h",
"projectimporter.cpp", "projectimporter.h",
"projectmacroexpander.cpp", "projectmacroexpander.h",
"projectmodels.cpp", "projectmodels.h",
"projectnodes.cpp", "projectnodes.h",
......@@ -126,8 +128,9 @@ QtcPlugin {
"target.cpp", "target.h",
"targetselector.cpp", "targetselector.h",
"targetsettingspanel.cpp", "targetsettingspanel.h",
"targetsettingswidget.cpp", "targetsettingswidget.h",
"targetsettingswidget.ui",
"targetsettingswidget.cpp", "targetsettingswidget.h", "targetsettingswidget.ui",
"targetsetuppage.cpp", "targetsetuppage.h",
"targetsetupwidget.cpp", "targetsetupwidget.h",
"task.cpp", "task.h",
"taskhub.cpp", "taskhub.h",
"taskmodel.cpp", "taskmodel.h",
......@@ -136,6 +139,7 @@ QtcPlugin {
"toolchainconfigwidget.cpp", "toolchainconfigwidget.h",
"toolchainmanager.cpp", "toolchainmanager.h",
"toolchainoptionspage.cpp", "toolchainoptionspage.h",
"unconfiguredprojectpanel.cpp", "unconfiguredprojectpanel.h",
"vcsannotatetaskhandler.cpp", "vcsannotatetaskhandler.h",
]
}
......
......@@ -246,6 +246,9 @@ const char VAR_CURRENTKIT_ID[] = "CurrentKit:Id";
const char VAR_CURRENTBUILD_NAME[] = "CurrentBuild:Name";
const char VAR_CURRENTBUILD_TYPE[] = "CurrentBuild:Type";
// Unconfigured Panel
const char UNCONFIGURED_PANEL_PAGE_ID[] = "UnconfiguredPanel";
} // namespace Constants
// Run modes
......
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "projectimporter.h"
#include "kit.h"
#include "kitmanager.h"
#include "project.h"
#include <coreplugin/idocument.h>
#include <utils/qtcassert.h>
namespace ProjectExplorer {
static const Core::Id KIT_IS_TEMPORARY("PE.TempKit");
static const Core::Id KIT_TEMPORARY_NAME("PE.TempName");
static const Core::Id KIT_FINAL_NAME("PE.FinalName");
static const Core::Id TEMPORARY_OF_PROJECTS("PE.TempProject");
ProjectImporter::ProjectImporter(const QString &path) : m_projectPath(path), m_isUpdating(false)
{ }
ProjectImporter::~ProjectImporter()
{
foreach (Kit *k, KitManager::kits())
removeProject(k, m_projectPath);
}
void ProjectImporter::markTemporary(Kit *k)
{
QTC_ASSERT(!k->hasValue(KIT_IS_TEMPORARY), return);
setIsUpdating(true);
const QString name = k->displayName();
k->setDisplayName(QCoreApplication::translate("ProjectExplorer::ProjectImporter",
"%1 - temporary").arg(name));
k->setValue(KIT_TEMPORARY_NAME, k->displayName());
k->setValue(KIT_FINAL_NAME, name);
k->setValue(KIT_IS_TEMPORARY, true);
setIsUpdating(false);
}
void ProjectImporter::makePermanent(Kit *k)
{
if (!k->hasValue(KIT_IS_TEMPORARY))
return;
setIsUpdating(true);
k->removeKey(KIT_IS_TEMPORARY);
k->removeKey(TEMPORARY_OF_PROJECTS);
const QString tempName = k->value(KIT_TEMPORARY_NAME).toString();
if (!tempName.isNull() && k->displayName() == tempName)
k->setDisplayName(k->value(KIT_FINAL_NAME).toString());
k->removeKey(KIT_TEMPORARY_NAME);
k->removeKey(KIT_FINAL_NAME);
setIsUpdating(false);
}
void ProjectImporter::cleanupKit(Kit *k)
{
Q_UNUSED(k);
}
void ProjectImporter::addProject(Kit *k)
{
if (!k->hasValue(KIT_IS_TEMPORARY))
return;
QStringList projects = k->value(TEMPORARY_OF_PROJECTS, QStringList()).toStringList();
projects.append(m_projectPath); // note: There can be more than one instance of the project added!
setIsUpdating(true);
k->setValue(TEMPORARY_OF_PROJECTS, projects);
setIsUpdating(false);
}
void ProjectImporter::removeProject(Kit *k, const QString &path)
{
if (!k->hasValue(KIT_IS_TEMPORARY))
return;
QStringList projects = k->value(TEMPORARY_OF_PROJECTS, QStringList()).toStringList();
projects.removeOne(path);
setIsUpdating(true);
if (projects.isEmpty())
ProjectExplorer::KitManager::deregisterKit(k);
else
k->setValue(TEMPORARY_OF_PROJECTS, projects);
setIsUpdating(false);
}
} // namespace ProjectExplorer
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef PROJECTIMPORTER_H
#define PROJECTIMPORTER_H
#include "projectexplorer_export.h"
#include <utils/fileutils.h>
namespace ProjectExplorer {
class BuildInfo;
class Kit;
class Project;
class Target;
// Documentation inside.
class PROJECTEXPLORER_EXPORT ProjectImporter
{
public:
ProjectImporter(const QString &path);
virtual ~ProjectImporter();
const QString projectFilePath() const { return m_projectPath; }
virtual QList<BuildInfo *> import(const Utils::FileName &importPath, bool silent = false) = 0;
virtual QStringList importCandidates(const Utils::FileName &projectFilePath) = 0;
virtual Target *preferredTarget(const QList<Target *> &possibleTargets) = 0;
bool isUpdating() const { return m_isUpdating; }
virtual void markTemporary(Kit *k);
virtual void makePermanent(Kit *k);
// Additional cleanup that has to happen when kits are removed
virtual void cleanupKit(Kit *k);
void addProject(Kit *k);
void removeProject(Kit *k, const QString &path);
protected:
void setIsUpdating(bool b) { m_isUpdating = b; }
private:
const QString m_projectPath;
bool m_isUpdating;
};
} // namespace ProjectExplorer
#endif // PROJECTIMPORTER_H
......@@ -528,7 +528,7 @@ void Target::updateDefaultBuildConfigurations()
qWarning("No build configuration factory found for target id '%s'.", qPrintable(id().toString()));