diff options
Diffstat (limited to 'src/plugins/qbsprojectmanager')
28 files changed, 548 insertions, 1119 deletions
diff --git a/src/plugins/qbsprojectmanager/CMakeLists.txt b/src/plugins/qbsprojectmanager/CMakeLists.txt index e02a516f1a..997e710a83 100644 --- a/src/plugins/qbsprojectmanager/CMakeLists.txt +++ b/src/plugins/qbsprojectmanager/CMakeLists.txt @@ -13,11 +13,9 @@ add_qtc_plugin(QbsProjectManager propertyprovider.h qbsbuildconfiguration.cpp qbsbuildconfiguration.h qbsbuildstep.cpp qbsbuildstep.h - qbsbuildstepconfigwidget.ui qbscleanstep.cpp qbscleanstep.h qbscleanstepconfigwidget.ui qbsinstallstep.cpp qbsinstallstep.h - qbsinstallstepconfigwidget.ui qbskitinformation.cpp qbskitinformation.h qbslogsink.cpp qbslogsink.h qbsnodes.cpp qbsnodes.h @@ -34,5 +32,4 @@ add_qtc_plugin(QbsProjectManager qbsprojectmanagerplugin.cpp qbsprojectmanagerplugin.h qbsprojectmanagersettings.cpp qbsprojectmanagersettings.h qbsprojectparser.cpp qbsprojectparser.h - qbsrunconfiguration.cpp qbsrunconfiguration.h ) diff --git a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp index 3f8f5e84cb..cfb7b63991 100644 --- a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp +++ b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp @@ -45,6 +45,8 @@ #include <android/androidconstants.h> #include <ios/iosconstants.h> +#include <qtsupport/baseqtversion.h> +#include <qtsupport/qtkitinformation.h> #include <winrt/winrtconstants.h> #include <QDir> @@ -126,11 +128,11 @@ static QStringList toolchainList(const ProjectExplorer::ToolChain *tc) { QStringList list; if (tc->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID - || (tc->typeId() == Android::Constants::ANDROID_TOOLCHAIN_ID + || (tc->typeId() == Android::Constants::ANDROID_TOOLCHAIN_TYPEID && tc->compilerCommand().toString().contains("clang"))) { list << QLatin1String("clang") << QLatin1String("llvm") << QLatin1String("gcc"); } else if (tc->typeId() == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID - || tc->typeId() == Android::Constants::ANDROID_TOOLCHAIN_ID) { + || tc->typeId() == Android::Constants::ANDROID_TOOLCHAIN_TYPEID) { list << QLatin1String("gcc"); // TODO: Detect llvm-gcc } else if (tc->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) { list << QLatin1String("mingw") << QLatin1String("gcc"); @@ -293,6 +295,18 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor data.insert("Android.ndk.ndkDir", ndkDir); } } + data.remove(QBS_ARCHITECTURES); + data.remove(QBS_ARCHITECTURE); + QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(k); + if (qtVersion) { + QStringList abis; + for (const auto &abi : qtVersion->qtAbis()) + abis << abi.param(); + if (abis.size() == 1) + data.insert(QLatin1String(QBS_ARCHITECTURE), abis.first()); + else + data.insert(QLatin1String(QBS_ARCHITECTURES), abis); + } } else { Utils::FilePath cCompilerPath; if (tcC) diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp index f3fd3d9f56..93cbde2eb1 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp @@ -59,13 +59,13 @@ using namespace Utils; namespace QbsProjectManager { namespace Internal { -static FilePath defaultBuildDirectory(const QString &projectFilePath, const Kit *k, +static FilePath defaultBuildDirectory(const FilePath &projectFilePath, const Kit *k, const QString &bcName, BuildConfiguration::BuildType buildType) { - const QString projectName = QFileInfo(projectFilePath).completeBaseName(); + const QString projectName = projectFilePath.toFileInfo().completeBaseName(); ProjectMacroExpander expander(projectFilePath, projectName, k, bcName, buildType); - QString projectDir = Project::projectDirectory(FilePath::fromString(projectFilePath)).toString(); + QString projectDir = Project::projectDirectory(projectFilePath).toString(); QString buildPath = expander.expand(ProjectExplorerPlugin::buildDirectoryTemplate()); return FilePath::fromString(FileUtils::resolvePath(projectDir, buildPath)); } @@ -86,24 +86,29 @@ QbsBuildConfiguration::QbsBuildConfiguration(Target *target, Core::Id id) connect(m_configurationName, &BaseStringAspect::changed, this, &BuildConfiguration::buildDirectoryChanged); - connect(project(), &Project::parsingStarted, this, &BuildConfiguration::enabledChanged); - connect(project(), &Project::parsingFinished, this, &BuildConfiguration::enabledChanged); + connect(this, &BuildConfiguration::environmentChanged, + this, &QbsBuildConfiguration::triggerReparseIfActive); + connect(this, &BuildConfiguration::buildDirectoryChanged, + this, &QbsBuildConfiguration::triggerReparseIfActive); + connect(this, &QbsBuildConfiguration::qbsConfigurationChanged, + this, &QbsBuildConfiguration::triggerReparseIfActive); } -void QbsBuildConfiguration::initialize(const BuildInfo &info) +void QbsBuildConfiguration::initialize() { - BuildConfiguration::initialize(info); + BuildConfiguration::initialize(); - QVariantMap configData = info.extraInfo.value<QVariantMap>(); + QVariantMap configData = extraInfo().value<QVariantMap>(); configData.insert(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY), - (info.buildType == BuildConfiguration::Debug) + (initialBuildType() == BuildConfiguration::Debug) ? QLatin1String(Constants::QBS_VARIANT_DEBUG) : QLatin1String(Constants::QBS_VARIANT_RELEASE)); - Utils::FilePath buildDir = info.buildDirectory; + Utils::FilePath buildDir = initialBuildDirectory(); if (buildDir.isEmpty()) - buildDir = defaultBuildDirectory(target()->project()->projectFilePath().toString(), - target()->kit(), info.displayName, info.buildType); + buildDir = defaultBuildDirectory(target()->project()->projectFilePath(), + target()->kit(), initialDisplayName(), + initialBuildType()); setBuildDirectory(buildDir); // Add the build configuration. @@ -111,24 +116,30 @@ void QbsBuildConfiguration::initialize(const BuildInfo &info) QString configName = bd.take("configName").toString(); if (configName.isEmpty()) { configName = "qtc_" + target()->kit()->fileSystemFriendlyName() + '_' - + Utils::FileUtils::fileSystemFriendlyName(info.displayName); + + Utils::FileUtils::fileSystemFriendlyName(initialDisplayName()); } m_configurationName->setValue(configName); BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); auto bs = new QbsBuildStep(buildSteps); - if (info.buildType == Release) + if (initialBuildType() == Release) bs->setQmlDebuggingEnabled(false); bs->setQbsConfiguration(bd); buildSteps->appendStep(bs); BuildStepList *cleanSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN); - cleanSteps->appendStep(new QbsCleanStep(cleanSteps)); + cleanSteps->appendStep(Constants::QBS_CLEANSTEP_ID); emit qbsConfigurationChanged(); } +void QbsBuildConfiguration::triggerReparseIfActive() +{ + if (isActive()) + qbsProject()->delayParsing(); +} + bool QbsBuildConfiguration::fromMap(const QVariantMap &map) { if (!BuildConfiguration::fromMap(map)) @@ -158,23 +169,9 @@ QVariantMap QbsBuildConfiguration::qbsConfiguration() const return config; } -Internal::QbsProject *QbsBuildConfiguration::project() const -{ - return qobject_cast<Internal::QbsProject *>(BuildConfiguration::project()); -} - -bool QbsBuildConfiguration::isEnabled() const -{ - return !project()->isParsing() && project()->hasParseResult(); -} - -QString QbsBuildConfiguration::disabledReason() const +Internal::QbsProject *QbsBuildConfiguration::qbsProject() const { - if (project()->isParsing()) - return tr("Parsing the Qbs project."); - if (!project()->hasParseResult()) - return tr("Parsing of Qbs project has failed."); - return QString(); + return qobject_cast<Internal::QbsProject *>(project()); } BuildConfiguration::BuildType QbsBuildConfiguration::buildType() const @@ -369,6 +366,39 @@ QbsBuildConfigurationFactory::QbsBuildConfigurationFactory() }); } +QList<BuildInfo> QbsBuildConfigurationFactory::availableBuilds(const Kit *k, const FilePath &projectPath, bool forSetup) const +{ + QList<BuildInfo> result; + + if (forSetup) { + + BuildInfo info = createBuildInfo(k, BuildConfiguration::Debug); + //: The name of the debug build configuration created by default for a qbs project. + info.displayName = tr("Debug"); + //: Non-ASCII characters in directory suffix may cause build issues. + info.buildDirectory + = defaultBuildDirectory(projectPath, k, tr("Debug", "Shadow build directory suffix"), + info.buildType); + result << info; + + info = createBuildInfo(k, BuildConfiguration::Release); + //: The name of the release build configuration created by default for a qbs project. + info.displayName = tr("Release"); + //: Non-ASCII characters in directory suffix may cause build issues. + info.buildDirectory + = defaultBuildDirectory(projectPath, k, tr("Release", "Shadow build directory suffix"), + info.buildType); + result << info; + + } else { + + result << createBuildInfo(k, BuildConfiguration::Debug); + + } + + return result; +} + BuildInfo QbsBuildConfigurationFactory::createBuildInfo(const Kit *k, BuildConfiguration::BuildType type) const { @@ -382,35 +412,5 @@ BuildInfo QbsBuildConfigurationFactory::createBuildInfo(const Kit *k, return info; } -QList<BuildInfo> QbsBuildConfigurationFactory::availableBuilds(const Target *parent) const -{ - return {createBuildInfo(parent->kit(), BuildConfiguration::Debug)}; -} - -QList<BuildInfo> QbsBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const -{ - QList<BuildInfo> result; - - BuildInfo info = createBuildInfo(k, BuildConfiguration::Debug); - //: The name of the debug build configuration created by default for a qbs project. - info.displayName = tr("Debug"); - //: Non-ASCII characters in directory suffix may cause build issues. - info.buildDirectory - = defaultBuildDirectory(projectPath, k, tr("Debug", "Shadow build directory suffix"), - info.buildType); - result << info; - - info = createBuildInfo(k, BuildConfiguration::Release); - //: The name of the release build configuration created by default for a qbs project. - info.displayName = tr("Release"); - //: Non-ASCII characters in directory suffix may cause build issues. - info.buildDirectory - = defaultBuildDirectory(projectPath, k, tr("Release", "Shadow build directory suffix"), - info.buildType); - result << info; - - return result; -} - } // namespace Internal } // namespace QbsProjectManager diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h index f34e552a40..0dbd442efb 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h +++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h @@ -48,15 +48,12 @@ class QbsBuildConfiguration : public ProjectExplorer::BuildConfiguration QbsBuildConfiguration(ProjectExplorer::Target *target, Core::Id id); public: - void initialize(const ProjectExplorer::BuildInfo &info) override; + void initialize() override; QbsBuildStep *qbsStep() const; QVariantMap qbsConfiguration() const; - Internal::QbsProject *project() const override; - - bool isEnabled() const override; - QString disabledReason() const override; + Internal::QbsProject *qbsProject() const; BuildType buildType() const override; @@ -78,6 +75,7 @@ signals: private: bool fromMap(const QVariantMap &map) override; + void triggerReparseIfActive(); QStringList m_changedFiles; QStringList m_activeFileTags; @@ -92,9 +90,8 @@ class QbsBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationF public: QbsBuildConfigurationFactory(); - QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Target *parent) const override; - QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *k, - const QString &projectPath) const override; + QList<ProjectExplorer::BuildInfo> availableBuilds + (const ProjectExplorer::Kit *k, const Utils::FilePath &projectPath, bool forSetup) const override; private: ProjectExplorer::BuildInfo createBuildInfo(const ProjectExplorer::Kit *k, diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp index da09f51c05..25d16c08ad 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp @@ -31,8 +31,6 @@ #include "qbsprojectmanagerconstants.h" #include "qbsprojectmanagersettings.h" -#include "ui_qbsbuildstepconfigwidget.h" - #include <coreplugin/icore.h> #include <coreplugin/variablechooser.h> #include <projectexplorer/buildsteplist.h> @@ -41,24 +39,36 @@ #include <projectexplorer/target.h> #include <qtsupport/qtversionmanager.h> #include <utils/macroexpander.h> +#include <utils/pathchooser.h> #include <utils/qtcassert.h> #include <utils/qtcprocess.h> #include <utils/utilsicons.h> -#include <qbs.h> +#include <QBoxLayout> +#include <QCheckBox> +#include <QComboBox> +#include <QFormLayout> +#include <QLabel> +#include <QPlainTextEdit> +#include <QSpinBox> -static const char QBS_CONFIG[] = "Qbs.Configuration"; -static const char QBS_DRY_RUN[] = "Qbs.DryRun"; -static const char QBS_KEEP_GOING[] = "Qbs.DryKeepGoing"; -static const char QBS_MAXJOBCOUNT[] = "Qbs.MaxJobs"; -static const char QBS_SHOWCOMMANDLINES[] = "Qbs.ShowCommandLines"; -static const char QBS_INSTALL[] = "Qbs.Install"; -static const char QBS_CLEAN_INSTALL_ROOT[] = "Qbs.CleanInstallRoot"; +#include <qbs.h> // -------------------------------------------------------------------- // Constants: // -------------------------------------------------------------------- +const char QBS_CONFIG[] = "Qbs.Configuration"; +const char QBS_DRY_RUN[] = "Qbs.DryRun"; +const char QBS_KEEP_GOING[] = "Qbs.DryKeepGoing"; +const char QBS_MAXJOBCOUNT[] = "Qbs.MaxJobs"; +const char QBS_SHOWCOMMANDLINES[] = "Qbs.ShowCommandLines"; +const char QBS_INSTALL[] = "Qbs.Install"; +const char QBS_CLEAN_INSTALL_ROOT[] = "Qbs.CleanInstallRoot"; + +using namespace ProjectExplorer; +using namespace Utils; + namespace QbsProjectManager { namespace Internal { @@ -67,7 +77,6 @@ class QbsBuildStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget Q_OBJECT public: QbsBuildStepConfigWidget(QbsBuildStep *step); - ~QbsBuildStepConfigWidget() override; private: void updateState(); @@ -92,8 +101,6 @@ private: bool validateProperties(Utils::FancyLineEdit *edit, QString *errorMessage); - Ui::QbsBuildStepConfigWidget *m_ui; - class Property { public: @@ -114,7 +121,22 @@ private: }; QList<Property> m_propertyCache; - bool m_ignoreChange; + bool m_ignoreChange = false; + + QComboBox *buildVariantComboBox; + QSpinBox *jobSpinBox; + QCheckBox *qmlDebuggingLibraryCheckBox; + FancyLineEdit *propertyEdit; + PathChooser *installDirChooser; + QLabel *qmlDebuggingWarningIcon; + QLabel *qmlDebuggingWarningText; + QCheckBox *keepGoingCheckBox; + QCheckBox *showCommandLinesCheckBox; + QCheckBox *forceProbesCheckBox; + QCheckBox *installCheckBox; + QCheckBox *cleanInstallRootCheckBox; + QCheckBox *defaultInstallDirCheckBox; + QPlainTextEdit *commandLineTextEdit; }; // -------------------------------------------------------------------- @@ -340,8 +362,7 @@ void QbsBuildStep::buildingDone(bool success) void QbsBuildStep::reparsingDone(bool success) { - disconnect(qbsProject(), &ProjectExplorer::Project::parsingFinished, - this, &QbsBuildStep::reparsingDone); + disconnect(project(), &Project::parsingFinished, this, &QbsBuildStep::reparsingDone); m_parsingProject = false; if (m_job) { // This was a scheduled reparsing after building. finish(); @@ -367,7 +388,7 @@ void QbsBuildStep::handleProgress(int value) void QbsBuildStep::handleCommandDescriptionReport(const QString &highlight, const QString &message) { - Q_UNUSED(highlight); + Q_UNUSED(highlight) emit addOutput(message, OutputFormat::Stdout); } @@ -469,8 +490,7 @@ void QbsBuildStep::setCleanInstallRoot(bool clean) void QbsBuildStep::parseProject() { m_parsingProject = true; - connect(qbsProject(), &ProjectExplorer::Project::parsingFinished, - this, &QbsBuildStep::reparsingDone); + connect(project(), &Project::parsingFinished, this, &QbsBuildStep::reparsingDone); qbsProject()->parseCurrentBuildConfiguration(); } @@ -526,7 +546,7 @@ QbsBuildStepConfigWidget::QbsBuildStepConfigWidget(QbsBuildStep *step) : BuildStepConfigWidget(step), m_ignoreChange(false) { - connect(step, &ProjectExplorer::ProjectConfiguration::displayNameChanged, + connect(step, &ProjectConfiguration::displayNameChanged, this, &QbsBuildStepConfigWidget::updateState); connect(step, &QbsBuildStep::qbsConfigurationChanged, this, &QbsBuildStepConfigWidget::updateState); @@ -534,76 +554,158 @@ QbsBuildStepConfigWidget::QbsBuildStepConfigWidget(QbsBuildStep *step) : this, &QbsBuildStepConfigWidget::updateState); connect(&QbsProjectManagerSettings::instance(), &QbsProjectManagerSettings::settingsBaseChanged, this, &QbsBuildStepConfigWidget::updateState); - step->target()->subscribeSignal(&ProjectExplorer::BuildConfiguration::buildDirectoryChanged, - this, [this]() { - if (this->step()->buildConfiguration() == sender()) - updateState(); - }); + connect(step->buildConfiguration(), &BuildConfiguration::buildDirectoryChanged, + this, &QbsBuildStepConfigWidget::updateState); setContentsMargins(0, 0, 0, 0); - m_ui = new Ui::QbsBuildStepConfigWidget; - m_ui->setupUi(this); - m_ui->installDirChooser->setExpectedKind(Utils::PathChooser::Directory); + buildVariantComboBox = new QComboBox(this); + buildVariantComboBox->addItem(tr("Debug")); + buildVariantComboBox->addItem(tr("Release")); + + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(buildVariantComboBox->sizePolicy().hasHeightForWidth()); + buildVariantComboBox->setSizePolicy(sizePolicy); + + auto horizontalLayout_5 = new QHBoxLayout(); + horizontalLayout_5->addWidget(buildVariantComboBox); + horizontalLayout_5->addItem(new QSpacerItem(70, 13, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + jobSpinBox = new QSpinBox(this); + + auto horizontalLayout_6 = new QHBoxLayout(); + horizontalLayout_6->addWidget(jobSpinBox); + horizontalLayout_6->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + qmlDebuggingLibraryCheckBox = new QCheckBox(this); + qmlDebuggingWarningIcon = new QLabel(this); + qmlDebuggingWarningText = new QLabel(this); + + auto qmlDebuggingLayout = new QHBoxLayout(); + qmlDebuggingLayout->addWidget(qmlDebuggingLibraryCheckBox); + qmlDebuggingLayout->addWidget(qmlDebuggingWarningIcon); + qmlDebuggingLayout->addWidget(qmlDebuggingWarningText); + qmlDebuggingLayout->addItem(new QSpacerItem(40, 5, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + propertyEdit = new FancyLineEdit(this); + + keepGoingCheckBox = new QCheckBox(this); + + showCommandLinesCheckBox = new QCheckBox(this); + + forceProbesCheckBox = new QCheckBox(this); + + auto flagsLayout = new QHBoxLayout(); + flagsLayout->addWidget(keepGoingCheckBox); + flagsLayout->addWidget(showCommandLinesCheckBox); + flagsLayout->addWidget(forceProbesCheckBox); + flagsLayout->addItem(new QSpacerItem(40, 13, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + installCheckBox = new QCheckBox(this); + + cleanInstallRootCheckBox = new QCheckBox(this); + + defaultInstallDirCheckBox = new QCheckBox(this); + + auto installLayout = new QHBoxLayout(); + installLayout->addWidget(installCheckBox); + installLayout->addWidget(cleanInstallRootCheckBox); + installLayout->addWidget(defaultInstallDirCheckBox); + installLayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + installDirChooser = new PathChooser(this); + installDirChooser->setExpectedKind(PathChooser::Directory); + + commandLineTextEdit = new QPlainTextEdit(this); + commandLineTextEdit->setUndoRedoEnabled(false); + commandLineTextEdit->setReadOnly(true); + commandLineTextEdit->setTextInteractionFlags(Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse); + + auto formLayout = new QFormLayout(this); + formLayout->addRow(tr("Build variant:"), horizontalLayout_5); + formLayout->addRow(tr("Parallel jobs:"), horizontalLayout_6); + formLayout->addRow(tr("Enable QML debugging:"), qmlDebuggingLayout); + formLayout->addRow(tr("Properties:"), propertyEdit); + formLayout->addRow(tr("Flags:"), flagsLayout); + formLayout->addRow(tr("Installation flags:"), installLayout); + formLayout->addRow(tr("Installation directory:"), installDirChooser); + formLayout->addRow(tr("Equivalent command line:"), commandLineTextEdit); + + QWidget::setTabOrder(buildVariantComboBox, jobSpinBox); + QWidget::setTabOrder(jobSpinBox, qmlDebuggingLibraryCheckBox); + QWidget::setTabOrder(qmlDebuggingLibraryCheckBox, propertyEdit); + QWidget::setTabOrder(propertyEdit, keepGoingCheckBox); + QWidget::setTabOrder(keepGoingCheckBox, showCommandLinesCheckBox); + QWidget::setTabOrder(showCommandLinesCheckBox, forceProbesCheckBox); + QWidget::setTabOrder(forceProbesCheckBox, installCheckBox); + QWidget::setTabOrder(installCheckBox, cleanInstallRootCheckBox); + QWidget::setTabOrder(cleanInstallRootCheckBox, commandLineTextEdit); + + jobSpinBox->setToolTip(tr("Number of concurrent build jobs.")); + propertyEdit->setToolTip(tr("Properties to pass to the project.")); + keepGoingCheckBox->setToolTip(tr("Keep going when errors occur (if at all possible).")); + keepGoingCheckBox->setText(tr("Keep going")); + showCommandLinesCheckBox->setText(tr("Show command lines")); + forceProbesCheckBox->setText(tr("Force probes")); + installCheckBox->setText(tr("Install")); + cleanInstallRootCheckBox->setText(tr("Clean install root")); + defaultInstallDirCheckBox->setText(tr("Use default location")); auto chooser = new Core::VariableChooser(this); - chooser->addSupportedWidget(m_ui->propertyEdit); - chooser->addSupportedWidget(m_ui->installDirChooser->lineEdit()); - m_ui->propertyEdit->setValidationFunction([this](Utils::FancyLineEdit *edit, - QString *errorMessage) { + chooser->addSupportedWidget(propertyEdit); + chooser->addSupportedWidget(installDirChooser->lineEdit()); + propertyEdit->setValidationFunction([this](FancyLineEdit *edit, QString *errorMessage) { return validateProperties(edit, errorMessage); }); - m_ui->qmlDebuggingWarningIcon->setPixmap(Utils::Icons::WARNING.pixmap()); - connect(m_ui->buildVariantComboBox, + qmlDebuggingWarningIcon->setPixmap(Utils::Icons::WARNING.pixmap()); + + connect(buildVariantComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QbsBuildStepConfigWidget::changeBuildVariant); - connect(m_ui->keepGoingCheckBox, &QAbstractButton::toggled, + connect(keepGoingCheckBox, &QAbstractButton::toggled, this, &QbsBuildStepConfigWidget::changeKeepGoing); - connect(m_ui->jobSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), + connect(jobSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &QbsBuildStepConfigWidget::changeJobCount); - connect(m_ui->showCommandLinesCheckBox, &QCheckBox::toggled, this, + connect(showCommandLinesCheckBox, &QCheckBox::toggled, this, &QbsBuildStepConfigWidget::changeShowCommandLines); - connect(m_ui->installCheckBox, &QCheckBox::toggled, this, + connect(installCheckBox, &QCheckBox::toggled, this, &QbsBuildStepConfigWidget::changeInstall); - connect(m_ui->cleanInstallRootCheckBox, &QCheckBox::toggled, this, + connect(cleanInstallRootCheckBox, &QCheckBox::toggled, this, &QbsBuildStepConfigWidget::changeCleanInstallRoot); - connect(m_ui->defaultInstallDirCheckBox, &QCheckBox::toggled, this, + connect(defaultInstallDirCheckBox, &QCheckBox::toggled, this, &QbsBuildStepConfigWidget::changeUseDefaultInstallDir); - connect(m_ui->installDirChooser, &Utils::PathChooser::rawPathChanged, this, + connect(installDirChooser, &Utils::PathChooser::rawPathChanged, this, &QbsBuildStepConfigWidget::changeInstallDir); - connect(m_ui->forceProbesCheckBox, &QCheckBox::toggled, this, + connect(forceProbesCheckBox, &QCheckBox::toggled, this, &QbsBuildStepConfigWidget::changeForceProbes); - connect(m_ui->qmlDebuggingLibraryCheckBox, &QAbstractButton::toggled, + connect(qmlDebuggingLibraryCheckBox, &QAbstractButton::toggled, this, &QbsBuildStepConfigWidget::linkQmlDebuggingLibraryChecked); updateState(); } -QbsBuildStepConfigWidget::~QbsBuildStepConfigWidget() -{ - delete m_ui; -} - void QbsBuildStepConfigWidget::updateState() { if (!m_ignoreChange) { - m_ui->keepGoingCheckBox->setChecked(qbsStep()->keepGoing()); - m_ui->jobSpinBox->setValue(qbsStep()->maxJobs()); - m_ui->showCommandLinesCheckBox->setChecked(qbsStep()->showCommandLines()); - m_ui->installCheckBox->setChecked(qbsStep()->install()); - m_ui->cleanInstallRootCheckBox->setChecked(qbsStep()->cleanInstallRoot()); - m_ui->forceProbesCheckBox->setChecked(qbsStep()->forceProbes()); + keepGoingCheckBox->setChecked(qbsStep()->keepGoing()); + jobSpinBox->setValue(qbsStep()->maxJobs()); + showCommandLinesCheckBox->setChecked(qbsStep()->showCommandLines()); + installCheckBox->setChecked(qbsStep()->install()); + cleanInstallRootCheckBox->setChecked(qbsStep()->cleanInstallRoot()); + forceProbesCheckBox->setChecked(qbsStep()->forceProbes()); updatePropertyEdit(qbsStep()->qbsConfiguration(QbsBuildStep::PreserveVariables)); - m_ui->qmlDebuggingLibraryCheckBox->setChecked(qbsStep()->isQmlDebuggingEnabled()); - m_ui->installDirChooser->setFileName(qbsStep()->installRoot(QbsBuildStep::PreserveVariables)); - m_ui->defaultInstallDirCheckBox->setChecked(!qbsStep()->hasCustomInstallRoot()); + qmlDebuggingLibraryCheckBox->setChecked(qbsStep()->isQmlDebuggingEnabled()); + installDirChooser->setFileName(qbsStep()->installRoot(QbsBuildStep::PreserveVariables)); + defaultInstallDirCheckBox->setChecked(!qbsStep()->hasCustomInstallRoot()); } updateQmlDebuggingOption(); const QString buildVariant = qbsStep()->buildVariant(); const int idx = (buildVariant == Constants::QBS_VARIANT_DEBUG) ? 0 : 1; - m_ui->buildVariantComboBox->setCurrentIndex(idx); + buildVariantComboBox->setCurrentIndex(idx); QString command = static_cast<QbsBuildConfiguration *>(step()->buildConfiguration()) ->equivalentCommandLine(qbsStep()); @@ -613,7 +715,7 @@ void QbsBuildStepConfigWidget::updateState() if (qbsStep()->isQmlDebuggingEnabled()) command.append(' ').append(Constants::QBS_CONFIG_QUICK_DEBUG_KEY).append(":true"); - m_ui->commandLineTextEdit->setPlainText(command); + commandLineTextEdit->setPlainText(command); setSummaryText(tr("<b>Qbs:</b> %1").arg(command)); } @@ -623,16 +725,15 @@ void QbsBuildStepConfigWidget::updateQmlDebuggingOption() QString warningText; bool supported = QtSupport::BaseQtVersion::isQmlDebuggingSupported(step()->target()->kit(), &warningText); - m_ui->qmlDebuggingLibraryCheckBox->setEnabled(supported); + qmlDebuggingLibraryCheckBox->setEnabled(supported); if (supported && qbsStep()->isQmlDebuggingEnabled()) warningText = tr("Might make your application vulnerable. Only use in a safe environment."); - m_ui->qmlDebuggingWarningText->setText(warningText); - m_ui->qmlDebuggingWarningIcon->setVisible(!warningText.isEmpty()); + qmlDebuggingWarningText->setText(warningText); + qmlDebuggingWarningIcon->setVisible(!warningText.isEmpty()); } - void QbsBuildStepConfigWidget::updatePropertyEdit(const QVariantMap &data) { QVariantMap editable = data; @@ -649,7 +750,7 @@ void QbsBuildStepConfigWidget::updatePropertyEdit(const QVariantMap &data) for (QVariantMap::const_iterator i = editable.constBegin(); i != editable.constEnd(); ++i) propertyList.append(i.key() + ':' + i.value().toString()); - m_ui->propertyEdit->setText(Utils::QtcProcess::joinArgs(propertyList)); + propertyEdit->setText(QtcProcess::joinArgs(propertyList)); } void QbsBuildStepConfigWidget::changeBuildVariant(int idx) @@ -703,11 +804,11 @@ void QbsBuildStepConfigWidget::changeUseDefaultInstallDir(bool useDefault) { m_ignoreChange = true; QVariantMap config = qbsStep()->qbsConfiguration(QbsBuildStep::PreserveVariables); - m_ui->installDirChooser->setEnabled(!useDefault); + installDirChooser->setEnabled(!useDefault); if (useDefault) config.remove(Constants::QBS_INSTALL_ROOT_KEY); else - config.insert(Constants::QBS_INSTALL_ROOT_KEY, m_ui->installDirChooser->rawPath()); + config.insert(Constants::QBS_INSTALL_ROOT_KEY, installDirChooser->rawPath()); qbsStep()->setQbsConfiguration(config); m_ignoreChange = false; } diff --git a/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui b/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui deleted file mode 100644 index 562dcc3e85..0000000000 --- a/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui +++ /dev/null @@ -1,319 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>QbsProjectManager::Internal::QbsBuildStepConfigWidget</class> - <widget class="QWidget" name="QbsProjectManager::Internal::QbsBuildStepConfigWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>809</width> - <height>416</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="buildVariantLabel"> - <property name="text"> - <string>Build variant:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <item> - <widget class="QComboBox" name="buildVariantComboBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <item> - <property name="text"> - <string>Debug</string> - </property> - </item> - <item> - <property name="text"> - <string>Release</string> - </property> - </item> - </widget> - </item> - <item> - <spacer name="spacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>70</width> - <height>13</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="jobsLabel"> - <property name="text"> - <string>Parallel jobs:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <item> - <widget class="QSpinBox" name="jobSpinBox"> - <property name="toolTip"> - <string>Number of concurrent build jobs.</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="qmlDebuggingLabel"> - <property name="text"> - <string>Enable QML debugging:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QCheckBox" name="qmlDebuggingLibraryCheckBox"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="qmlDebuggingWarningIcon"/> - </item> - <item> - <widget class="QLabel" name="qmlDebuggingWarningText"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>5</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="propertyLabel"> - <property name="text"> - <string>Properties:</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="Utils::FancyLineEdit" name="propertyEdit"> - <property name="toolTip"> - <string>Properties to pass to the project.</string> - </property> - <property name="text"> - <string notr="true"/> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="flagsLabel"> - <property name="text"> - <string>Flags:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="4" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QCheckBox" name="keepGoingCheckBox"> - <property name="toolTip"> - <string>Keep going when errors occur (if at all possible).</string> - </property> - <property name="text"> - <string>Keep going</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="showCommandLinesCheckBox"> - <property name="text"> - <string>Show command lines</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="forceProbesCheckBox"> - <property name="text"> - <string>Force probes</string> - </property> - </widget> - </item> - <item> - <spacer name="checkBoxSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>13</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="installFlagsLabel"> - <property name="text"> - <string>Installation flags:</string> - </property> - </widget> - </item> - <item row="5" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <widget class="QCheckBox" name="installCheckBox"> - <property name="text"> - <string>Install</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cleanInstallRootCheckBox"> - <property name="text"> - <string>Clean install root</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="defaultInstallDirCheckBox"> - <property name="text"> - <string>Use default location</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="6" column="0"> - <widget class="QLabel" name="installDirLabel"> - <property name="text"> - <string>Installation directory:</string> - </property> - </widget> - </item> - <item row="6" column="1"> - <widget class="Utils::PathChooser" name="installDirChooser"/> - </item> - <item row="7" column="0"> - <widget class="QLabel" name="commandLineKeyLabel"> - <property name="text"> - <string>Equivalent command line:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="7" column="1"> - <widget class="QPlainTextEdit" name="commandLineTextEdit"> - <property name="undoRedoEnabled"> - <bool>false</bool> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - <property name="plainText"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - </layout> - <zorder>buildVariantLabel</zorder> - <zorder>qmlDebuggingLabel</zorder> - <zorder>propertyLabel</zorder> - <zorder>propertyEdit</zorder> - <zorder>commandLineKeyLabel</zorder> - <zorder>flagsLabel</zorder> - <zorder>jobsLabel</zorder> - <zorder>commandLineTextEdit</zorder> - <zorder>installFlagsLabel</zorder> - <zorder>defaultInstallDirCheckBox</zorder> - <zorder>installDirChooser</zorder> - <zorder>installDirLabel</zorder> - </widget> - <customwidgets> - <customwidget> - <class>Utils::FancyLineEdit</class> - <extends>QLineEdit</extends> - <header location="global">utils/fancylineedit.h</header> - </customwidget> - <customwidget> - <class>Utils::PathChooser</class> - <extends>QLineEdit</extends> - <header location="global">utils/pathchooser.h</header> - </customwidget> - </customwidgets> - <tabstops> - <tabstop>buildVariantComboBox</tabstop> - <tabstop>jobSpinBox</tabstop> - <tabstop>qmlDebuggingLibraryCheckBox</tabstop> - <tabstop>propertyEdit</tabstop> - <tabstop>keepGoingCheckBox</tabstop> - <tabstop>showCommandLinesCheckBox</tabstop> - <tabstop>forceProbesCheckBox</tabstop> - <tabstop>installCheckBox</tabstop> - <tabstop>cleanInstallRootCheckBox</tabstop> - <tabstop>commandLineTextEdit</tabstop> - </tabstops> - <resources/> - <connections/> -</ui> diff --git a/src/plugins/qbsprojectmanager/qbscleanstep.cpp b/src/plugins/qbsprojectmanager/qbscleanstep.cpp index 167299a0bb..7b64b888ce 100644 --- a/src/plugins/qbsprojectmanager/qbscleanstep.cpp +++ b/src/plugins/qbsprojectmanager/qbscleanstep.cpp @@ -58,18 +58,16 @@ QbsCleanStep::QbsCleanStep(ProjectExplorer::BuildStepList *bsl) : m_keepGoingAspect->setSettingsKey("Qbs.DryKeepGoing"); m_keepGoingAspect->setLabel(tr("Keep going")); - m_effectiveCommandAspect = addAspect<BaseStringAspect>(); - m_effectiveCommandAspect->setDisplayStyle(BaseStringAspect::TextEditDisplay); - m_effectiveCommandAspect->setLabelText(tr("Equivalent command line:")); - - updateState(); - - connect(this, &ProjectExplorer::ProjectConfiguration::displayNameChanged, - this, &QbsCleanStep::updateState); - connect(m_dryRunAspect, &BaseBoolAspect::changed, - this, &QbsCleanStep::updateState); - connect(m_keepGoingAspect, &BaseBoolAspect::changed, - this, &QbsCleanStep::updateState); + auto effectiveCommandAspect = addAspect<BaseStringAspect>(); + effectiveCommandAspect->setDisplayStyle(BaseStringAspect::TextEditDisplay); + effectiveCommandAspect->setLabelText(tr("Equivalent command line:")); + + setSummaryUpdater([this, effectiveCommandAspect] { + QString command = static_cast<QbsBuildConfiguration *>(buildConfiguration()) + ->equivalentCommandLine(this); + effectiveCommandAspect->setValue(command); + return tr("<b>Qbs:</b> %1").arg(command); + }); } QbsCleanStep::~QbsCleanStep() @@ -119,15 +117,6 @@ void QbsCleanStep::doRun() this, &QbsCleanStep::handleProgress); } -ProjectExplorer::BuildStepConfigWidget *QbsCleanStep::createConfigWidget() -{ - auto w = BuildStep::createConfigWidget(); - connect(this, &QbsCleanStep::stateChanged, w, [this, w] { - w->setSummaryText(tr("<b>Qbs:</b> %1").arg(m_effectiveCommandAspect->value())); - }); - return w; -} - void QbsCleanStep::doCancel() { if (m_job) @@ -149,7 +138,7 @@ void QbsCleanStep::cleaningDone(bool success) void QbsCleanStep::handleTaskStarted(const QString &desciption, int max) { - Q_UNUSED(desciption); + Q_UNUSED(desciption) m_maxProgress = max; } @@ -159,14 +148,6 @@ void QbsCleanStep::handleProgress(int value) emit progress(value * 100 / m_maxProgress, m_description); } -void QbsCleanStep::updateState() -{ - QString command = static_cast<QbsBuildConfiguration *>(buildConfiguration()) - ->equivalentCommandLine(this); - m_effectiveCommandAspect->setValue(command); - emit stateChanged(); -} - void QbsCleanStep::createTaskAndOutput(ProjectExplorer::Task::TaskType type, const QString &message, const QString &file, int line) { ProjectExplorer::Task task = ProjectExplorer::Task(type, message, diff --git a/src/plugins/qbsprojectmanager/qbscleanstep.h b/src/plugins/qbsprojectmanager/qbscleanstep.h index bfac0d2b68..fa07d35292 100644 --- a/src/plugins/qbsprojectmanager/qbscleanstep.h +++ b/src/plugins/qbsprojectmanager/qbscleanstep.h @@ -47,26 +47,20 @@ public: bool dryRun() const { return m_dryRunAspect->value(); } bool keepGoing() const { return m_keepGoingAspect->value(); } -signals: - void stateChanged(); - private: bool init() override; void doRun() override; void doCancel() override; - ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override; void cleaningDone(bool success); void handleTaskStarted(const QString &desciption, int max); void handleProgress(int value); - void updateState(); void createTaskAndOutput(ProjectExplorer::Task::TaskType type, const QString &message, const QString &file, int line); ProjectExplorer::BaseBoolAspect *m_dryRunAspect = nullptr; ProjectExplorer::BaseBoolAspect *m_keepGoingAspect = nullptr; - ProjectExplorer::BaseStringAspect *m_effectiveCommandAspect = nullptr; QStringList m_products; diff --git a/src/plugins/qbsprojectmanager/qbsinstallstep.cpp b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp index ddfaadf8df..d0ea258853 100644 --- a/src/plugins/qbsprojectmanager/qbsinstallstep.cpp +++ b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp @@ -30,8 +30,6 @@ #include "qbsproject.h" #include "qbsprojectmanagerconstants.h" -#include "ui_qbsinstallstepconfigwidget.h" - #include <coreplugin/icore.h> #include <projectexplorer/buildsteplist.h> #include <projectexplorer/deployconfiguration.h> @@ -40,7 +38,14 @@ #include <projectexplorer/target.h> #include <utils/qtcassert.h> +#include <QCheckBox> #include <QFileInfo> +#include <QFormLayout> +#include <QLabel> +#include <QPlainTextEdit> +#include <QSpacerItem> + +using namespace ProjectExplorer; // -------------------------------------------------------------------- // Constants: @@ -53,6 +58,29 @@ static const char QBS_KEEP_GOING[] = "Qbs.DryKeepGoing"; namespace QbsProjectManager { namespace Internal { +class QbsInstallStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget +{ +public: + QbsInstallStepConfigWidget(QbsInstallStep *step); + +private: + void updateState(); + + void changeRemoveFirst(bool rf) { m_step->setRemoveFirst(rf); } + void changeDryRun(bool dr) { m_step->setDryRun(dr); } + void changeKeepGoing(bool kg) { m_step->setKeepGoing(kg); } + +private: + QbsInstallStep *m_step; + bool m_ignoreChange; + + QCheckBox *m_dryRunCheckBox; + QCheckBox *m_keepGoingCheckBox; + QCheckBox *m_removeFirstCheckBox; + QPlainTextEdit *m_commandLineTextEdit; + QLabel *m_installRootValueLabel; +}; + // -------------------------------------------------------------------- // QbsInstallStep: // -------------------------------------------------------------------- @@ -248,60 +276,88 @@ QbsInstallStepConfigWidget::QbsInstallStepConfigWidget(QbsInstallStep *step) : setContentsMargins(0, 0, 0, 0); - auto project = static_cast<QbsProject *>(m_step->project()); - - m_ui = new Ui::QbsInstallStepConfigWidget; - m_ui->setupUi(this); - - connect(m_ui->removeFirstCheckBox, &QAbstractButton::toggled, + auto installRootLabel = new QLabel(this); + + auto flagsLabel = new QLabel(this); + + m_dryRunCheckBox = new QCheckBox(this); + m_keepGoingCheckBox = new QCheckBox(this); + m_removeFirstCheckBox = new QCheckBox(this); + + auto horizontalLayout = new QHBoxLayout(); + horizontalLayout->addWidget(m_dryRunCheckBox); + horizontalLayout->addWidget(m_keepGoingCheckBox); + horizontalLayout->addWidget(m_removeFirstCheckBox); + horizontalLayout->addStretch(1); + + auto commandLineKeyLabel = new QLabel(this); + QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(commandLineKeyLabel->sizePolicy().hasHeightForWidth()); + commandLineKeyLabel->setSizePolicy(sizePolicy); + commandLineKeyLabel->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); + + m_commandLineTextEdit = new QPlainTextEdit(this); + QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Preferred); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(m_commandLineTextEdit->sizePolicy().hasHeightForWidth()); + m_commandLineTextEdit->setSizePolicy(sizePolicy1); + m_commandLineTextEdit->setReadOnly(true); + m_commandLineTextEdit->setTextInteractionFlags(Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse); + + m_installRootValueLabel = new QLabel(this); + + auto formLayout = new QFormLayout(this); + formLayout->setWidget(0, QFormLayout::LabelRole, installRootLabel); + formLayout->setWidget(0, QFormLayout::FieldRole, m_installRootValueLabel); + formLayout->setWidget(1, QFormLayout::LabelRole, flagsLabel); + formLayout->setLayout(1, QFormLayout::FieldRole, horizontalLayout); + formLayout->setWidget(2, QFormLayout::LabelRole, commandLineKeyLabel); + formLayout->setWidget(2, QFormLayout::FieldRole, m_commandLineTextEdit); + + QWidget::setTabOrder(m_dryRunCheckBox, m_keepGoingCheckBox); + QWidget::setTabOrder(m_keepGoingCheckBox, m_removeFirstCheckBox); + QWidget::setTabOrder(m_removeFirstCheckBox, m_commandLineTextEdit); + + installRootLabel->setText(QbsInstallStep::tr("Install root:")); + flagsLabel->setText(QbsInstallStep::tr("Flags:")); + m_dryRunCheckBox->setText(QbsInstallStep::tr("Dry run")); + m_keepGoingCheckBox->setText(QbsInstallStep::tr("Keep going")); + m_removeFirstCheckBox->setText(QbsInstallStep::tr("Remove first")); + commandLineKeyLabel->setText(QbsInstallStep::tr("Equivalent command line:")); + m_installRootValueLabel->setText(QString()); + + connect(m_removeFirstCheckBox, &QAbstractButton::toggled, this, &QbsInstallStepConfigWidget::changeRemoveFirst); - connect(m_ui->dryRunCheckBox, &QAbstractButton::toggled, + connect(m_dryRunCheckBox, &QAbstractButton::toggled, this, &QbsInstallStepConfigWidget::changeDryRun); - connect(m_ui->keepGoingCheckBox, &QAbstractButton::toggled, + connect(m_keepGoingCheckBox, &QAbstractButton::toggled, this, &QbsInstallStepConfigWidget::changeKeepGoing); - connect(project, &ProjectExplorer::Project::parsingFinished, + connect(m_step->project(), &Project::parsingFinished, this, &QbsInstallStepConfigWidget::updateState); updateState(); } -QbsInstallStepConfigWidget::~QbsInstallStepConfigWidget() -{ - delete m_ui; -} - void QbsInstallStepConfigWidget::updateState() { if (!m_ignoreChange) { - m_ui->installRootValueLabel->setText(m_step->installRoot()); - m_ui->removeFirstCheckBox->setChecked(m_step->removeFirst()); - m_ui->dryRunCheckBox->setChecked(m_step->dryRun()); - m_ui->keepGoingCheckBox->setChecked(m_step->keepGoing()); + m_installRootValueLabel->setText(m_step->installRoot()); + m_removeFirstCheckBox->setChecked(m_step->removeFirst()); + m_dryRunCheckBox->setChecked(m_step->dryRun()); + m_keepGoingCheckBox->setChecked(m_step->keepGoing()); } QString command = m_step->buildConfig()->equivalentCommandLine(m_step); - m_ui->commandLineTextEdit->setPlainText(command); + m_commandLineTextEdit->setPlainText(command); setSummaryText(tr("<b>Qbs:</b> %1").arg(command)); } -void QbsInstallStepConfigWidget::changeRemoveFirst(bool rf) -{ - m_step->setRemoveFirst(rf); -} - -void QbsInstallStepConfigWidget::changeDryRun(bool dr) -{ - m_step->setDryRun(dr); -} - -void QbsInstallStepConfigWidget::changeKeepGoing(bool kg) -{ - m_step->setKeepGoing(kg); -} - // -------------------------------------------------------------------- // QbsInstallStepFactory: // -------------------------------------------------------------------- diff --git a/src/plugins/qbsprojectmanager/qbsinstallstep.h b/src/plugins/qbsprojectmanager/qbsinstallstep.h index 6b5c62eb73..5f58d006a3 100644 --- a/src/plugins/qbsprojectmanager/qbsinstallstep.h +++ b/src/plugins/qbsprojectmanager/qbsinstallstep.h @@ -35,8 +35,6 @@ namespace QbsProjectManager { namespace Internal { -class QbsInstallStepConfigWidget; - class QbsInstallStep : public ProjectExplorer::BuildStep { Q_OBJECT @@ -86,29 +84,6 @@ private: friend class QbsInstallStepConfigWidget; }; -namespace Ui { class QbsInstallStepConfigWidget; } - -class QbsInstallStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget -{ - Q_OBJECT -public: - QbsInstallStepConfigWidget(QbsInstallStep *step); - ~QbsInstallStepConfigWidget() override; - -private: - void updateState(); - - void changeRemoveFirst(bool rf); - void changeDryRun(bool dr); - void changeKeepGoing(bool kg); - -private: - Ui::QbsInstallStepConfigWidget *m_ui; - - QbsInstallStep *m_step; - bool m_ignoreChange; -}; - class QbsInstallStepFactory : public ProjectExplorer::BuildStepFactory { public: diff --git a/src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui b/src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui deleted file mode 100644 index 69c5102203..0000000000 --- a/src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui +++ /dev/null @@ -1,118 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>QbsProjectManager::Internal::QbsInstallStepConfigWidget</class> - <widget class="QWidget" name="QbsProjectManager::Internal::QbsInstallStepConfigWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>474</width> - <height>146</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="installRootLabel"> - <property name="text"> - <string>Install root:</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="flagsLabel"> - <property name="text"> - <string>Flags:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QCheckBox" name="dryRunCheckBox"> - <property name="text"> - <string>Dry run</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="keepGoingCheckBox"> - <property name="text"> - <string>Keep going</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="removeFirstCheckBox"> - <property name="text"> - <string>Remove first</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="commandLineKeyLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Equivalent command line:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QPlainTextEdit" name="commandLineTextEdit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - <property name="plainText"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="installRootValueLabel"> - <property name="text"> - <string/> - </property> - </widget> - </item> - </layout> - </widget> - <tabstops> - <tabstop>dryRunCheckBox</tabstop> - <tabstop>keepGoingCheckBox</tabstop> - <tabstop>removeFirstCheckBox</tabstop> - <tabstop>commandLineTextEdit</tabstop> - </tabstops> - <resources/> - <connections/> -</ui> diff --git a/src/plugins/qbsprojectmanager/qbslogsink.cpp b/src/plugins/qbsprojectmanager/qbslogsink.cpp index 9e635c2958..d73f844052 100644 --- a/src/plugins/qbsprojectmanager/qbslogsink.cpp +++ b/src/plugins/qbsprojectmanager/qbslogsink.cpp @@ -77,7 +77,7 @@ void QbsLogSink::doPrintWarning(const qbs::ErrorInfo &warning) void QbsLogSink::doPrintMessage(qbs::LoggerLevel level, const QString &message, const QString &tag) { - Q_UNUSED(tag); + Q_UNUSED(tag) { QMutexLocker l(&m_mutex); diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp index 62762069b2..719897ec78 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp @@ -28,7 +28,7 @@ #include "qbsnodetreebuilder.h" #include "qbsproject.h" #include "qbsprojectmanagerconstants.h" -#include "qbsrunconfiguration.h" +#include "qbsprojectmanagerplugin.h" #include <android/androidconstants.h> #include <coreplugin/fileiconprovider.h> @@ -266,7 +266,8 @@ bool QbsGroupNode::addFiles(const QStringList &filePaths, QStringList *notAdded) m_qbsGroupData, notAdded); } -bool QbsGroupNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved) +RemovedFilesFromProject QbsGroupNode::removeFiles(const QStringList &filePaths, + QStringList *notRemoved) { QStringList notRemovedDummy; if (!notRemoved) @@ -275,13 +276,13 @@ bool QbsGroupNode::removeFiles(const QStringList &filePaths, QStringList *notRem const QbsProjectNode *prjNode = parentQbsProjectNode(this); if (!prjNode || !prjNode->qbsProject().isValid()) { *notRemoved += filePaths; - return false; + return RemovedFilesFromProject::Error; } const QbsProductNode *prdNode = parentQbsProductNode(this); if (!prdNode || !prdNode->qbsProductData().isValid()) { *notRemoved += filePaths; - return false; + return RemovedFilesFromProject::Error; } return prjNode->project()->removeFilesFromProduct(filePaths, prdNode->qbsProductData(), @@ -310,6 +311,13 @@ FolderNode::AddNewInformation QbsGroupNode::addNewInformation(const QStringList return info; } +QVariant QbsGroupNode::data(Core::Id role) const +{ + if (role == ProjectExplorer::Constants::QT_KEYWORDS_ENABLED) + return m_qbsGroupData.properties().getModuleProperty("Qt.core", "enableKeywords"); + return QVariant(); +} + // -------------------------------------------------------------------- // QbsProductNode: // -------------------------------------------------------------------- @@ -351,7 +359,8 @@ bool QbsProductNode::addFiles(const QStringList &filePaths, QStringList *notAdde QTC_ASSERT(false, return false); } -bool QbsProductNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved) +RemovedFilesFromProject QbsProductNode::removeFiles(const QStringList &filePaths, + QStringList *notRemoved) { QStringList notRemovedDummy; if (!notRemoved) @@ -360,7 +369,7 @@ bool QbsProductNode::removeFiles(const QStringList &filePaths, QStringList *notR const QbsProjectNode *prjNode = parentQbsProjectNode(this); if (!prjNode || !prjNode->qbsProject().isValid()) { *notRemoved += filePaths; - return false; + return RemovedFilesFromProject::Error; } qbs::GroupData grp = findMainQbsGroup(m_qbsProductData); @@ -369,7 +378,7 @@ bool QbsProductNode::removeFiles(const QStringList &filePaths, QStringList *notR notRemoved); } - QTC_ASSERT(false, return false); + QTC_ASSERT(false, return RemovedFilesFromProject::Error); } bool QbsProductNode::renameFile(const QString &filePath, const QString &newFilePath) @@ -382,6 +391,12 @@ bool QbsProductNode::renameFile(const QString &filePath, const QString &newFileP return prjNode->project()->renameFileInProduct(filePath, newFilePath, m_qbsProductData, grp); } +void QbsProductNode::build() +{ + QbsProjectManagerPlugin::buildNamedProduct(static_cast<QbsProject *>(getProject()), + QbsProject::uniqueProductName(qbsProductData())); +} + QStringList QbsProductNode::targetApplications() const { return QStringList{m_qbsProductData.targetExecutable()}; @@ -424,6 +439,9 @@ QVariant QbsProductNode::data(Core::Id role) const if (role == Android::Constants::AndroidApk) return m_qbsProductData.targetExecutable(); + if (role == ProjectExplorer::Constants::QT_KEYWORDS_ENABLED) + return m_qbsProductData.moduleProperties().getModuleProperty("Qt.core", "enableKeywords"); + return {}; } diff --git a/src/plugins/qbsprojectmanager/qbsnodes.h b/src/plugins/qbsprojectmanager/qbsnodes.h index 3d8f90c3df..e31fc2b9b9 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.h +++ b/src/plugins/qbsprojectmanager/qbsnodes.h @@ -47,11 +47,13 @@ public: bool showInSimpleTree() const final { return false; } bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const final; bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override; - bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = nullptr) override; + ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths, + QStringList *notRemoved = nullptr) override; bool renameFile(const QString &filePath, const QString &newFilePath) override; private: AddNewInformation addNewInformation(const QStringList &files, Node *context) const override; + QVariant data(Core::Id role) const override; qbs::GroupData m_qbsGroupData; QString m_productPath; @@ -68,8 +70,10 @@ public: bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const final; bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override; - bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = nullptr) override; + ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths, + QStringList *notRemoved = nullptr) override; bool renameFile(const QString &filePath, const QString &newFilePath) override; + void build() override; QStringList targetApplications() const override; QString buildKey() const override; diff --git a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp index f7f143b025..f7bbde2a13 100644 --- a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp @@ -82,7 +82,7 @@ void setupArtifacts(FolderNode *root, const QList<qbs::ArtifactData> &artifacts) }; auto node = std::make_unique<FileNode>(path, type); node->setIsGenerated(isGenerated); - node->setListInProject(!isGenerated || ad.fileTags().toSet().intersects(sourceTags)); + node->setListInProject(!isGenerated || Utils::toSet(ad.fileTags()).intersects(sourceTags)); root->addNestedNode(std::move(node)); } root->compress(); @@ -194,7 +194,7 @@ QStringList unreferencedBuildSystemFiles(const qbs::Project &p) return result; const std::set<QString> &available = p.buildSystemFiles(); - QList<QString> referenced = referencedBuildSystemFiles(p.projectData()).toList(); + QList<QString> referenced = Utils::toList(referencedBuildSystemFiles(p.projectData())); Utils::sort(referenced); std::set_difference(available.begin(), available.end(), referenced.begin(), referenced.end(), std::back_inserter(result)); diff --git a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp index 5a79d42062..3f3fe351ce 100644 --- a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp +++ b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp @@ -52,7 +52,7 @@ class QbsProfilesSettingsWidget : public QWidget { Q_OBJECT public: - QbsProfilesSettingsWidget(QWidget *parent = nullptr); + QbsProfilesSettingsWidget(); void apply(); @@ -64,10 +64,8 @@ private: qbs::SettingsModel m_model; }; -QbsProfilesSettingsPage::QbsProfilesSettingsPage(QObject *parent) - : Core::IOptionsPage(parent) - , m_useQtcSettingsDirPersistent(QbsProjectManagerSettings::useCreatorSettingsDirForQbs()) - +QbsProfilesSettingsPage::QbsProfilesSettingsPage() + : m_useQtcSettingsDirPersistent(QbsProjectManagerSettings::useCreatorSettingsDirForQbs()) { setId("Y.QbsProfiles"); setDisplayName(QCoreApplication::translate("QbsProjectManager", "Qbs")); @@ -97,9 +95,8 @@ void QbsProfilesSettingsPage::finish() } -QbsProfilesSettingsWidget::QbsProfilesSettingsWidget(QWidget *parent) - : QWidget(parent) - , m_model(QbsProjectManagerSettings::qbsSettingsBaseDir(), qbs::Settings::UserScope) +QbsProfilesSettingsWidget::QbsProfilesSettingsWidget() + : m_model(QbsProjectManagerSettings::qbsSettingsBaseDir(), qbs::Settings::UserScope) { m_model.setEditable(false); m_ui.setupUi(this); diff --git a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.h b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.h index f146b92c72..6227c6f999 100644 --- a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.h +++ b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.h @@ -34,7 +34,7 @@ class QbsProfilesSettingsWidget; class QbsProfilesSettingsPage : public Core::IOptionsPage { public: - QbsProfilesSettingsPage(QObject *parent = nullptr); + QbsProfilesSettingsPage(); private: QWidget *widget() override; diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 209e87b4bc..341a58d8f8 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -37,20 +37,23 @@ #include <coreplugin/documentmanager.h> #include <coreplugin/icontext.h> -#include <coreplugin/id.h> #include <coreplugin/icore.h> +#include <coreplugin/id.h> #include <coreplugin/iversioncontrol.h> -#include <coreplugin/vcsmanager.h> #include <coreplugin/messagemanager.h> #include <coreplugin/progressmanager/progressmanager.h> +#include <coreplugin/vcsmanager.h> #include <cpptools/cppmodelmanager.h> #include <cpptools/cppprojectupdater.h> +#include <cpptools/cpptoolsconstants.h> +#include <cpptools/generatedcodemodelsupport.h> #include <extensionsystem/pluginmanager.h> #include <projectexplorer/buildenvironmentwidget.h> #include <projectexplorer/buildinfo.h> #include <projectexplorer/buildmanager.h> #include <projectexplorer/buildtargetinfo.h> #include <projectexplorer/deploymentdata.h> +#include <projectexplorer/headerpath.h> #include <projectexplorer/kit.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/projectexplorer.h> @@ -58,14 +61,13 @@ #include <projectexplorer/target.h> #include <projectexplorer/taskhub.h> #include <projectexplorer/toolchain.h> -#include <projectexplorer/headerpath.h> -#include <qtsupport/qtcppkitinfo.h> -#include <qtsupport/qtkitinformation.h> -#include <cpptools/generatedcodemodelsupport.h> -#include <qmljstools/qmljsmodelmanager.h> -#include <qmljs/qmljsmodelmanagerinterface.h> +#include <utils/algorithm.h> #include <utils/hostosinfo.h> #include <utils/qtcassert.h> +#include <qmljs/qmljsmodelmanagerinterface.h> +#include <qmljstools/qmljsmodelmanager.h> +#include <qtsupport/qtcppkitinfo.h> +#include <qtsupport/qtkitinformation.h> #include <qbs.h> @@ -121,14 +123,15 @@ private: // QbsProject: // -------------------------------------------------------------------- -QbsProject::QbsProject(const FilePath &fileName) : - Project(Constants::MIME_TYPE, fileName, [this] { delayParsing(); }), - m_cppCodeModelUpdater(new CppTools::CppProjectUpdater) +QbsProject::QbsProject(const FilePath &fileName) + : Project(Constants::MIME_TYPE, fileName) + , m_cppCodeModelUpdater(new CppTools::CppProjectUpdater) { m_parsingDelay.setInterval(1000); // delay parsing by 1s. setId(Constants::PROJECT_ID); setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); + setCanBuildProducts(); rebuildProjectTree(); @@ -145,16 +148,13 @@ QbsProject::QbsProject(const FilePath &fileName) : } m_qbsProjects.erase(it); }); - auto delayedParsing = [this]() { - if (static_cast<ProjectConfiguration *>(sender())->isActive()) - delayParsing(); - }; - subscribeSignal(&BuildConfiguration::environmentChanged, this, delayedParsing); - subscribeSignal(&BuildConfiguration::buildDirectoryChanged, this, delayedParsing); - subscribeSignal(&QbsBuildConfiguration::qbsConfigurationChanged, this, delayedParsing); - subscribeSignal(&Target::activeBuildConfigurationChanged, this, delayedParsing); + + connect(this, &Project::activeBuildConfigurationChanged, + this, &QbsProject::delayParsing); connect(&m_parsingDelay, &QTimer::timeout, this, &QbsProject::startParsing); + + connect(this, &QbsProject::projectFileIsDirty, this, &QbsProject::delayParsing); } QbsProject::~QbsProject() @@ -169,8 +169,6 @@ QbsProject::~QbsProject() m_qbsUpdateFutureInterface = nullptr; } qDeleteAll(m_extraCompilers); - std::for_each(m_qbsDocuments.cbegin(), m_qbsDocuments.cend(), - [](Core::IDocument *doc) { doc->deleteLater(); }); } void QbsProject::projectLoaded() @@ -219,36 +217,6 @@ bool QbsProject::isProjectEditable() const return m_qbsProject.isValid() && !isParsing() && !BuildManager::isBuilding(); } -class ChangeExpector -{ -public: - ChangeExpector(const QString &filePath, const QSet<IDocument *> &documents) - : m_document(nullptr) - { - foreach (IDocument * const doc, documents) { - if (doc->filePath().toString() == filePath) { - m_document = doc; - break; - } - } - QTC_ASSERT(m_document, return); - DocumentManager::expectFileChange(filePath); - m_wasInDocumentManager = DocumentManager::removeDocument(m_document); - QTC_CHECK(m_wasInDocumentManager); - } - - ~ChangeExpector() - { - QTC_ASSERT(m_document, return); - DocumentManager::addDocument(m_document); - DocumentManager::unexpectFileChange(m_document->filePath().toString()); - } - -private: - IDocument *m_document; - bool m_wasInDocumentManager; -}; - bool QbsProject::ensureWriteableQbsFile(const QString &file) { // Ensure that the file is not read only @@ -277,7 +245,7 @@ bool QbsProject::addFilesToProduct(const QStringList &filePaths, QTC_ASSERT(m_qbsProject.isValid(), return false); QStringList allPaths = groupData.allFilePaths(); const QString productFilePath = productData.location().filePath(); - ChangeExpector expector(productFilePath, m_qbsDocuments); + Core::FileChangeBlocker expector(productFilePath); ensureWriteableQbsFile(productFilePath); foreach (const QString &path, filePaths) { qbs::ErrorInfo err = m_qbsProject.addFiles(productData, groupData, QStringList() << path); @@ -295,31 +263,50 @@ bool QbsProject::addFilesToProduct(const QStringList &filePaths, return notAdded->isEmpty(); } -bool QbsProject::removeFilesFromProduct(const QStringList &filePaths, - const qbs::ProductData productData, - const qbs::GroupData groupData, - QStringList *notRemoved) +RemovedFilesFromProject QbsProject::removeFilesFromProduct(const QStringList &filePaths, + const qbs::ProductData &productData, + const qbs::GroupData &groupData, + QStringList *notRemoved) { - QTC_ASSERT(m_qbsProject.isValid(), return false); - QStringList allPaths = groupData.allFilePaths(); + QTC_ASSERT(m_qbsProject.isValid(), return RemovedFilesFromProject::Error); + + const QList<qbs::ArtifactData> allWildcardsInGroup = groupData.sourceArtifactsFromWildcards(); + QStringList wildcardFiles; + QStringList nonWildcardFiles; + for (const QString &filePath : filePaths) { + if (contains(allWildcardsInGroup, [filePath](const qbs::ArtifactData &artifact) { + return artifact.filePath() == filePath; })) { + wildcardFiles << filePath; + } else { + nonWildcardFiles << filePath; + } + } const QString productFilePath = productData.location().filePath(); - ChangeExpector expector(productFilePath, m_qbsDocuments); + Core::FileChangeBlocker expector(productFilePath); ensureWriteableQbsFile(productFilePath); - foreach (const QString &path, filePaths) { - qbs::ErrorInfo err - = m_qbsProject.removeFiles(productData, groupData, QStringList() << path); + for (const QString &path : qAsConst(nonWildcardFiles)) { + const qbs::ErrorInfo err = m_qbsProject.removeFiles(productData, groupData, {path}); if (err.hasError()) { MessageManager::write(err.toString()); *notRemoved += path; - } else { - allPaths.removeOne(path); } } + if (notRemoved->count() != filePaths.count()) { m_projectData = m_qbsProject.projectData(); delayedUpdateAfterParse(); } - return notRemoved->isEmpty(); + + const bool success = notRemoved->isEmpty(); + if (!wildcardFiles.isEmpty()) { + *notRemoved += wildcardFiles; + delayParsing(); + } + if (!success) + return RemovedFilesFromProject::Error; + if (!wildcardFiles.isEmpty()) + return RemovedFilesFromProject::Wildcard; + return RemovedFilesFromProject::Ok; } bool QbsProject::renameFileInProduct(const QString &oldPath, const QString &newPath, @@ -329,8 +316,10 @@ bool QbsProject::renameFileInProduct(const QString &oldPath, const QString &newP if (newPath.isEmpty()) return false; QStringList dummy; - if (!removeFilesFromProduct(QStringList(oldPath), productData, groupData, &dummy)) + if (removeFilesFromProduct(QStringList(oldPath), productData, groupData, &dummy) + != RemovedFilesFromProject::Ok) { return false; + } qbs::ProductData newProductData; foreach (const qbs::ProductData &p, m_projectData.allProducts()) { if (uniqueProductName(p) == uniqueProductName(productData)) { @@ -422,11 +411,6 @@ QString QbsProject::profileForTarget(const Target *t) const return QbsManager::profileForKit(t->kit()); } -bool QbsProject::hasParseResult() const -{ - return qbsProject().isValid(); -} - qbs::Project QbsProject::qbsProject() const { return m_qbsProject; @@ -446,25 +430,17 @@ bool QbsProject::checkCancelStatus() qCDebug(qbsPmLog) << "Cancel request while parsing, starting re-parse"; m_qbsProjectParser->deleteLater(); m_qbsProjectParser = nullptr; - emitParsingFinished(false); + m_guard = {}; parseCurrentBuildConfiguration(); return true; } -static QSet<QString> toQStringSet(const std::set<QString> &src) -{ - QSet<QString> result; - result.reserve(int(src.size())); - std::copy(src.begin(), src.end(), Utils::inserter(result)); - return result; -} - void QbsProject::updateAfterParse() { qCDebug(qbsPmLog) << "Updating data after parse"; OpTimer opTimer("updateAfterParse"); updateProjectNodes(); - updateDocuments(toQStringSet(m_qbsProject.buildSystemFiles())); + updateDocuments(m_qbsProject.buildSystemFiles()); updateBuildTargetData(); updateCppCodeModel(); updateQmlJsCodeModel(); @@ -511,6 +487,8 @@ void QbsProject::handleQbsParsingDone(bool success) m_qbsProject = m_qbsProjectParser->qbsProject(); m_qbsProjects.insert(activeTarget(), m_qbsProject); bool dataChanged = false; + bool envChanged = m_lastParseEnv != m_qbsProjectParser->environment(); + m_lastParseEnv = m_qbsProjectParser->environment(); if (success) { QTC_ASSERT(m_qbsProject.isValid(), return); const qbs::ProjectData &projectData = m_qbsProject.projectData(); @@ -530,7 +508,10 @@ void QbsProject::handleQbsParsingDone(bool success) if (dataChanged) updateAfterParse(); - emitParsingFinished(success); + else if (envChanged) + updateCppCodeModel(); + m_guard.markAsSuccess(); + m_guard = {}; } void QbsProject::rebuildProjectTree() @@ -691,20 +672,15 @@ QString QbsProject::uniqueProductName(const qbs::ProductData &product) return product.name() + QLatin1Char('.') + product.multiplexConfigurationId(); } -void QbsProject::configureAsExampleProject(const QSet<Id> &platforms) +void QbsProject::configureAsExampleProject() { QList<BuildInfo> infoList; - QList<Kit *> kits = KitManager::kits(); - const auto qtVersionMatchesPlatform = [platforms](const QtSupport::BaseQtVersion *version) { - return platforms.isEmpty() || platforms.intersects(version->targetDeviceTypes()); - }; - foreach (Kit *k, kits) { - const QtSupport::BaseQtVersion * const qtVersion - = QtSupport::QtKitAspect::qtVersion(k); - if (!qtVersion || !qtVersionMatchesPlatform(qtVersion)) - continue; - if (auto factory = BuildConfigurationFactory::find(k, projectFilePath().toString())) - infoList << factory->allAvailableSetups(k, projectFilePath().toString()); + const QList<Kit *> kits = KitManager::kits(); + for (Kit *k : kits) { + if (QtSupport::QtKitAspect::qtVersion(k) != nullptr) { + if (auto factory = BuildConfigurationFactory::find(k, projectFilePath())) + infoList << factory->allAvailableSetups(k, projectFilePath()); + } } setup(infoList); prepareForParsing(); @@ -713,6 +689,8 @@ void QbsProject::configureAsExampleProject(const QSet<Id> &platforms) void QbsProject::parse(const QVariantMap &config, const Environment &env, const QString &dir, const QString &configName) { + m_guard = guardParsingRun(); + prepareForParsing(); QTC_ASSERT(!m_qbsProjectParser, return); @@ -720,7 +698,6 @@ void QbsProject::parse(const QVariantMap &config, const Environment &env, const QbsManager::updateProfileIfNecessary(activeTarget()->kit()); m_qbsProjectParser->parse(config, env, dir, configName); - emitParsingStarted(); } void QbsProject::prepareForParsing() @@ -740,58 +717,37 @@ void QbsProject::prepareForParsing() m_qbsUpdateFutureInterface->reportStarted(); } -void QbsProject::updateDocuments(const QSet<QString> &files) +void QbsProject::updateDocuments(const std::set<QString> &files) { OpTimer opTimer("updateDocuments"); - // Update documents: - QSet<QString> newFiles = files; - QTC_ASSERT(!newFiles.isEmpty(), newFiles << projectFilePath().toString()); - QSet<QString> oldFiles; - foreach (IDocument *doc, m_qbsDocuments) - oldFiles.insert(doc->filePath().toString()); - - QSet<QString> filesToAdd = newFiles; - filesToAdd.subtract(oldFiles); - QSet<QString> filesToRemove = oldFiles; - filesToRemove.subtract(newFiles); - - QSet<IDocument *> currentDocuments = m_qbsDocuments; - foreach (IDocument *doc, currentDocuments) { - if (filesToRemove.contains(doc->filePath().toString())) { - m_qbsDocuments.remove(doc); - doc->deleteLater(); - } - } - QSet<IDocument *> toAdd; + + const QVector<FilePath> filePaths = transform<QVector>(files, &FilePath::fromString); + const FilePath buildDir = FilePath::fromString(m_projectData.buildDirectory()); - for (const QString &f : qAsConst(filesToAdd)) { - // A changed qbs file (project, module etc) should trigger a re-parse, but not if - // the file was generated by qbs itself, in which case that might cause an infinite loop. - const FilePath fp = FilePath::fromString(f); - static const ProjectDocument::ProjectCallback noOpCallback = []{}; - const ProjectDocument::ProjectCallback reparseCallback = [this]() { delayParsing(); }; - toAdd.insert(new ProjectDocument(Constants::MIME_TYPE, fp, fp.isChildOf(buildDir) - ? noOpCallback : reparseCallback)); - } - m_qbsDocuments.unite(toAdd); + const QVector<FilePath> nonBuildDirFilePaths = filtered(filePaths, + [buildDir](const FilePath &p) { + return p.isChildOf(buildDir); + }); + + setExtraProjectFiles(nonBuildDirFilePaths); } -static CppTools::ProjectFile::Kind cppFileType(const qbs::ArtifactData &sourceFile) +static QString getMimeType(const qbs::ArtifactData &sourceFile) { - if (sourceFile.fileTags().contains(QLatin1String("hpp"))) { + if (sourceFile.fileTags().contains("hpp")) { if (CppTools::ProjectFile::isAmbiguousHeader(sourceFile.filePath())) - return CppTools::ProjectFile::AmbiguousHeader; - return CppTools::ProjectFile::CXXHeader; + return QString(CppTools::Constants::AMBIGUOUS_HEADER_MIMETYPE); + return QString(CppTools::Constants::CPP_HEADER_MIMETYPE); } - if (sourceFile.fileTags().contains(QLatin1String("cpp"))) - return CppTools::ProjectFile::CXXSource; - if (sourceFile.fileTags().contains(QLatin1String("c"))) - return CppTools::ProjectFile::CSource; - if (sourceFile.fileTags().contains(QLatin1String("objc"))) - return CppTools::ProjectFile::ObjCSource; - if (sourceFile.fileTags().contains(QLatin1String("objcpp"))) - return CppTools::ProjectFile::ObjCXXSource; - return CppTools::ProjectFile::Unsupported; + if (sourceFile.fileTags().contains("cpp")) + return QString(CppTools::Constants::CPP_SOURCE_MIMETYPE); + if (sourceFile.fileTags().contains("c")) + return QString(CppTools::Constants::C_SOURCE_MIMETYPE); + if (sourceFile.fileTags().contains("objc")) + return QString(CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE); + if (sourceFile.fileTags().contains("objcpp")) + return QString(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE); + return {}; } static QString groupLocationToCallGroupId(const qbs::CodeLocation &location) @@ -918,7 +874,7 @@ void QbsProject::updateCppCodeModel() QtSupport::CppKitInfo kitInfo(this); QTC_ASSERT(kitInfo.isValid(), return); - CppTools::RawProjectParts rpps; + RawProjectParts rpps; foreach (const qbs::ProductData &prd, m_projectData.allProducts()) { QString cPch; QString cxxPch; @@ -942,13 +898,13 @@ void QbsProject::updateCppCodeModel() std::for_each(sourceArtifacts.cbegin(), sourceArtifacts.cend(), pchFinder); } - const CppTools::ProjectPart::QtVersion qtVersionForPart = - prd.moduleProperties().getModuleProperty("Qt.core", "version").isValid() - ? kitInfo.projectPartQtVersion - : CppTools::ProjectPart::NoQt; + const Utils::QtVersion qtVersionForPart + = prd.moduleProperties().getModuleProperty("Qt.core", "version").isValid() + ? kitInfo.projectPartQtVersion + : Utils::QtVersion::None; foreach (const qbs::GroupData &grp, prd.groups()) { - CppTools::RawProjectPart rpp; + RawProjectPart rpp; rpp.setQtVersion(qtVersionForPart); const qbs::PropertyMap &props = grp.properties(); rpp.setCallGroupId(groupLocationToCallGroupId(grp.location())); @@ -964,15 +920,19 @@ void QbsProject::updateCppCodeModel() QLatin1String(CONFIG_DEFINES)); rpp.setMacros(Utils::transform<QVector>(list, [](const QString &s) { return ProjectExplorer::Macro::fromKeyValue(s); })); - list = props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE), - QLatin1String(CONFIG_INCLUDEPATHS)); - list.append(props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE), - QLatin1String(CONFIG_SYSTEM_INCLUDEPATHS))); - list.removeDuplicates(); ProjectExplorer::HeaderPaths grpHeaderPaths; - foreach (const QString &p, list) + list = props.getModulePropertiesAsStringList(CONFIG_CPP_MODULE, CONFIG_INCLUDEPATHS); + list.removeDuplicates(); + for (const QString &p : qAsConst(list)) grpHeaderPaths += {FilePath::fromUserInput(p).toString(), HeaderPathType::User}; + list = props.getModulePropertiesAsStringList(CONFIG_CPP_MODULE, + CONFIG_SYSTEM_INCLUDEPATHS); + + list.removeDuplicates(); + for (const QString &p : qAsConst(list)) + grpHeaderPaths += {FilePath::fromUserInput(p).toString(), HeaderPathType::System}; + list = props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE), QLatin1String(CONFIG_FRAMEWORKPATHS)); list.append(props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE), @@ -987,8 +947,8 @@ void QbsProject::updateCppCodeModel() rpp.setProjectFileLocation(grp.location().filePath(), grp.location().line(), grp.location().column()); rpp.setBuildSystemTarget(uniqueProductName(prd)); - rpp.setBuildTargetType(prd.isRunnable() ? CppTools::ProjectPart::Executable - : CppTools::ProjectPart::Library); + rpp.setBuildTargetType(prd.isRunnable() ? ProjectExplorer::BuildTargetType::Executable + : ProjectExplorer::BuildTargetType::Library); QHash<QString, qbs::ArtifactData> filePathToSourceArtifact; bool hasCFiles = false; @@ -1051,12 +1011,13 @@ void QbsProject::updateCppCodeModel() << grp.name() << "in product" << prd.name(); qCWarning(qbsPmLog) << "Expect problems with code model"; } - rpp.setPreCompiledHeaders(pchFiles.toList()); - rpp.setFiles(grp.allFilePaths(), [filePathToSourceArtifact](const QString &filePath) { - // Keep this lambda thread-safe! - return CppTools::ProjectFile(filePath, - cppFileType(filePathToSourceArtifact.value(filePath))); - }); + rpp.setPreCompiledHeaders(Utils::toList(pchFiles)); + rpp.setFiles(grp.allFilePaths(), + {}, + [filePathToSourceArtifact](const QString &filePath) { + // Keep this lambda thread-safe! + return getMimeType(filePathToSourceArtifact.value(filePath)); + }); rpps.append(rpp); @@ -1064,7 +1025,7 @@ void QbsProject::updateCppCodeModel() } CppTools::GeneratedCodeModelSupport::update(m_extraCompilers); - m_cppCodeModelUpdater->update({this, kitInfo, rpps}); + m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), rpps}); } void QbsProject::updateQmlJsCodeModel() @@ -1174,8 +1135,6 @@ void QbsProject::updateBuildTargetData() OpTimer optimer("updateBuildTargetData"); updateApplicationTargets(); updateDeploymentInfo(); - if (activeTarget()) - activeTarget()->updateDefaultRunConfigurations(); } } // namespace Internal diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h index f186bb2c13..56798792bf 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.h +++ b/src/plugins/qbsprojectmanager/qbsproject.h @@ -67,8 +67,8 @@ public: // for shared data. bool addFilesToProduct(const QStringList &filePaths, const qbs::ProductData productData, const qbs::GroupData groupData, QStringList *notAdded); - bool removeFilesFromProduct(const QStringList &filePaths, - const qbs::ProductData productData, const qbs::GroupData groupData, + ProjectExplorer::RemovedFilesFromProject removeFilesFromProduct(const QStringList &filePaths, + const qbs::ProductData &productData, const qbs::GroupData &groupData, QStringList *notRemoved); bool renameFileInProduct(const QString &oldPath, const QString &newPath, const qbs::ProductData productData, @@ -82,7 +82,6 @@ public: static ProjectExplorer::FileType fileTypeFor(const QSet<QString> &tags); QString profileForTarget(const ProjectExplorer::Target *t) const; - bool hasParseResult() const; void parseCurrentBuildConfiguration(); void scheduleParsing() { m_parsingScheduled = true; } bool parsingScheduled() const { return m_parsingScheduled; } @@ -98,7 +97,7 @@ public: static QString uniqueProductName(const qbs::ProductData &product); - void configureAsExampleProject(const QSet<Core::Id> &platforms) final; + void configureAsExampleProject() final; void delayParsing(); @@ -117,7 +116,7 @@ private: const QString &configName); void prepareForParsing(); - void updateDocuments(const QSet<QString> &files); + void updateDocuments(const std::set<QString> &files); void updateCppCodeModel(); void updateQmlJsCodeModel(); void updateApplicationTargets(); @@ -144,7 +143,7 @@ private: QHash<ProjectExplorer::Target *, qbs::Project> m_qbsProjects; qbs::Project m_qbsProject; // for activeTarget() qbs::ProjectData m_projectData; // Cached m_qbsProject.projectData() - QSet<Core::IDocument *> m_qbsDocuments; + Utils::Environment m_lastParseEnv; QbsProjectParser *m_qbsProjectParser = nullptr; @@ -166,6 +165,8 @@ private: bool m_extraCompilersPending = false; QHash<QString, Utils::Environment> m_envCache; + + ParseGuard m_guard; }; } // namespace Internal diff --git a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp index 69c4e5af1d..dd8600095d 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp @@ -87,13 +87,12 @@ QbsProjectImporter::QbsProjectImporter(const FilePath &path) : QtProjectImporter { } -static QString buildDir(const QString &projectFilePath, const Kit *k) +static QString buildDir(const FilePath &projectFilePath, const Kit *k) { - const QString projectName = QFileInfo(projectFilePath).completeBaseName(); + const QString projectName = projectFilePath.toFileInfo().completeBaseName(); ProjectMacroExpander expander(projectFilePath, projectName, k, QString(), BuildConfiguration::Unknown); - const QString projectDir - = Project::projectDirectory(FilePath::fromString(projectFilePath)).toString(); + const QString projectDir = Project::projectDirectory(projectFilePath).toString(); const QString buildPath = expander.expand(ProjectExplorerPlugin::buildDirectoryTemplate()); return FileUtils::resolvePath(projectDir, buildPath); } @@ -125,7 +124,7 @@ QStringList QbsProjectImporter::importCandidates() seenCandidates.insert(projectDir); const auto &kits = KitManager::kits(); for (Kit * const k : kits) { - QFileInfo fi(buildDir(projectFilePath().toString(), k)); + QFileInfo fi(buildDir(projectFilePath(), k)); const QString candidate = fi.absolutePath(); if (!seenCandidates.contains(candidate)) { seenCandidates.insert(candidate); @@ -209,9 +208,9 @@ Kit *QbsProjectImporter::createKit(void *directoryData) const return createTemporaryKit(qtVersionData,[this, bgData](Kit *k) -> void { QList<ToolChainData> tcData; if (!bgData->cxxCompilerPath.isEmpty()) - tcData << findOrCreateToolChains(bgData->cxxCompilerPath, Constants::CXX_LANGUAGE_ID); + tcData << findOrCreateToolChains({bgData->cxxCompilerPath, Constants::CXX_LANGUAGE_ID}); if (!bgData->cCompilerPath.isEmpty()) - tcData << findOrCreateToolChains(bgData->cCompilerPath, Constants::C_LANGUAGE_ID); + tcData << findOrCreateToolChains({bgData->cCompilerPath, Constants::C_LANGUAGE_ID}); foreach (const ToolChainData &tc, tcData) { if (!tc.tcs.isEmpty()) ToolChainKitAspect::setToolChain(k, tc.tcs.first()); @@ -224,7 +223,7 @@ const QList<BuildInfo> QbsProjectImporter::buildInfoListForKit(const Kit *k, voi { qCDebug(qbsPmLog) << "creating build info for kit" << k->displayName(); const auto factory = qobject_cast<QbsBuildConfigurationFactory *>( - BuildConfigurationFactory::find(k, projectFilePath().toString())); + BuildConfigurationFactory::find(k, projectFilePath())); if (!factory) { qCDebug(qbsPmLog) << "no build config factory found"; return {}; diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.pro b/src/plugins/qbsprojectmanager/qbsprojectmanager.pro index 831422f262..1b8896b33c 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanager.pro +++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.pro @@ -37,8 +37,7 @@ HEADERS = \ qbsprojectmanagerconstants.h \ qbsprojectmanagerplugin.h \ qbsprojectmanagersettings.h \ - qbsprojectparser.h \ - qbsrunconfiguration.h + qbsprojectparser.h SOURCES = \ customqbspropertiesdialog.cpp \ @@ -59,14 +58,11 @@ SOURCES = \ qbsprojectmanager.cpp \ qbsprojectmanagerplugin.cpp \ qbsprojectmanagersettings.cpp \ - qbsprojectparser.cpp \ - qbsrunconfiguration.cpp + qbsprojectparser.cpp FORMS = \ customqbspropertiesdialog.ui \ - qbsbuildstepconfigwidget.ui \ qbscleanstepconfigwidget.ui \ - qbsinstallstepconfigwidget.ui \ qbsprofilessettingswidget.ui RESOURCES += \ diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs index 1ef3f1b63b..5c933991af 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs +++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs @@ -68,13 +68,11 @@ QtcPlugin { "qbsbuildconfiguration.h", "qbsbuildstep.cpp", "qbsbuildstep.h", - "qbsbuildstepconfigwidget.ui", "qbscleanstep.cpp", "qbscleanstep.h", "qbscleanstepconfigwidget.ui", "qbsinstallstep.cpp", "qbsinstallstep.h", - "qbsinstallstepconfigwidget.ui", "qbskitinformation.cpp", "qbskitinformation.h", "qbslogsink.cpp", @@ -105,8 +103,6 @@ QtcPlugin { "qbsprojectmanagersettings.h", "qbsprojectparser.cpp", "qbsprojectparser.h", - "qbsrunconfiguration.cpp", - "qbsrunconfiguration.h", ] // QML typeinfo stuff diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp index f8eb477e64..bc123b09c7 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp @@ -35,7 +35,6 @@ #include "qbsproject.h" #include "qbsprojectmanager.h" #include "qbsprojectmanagerconstants.h" -#include "qbsrunconfiguration.h" #include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actionmanager.h> @@ -91,9 +90,7 @@ public: QbsBuildStepFactory buildStepFactory; QbsCleanStepFactory cleanStepFactory; QbsInstallStepFactory installStepFactory; - QbsRunConfigurationFactory runConfigFactory; - SimpleRunWorkerFactory<SimpleTargetRunner, QbsRunConfiguration> runWorkerFactory; - QbsProfilesSettingsPage profilesSetttingsPage; + QbsProfilesSettingsPage profilesSettingsPage; QbsKitAspect qbsKitAspect; }; @@ -104,8 +101,8 @@ QbsProjectManagerPlugin::~QbsProjectManagerPlugin() bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorMessage) { - Q_UNUSED(arguments); - Q_UNUSED(errorMessage); + Q_UNUSED(arguments) + Q_UNUSED(errorMessage) d = new QbsProjectManagerPluginPrivate; @@ -578,5 +575,11 @@ void QbsProjectManagerPlugin::reparseProject(QbsProject *project) project->parseCurrentBuildConfiguration(); } +void QbsProjectManagerPlugin::buildNamedProduct(QbsProject *project, const QString &product) +{ + QbsProjectManagerPlugin::runStepsForProducts(project, QStringList(product), + {Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)}); +} + } // namespace Internal } // namespace QbsProjectManager diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h index f7b37e8d80..267b7777ae 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h @@ -42,6 +42,10 @@ class QbsProjectManagerPlugin : public ExtensionSystem::IPlugin Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QbsProjectManager.json") +public: + static void buildNamedProduct(QbsProject *project, const QString &product); + +private: ~QbsProjectManagerPlugin() final; bool initialize(const QStringList &arguments, QString *errorMessage) final; @@ -77,8 +81,8 @@ class QbsProjectManagerPlugin : public ExtensionSystem::IPlugin const QStringList &activeFileTags); void buildSingleFile(QbsProject *project, const QString &file); - void runStepsForProducts(QbsProject *project, const QStringList &products, - const QList<Core::Id> &stepTypes); + static void runStepsForProducts(QbsProject *project, const QStringList &products, + const QList<Core::Id> &stepTypes); QbsProjectManagerPluginPrivate *d = nullptr; QAction *m_reparseQbs = nullptr; diff --git a/src/plugins/qbsprojectmanager/qbsprojectparser.cpp b/src/plugins/qbsprojectmanager/qbsprojectparser.cpp index 3d67a087e3..10196cbd37 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectparser.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectparser.cpp @@ -82,6 +82,7 @@ void QbsProjectParser::parse(const QVariantMap &config, const Environment &env, QTC_ASSERT(!dir.isEmpty(), return); m_currentProgressBase = 0; + m_environment = env; qbs::SetupProjectParameters params; QVariantMap userConfig = config; @@ -186,7 +187,7 @@ void QbsProjectParser::handleQbsParsingProgress(int progress) void QbsProjectParser::handleQbsParsingTaskSetup(const QString &description, int maximumProgressValue) { - Q_UNUSED(description); + Q_UNUSED(description) if (m_fi) { m_currentProgressBase = m_fi->progressValue(); m_fi->setProgressRange(0, m_currentProgressBase + maximumProgressValue); diff --git a/src/plugins/qbsprojectmanager/qbsprojectparser.h b/src/plugins/qbsprojectmanager/qbsprojectparser.h index 4c54d08b3b..37b9e5f6d2 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectparser.h +++ b/src/plugins/qbsprojectmanager/qbsprojectparser.h @@ -50,6 +50,7 @@ public: const QString &configName); void startRuleExecution(); void cancel(); + Utils::Environment environment() const { return m_environment; } qbs::Project qbsProject() const; qbs::ErrorInfo error(); @@ -69,6 +70,7 @@ private: void handleRuleExecutionDone(); + Utils::Environment m_environment; QString m_projectFilePath; qbs::SetupProjectJob *m_qbsSetupProjectJob = nullptr; qbs::BuildJob *m_ruleExecutionJob = nullptr; diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp deleted file mode 100644 index d4960b3524..0000000000 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp +++ /dev/null @@ -1,169 +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 "qbsrunconfiguration.h" - -#include "qbsnodes.h" -#include "qbspmlogging.h" -#include "qbsprojectmanagerconstants.h" -#include "qbsproject.h" - -#include <projectexplorer/buildmanager.h> -#include <projectexplorer/deploymentdata.h> -#include <projectexplorer/localenvironmentaspect.h> -#include <projectexplorer/project.h> -#include <projectexplorer/runcontrol.h> -#include <projectexplorer/runconfigurationaspects.h> -#include <projectexplorer/target.h> - -#include <qtsupport/qtoutputformatter.h> - -#include <QFileInfo> - -using namespace ProjectExplorer; -using namespace Utils; - -namespace QbsProjectManager { -namespace Internal { - -// -------------------------------------------------------------------- -// QbsRunConfiguration: -// -------------------------------------------------------------------- - -QbsRunConfiguration::QbsRunConfiguration(Target *target, Core::Id id) - : RunConfiguration(target, id) -{ - auto envAspect = addAspect<LocalEnvironmentAspect>(target); - envAspect->addModifier([this](Environment &env) { - bool usingLibraryPaths = aspect<UseLibraryPathsAspect>()->value(); - - BuildTargetInfo bti = buildTargetInfo(); - if (bti.runEnvModifier) - bti.runEnvModifier(env, usingLibraryPaths); - }); - - addAspect<ExecutableAspect>(); - addAspect<ArgumentsAspect>(); - addAspect<WorkingDirectoryAspect>(); - addAspect<TerminalAspect>(); - - setOutputFormatter<QtSupport::QtOutputFormatter>(); - - auto libAspect = addAspect<UseLibraryPathsAspect>(); - connect(libAspect, &UseLibraryPathsAspect::changed, - envAspect, &EnvironmentAspect::environmentChanged); - if (HostOsInfo::isMacHost()) { - auto dyldAspect = addAspect<UseDyldSuffixAspect>(); - connect(dyldAspect, &UseDyldSuffixAspect::changed, - envAspect, &EnvironmentAspect::environmentChanged); - envAspect->addModifier([dyldAspect](Environment &env) { - if (dyldAspect->value()) - env.set("DYLD_IMAGE_SUFFIX", "_debug"); - }); - } - - connect(project(), &Project::parsingFinished, this, - [envAspect]() { envAspect->buildEnvironmentHasChanged(); }); - - connect(target, &Target::deploymentDataChanged, - this, &QbsRunConfiguration::updateTargetInformation); - connect(target, &Target::applicationTargetsChanged, - this, &QbsRunConfiguration::updateTargetInformation); - // Handles device changes, etc. - connect(target, &Target::kitChanged, - this, &QbsRunConfiguration::updateTargetInformation); - - auto qbsProject = static_cast<QbsProject *>(target->project()); - connect(qbsProject, &Project::parsingFinished, - this, &QbsRunConfiguration::updateTargetInformation); -} - -QVariantMap QbsRunConfiguration::toMap() const -{ - return RunConfiguration::toMap(); -} - -bool QbsRunConfiguration::fromMap(const QVariantMap &map) -{ - if (!RunConfiguration::fromMap(map)) - return false; - - updateTargetInformation(); - return true; -} - -void QbsRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &info) -{ - setDefaultDisplayName(info.displayName); - updateTargetInformation(); -} - -Utils::FilePath QbsRunConfiguration::executableToRun(const BuildTargetInfo &targetInfo) const -{ - const FilePath appInBuildDir = targetInfo.targetFilePath; - if (target()->deploymentData().localInstallRoot().isEmpty()) - return appInBuildDir; - const QString deployedAppFilePath = target()->deploymentData() - .deployableForLocalFile(appInBuildDir.toString()).remoteFilePath(); - if (deployedAppFilePath.isEmpty()) - return appInBuildDir; - const FilePath appInLocalInstallDir = target()->deploymentData().localInstallRoot() - + deployedAppFilePath; - return appInLocalInstallDir.exists() ? appInLocalInstallDir : appInBuildDir; -} - -void QbsRunConfiguration::updateTargetInformation() -{ - BuildTargetInfo bti = buildTargetInfo(); - const FilePath executable = executableToRun(bti); - auto terminalAspect = aspect<TerminalAspect>(); - terminalAspect->setUseTerminalHint(bti.usesTerminal); - - aspect<ExecutableAspect>()->setExecutable(executable); - - if (!executable.isEmpty()) { - QString defaultWorkingDir = QFileInfo(executable.toString()).absolutePath(); - if (!defaultWorkingDir.isEmpty()) { - auto wdAspect = aspect<WorkingDirectoryAspect>(); - wdAspect->setDefaultWorkingDirectory(FilePath::fromString(defaultWorkingDir)); - } - } - - emit enabledChanged(); -} - -// -------------------------------------------------------------------- -// QbsRunConfigurationFactory: -// -------------------------------------------------------------------- - -QbsRunConfigurationFactory::QbsRunConfigurationFactory() -{ - registerRunConfiguration<QbsRunConfiguration>("Qbs.RunConfiguration:"); - addSupportedProjectType(Constants::PROJECT_ID); - addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); -} - -} // namespace Internal -} // namespace QbsProjectManager diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h deleted file mode 100644 index 934f676624..0000000000 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h +++ /dev/null @@ -1,60 +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/runconfiguration.h> - -#include <QHash> -#include <QPair> -#include <QStringList> - -namespace QbsProjectManager { -namespace Internal { - -class QbsRunConfiguration : public ProjectExplorer::RunConfiguration -{ - Q_OBJECT - -public: - QbsRunConfiguration(ProjectExplorer::Target *target, Core::Id id); - -private: - Utils::FilePath executableToRun(const ProjectExplorer::BuildTargetInfo &targetInfo) const; - QVariantMap toMap() const final; - bool fromMap(const QVariantMap &map) final; - void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &rci) final; - - void updateTargetInformation(); -}; - -class QbsRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory -{ -public: - QbsRunConfigurationFactory(); -}; - -} // namespace Internal -} // namespace QbsProjectManager |