Qmake: Make proper use of BuildDirectoryAspect

Change-Id: I439496c85f7e0f402ab038de6a8171dd2f7d2ffd
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2019-11-26 17:11:01 +01:00
parent b31f6aa502
commit 221d356210
19 changed files with 187 additions and 469 deletions

View File

@@ -203,7 +203,8 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
m_multiProcessAspect = new BaseBoolAspect;
m_multiProcessAspect->setSettingsKey("RunConfiguration.UseMultiProcess");
m_multiProcessAspect->setLabel(tr("Enable Debugging of Subprocesses"));
m_multiProcessAspect->setLabel(tr("Enable Debugging of Subprocesses"),
BaseBoolAspect::LabelPlacement::AtCheckBox);
m_overrideStartupAspect = new BaseStringAspect;
m_overrideStartupAspect->setSettingsKey("RunConfiguration.OverrideDebuggerStartup");

View File

@@ -51,7 +51,6 @@ BuildDirectoryAspect::BuildDirectoryAspect() : d(new Private)
setLabelText(tr("Build directory:"));
setDisplayStyle(PathChooserDisplay);
setExpectedKind(Utils::PathChooser::Directory);
setUncheckedSemantics(UncheckedSemantics::ReadOnly);
}
BuildDirectoryAspect::~BuildDirectoryAspect()
@@ -62,7 +61,7 @@ BuildDirectoryAspect::~BuildDirectoryAspect()
void BuildDirectoryAspect::allowInSourceBuilds(const FilePath &sourceDir)
{
d->sourceDir = sourceDir;
makeCheckable(tr("Shadow Build"), QString());
makeCheckable(CheckBoxPlacement::Top, tr("Shadow build:"), QString());
}
bool BuildDirectoryAspect::isShadowBuild() const
@@ -108,7 +107,8 @@ void BuildDirectoryAspect::addToLayout(LayoutBuilder &builder)
if (!d->sourceDir.isEmpty()) {
connect(this, &BaseStringAspect::checkedChanged, builder.layout(), [this] {
if (isChecked()) {
setFilePath(d->savedShadowBuildDir);
setFilePath(d->savedShadowBuildDir.isEmpty()
? d->sourceDir : d->savedShadowBuildDir);
} else {
d->savedShadowBuildDir = filePath();
setFilePath(d->sourceDir);

View File

@@ -57,6 +57,7 @@ namespace Internal {
class BaseBoolAspectPrivate
{
public:
BaseBoolAspect::LabelPlacement m_labelPlacement = BaseBoolAspect::LabelPlacement::AtCheckBox;
bool m_value = false;
bool m_defaultValue = false;
QString m_label;
@@ -85,8 +86,10 @@ class BaseStringAspectPrivate
{
public:
BaseStringAspect::DisplayStyle m_displayStyle = BaseStringAspect::LabelDisplay;
BaseStringAspect::CheckBoxPlacement m_checkBoxPlacement
= BaseStringAspect::CheckBoxPlacement::Right;
BaseStringAspect::UncheckedSemantics m_uncheckedSemantics
= BaseStringAspect::UncheckedSemantics::ReadOnly;
= BaseStringAspect::UncheckedSemantics::Disabled;
QString m_labelText;
std::function<QString(const QString &)> m_displayFilter;
std::unique_ptr<BaseBoolAspect> m_checker;
@@ -292,6 +295,12 @@ void BaseStringAspect::setUncheckedSemantics(BaseStringAspect::UncheckedSemantic
void BaseStringAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!d->m_label);
if (d->m_checker && d->m_checkBoxPlacement == CheckBoxPlacement::Top) {
d->m_checker->addToLayout(builder);
builder.startNewRow();
}
d->m_label = new QLabel;
d->m_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
d->m_label->setText(d->m_labelText);
@@ -353,7 +362,7 @@ void BaseStringAspect::addToLayout(LayoutBuilder &builder)
break;
}
if (d->m_checker)
if (d->m_checker && d->m_checkBoxPlacement == CheckBoxPlacement::Right)
d->m_checker->addToLayout(builder);
update();
@@ -391,11 +400,15 @@ void BaseStringAspect::update()
}
}
void BaseStringAspect::makeCheckable(const QString &checkerLabel, const QString &checkerKey)
void BaseStringAspect::makeCheckable(CheckBoxPlacement checkBoxPlacement,
const QString &checkerLabel, const QString &checkerKey)
{
QTC_ASSERT(!d->m_checker, return);
d->m_checkBoxPlacement = checkBoxPlacement;
d->m_checker.reset(new BaseBoolAspect);
d->m_checker->setLabel(checkerLabel);
d->m_checker->setLabel(checkerLabel, checkBoxPlacement == CheckBoxPlacement::Top
? BaseBoolAspect::LabelPlacement::InExtraLabel
: BaseBoolAspect::LabelPlacement::AtCheckBox);
d->m_checker->setSettingsKey(checkerKey);
connect(d->m_checker.get(), &BaseBoolAspect::changed, this, &BaseStringAspect::update);
@@ -420,10 +433,16 @@ BaseBoolAspect::~BaseBoolAspect() = default;
void BaseBoolAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!d->m_checkBox);
d->m_checkBox = new QCheckBox(d->m_label);
d->m_checkBox = new QCheckBox();
if (d->m_labelPlacement == LabelPlacement::AtCheckBox) {
d->m_checkBox->setText(d->m_label);
builder.addItem(QString());
} else {
builder.addItem(d->m_label);
}
d->m_checkBox->setChecked(d->m_value);
d->m_checkBox->setToolTip(d->m_tooltip);
builder.addItems(QString(), d->m_checkBox.data());
builder.addItem(d->m_checkBox.data());
connect(d->m_checkBox.data(), &QAbstractButton::clicked, this, [this] {
d->m_value = d->m_checkBox->isChecked();
emit changed();
@@ -463,9 +482,10 @@ void BaseBoolAspect::setValue(bool value)
d->m_checkBox->setChecked(d->m_value);
}
void BaseBoolAspect::setLabel(const QString &label)
void BaseBoolAspect::setLabel(const QString &label, LabelPlacement labelPlacement)
{
d->m_label = label;
d->m_labelPlacement = labelPlacement;
}
void BaseBoolAspect::setToolTip(const QString &tooltip)

View File

@@ -63,7 +63,8 @@ public:
bool defaultValue() const;
void setDefaultValue(bool defaultValue);
void setLabel(const QString &label);
enum class LabelPlacement { AtCheckBox, InExtraLabel };
void setLabel(const QString &label, LabelPlacement labelPlacement);
void setToolTip(const QString &tooltip);
void fromMap(const QVariantMap &map) override;
@@ -132,10 +133,12 @@ public:
void setMacroExpanderProvider(const Utils::MacroExpanderProvider &expanderProvider);
enum class UncheckedSemantics { Disabled, ReadOnly };
enum class CheckBoxPlacement { Top, Right };
void setUncheckedSemantics(UncheckedSemantics semantics);
bool isChecked() const;
void setChecked(bool checked);
void makeCheckable(const QString &optionalLabel, const QString &optionalBaseKey);
void makeCheckable(CheckBoxPlacement checkBoxPlacement, const QString &optionalLabel,
const QString &optionalBaseKey);
enum DisplayStyle {
LabelDisplay,

View File

@@ -436,7 +436,8 @@ void ExecutableAspect::makeOverridable(const QString &overridingKey, const QStri
m_alternativeExecutable->setDisplayStyle(BaseStringAspect::LineEditDisplay);
m_alternativeExecutable->setLabelText(tr("Alternate executable on device:"));
m_alternativeExecutable->setSettingsKey(overridingKey);
m_alternativeExecutable->makeCheckable(tr("Use this command instead"), useOverridableKey);
m_alternativeExecutable->makeCheckable(BaseStringAspect::CheckBoxPlacement::Right,
tr("Use this command instead"), useOverridableKey);
connect(m_alternativeExecutable, &BaseStringAspect::changed,
this, &ExecutableAspect::changed);
}
@@ -501,12 +502,15 @@ UseLibraryPathsAspect::UseLibraryPathsAspect()
{
setId("UseLibraryPath");
setSettingsKey("RunConfiguration.UseLibrarySearchPath");
if (HostOsInfo::isMacHost())
setLabel(tr("Add build library search path to DYLD_LIBRARY_PATH and DYLD_FRAMEWORK_PATH"));
else if (HostOsInfo::isWindowsHost())
setLabel(tr("Add build library search path to PATH"));
else
setLabel(tr("Add build library search path to LD_LIBRARY_PATH"));
if (HostOsInfo::isMacHost()) {
setLabel(tr("Add build library search path to DYLD_LIBRARY_PATH and DYLD_FRAMEWORK_PATH:"),
LabelPlacement::InExtraLabel);
} else if (HostOsInfo::isWindowsHost()) {
setLabel(tr("Add build library search path to PATH"), LabelPlacement::InExtraLabel);
} else {
setLabel(tr("Add build library search path to LD_LIBRARY_PATH:"),
LabelPlacement::InExtraLabel);
}
setValue(ProjectExplorerPlugin::projectExplorerSettings().addLibraryPathsToRunEnv);
}
@@ -518,7 +522,8 @@ UseDyldSuffixAspect::UseDyldSuffixAspect()
{
setId("UseDyldSuffix");
setSettingsKey("RunConfiguration.UseDyldImageSuffix");
setLabel(tr("Use debug version of frameworks (DYLD_IMAGE_SUFFIX=_debug)"));
setLabel(tr("Use debug version of frameworks (DYLD_IMAGE_SUFFIX=_debug):"),
LabelPlacement::InExtraLabel);
}
} // namespace ProjectExplorer

View File

@@ -56,11 +56,11 @@ QbsCleanStep::QbsCleanStep(ProjectExplorer::BuildStepList *bsl) :
m_dryRunAspect = addAspect<BaseBoolAspect>();
m_dryRunAspect->setSettingsKey("Qbs.DryRun");
m_dryRunAspect->setLabel(tr("Dry run"));
m_dryRunAspect->setLabel(tr("Dry run:"), BaseBoolAspect::LabelPlacement::InExtraLabel);
m_keepGoingAspect = addAspect<BaseBoolAspect>();
m_keepGoingAspect->setSettingsKey("Qbs.DryKeepGoing");
m_keepGoingAspect->setLabel(tr("Keep going"));
m_keepGoingAspect->setLabel(tr("Keep going:"), BaseBoolAspect::LabelPlacement::InExtraLabel);
auto effectiveCommandAspect = addAspect<BaseStringAspect>();
effectiveCommandAspect->setDisplayStyle(BaseStringAspect::TextEditDisplay);

View File

@@ -31,7 +31,6 @@ add_qtc_plugin(QmakeProjectManager
qmakeparser.cpp qmakeparser.h
qmakeparsernodes.cpp qmakeparsernodes.h
qmakeproject.cpp qmakeproject.h
qmakeprojectconfigwidget.cpp qmakeprojectconfigwidget.h
qmakeprojectimporter.cpp qmakeprojectimporter.h
qmakeprojectmanager.cpp qmakeprojectmanager.h
qmakeprojectmanager.qrc

View File

@@ -28,7 +28,6 @@
#include "qmakebuildinfo.h"
#include "qmakekitinformation.h"
#include "qmakeproject.h"
#include "qmakeprojectconfigwidget.h"
#include "qmakeprojectmanagerconstants.h"
#include "qmakenodes.h"
#include "qmakesettings.h"
@@ -42,6 +41,7 @@
#include <coreplugin/documentmanager.h>
#include <coreplugin/icore.h>
#include <projectexplorer/buildaspects.h>
#include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/buildsteplist.h>
@@ -106,6 +106,8 @@ enum { debug = 0 };
QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id)
: BuildConfiguration(target, id)
{
setConfigWidgetDisplayName(tr("General"));
setConfigWidgetHasFrame(true);
m_buildSystem = new QmakeBuildSystem(this);
connect(target, &Target::kitChanged,
@@ -117,6 +119,17 @@ QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id)
return file;
return QLatin1String("Makefile");
});
buildDirectoryAspect()->allowInSourceBuilds(target->project()->projectDirectory());
connect(this, &BuildConfiguration::buildDirectoryChanged,
this, &QmakeBuildConfiguration::updateProblemLabel);
connect(this, &QmakeBuildConfiguration::qmakeBuildConfigurationChanged,
this, &QmakeBuildConfiguration::updateProblemLabel);
connect(&QmakeSettings::instance(), &QmakeSettings::settingsChanged,
this, &QmakeBuildConfiguration::updateProblemLabel);
connect(target, &Target::parsingFinished, this, &QmakeBuildConfiguration::updateProblemLabel);
connect(target, &Target::kitChanged, this, &QmakeBuildConfiguration::updateProblemLabel);
}
void QmakeBuildConfiguration::initialize()
@@ -202,16 +215,112 @@ void QmakeBuildConfiguration::kitChanged()
}
}
void QmakeBuildConfiguration::updateProblemLabel()
{
ProjectExplorer::Kit * const k = target()->kit();
const QString proFileName = target()->project()->projectFilePath().toString();
// Check for Qt version:
QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k);
if (!version) {
buildDirectoryAspect()->setProblem(tr("This kit cannot build this project since it "
"does not define a Qt version."));
return;
}
const auto bs = qmakeBuildSystem();
if (bs->rootProFile()->parseInProgress() || !bs->rootProFile()->validParse()) {
buildDirectoryAspect()->setProblem({});
return;
}
bool targetMismatch = false;
bool incompatibleBuild = false;
bool allGood = false;
// we only show if we actually have a qmake and makestep
QString errorString;
if (qmakeStep() && makeStep()) {
QString makefile = buildDirectory().toString() + QLatin1Char('/');
if (this->makefile().isEmpty())
makefile.append(QLatin1String("Makefile"));
else
makefile.append(this->makefile());
switch (compareToImportFrom(makefile, &errorString)) {
case QmakeBuildConfiguration::MakefileMatches:
allGood = true;
break;
case QmakeBuildConfiguration::MakefileMissing:
allGood = true;
break;
case QmakeBuildConfiguration::MakefileIncompatible:
incompatibleBuild = true;
break;
case QmakeBuildConfiguration::MakefileForWrongProject:
targetMismatch = true;
break;
}
}
const bool unalignedBuildDir = QmakeSettings::warnAgainstUnalignedBuildDir()
&& !isBuildDirAtSafeLocation();
if (unalignedBuildDir)
allGood = false;
if (allGood) {
Tasks issues;
issues = version->reportIssues(proFileName, buildDirectory().toString());
Utils::sort(issues);
if (!issues.isEmpty()) {
QString text = QLatin1String("<nobr>");
foreach (const ProjectExplorer::Task &task, issues) {
QString type;
switch (task.type) {
case ProjectExplorer::Task::Error:
type = tr("Error:");
type += QLatin1Char(' ');
break;
case ProjectExplorer::Task::Warning:
type = tr("Warning:");
type += QLatin1Char(' ');
break;
case ProjectExplorer::Task::Unknown:
default:
break;
}
if (!text.endsWith(QLatin1String("br>")))
text.append(QLatin1String("<br>"));
text.append(type + task.description);
}
buildDirectoryAspect()->setProblem(text);
return;
}
} else if (targetMismatch) {
buildDirectoryAspect()->setProblem(tr("A build for a different project exists in %1, "
"which will be overwritten.",
"%1 build directory")
.arg(buildDirectory().toUserOutput()));
return;
} else if (incompatibleBuild) {
buildDirectoryAspect()->setProblem(tr("%1 The build in %2 will be overwritten.",
"%1 error message, %2 build directory")
.arg(errorString)
.arg(buildDirectory().toUserOutput()));
return;
} else if (unalignedBuildDir) {
buildDirectoryAspect()->setProblem(unalignedBuildDirWarning());
return;
}
buildDirectoryAspect()->setProblem({});
}
BuildSystem *QmakeBuildConfiguration::buildSystem() const
{
return m_buildSystem;
}
NamedWidget *QmakeBuildConfiguration::createConfigWidget()
{
return new QmakeProjectConfigWidget(this);
}
/// If only a sub tree should be build this function returns which sub node
/// should be build
/// \see QMakeBuildConfiguration::setSubNodeBuild

