forked from qt-creator/qt-creator
ProjectExplorer: Introduce BuildDirectoryAspect
Change-Id: Id57d0a7901d2cec7b2d4f1fbeed6a1ecb41642cc Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -25,8 +25,108 @@
|
||||
|
||||
#include "buildaspects.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
class BuildDirectoryAspect::Private
|
||||
{
|
||||
public:
|
||||
FilePath sourceDir;
|
||||
FilePath savedShadowBuildDir;
|
||||
QString problem;
|
||||
QPointer<QLabel> warningLabel;
|
||||
QPointer<QLabel> problemLabel;
|
||||
};
|
||||
|
||||
BuildDirectoryAspect::BuildDirectoryAspect() : d(new Private)
|
||||
{
|
||||
setSettingsKey("ProjectExplorer.BuildConfiguration.BuildDirectory");
|
||||
setLabelText(tr("Build directory:"));
|
||||
setDisplayStyle(PathChooserDisplay);
|
||||
setExpectedKind(Utils::PathChooser::Directory);
|
||||
setUncheckedSemantics(UncheckedSemantics::ReadOnly);
|
||||
}
|
||||
|
||||
BuildDirectoryAspect::~BuildDirectoryAspect()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void BuildDirectoryAspect::allowInSourceBuilds(const FilePath &sourceDir)
|
||||
{
|
||||
d->sourceDir = sourceDir;
|
||||
makeCheckable(tr("Shadow Build"), QString());
|
||||
}
|
||||
|
||||
bool BuildDirectoryAspect::isShadowBuild() const
|
||||
{
|
||||
return !d->sourceDir.isEmpty() && d->sourceDir != filePath();
|
||||
}
|
||||
|
||||
void BuildDirectoryAspect::setProblem(const QString &description)
|
||||
{
|
||||
d->problem = description;
|
||||
updateProblemLabel();
|
||||
}
|
||||
|
||||
void BuildDirectoryAspect::toMap(QVariantMap &map) const
|
||||
{
|
||||
BaseStringAspect::toMap(map);
|
||||
if (!d->sourceDir.isEmpty()) {
|
||||
const FilePath shadowDir = isChecked() ? filePath() : d->savedShadowBuildDir;
|
||||
map.insert(settingsKey() + ".shadowDir", shadowDir.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void BuildDirectoryAspect::fromMap(const QVariantMap &map)
|
||||
{
|
||||
BaseStringAspect::fromMap(map);
|
||||
if (!d->sourceDir.isEmpty()) {
|
||||
d->savedShadowBuildDir = FilePath::fromString(map.value(settingsKey() + ".shadowDir")
|
||||
.toString());
|
||||
setChecked(d->sourceDir != filePath());
|
||||
}
|
||||
}
|
||||
|
||||
void BuildDirectoryAspect::addToLayout(LayoutBuilder &builder)
|
||||
{
|
||||
BaseStringAspect::addToLayout(builder);
|
||||
d->warningLabel = new QLabel;
|
||||
d->warningLabel->setAlignment(Qt::AlignTop);
|
||||
d->warningLabel->setPixmap(Icons::WARNING.pixmap());
|
||||
d->problemLabel = new QLabel;
|
||||
d->problemLabel->setAlignment(Qt::AlignTop);
|
||||
builder.startNewRow().addItems(QString(), d->warningLabel.data(), d->problemLabel.data());
|
||||
updateProblemLabel();
|
||||
if (!d->sourceDir.isEmpty()) {
|
||||
connect(this, &BaseStringAspect::checkedChanged, builder.layout(), [this] {
|
||||
if (isChecked()) {
|
||||
setFilePath(d->savedShadowBuildDir);
|
||||
} else {
|
||||
d->savedShadowBuildDir = filePath();
|
||||
setFilePath(d->sourceDir);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void BuildDirectoryAspect::updateProblemLabel()
|
||||
{
|
||||
if (!d->warningLabel)
|
||||
return;
|
||||
QTC_ASSERT(d->problemLabel, return);
|
||||
d->problemLabel->setText(d->problem);
|
||||
d->problemLabel->setVisible(!d->problem.isEmpty());
|
||||
d->warningLabel->setVisible(!d->problem.isEmpty());
|
||||
}
|
||||
|
||||
SeparateDebugInfoAspect::SeparateDebugInfoAspect()
|
||||
{
|
||||
setDisplayName(tr("Separate Debug Info"));
|
||||
|
@@ -28,8 +28,32 @@
|
||||
#include "projectexplorer_export.h"
|
||||
#include "projectconfigurationaspects.h"
|
||||
|
||||
namespace Utils { class FilePath; }
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
class PROJECTEXPLORER_EXPORT BuildDirectoryAspect : public BaseStringAspect
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
BuildDirectoryAspect();
|
||||
~BuildDirectoryAspect() override;
|
||||
|
||||
void allowInSourceBuilds(const Utils::FilePath &sourceDir);
|
||||
bool isShadowBuild() const;
|
||||
void setProblem(const QString &description);
|
||||
|
||||
private:
|
||||
void toMap(QVariantMap &map) const override;
|
||||
void fromMap(const QVariantMap &map) override;
|
||||
void addToLayout(LayoutBuilder &builder) override;
|
||||
|
||||
void updateProblemLabel();
|
||||
|
||||
class Private;
|
||||
Private * const d;
|
||||
};
|
||||
|
||||
class PROJECTEXPLORER_EXPORT SeparateDebugInfoAspect : public BaseTriStateAspect
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "buildconfiguration.h"
|
||||
|
||||
#include "buildaspects.h"
|
||||
#include "buildenvironmentwidget.h"
|
||||
#include "buildinfo.h"
|
||||
#include "buildsteplist.h"
|
||||
@@ -35,7 +36,6 @@
|
||||
#include "kitinformation.h"
|
||||
#include "kitmanager.h"
|
||||
#include "project.h"
|
||||
#include "projectconfigurationaspects.h"
|
||||
#include "projectexplorer.h"
|
||||
#include "projectexplorerconstants.h"
|
||||
#include "projectmacroexpander.h"
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "session.h"
|
||||
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <coreplugin/variablechooser.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/detailswidget.h>
|
||||
@@ -61,7 +62,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 BUILDDIRECTORY_KEY[] = "ProjectExplorer.BuildConfiguration.BuildDirectory";
|
||||
|
||||
namespace ProjectExplorer {
|
||||
namespace Internal {
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
bool m_clearSystemEnvironment = false;
|
||||
Utils::EnvironmentItems m_userEnvironmentChanges;
|
||||
QList<BuildStepList *> m_stepLists;
|
||||
ProjectExplorer::BaseStringAspect *m_buildDirectoryAspect = nullptr;
|
||||
BuildDirectoryAspect *m_buildDirectoryAspect = nullptr;
|
||||
Utils::FilePath m_lastEmittedBuildDirectory;
|
||||
mutable Utils::Environment m_cachedEnvironment;
|
||||
QString m_configWidgetDisplayName;
|
||||
@@ -116,16 +116,12 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
|
||||
connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
|
||||
this, &BuildConfiguration::updateCacheAndEmitEnvironmentChanged);
|
||||
|
||||
d->m_buildDirectoryAspect = addAspect<BaseStringAspect>();
|
||||
d->m_buildDirectoryAspect->setSettingsKey(BUILDDIRECTORY_KEY);
|
||||
d->m_buildDirectoryAspect->setLabelText(tr("Build directory:"));
|
||||
d->m_buildDirectoryAspect->setDisplayStyle(BaseStringAspect::PathChooserDisplay);
|
||||
d->m_buildDirectoryAspect->setExpectedKind(Utils::PathChooser::Directory);
|
||||
d->m_buildDirectoryAspect = addAspect<BuildDirectoryAspect>();
|
||||
d->m_buildDirectoryAspect->setBaseFileName(target->project()->projectDirectory());
|
||||
d->m_buildDirectoryAspect->setEnvironment(environment());
|
||||
d->m_buildDirectoryAspect->setMacroExpanderProvider([this] { return macroExpander(); });
|
||||
connect(d->m_buildDirectoryAspect, &BaseStringAspect::changed,
|
||||
this, &BuildConfiguration::buildDirectoryChanged);
|
||||
|
||||
connect(this, &BuildConfiguration::environmentChanged, this, [this] {
|
||||
d->m_buildDirectoryAspect->setEnvironment(environment());
|
||||
this->target()->buildEnvironmentChanged(this);
|
||||
@@ -133,7 +129,6 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
|
||||
|
||||
connect(target, &Target::parsingStarted, this, &BuildConfiguration::enabledChanged);
|
||||
connect(target, &Target::parsingFinished, this, &BuildConfiguration::enabledChanged);
|
||||
|
||||
connect(this, &BuildConfiguration::enabledChanged, this, [this] {
|
||||
if (isActive() && project() == SessionManager::startupProject()) {
|
||||
ProjectExplorerPlugin::updateActions();
|
||||
@@ -309,7 +304,7 @@ QVariant BuildConfiguration::extraInfo() const
|
||||
return d->m_extraInfo;
|
||||
}
|
||||
|
||||
ProjectExplorer::BaseStringAspect *BuildConfiguration::buildDirectoryAspect() const
|
||||
ProjectExplorer::BuildDirectoryAspect *BuildConfiguration::buildDirectoryAspect() const
|
||||
{
|
||||
return d->m_buildDirectoryAspect;
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ namespace ProjectExplorer {
|
||||
|
||||
namespace Internal { class BuildConfigurationPrivate; }
|
||||
|
||||
class BaseStringAspect;
|
||||
class BuildDirectoryAspect;
|
||||
class BuildInfo;
|
||||
class BuildSystem;
|
||||
class BuildStepList;
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
static void prependCompilerPathToEnvironment(Kit *k, Utils::Environment &env);
|
||||
void updateCacheAndEmitEnvironmentChanged();
|
||||
|
||||
ProjectExplorer::BaseStringAspect *buildDirectoryAspect() const;
|
||||
ProjectExplorer::BuildDirectoryAspect *buildDirectoryAspect() const;
|
||||
void setConfigWidgetDisplayName(const QString &display);
|
||||
void setBuildDirectoryHistoryCompleter(const QString &history);
|
||||
void setConfigWidgetHasFrame(bool configWidgetHasFrame);
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "runconfiguration.h"
|
||||
#include "target.h"
|
||||
|
||||
#include <coreplugin/variablechooser.h>
|
||||
#include <utils/utilsicons.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/pathchooser.h>
|
||||
@@ -84,6 +85,8 @@ class BaseStringAspectPrivate
|
||||
{
|
||||
public:
|
||||
BaseStringAspect::DisplayStyle m_displayStyle = BaseStringAspect::LabelDisplay;
|
||||
BaseStringAspect::UncheckedSemantics m_uncheckedSemantics
|
||||
= BaseStringAspect::UncheckedSemantics::ReadOnly;
|
||||
QString m_labelText;
|
||||
std::function<QString(const QString &)> m_displayFilter;
|
||||
std::unique_ptr<BaseBoolAspect> m_checker;
|
||||
@@ -98,10 +101,20 @@ public:
|
||||
QPointer<FancyLineEdit> m_lineEditDisplay;
|
||||
QPointer<PathChooser> m_pathChooserDisplay;
|
||||
QPointer<QTextEdit> m_textEditDisplay;
|
||||
Utils::MacroExpanderProvider m_expanderProvider;
|
||||
QPixmap m_labelPixmap;
|
||||
Utils::FilePath m_baseFileName;
|
||||
bool m_readOnly = false;
|
||||
bool m_showToolTipOnLabel = false;
|
||||
|
||||
template<class Widget> void updateWidgetFromCheckStatus(Widget *w)
|
||||
{
|
||||
const bool enabled = !m_checker || m_checker->value();
|
||||
if (m_uncheckedSemantics == BaseStringAspect::UncheckedSemantics::Disabled)
|
||||
w->setEnabled(enabled);
|
||||
else
|
||||
w->setReadOnly(!enabled);
|
||||
}
|
||||
};
|
||||
|
||||
class BaseIntegerAspectPrivate
|
||||
@@ -205,6 +218,12 @@ bool BaseStringAspect::isChecked() const
|
||||
return !d->m_checker || d->m_checker->value();
|
||||
}
|
||||
|
||||
void BaseStringAspect::setChecked(bool checked)
|
||||
{
|
||||
QTC_ASSERT(d->m_checker, return);
|
||||
d->m_checker->setValue(checked);
|
||||
}
|
||||
|
||||
void BaseStringAspect::setDisplayStyle(DisplayStyle displayStyle)
|
||||
{
|
||||
d->m_displayStyle = displayStyle;
|
||||
@@ -260,6 +279,16 @@ void BaseStringAspect::setReadOnly(bool readOnly)
|
||||
d->m_textEditDisplay->setReadOnly(readOnly);
|
||||
}
|
||||
|
||||
void BaseStringAspect::setMacroExpanderProvider(const MacroExpanderProvider &expanderProvider)
|
||||
{
|
||||
d->m_expanderProvider = expanderProvider;
|
||||
}
|
||||
|
||||
void BaseStringAspect::setUncheckedSemantics(BaseStringAspect::UncheckedSemantics semantics)
|
||||
{
|
||||
d->m_uncheckedSemantics = semantics;
|
||||
}
|
||||
|
||||
void BaseStringAspect::addToLayout(LayoutBuilder &builder)
|
||||
{
|
||||
QTC_CHECK(!d->m_label);
|
||||
@@ -270,6 +299,14 @@ void BaseStringAspect::addToLayout(LayoutBuilder &builder)
|
||||
d->m_label->setPixmap(d->m_labelPixmap);
|
||||
builder.addItem(d->m_label.data());
|
||||
|
||||
const auto useMacroExpander = [this, &builder](QWidget *w) {
|
||||
if (!d->m_expanderProvider)
|
||||
return;
|
||||
const auto chooser = new Core::VariableChooser(builder.layout()->parentWidget());
|
||||
chooser->addSupportedWidget(w);
|
||||
chooser->addMacroExpanderProvider(d->m_expanderProvider);
|
||||
};
|
||||
|
||||
switch (d->m_displayStyle) {
|
||||
case PathChooserDisplay:
|
||||
d->m_pathChooserDisplay = new PathChooser;
|
||||
@@ -279,6 +316,7 @@ void BaseStringAspect::addToLayout(LayoutBuilder &builder)
|
||||
d->m_pathChooserDisplay->setEnvironment(d->m_environment);
|
||||
d->m_pathChooserDisplay->setBaseFileName(d->m_baseFileName);
|
||||
d->m_pathChooserDisplay->setReadOnly(d->m_readOnly);
|
||||
useMacroExpander(d->m_pathChooserDisplay->lineEdit());
|
||||
connect(d->m_pathChooserDisplay, &PathChooser::pathChanged,
|
||||
this, &BaseStringAspect::setValue);
|
||||
builder.addItem(d->m_pathChooserDisplay.data());
|
||||
@@ -289,6 +327,7 @@ void BaseStringAspect::addToLayout(LayoutBuilder &builder)
|
||||
if (!d->m_historyCompleterKey.isEmpty())
|
||||
d->m_lineEditDisplay->setHistoryCompleter(d->m_historyCompleterKey);
|
||||
d->m_lineEditDisplay->setReadOnly(d->m_readOnly);
|
||||
useMacroExpander(d->m_lineEditDisplay);
|
||||
connect(d->m_lineEditDisplay, &FancyLineEdit::textEdited,
|
||||
this, &BaseStringAspect::setValue);
|
||||
builder.addItem(d->m_lineEditDisplay.data());
|
||||
@@ -297,6 +336,7 @@ void BaseStringAspect::addToLayout(LayoutBuilder &builder)
|
||||
d->m_textEditDisplay = new QTextEdit;
|
||||
d->m_textEditDisplay->setPlaceholderText(d->m_placeHolderText);
|
||||
d->m_textEditDisplay->setReadOnly(d->m_readOnly);
|
||||
useMacroExpander(d->m_textEditDisplay);
|
||||
connect(d->m_textEditDisplay, &QTextEdit::textChanged, this, [this] {
|
||||
const QString value = d->m_textEditDisplay->document()->toPlainText();
|
||||
if (value != d->m_value) {
|
||||
@@ -324,21 +364,19 @@ void BaseStringAspect::update()
|
||||
const QString displayedString = d->m_displayFilter ? d->m_displayFilter(d->m_value)
|
||||
: d->m_value;
|
||||
|
||||
const bool enabled = !d->m_checker || d->m_checker->value();
|
||||
|
||||
if (d->m_pathChooserDisplay) {
|
||||
d->m_pathChooserDisplay->setFileName(FilePath::fromString(displayedString));
|
||||
d->m_pathChooserDisplay->setEnabled(enabled);
|
||||
d->updateWidgetFromCheckStatus(d->m_pathChooserDisplay.data());
|
||||
}
|
||||
|
||||
if (d->m_lineEditDisplay) {
|
||||
d->m_lineEditDisplay->setTextKeepingActiveCursor(displayedString);
|
||||
d->m_lineEditDisplay->setEnabled(enabled);
|
||||
d->updateWidgetFromCheckStatus(d->m_lineEditDisplay.data());
|
||||
}
|
||||
|
||||
if (d->m_textEditDisplay) {
|
||||
d->m_textEditDisplay->setText(displayedString);
|
||||
d->m_textEditDisplay->setEnabled(enabled);
|
||||
d->updateWidgetFromCheckStatus(d->m_textEditDisplay.data());
|
||||
}
|
||||
|
||||
if (d->m_labelDisplay) {
|
||||
@@ -362,6 +400,7 @@ void BaseStringAspect::makeCheckable(const QString &checkerLabel, const QString
|
||||
|
||||
connect(d->m_checker.get(), &BaseBoolAspect::changed, this, &BaseStringAspect::update);
|
||||
connect(d->m_checker.get(), &BaseBoolAspect::changed, this, &BaseStringAspect::changed);
|
||||
connect(d->m_checker.get(), &BaseBoolAspect::changed, this, &BaseStringAspect::checkedChanged);
|
||||
|
||||
update();
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "environmentaspect.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/macroexpander.h>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -128,8 +129,12 @@ public:
|
||||
void setEnvironment(const Utils::Environment &env);
|
||||
void setBaseFileName(const Utils::FilePath &baseFileName);
|
||||
void setReadOnly(bool readOnly);
|
||||
void setMacroExpanderProvider(const Utils::MacroExpanderProvider &expanderProvider);
|
||||
|
||||
enum class UncheckedSemantics { Disabled, ReadOnly };
|
||||
void setUncheckedSemantics(UncheckedSemantics semantics);
|
||||
bool isChecked() const;
|
||||
void setChecked(bool checked);
|
||||
void makeCheckable(const QString &optionalLabel, const QString &optionalBaseKey);
|
||||
|
||||
enum DisplayStyle {
|
||||
@@ -146,6 +151,9 @@ public:
|
||||
Utils::FilePath filePath() const;
|
||||
void setFilePath(const Utils::FilePath &val);
|
||||
|
||||
signals:
|
||||
void checkedChanged();
|
||||
|
||||
private:
|
||||
void update();
|
||||
|
||||
|
Reference in New Issue
Block a user