forked from qt-creator/qt-creator
CMake: Fix several issues with the CMakeBuildStep
- Store the selection of the "Current executable" target again
(broke apparently with 2c822ae3
)
- Display the resolved target of the "Current executable" seletion
in the command line, instead of the fixed "
'<Current executable>' text
- Make the "Current executable" translatable
- Add a tooltip explaining what it is
- Use a Utils::TreeModel instead of a QStandardItemModel for the
target model
- As side-effect, searching in the target view using Ctrl-F seems
to magically work again.
Change-Id: Ia4d0913f6e586f49f74da66651a9177437dad6d9
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -46,7 +46,9 @@
|
|||||||
#include <QBoxLayout>
|
#include <QBoxLayout>
|
||||||
#include <QListWidget>
|
#include <QListWidget>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
|
using namespace Core;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
@@ -56,8 +58,8 @@ namespace Internal {
|
|||||||
const char BUILD_TARGETS_KEY[] = "CMakeProjectManager.MakeStep.BuildTargets";
|
const char BUILD_TARGETS_KEY[] = "CMakeProjectManager.MakeStep.BuildTargets";
|
||||||
const char CMAKE_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.CMakeArguments";
|
const char CMAKE_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.CMakeArguments";
|
||||||
const char TOOL_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.AdditionalArguments";
|
const char TOOL_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.AdditionalArguments";
|
||||||
const char ADD_RUNCONFIGURATION_ARGUMENT_KEY[] = "CMakeProjectManager.MakeStep.AddRunConfigurationArgument";
|
|
||||||
const char ADD_RUNCONFIGURATION_TEXT[] = "Current executable";
|
// CmakeProgressParser
|
||||||
|
|
||||||
class CmakeProgressParser : public Utils::OutputLineParser
|
class CmakeProgressParser : public Utils::OutputLineParser
|
||||||
{
|
{
|
||||||
@@ -106,28 +108,63 @@ private:
|
|||||||
bool m_useNinja = false;
|
bool m_useNinja = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMakeBuildStepConfigWidget : public BuildStepConfigWidget
|
|
||||||
|
// CmakeTargetItem
|
||||||
|
|
||||||
|
CMakeTargetItem::CMakeTargetItem(const QString &target, CMakeBuildStep *step, bool special)
|
||||||
|
: m_target(target), m_step(step), m_special(special)
|
||||||
{
|
{
|
||||||
Q_DECLARE_TR_FUNCTIONS(CMakeProjectManager::Internal::CMakeBuildStepConfigWidget)
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CMakeBuildStepConfigWidget(CMakeBuildStep *buildStep);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void itemsChanged();
|
|
||||||
void updateDetails();
|
|
||||||
void buildTargetsChanged();
|
|
||||||
void updateBuildTargets();
|
|
||||||
|
|
||||||
CMakeBuildStep *m_buildStep;
|
|
||||||
QListWidget *m_buildTargetsList;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool isCurrentExecutableTarget(const QString &target)
|
|
||||||
{
|
|
||||||
return target == ADD_RUNCONFIGURATION_TEXT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant CMakeTargetItem::data(int column, int role) const
|
||||||
|
{
|
||||||
|
if (column == 0) {
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
if (m_target.isEmpty())
|
||||||
|
return CMakeBuildStep::tr("Current executable");
|
||||||
|
return m_target;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == Qt::ToolTipRole) {
|
||||||
|
if (m_target.isEmpty()) {
|
||||||
|
return CMakeBuildStep::tr("Build the executable used in the active Run "
|
||||||
|
"configuration. Currently: %1")
|
||||||
|
.arg(m_step->activeRunConfigTarget());
|
||||||
|
}
|
||||||
|
return CMakeBuildStep::tr("Target: %1").arg(m_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == Qt::CheckStateRole)
|
||||||
|
return m_step->buildsBuildTarget(m_target) ? Qt::Checked : Qt::Unchecked;
|
||||||
|
|
||||||
|
if (role == Qt::FontRole) {
|
||||||
|
if (m_special) {
|
||||||
|
QFont italics;
|
||||||
|
italics.setItalic(true);
|
||||||
|
return italics;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMakeTargetItem::setData(int column, const QVariant &data, int role)
|
||||||
|
{
|
||||||
|
if (column == 0 && role == Qt::CheckStateRole) {
|
||||||
|
m_step->setBuildsBuildTarget(m_target, data.value<Qt::CheckState>() == Qt::Checked);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return TreeItem::setData(column, data, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags CMakeTargetItem::flags(int) const
|
||||||
|
{
|
||||||
|
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CMakeBuildStep
|
||||||
|
|
||||||
CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl, Utils::Id id) :
|
CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl, Utils::Id id) :
|
||||||
AbstractProcessStep(bsl, id)
|
AbstractProcessStep(bsl, id)
|
||||||
{
|
{
|
||||||
@@ -144,8 +181,8 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl, Utils::Id id) :
|
|||||||
m_toolArguments->setLabelText(tr("Tool arguments:"));
|
m_toolArguments->setLabelText(tr("Tool arguments:"));
|
||||||
m_toolArguments->setDisplayStyle(StringAspect::LineEditDisplay);
|
m_toolArguments->setDisplayStyle(StringAspect::LineEditDisplay);
|
||||||
|
|
||||||
// Set a good default build target:
|
m_buildTargetModel.setHeader({tr("Target")});
|
||||||
if (m_buildTargets.isEmpty())
|
|
||||||
setBuildTargets({defaultBuildTarget()});
|
setBuildTargets({defaultBuildTarget()});
|
||||||
|
|
||||||
setLowPriority();
|
setLowPriority();
|
||||||
@@ -157,51 +194,39 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl, Utils::Id id) :
|
|||||||
env.set("NINJA_STATUS", ninjaProgressString + "%o/sec] ");
|
env.set("NINJA_STATUS", ninjaProgressString + "%o/sec] ");
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(target(), &Target::parsingFinished,
|
connect(target(), &Target::parsingFinished, this, [this](bool success) {
|
||||||
this, &CMakeBuildStep::handleBuildTargetsChanges);
|
if (success) // Do not change when parsing failed.
|
||||||
|
recreateBuildTargetsModel();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(target(), &Target::activeRunConfigurationChanged,
|
||||||
|
this, &CMakeBuildStep::updateBuildTargetsModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildStep::handleBuildTargetsChanges(bool success)
|
|
||||||
{
|
|
||||||
if (!success)
|
|
||||||
return; // Do not change when parsing failed.
|
|
||||||
const QStringList results = Utils::filtered(m_buildTargets, [this](const QString &s) {
|
|
||||||
return knownBuildTargets().contains(s);
|
|
||||||
});
|
|
||||||
if (results.isEmpty())
|
|
||||||
setBuildTargets({defaultBuildTarget()});
|
|
||||||
else {
|
|
||||||
setBuildTargets(results);
|
|
||||||
}
|
|
||||||
emit buildTargetsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantMap CMakeBuildStep::toMap() const
|
QVariantMap CMakeBuildStep::toMap() const
|
||||||
{
|
{
|
||||||
QVariantMap map(AbstractProcessStep::toMap());
|
QVariantMap map(AbstractProcessStep::toMap());
|
||||||
// Use QStringList for compatibility with old files
|
map.insert(BUILD_TARGETS_KEY, m_buildTargets);
|
||||||
map.insert(BUILD_TARGETS_KEY, QStringList(m_buildTargets));
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMakeBuildStep::fromMap(const QVariantMap &map)
|
bool CMakeBuildStep::fromMap(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
m_buildTargets = map.value(BUILD_TARGETS_KEY).toStringList();
|
setBuildTargets(map.value(BUILD_TARGETS_KEY).toStringList());
|
||||||
if (map.value(ADD_RUNCONFIGURATION_ARGUMENT_KEY, false).toBool())
|
|
||||||
m_buildTargets = QStringList(ADD_RUNCONFIGURATION_TEXT);
|
|
||||||
|
|
||||||
return BuildStep::fromMap(map);
|
return BuildStep::fromMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMakeBuildStep::init()
|
bool CMakeBuildStep::init()
|
||||||
{
|
{
|
||||||
bool canInit = true;
|
|
||||||
BuildConfiguration *bc = buildConfiguration();
|
BuildConfiguration *bc = buildConfiguration();
|
||||||
QTC_ASSERT(bc, return false);
|
QTC_ASSERT(bc, return false);
|
||||||
|
|
||||||
if (!bc->isEnabled()) {
|
if (!bc->isEnabled()) {
|
||||||
emit addTask(BuildSystemTask(Task::Error,
|
emit addTask(BuildSystemTask(Task::Error,
|
||||||
tr("The build configuration is currently disabled.")));
|
tr("The build configuration is currently disabled.")));
|
||||||
canInit = false;
|
emitFaultyConfigurationMessage();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMakeTool *tool = CMakeKitAspect::cmakeTool(kit());
|
CMakeTool *tool = CMakeKitAspect::cmakeTool(kit());
|
||||||
@@ -209,24 +234,22 @@ bool CMakeBuildStep::init()
|
|||||||
emit addTask(BuildSystemTask(Task::Error,
|
emit addTask(BuildSystemTask(Task::Error,
|
||||||
tr("A CMake tool must be set up for building. "
|
tr("A CMake tool must be set up for building. "
|
||||||
"Configure a CMake tool in the kit options.")));
|
"Configure a CMake tool in the kit options.")));
|
||||||
canInit = false;
|
emitFaultyConfigurationMessage();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_buildTargets.contains(QString())) {
|
||||||
RunConfiguration *rc = target()->activeRunConfiguration();
|
RunConfiguration *rc = target()->activeRunConfiguration();
|
||||||
const bool buildCurrent = Utils::contains(m_buildTargets, [](const QString &s) { return isCurrentExecutableTarget(s); });
|
if (!rc || rc->buildKey().isEmpty()) {
|
||||||
if (buildCurrent && (!rc || rc->buildKey().isEmpty())) {
|
|
||||||
emit addTask(BuildSystemTask(Task::Error,
|
emit addTask(BuildSystemTask(Task::Error,
|
||||||
QCoreApplication::translate("ProjectExplorer::Task",
|
QCoreApplication::translate("ProjectExplorer::Task",
|
||||||
"You asked to build the current Run Configuration's build target only, "
|
"You asked to build the current Run Configuration's build target only, "
|
||||||
"but it is not associated with a build target. "
|
"but it is not associated with a build target. "
|
||||||
"Update the Make Step in your build settings.")));
|
"Update the Make Step in your build settings.")));
|
||||||
canInit = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!canInit) {
|
|
||||||
emitFaultyConfigurationMessage();
|
emitFaultyConfigurationMessage();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Warn if doing out-of-source builds with a CMakeCache.txt is the source directory
|
// Warn if doing out-of-source builds with a CMakeCache.txt is the source directory
|
||||||
const Utils::FilePath projectDirectory = bc->target()->project()->projectDirectory();
|
const Utils::FilePath projectDirectory = bc->target()->project()->projectDirectory();
|
||||||
@@ -244,7 +267,7 @@ bool CMakeBuildStep::init()
|
|||||||
|
|
||||||
ProcessParameters *pp = processParameters();
|
ProcessParameters *pp = processParameters();
|
||||||
setupProcessParameters(pp);
|
setupProcessParameters(pp);
|
||||||
pp->setCommandLine(cmakeCommand(rc));
|
pp->setCommandLine(cmakeCommand());
|
||||||
|
|
||||||
return AbstractProcessStep::init();
|
return AbstractProcessStep::init();
|
||||||
}
|
}
|
||||||
@@ -308,11 +331,6 @@ void CMakeBuildStep::handleProjectWasParsed(bool success)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildStepConfigWidget *CMakeBuildStep::createConfigWidget()
|
|
||||||
{
|
|
||||||
return new CMakeBuildStepConfigWidget(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CMakeBuildStep::defaultBuildTarget() const
|
QString CMakeBuildStep::defaultBuildTarget() const
|
||||||
{
|
{
|
||||||
const BuildStepList *const bsl = stepList();
|
const BuildStepList *const bsl = stepList();
|
||||||
@@ -335,15 +353,26 @@ bool CMakeBuildStep::buildsBuildTarget(const QString &target) const
|
|||||||
return m_buildTargets.contains(target);
|
return m_buildTargets.contains(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildStep::setBuildTargets(const QStringList &buildTargets)
|
void CMakeBuildStep::setBuildsBuildTarget(const QString &target, bool on)
|
||||||
{
|
{
|
||||||
if (m_buildTargets == buildTargets)
|
QStringList targets = m_buildTargets;
|
||||||
return;
|
if (on && !m_buildTargets.contains(target))
|
||||||
m_buildTargets = buildTargets;
|
targets.append(target);
|
||||||
emit targetsToBuildChanged();
|
if (!on)
|
||||||
|
targets.removeAll(target);
|
||||||
|
setBuildTargets(targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::CommandLine CMakeBuildStep::cmakeCommand(RunConfiguration *rc) const
|
void CMakeBuildStep::setBuildTargets(const QStringList &buildTargets)
|
||||||
|
{
|
||||||
|
if (buildTargets.isEmpty())
|
||||||
|
m_buildTargets = QStringList(defaultBuildTarget());
|
||||||
|
else
|
||||||
|
m_buildTargets = buildTargets;
|
||||||
|
updateBuildTargetsModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandLine CMakeBuildStep::cmakeCommand() const
|
||||||
{
|
{
|
||||||
CMakeTool *tool = CMakeKitAspect::cmakeTool(kit());
|
CMakeTool *tool = CMakeKitAspect::cmakeTool(kit());
|
||||||
|
|
||||||
@@ -351,20 +380,12 @@ Utils::CommandLine CMakeBuildStep::cmakeCommand(RunConfiguration *rc) const
|
|||||||
cmd.addArgs({"--build", "."});
|
cmd.addArgs({"--build", "."});
|
||||||
|
|
||||||
cmd.addArg("--target");
|
cmd.addArg("--target");
|
||||||
cmd.addArgs(Utils::transform(m_buildTargets, [rc](const QString &s) {
|
cmd.addArgs(Utils::transform(m_buildTargets, [this](const QString &s) {
|
||||||
QString target = s;
|
if (s.isEmpty()) {
|
||||||
if (isCurrentExecutableTarget(s)) {
|
if (RunConfiguration *rc = target()->activeRunConfiguration())
|
||||||
if (rc) {
|
return rc->buildKey();
|
||||||
target = rc->buildKey();
|
|
||||||
const int pos = target.indexOf("///::///");
|
|
||||||
if (pos >= 0) {
|
|
||||||
target = target.mid(pos + 8);
|
|
||||||
}
|
}
|
||||||
} else {
|
return s;
|
||||||
target = "<i><" + tr(ADD_RUNCONFIGURATION_TEXT) + "></i>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (!m_cmakeArguments->value().isEmpty())
|
if (!m_cmakeArguments->value().isEmpty())
|
||||||
@@ -378,12 +399,6 @@ Utils::CommandLine CMakeBuildStep::cmakeCommand(RunConfiguration *rc) const
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList CMakeBuildStep::knownBuildTargets()
|
|
||||||
{
|
|
||||||
auto bs = qobject_cast<CMakeBuildSystem *>(buildSystem());
|
|
||||||
return bs ? bs->buildTargetTitles() : QStringList();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CMakeBuildStep::cleanTarget()
|
QString CMakeBuildStep::cleanTarget()
|
||||||
{
|
{
|
||||||
return QString("clean");
|
return QString("clean");
|
||||||
@@ -409,139 +424,82 @@ QStringList CMakeBuildStep::specialTargets()
|
|||||||
return { allTarget(), cleanTarget(), installTarget(), testTarget() };
|
return { allTarget(), cleanTarget(), installTarget(), testTarget() };
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
QString CMakeBuildStep::activeRunConfigTarget() const
|
||||||
// CMakeBuildStepConfigWidget
|
|
||||||
//
|
|
||||||
|
|
||||||
CMakeBuildStepConfigWidget::CMakeBuildStepConfigWidget(CMakeBuildStep *buildStep)
|
|
||||||
: BuildStepConfigWidget(buildStep)
|
|
||||||
, m_buildStep(buildStep)
|
|
||||||
, m_buildTargetsList(new QListWidget)
|
|
||||||
{
|
{
|
||||||
setDisplayName(tr("Build", "CMakeProjectManager::CMakeBuildStepConfigWidget display name."));
|
RunConfiguration *rc = target()->activeRunConfiguration();
|
||||||
|
return rc ? rc->buildKey() : QString();
|
||||||
|
}
|
||||||
|
|
||||||
LayoutBuilder builder(this);
|
BuildStepConfigWidget *CMakeBuildStep::createConfigWidget()
|
||||||
builder.addRow(buildStep->m_cmakeArguments);
|
{
|
||||||
builder.addRow(buildStep->m_toolArguments);
|
auto widget = new BuildStepConfigWidget(this);
|
||||||
|
|
||||||
m_buildTargetsList->setFrameStyle(QFrame::NoFrame);
|
auto updateDetails = [this, widget] {
|
||||||
m_buildTargetsList->setMinimumHeight(200);
|
ProcessParameters param;
|
||||||
|
setupProcessParameters(¶m);
|
||||||
|
param.setCommandLine(cmakeCommand());
|
||||||
|
widget->setSummaryText(param.summary(displayName()));
|
||||||
|
};
|
||||||
|
|
||||||
auto frame = new QFrame(this);
|
widget->setDisplayName(tr("Build", "ConfigWidget display name."));
|
||||||
frame->setFrameStyle(QFrame::StyledPanel);
|
|
||||||
auto frameLayout = new QVBoxLayout(frame);
|
LayoutBuilder builder(widget);
|
||||||
frameLayout->setContentsMargins(0, 0, 0, 0);
|
builder.addRow(m_cmakeArguments);
|
||||||
frameLayout->addWidget(Core::ItemViewFind::createSearchableWrapper(m_buildTargetsList,
|
builder.addRow(m_toolArguments);
|
||||||
Core::ItemViewFind::LightColored));
|
|
||||||
|
auto buildTargetsView = new QTreeView;
|
||||||
|
buildTargetsView->setMinimumHeight(200);
|
||||||
|
buildTargetsView->setModel(&m_buildTargetModel);
|
||||||
|
buildTargetsView->setRootIsDecorated(false);
|
||||||
|
buildTargetsView->setHeaderHidden(true);
|
||||||
|
|
||||||
|
auto frame = ItemViewFind::createSearchableWrapper(buildTargetsView,
|
||||||
|
ItemViewFind::LightColored);
|
||||||
|
|
||||||
builder.startNewRow().addItems(tr("Targets:"), frame);
|
builder.startNewRow().addItems(tr("Targets:"), frame);
|
||||||
|
|
||||||
buildTargetsChanged();
|
|
||||||
updateDetails();
|
updateDetails();
|
||||||
|
|
||||||
connect(buildStep->m_cmakeArguments, &StringAspect::changed,
|
connect(m_cmakeArguments, &StringAspect::changed, this, updateDetails);
|
||||||
this, &CMakeBuildStepConfigWidget::updateDetails);
|
connect(m_toolArguments, &StringAspect::changed, this, updateDetails);
|
||||||
connect(buildStep->m_toolArguments, &StringAspect::changed,
|
|
||||||
this, &CMakeBuildStepConfigWidget::updateDetails);
|
|
||||||
|
|
||||||
connect(m_buildTargetsList, &QListWidget::itemChanged,
|
|
||||||
this, &CMakeBuildStepConfigWidget::itemsChanged);
|
|
||||||
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
|
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
|
||||||
this, &CMakeBuildStepConfigWidget::updateDetails);
|
this, updateDetails);
|
||||||
|
|
||||||
connect(m_buildStep,
|
connect(buildConfiguration(), &BuildConfiguration::environmentChanged,
|
||||||
&CMakeBuildStep::buildTargetsChanged,
|
this, updateDetails);
|
||||||
this,
|
|
||||||
&CMakeBuildStepConfigWidget::buildTargetsChanged);
|
|
||||||
|
|
||||||
connect(m_buildStep,
|
connect(this, &CMakeBuildStep::buildTargetsChanged, widget, updateDetails);
|
||||||
&CMakeBuildStep::targetsToBuildChanged,
|
|
||||||
this,
|
|
||||||
&CMakeBuildStepConfigWidget::updateBuildTargets);
|
|
||||||
|
|
||||||
connect(m_buildStep->buildConfiguration(),
|
return widget;
|
||||||
&BuildConfiguration::environmentChanged,
|
|
||||||
this,
|
|
||||||
&CMakeBuildStepConfigWidget::updateDetails);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildStepConfigWidget::itemsChanged()
|
void CMakeBuildStep::recreateBuildTargetsModel()
|
||||||
{
|
{
|
||||||
const QList<QListWidgetItem *> items = [this]() {
|
auto addItem = [this](const QString &target, bool special = false) {
|
||||||
QList<QListWidgetItem *> items;
|
auto item = new CMakeTargetItem(target, this, special);
|
||||||
for (int row = 0; row < m_buildTargetsList->count(); ++row)
|
m_buildTargetModel.rootItem()->appendChild(item);
|
||||||
items.append(m_buildTargetsList->item(row));
|
|
||||||
return items;
|
|
||||||
}();
|
|
||||||
const QStringList targetsToBuild = Utils::transform(Utils::filtered(items, Utils::equal(&QListWidgetItem::checkState, Qt::Checked)),
|
|
||||||
[](const QListWidgetItem *i) { return i->data(Qt::UserRole).toString(); });
|
|
||||||
m_buildStep->setBuildTargets(targetsToBuild);
|
|
||||||
updateDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMakeBuildStepConfigWidget::buildTargetsChanged()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
QFont italics;
|
|
||||||
italics.setItalic(true);
|
|
||||||
|
|
||||||
auto addItem = [italics, this](const QString &buildTarget, const QString &displayName, bool special = false) {
|
|
||||||
auto item = new QListWidgetItem(displayName, m_buildTargetsList);
|
|
||||||
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
|
|
||||||
item->setData(Qt::UserRole, buildTarget);
|
|
||||||
if (special)
|
|
||||||
item->setFont(italics);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QSignalBlocker blocker(m_buildTargetsList);
|
m_buildTargetModel.clear();
|
||||||
m_buildTargetsList->clear();
|
|
||||||
|
auto bs = qobject_cast<CMakeBuildSystem *>(buildSystem());
|
||||||
|
QStringList targetList = bs ? bs->buildTargetTitles() : QStringList();
|
||||||
|
|
||||||
QStringList targetList = m_buildStep->knownBuildTargets();
|
|
||||||
targetList.sort();
|
targetList.sort();
|
||||||
|
|
||||||
addItem(ADD_RUNCONFIGURATION_TEXT, tr(ADD_RUNCONFIGURATION_TEXT), true);
|
addItem(QString(), true);
|
||||||
|
|
||||||
foreach (const QString &buildTarget, targetList)
|
for (const QString &buildTarget : qAsConst(targetList))
|
||||||
addItem(buildTarget, buildTarget, CMakeBuildStep::specialTargets().contains(buildTarget));
|
addItem(buildTarget, specialTargets().contains(buildTarget));
|
||||||
|
|
||||||
updateBuildTargets();
|
updateBuildTargetsModel();
|
||||||
}
|
|
||||||
updateDetails();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildStepConfigWidget::updateBuildTargets()
|
void CMakeBuildStep::updateBuildTargetsModel()
|
||||||
{
|
{
|
||||||
const QStringList buildTargets = m_buildStep->buildTargets();
|
emit m_buildTargetModel.layoutChanged();
|
||||||
{
|
emit buildTargetsChanged();
|
||||||
QSignalBlocker blocker(m_buildTargetsList);
|
|
||||||
for (int row = 0; row < m_buildTargetsList->count(); ++row) {
|
|
||||||
QListWidgetItem *item = m_buildTargetsList->item(row);
|
|
||||||
const QString title = item->data(Qt::UserRole).toString();
|
|
||||||
|
|
||||||
item->setCheckState(m_buildStep->buildsBuildTarget(title) ? Qt::Checked : Qt::Unchecked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMakeBuildStepConfigWidget::updateDetails()
|
|
||||||
{
|
|
||||||
ProcessParameters param;
|
|
||||||
m_buildStep->setupProcessParameters(¶m);
|
|
||||||
param.setCommandLine(m_buildStep->cmakeCommand(nullptr));
|
|
||||||
|
|
||||||
setSummaryText(param.summary(displayName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// CMakeBuildStepFactory
|
|
||||||
//
|
|
||||||
|
|
||||||
CMakeBuildStepFactory::CMakeBuildStepFactory()
|
|
||||||
{
|
|
||||||
registerStep<CMakeBuildStep>(Constants::CMAKE_BUILD_STEP_ID);
|
|
||||||
setDisplayName(CMakeBuildStep::tr("Build", "Display name for CMakeProjectManager::CMakeBuildStep id."));
|
|
||||||
setSupportedProjectType(Constants::CMAKE_PROJECT_ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildStep::processFinished(int exitCode, QProcess::ExitStatus status)
|
void CMakeBuildStep::processFinished(int exitCode, QProcess::ExitStatus status)
|
||||||
@@ -550,6 +508,15 @@ void CMakeBuildStep::processFinished(int exitCode, QProcess::ExitStatus status)
|
|||||||
emit progress(100, QString());
|
emit progress(100, QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CMakeBuildStepFactory
|
||||||
|
|
||||||
|
CMakeBuildStepFactory::CMakeBuildStepFactory()
|
||||||
|
{
|
||||||
|
registerStep<CMakeBuildStep>(Constants::CMAKE_BUILD_STEP_ID);
|
||||||
|
setDisplayName(CMakeBuildStep::tr("Build", "Display name for CMakeProjectManager::CMakeBuildStep id."));
|
||||||
|
setSupportedProjectType(Constants::CMAKE_PROJECT_ID);
|
||||||
|
}
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
} // CMakeProjectManager
|
} // CMakeProjectManager
|
||||||
|
|
||||||
|
@@ -26,19 +26,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <projectexplorer/abstractprocessstep.h>
|
#include <projectexplorer/abstractprocessstep.h>
|
||||||
|
#include <utils/treemodel.h>
|
||||||
#include <QRegularExpression>
|
|
||||||
|
|
||||||
namespace Utils { class CommandLine; }
|
namespace Utils { class CommandLine; }
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer { class StringAspect; }
|
||||||
class RunConfiguration;
|
|
||||||
class StringAspect;
|
|
||||||
} // ProjectExplorer
|
|
||||||
|
|
||||||
namespace CMakeProjectManager {
|
namespace CMakeProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class CMakeBuildStep;
|
||||||
|
|
||||||
|
class CMakeTargetItem : public Utils::TreeItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMakeTargetItem() = default;
|
||||||
|
CMakeTargetItem(const QString &target, CMakeBuildStep *step, bool special);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVariant data(int column, int role) const final;
|
||||||
|
bool setData(int column, const QVariant &data, int role) final;
|
||||||
|
Qt::ItemFlags flags(int column) const final;
|
||||||
|
|
||||||
|
QString m_target;
|
||||||
|
CMakeBuildStep *m_step = nullptr;
|
||||||
|
bool m_special = false;
|
||||||
|
};
|
||||||
|
|
||||||
class CMakeBuildStep : public ProjectExplorer::AbstractProcessStep
|
class CMakeBuildStep : public ProjectExplorer::AbstractProcessStep
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -47,12 +61,10 @@ public:
|
|||||||
CMakeBuildStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
|
CMakeBuildStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
|
||||||
|
|
||||||
QStringList buildTargets() const;
|
QStringList buildTargets() const;
|
||||||
bool buildsBuildTarget(const QString &target) const;
|
|
||||||
void setBuildTargets(const QStringList &target);
|
void setBuildTargets(const QStringList &target);
|
||||||
|
|
||||||
Utils::CommandLine cmakeCommand(ProjectExplorer::RunConfiguration *rc) const;
|
bool buildsBuildTarget(const QString &target) const;
|
||||||
|
void setBuildsBuildTarget(const QString &target, bool on);
|
||||||
QStringList knownBuildTargets();
|
|
||||||
|
|
||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
|
|
||||||
@@ -62,16 +74,17 @@ public:
|
|||||||
static QString testTarget();
|
static QString testTarget();
|
||||||
static QStringList specialTargets();
|
static QStringList specialTargets();
|
||||||
|
|
||||||
|
QString activeRunConfigTarget() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void targetsToBuildChanged();
|
|
||||||
void buildTargetsChanged();
|
void buildTargetsChanged();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
void processFinished(int exitCode, QProcess::ExitStatus status) override;
|
Utils::CommandLine cmakeCommand() const;
|
||||||
|
|
||||||
|
void processFinished(int exitCode, QProcess::ExitStatus status) override;
|
||||||
bool fromMap(const QVariantMap &map) override;
|
bool fromMap(const QVariantMap &map) override;
|
||||||
|
|
||||||
private:
|
|
||||||
bool init() override;
|
bool init() override;
|
||||||
void setupOutputFormatter(Utils::OutputFormatter *formatter) override;
|
void setupOutputFormatter(Utils::OutputFormatter *formatter) override;
|
||||||
void doRun() override;
|
void doRun() override;
|
||||||
@@ -83,14 +96,18 @@ private:
|
|||||||
void handleProjectWasParsed(bool success);
|
void handleProjectWasParsed(bool success);
|
||||||
|
|
||||||
void handleBuildTargetsChanges(bool success);
|
void handleBuildTargetsChanges(bool success);
|
||||||
|
void recreateBuildTargetsModel();
|
||||||
|
void updateBuildTargetsModel();
|
||||||
|
|
||||||
QMetaObject::Connection m_runTrigger;
|
QMetaObject::Connection m_runTrigger;
|
||||||
|
|
||||||
friend class CMakeBuildStepConfigWidget;
|
friend class CMakeBuildStepConfigWidget;
|
||||||
QStringList m_buildTargets;
|
QStringList m_buildTargets; // Convention: Empty string member signifies "Current executable"
|
||||||
ProjectExplorer::StringAspect *m_cmakeArguments = nullptr;
|
ProjectExplorer::StringAspect *m_cmakeArguments = nullptr;
|
||||||
ProjectExplorer::StringAspect *m_toolArguments = nullptr;
|
ProjectExplorer::StringAspect *m_toolArguments = nullptr;
|
||||||
bool m_waiting = false;
|
bool m_waiting = false;
|
||||||
|
|
||||||
|
Utils::TreeModel<Utils::TreeItem, CMakeTargetItem> m_buildTargetModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMakeBuildStepFactory : public ProjectExplorer::BuildStepFactory
|
class CMakeBuildStepFactory : public ProjectExplorer::BuildStepFactory
|
||||||
|
Reference in New Issue
Block a user