View File

@@ -50,7 +50,6 @@ public:
ProjectExplorer::BuildSystem *buildSystem() const final;
void initialize() override;
ProjectExplorer::NamedWidget *createConfigWidget() override;
void setSubNodeBuild(QmakeProFileNode *node);
QmakeProFileNode *subNodeBuild() const;
@@ -109,6 +108,7 @@ private:
void kitChanged();
void toolChainUpdated(ProjectExplorer::ToolChain *tc);
void qtVersionsChanged(const QList<int> &, const QList<int> &, const QList<int> &changed);
void updateProblemLabel();
class LastKitState
{

View File

@@ -1,342 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "qmakeprojectconfigwidget.h"
#include "qmakeproject.h"
#include "qmakebuildconfiguration.h"
#include "qmakenodes.h"
#include "qmakesettings.h"
#include <QBoxLayout>
#include <coreplugin/coreicons.h>
#include <coreplugin/variablechooser.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/algorithm.h>
#include <utils/detailswidget.h>
#include <utils/utilsicons.h>
using namespace QmakeProjectManager;
using namespace QmakeProjectManager::Internal;
using namespace ProjectExplorer;
/// returns whether this is a shadow build configuration or not
/// note, even if shadowBuild() returns true, it might be using the
/// source directory as the shadow build directory, thus it
/// still is a in-source build
static bool isShadowBuild(BuildConfiguration *bc)
{
return bc->buildDirectory() != bc->target()->project()->projectDirectory();
}
QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
: NamedWidget(tr("General")),
m_buildConfiguration(bc)
{
Project *project = bc->target()->project();
m_defaultShadowBuildDir
= QmakeBuildConfiguration::shadowBuildDirectory(project->projectFilePath(),
bc->target()->kit(),
Utils::FileUtils::qmakeFriendlyName(bc->displayName()),
bc->buildType());
m_detailsContainer = new Utils::DetailsWidget(this);
m_detailsContainer->setState(Utils::DetailsWidget::NoSummary);
auto vbox = new QVBoxLayout(this);
vbox->setContentsMargins(0, 0, 0, 0);
vbox->addWidget(m_detailsContainer);
auto details = new QWidget(m_detailsContainer);
m_detailsContainer->setWidget(details);
shadowBuildLabel = new QLabel(details);
shadowBuildLabel->setText(tr("Shadow build:"));
shadowBuildCheckBox = new QCheckBox(details);
shadowBuildCheckBox->setChecked(isShadowBuild(m_buildConfiguration));
buildDirLabel = new QLabel(details);
buildDirLabel->setText(tr("Build directory:"));
shadowBuildDirEdit = new Utils::PathChooser(details);
inSourceBuildDirEdit = new Utils::PathChooser(details);
warningLabel = new QLabel(details);
warningLabel->setPixmap(Utils::Icons::WARNING.pixmap());
problemLabel = new QLabel(details);
QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy2.setHorizontalStretch(10);
sizePolicy2.setVerticalStretch(0);
problemLabel->setSizePolicy(sizePolicy2);
problemLabel->setWordWrap(true);
auto horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->addWidget(warningLabel);
horizontalLayout_2->addWidget(problemLabel);
auto horizontalLayout = new QHBoxLayout();
horizontalLayout->addWidget(shadowBuildDirEdit);
horizontalLayout->addWidget(inSourceBuildDirEdit);
auto layout = new QGridLayout(details);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(shadowBuildLabel, 0, 0, 1, 1);
layout->addWidget(shadowBuildCheckBox, 0, 1, 1, 1);
layout->addWidget(buildDirLabel, 1, 0, 1, 1);
layout->addLayout(horizontalLayout, 1, 1, 1, 1);
layout->addLayout(horizontalLayout_2, 2, 1, 1, 1);
problemLabel->setText(tr("problemLabel"));
m_browseButton = shadowBuildDirEdit->buttonAtIndex(0);
shadowBuildDirEdit->setPromptDialogTitle(tr("Shadow Build Directory"));
shadowBuildDirEdit->setExpectedKind(Utils::PathChooser::ExistingDirectory);
shadowBuildDirEdit->setHistoryCompleter(QLatin1String("Qmake.BuildDir.History"));
shadowBuildDirEdit->setEnvironment(bc->environment());
shadowBuildDirEdit->setBaseFileName(project->projectDirectory());
if (isShadowBuild(m_buildConfiguration)) {
shadowBuildDirEdit->setPath(bc->rawBuildDirectory().toString());
inSourceBuildDirEdit->setVisible(false);
} else {
shadowBuildDirEdit->setPath(m_defaultShadowBuildDir);
shadowBuildDirEdit->setVisible(false);
}
inSourceBuildDirEdit->setFileName(project->projectDirectory());
inSourceBuildDirEdit->setReadOnly(true);
inSourceBuildDirEdit->setEnabled(false);
auto chooser = new Core::VariableChooser(this);
chooser->addSupportedWidget(shadowBuildDirEdit->lineEdit());
connect(shadowBuildCheckBox, &QAbstractButton::clicked,
this, &QmakeProjectConfigWidget::shadowBuildClicked);
connect(shadowBuildDirEdit, &Utils::PathChooser::beforeBrowsing,
this, &QmakeProjectConfigWidget::onBeforeBeforeShadowBuildDirBrowsed);
connect(shadowBuildDirEdit, &Utils::PathChooser::rawPathChanged,
this, &QmakeProjectConfigWidget::shadowBuildEdited);
connect(bc, &BuildConfiguration::enabledChanged,
this, &QmakeProjectConfigWidget::environmentChanged);
connect(bc->target(), &Target::parsingFinished,
this, &QmakeProjectConfigWidget::updateProblemLabel);
connect(&QmakeSettings::instance(), &QmakeSettings::settingsChanged,
this, &QmakeProjectConfigWidget::updateProblemLabel);
connect(bc->target(), &Target::kitChanged, this, &QmakeProjectConfigWidget::updateProblemLabel);
connect(m_buildConfiguration, &BuildConfiguration::buildDirectoryChanged,
this, &QmakeProjectConfigWidget::buildDirectoryChanged);
connect(m_buildConfiguration, &QmakeBuildConfiguration::qmakeBuildConfigurationChanged,
this, &QmakeProjectConfigWidget::updateProblemLabel);
updateDetails();
updateProblemLabel();
}
void QmakeProjectConfigWidget::updateDetails()
{
m_detailsContainer->setSummaryText(
tr("building in <b>%1</b>")
.arg(m_buildConfiguration->buildDirectory().toUserOutput()));
}
void QmakeProjectConfigWidget::setProblemLabel(const QString &text)
{
warningLabel->setVisible(!text.isEmpty());
problemLabel->setVisible(!text.isEmpty());
problemLabel->setText(text);
}
void QmakeProjectConfigWidget::environmentChanged()
{
shadowBuildDirEdit->setEnvironment(m_buildConfiguration->environment());
}
void QmakeProjectConfigWidget::buildDirectoryChanged()
{
if (m_ignoreChange)
return;
bool shadowBuild = shadowBuildCheckBox->isChecked();
inSourceBuildDirEdit->setVisible(!shadowBuild);
shadowBuildDirEdit->setVisible(shadowBuild);
shadowBuildDirEdit->setEnabled(shadowBuild);
m_browseButton->setEnabled(shadowBuild);
shadowBuildDirEdit->setPath(m_buildConfiguration->rawBuildDirectory().toString());
updateDetails();
updateProblemLabel();
}
void QmakeProjectConfigWidget::onBeforeBeforeShadowBuildDirBrowsed()
{
Utils::FilePath initialDirectory = m_buildConfiguration->target()->project()->projectDirectory();
if (!initialDirectory.isEmpty())
shadowBuildDirEdit->setInitialBrowsePathBackup(initialDirectory.toString());
}
void QmakeProjectConfigWidget::shadowBuildClicked(bool checked)
{
shadowBuildDirEdit->setEnabled(checked);
m_browseButton->setEnabled(checked);
shadowBuildDirEdit->setVisible(checked);
inSourceBuildDirEdit->setVisible(!checked);
m_ignoreChange = true;
if (checked)
m_buildConfiguration->setBuildDirectory(Utils::FilePath::fromString(shadowBuildDirEdit->rawPath()));
else
m_buildConfiguration->setBuildDirectory(Utils::FilePath::fromString(inSourceBuildDirEdit->rawPath()));
m_ignoreChange = false;
updateDetails();
updateProblemLabel();
}
void QmakeProjectConfigWidget::shadowBuildEdited()
{
if (m_buildConfiguration->rawBuildDirectory().toString() == shadowBuildDirEdit->rawPath())
return;
m_ignoreChange = true;
m_buildConfiguration->setBuildDirectory(Utils::FilePath::fromString(shadowBuildDirEdit->rawPath()));
m_ignoreChange = false;
}
void QmakeProjectConfigWidget::updateProblemLabel()
{
shadowBuildDirEdit->triggerChanged();
ProjectExplorer::Kit *k = m_buildConfiguration->target()->kit();
const QString proFileName = m_buildConfiguration->target()->project()->projectFilePath().toString();
// Check for Qt version:
QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k);
if (!version) {
setProblemLabel(tr("This kit cannot build this project since it does not define a Qt version."));
return;
}
auto bs = m_buildConfiguration->qmakeBuildSystem();
if (bs->rootProFile()->parseInProgress() || !bs->rootProFile()->validParse()) {
setProblemLabel(QString());
return;
}
bool targetMismatch = false;
bool incompatibleBuild = false;
bool allGood = false;
// we only show if we actually have a qmake and makestep
QString errorString;
if (m_buildConfiguration->qmakeStep() && m_buildConfiguration->makeStep()) {
QString makefile = m_buildConfiguration->buildDirectory().toString() + QLatin1Char('/');
if (m_buildConfiguration->makefile().isEmpty())
makefile.append(QLatin1String("Makefile"));
else
makefile.append(m_buildConfiguration->makefile());
switch (m_buildConfiguration->compareToImportFrom(makefile, &errorString)) {
case QmakeBuildConfiguration::MakefileMatches:
allGood = true;
break;
case QmakeBuildConfiguration::MakefileMissing:
allGood = true;
break;
case QmakeBuildConfiguration::MakefileIncompatible:
incompatibleBuild = true;
break;
case QmakeBuildConfiguration::MakefileForWrongProject:
targetMismatch = true;
break;
}
}
const bool unalignedBuildDir = QmakeSettings::warnAgainstUnalignedBuildDir()
&& !m_buildConfiguration->isBuildDirAtSafeLocation();
if (unalignedBuildDir)
allGood = false;
if (allGood) {
QString buildDirectory = m_buildConfiguration->target()->project()->projectDirectory().toString();
if (isShadowBuild(m_buildConfiguration))
buildDirectory = m_buildConfiguration->buildDirectory().toString();
Tasks issues;
issues = version->reportIssues(proFileName, buildDirectory);
Utils::sort(issues);
if (!issues.isEmpty()) {
QString text = QLatin1String("<nobr>");
foreach (const ProjectExplorer::Task &task, issues) {
QString type;
switch (task.type) {
case ProjectExplorer::Task::Error:
type = tr("Error:");
type += QLatin1Char(' ');
break;
case ProjectExplorer::Task::Warning:
type = tr("Warning:");
type += QLatin1Char(' ');
break;
case ProjectExplorer::Task::Unknown:
default:
break;
}
if (!text.endsWith(QLatin1String("br>")))
text.append(QLatin1String("<br>"));
text.append(type + task.description);
}
setProblemLabel(text);
return;
}
} else if (targetMismatch) {
setProblemLabel(tr("A build for a different project exists in %1, which will be overwritten.",
"%1 build directory")
.arg(m_buildConfiguration->buildDirectory().toUserOutput()));
return;
} else if (incompatibleBuild) {
setProblemLabel(tr("%1 The build in %2 will be overwritten.",
"%1 error message, %2 build directory")
.arg(errorString)
.arg(m_buildConfiguration->buildDirectory().toUserOutput()));
return;
} else if (unalignedBuildDir) {
setProblemLabel(m_buildConfiguration->unalignedBuildDirWarning());
return;
}
setProblemLabel(QString());
}

View File

@@ -1,82 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <projectexplorer/namedwidget.h>
#include <utils/pathchooser.h>
#include <QCheckBox>
#include <QLabel>
QT_BEGIN_NAMESPACE
class QAbstractButton;
QT_END_NAMESPACE
namespace Utils { class DetailsWidget; }
namespace QmakeProjectManager {
class QmakeBuildConfiguration;
namespace Internal {
class QmakeProjectConfigWidget : public ProjectExplorer::NamedWidget
{
Q_OBJECT
public:
QmakeProjectConfigWidget(QmakeBuildConfiguration *bc);
private:
// User changes in our widgets
void shadowBuildClicked(bool checked);
void onBeforeBeforeShadowBuildDirBrowsed();
void shadowBuildEdited();
// Changes triggered from creator
void buildDirectoryChanged();
void updateProblemLabel();
void environmentChanged();
void updateDetails();
void setProblemLabel(const QString &text);
QAbstractButton *m_browseButton;
QmakeBuildConfiguration *m_buildConfiguration;
Utils::DetailsWidget *m_detailsContainer;
QString m_defaultShadowBuildDir;
bool m_ignoreChange = false;
QLabel *shadowBuildLabel;
QCheckBox *shadowBuildCheckBox;
QLabel *buildDirLabel;
Utils::PathChooser *shadowBuildDirEdit;
Utils::PathChooser *inSourceBuildDirEdit;
QLabel *warningLabel;
QLabel *problemLabel;
};
} // namespace Internal
} // namespace QmakeProjectManager

View File

@@ -26,7 +26,6 @@ HEADERS += \
wizards/simpleprojectwizard.h \
qmakeprojectmanagerconstants.h \
qmakestep.h \
qmakeprojectconfigwidget.h \
externaleditors.h \
qmakebuildconfiguration.h \
qmakeparser.h \
@@ -57,7 +56,6 @@ SOURCES += \
wizards/subdirsprojectwizarddialog.cpp \
wizards/simpleprojectwizard.cpp \
qmakestep.cpp \
qmakeprojectconfigwidget.cpp \
externaleditors.cpp \
qmakebuildconfiguration.cpp \
qmakeparser.cpp \

View File

@@ -46,7 +46,6 @@ Project {
"qmakenodes.cpp", "qmakenodes.h",
"qmakenodetreebuilder.cpp", "qmakenodetreebuilder.h",
"qmakeproject.cpp", "qmakeproject.h",
"qmakeprojectconfigwidget.cpp", "qmakeprojectconfigwidget.h",
"qmakeprojectmanager.cpp", "qmakeprojectmanager.h",
"qmakeprojectmanager.qrc",
"qmakeprojectmanager_global.h",

View File

@@ -42,13 +42,14 @@ GenericDirectUploadStep::GenericDirectUploadStep(BuildStepList *bsl)
auto incremental = addAspect<BaseBoolAspect>();
incremental->setSettingsKey("RemoteLinux.GenericDirectUploadStep.Incremental");
incremental->setLabel(tr("Incremental deployment"));
incremental->setLabel(tr("Incremental deployment"), BaseBoolAspect::LabelPlacement::AtCheckBox);
incremental->setValue(true);
incremental->setDefaultValue(true);
auto ignoreMissingFiles = addAspect<BaseBoolAspect>();
ignoreMissingFiles->setSettingsKey("RemoteLinux.GenericDirectUploadStep.IgnoreMissingFiles");
ignoreMissingFiles->setLabel(tr("Ignore missing files"));
ignoreMissingFiles->setLabel(tr("Ignore missing files"),
BaseBoolAspect::LabelPlacement::AtCheckBox);
ignoreMissingFiles->setValue(false);
setInternalInitializer([incremental, ignoreMissingFiles, service] {

View File

@@ -76,7 +76,8 @@ MakeInstallStep::MakeInstallStep(BuildStepList *parent) : MakeStep(parent, stepI
const auto cleanInstallRootAspect = addAspect<BaseBoolAspect>();
cleanInstallRootAspect->setId(CleanInstallRootAspectId);
cleanInstallRootAspect->setSettingsKey(CleanInstallRootAspectId);
cleanInstallRootAspect->setLabel(tr("Clean install root first"));
cleanInstallRootAspect->setLabel(tr("Clean install root first"),
BaseBoolAspect::LabelPlacement::AtCheckBox);
cleanInstallRootAspect->setValue(false);
const auto commandLineAspect = addAspect<BaseStringAspect>();

View File

@@ -40,7 +40,8 @@ X11ForwardingAspect::X11ForwardingAspect()
setDisplayStyle(LineEditDisplay);
setId("X11ForwardingAspect");
setSettingsKey("RunConfiguration.X11Forwarding");
makeCheckable(tr("Forward to local display"), "RunConfiguration.UseX11Forwarding");
makeCheckable(CheckBoxPlacement::Right, tr("Forward to local display"),
"RunConfiguration.UseX11Forwarding");
setValue(defaultDisplay());
}

View File

@@ -190,7 +190,8 @@ RsyncDeployStep::RsyncDeployStep(BuildStepList *bsl)
auto ignoreMissingFiles = addAspect<BaseBoolAspect>();
ignoreMissingFiles->setSettingsKey("RemoteLinux.RsyncDeployStep.IgnoreMissingFiles");
ignoreMissingFiles->setLabel(tr("Ignore missing files"));
ignoreMissingFiles->setLabel(tr("Ignore missing files:"),
BaseBoolAspect::LabelPlacement::InExtraLabel);
ignoreMissingFiles->setValue(false);
setDefaultDisplayName(displayName());

View File

@@ -76,11 +76,13 @@ TarPackageCreationStep::TarPackageCreationStep(BuildStepList *bsl)
setDefaultDisplayName(displayName());
m_ignoreMissingFilesAspect = addAspect<BaseBoolAspect>();
m_ignoreMissingFilesAspect->setLabel(tr("Ignore missing files"));
m_ignoreMissingFilesAspect->setLabel(tr("Ignore missing files"),
BaseBoolAspect::LabelPlacement::AtCheckBox);
m_ignoreMissingFilesAspect->setSettingsKey(IgnoreMissingFilesKey);
m_incrementalDeploymentAspect = addAspect<BaseBoolAspect>();
m_incrementalDeploymentAspect->setLabel(tr("Package modified files only"));
m_incrementalDeploymentAspect->setLabel(tr("Package modified files only"),
BaseBoolAspect::LabelPlacement::AtCheckBox);
m_incrementalDeploymentAspect->setSettingsKey(IncrementalDeploymentKey);
setSummaryUpdater([this] {

View File

@@ -40,7 +40,8 @@ namespace Internal {
UninstallAfterStopAspect::UninstallAfterStopAspect()
: BaseBoolAspect("WinRtRunConfigurationUninstallAfterStopId")
{
setLabel(WinRtRunConfiguration::tr("Uninstall package after application stops"));
setLabel(WinRtRunConfiguration::tr("Uninstall package after application stops"),
LabelPlacement::AtCheckBox);
}
// LoopbackExemptClientAspect
@@ -48,8 +49,8 @@ UninstallAfterStopAspect::UninstallAfterStopAspect()
LoopbackExemptClientAspect::LoopbackExemptClientAspect()
: BaseBoolAspect("WinRtRunConfigurationLoopbackExemptClient")
{
setLabel(WinRtRunConfiguration::tr("Enable localhost communication for "
"clients"));
setLabel(WinRtRunConfiguration::tr("Enable localhost communication for clients"),
LabelPlacement::AtCheckBox);
}
// LoopbackExemptServerAspect
@@ -58,7 +59,8 @@ LoopbackExemptServerAspect::LoopbackExemptServerAspect()
: BaseBoolAspect("WinRtRunConfigurationLoopbackExemptServer")
{
setLabel(WinRtRunConfiguration::tr("Enable localhost communication for "
"servers (requires elevated rights)"));
"servers (requires elevated rights)"),
LabelPlacement::AtCheckBox);
}
// WinRtRunConfiguration