mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 08:20:18 -06:00
CMake GUI: Add presets functionality
This commit is contained in:
@@ -92,6 +92,12 @@ set(SRCS
|
||||
QCMake.h
|
||||
QCMakeCacheView.cxx
|
||||
QCMakeCacheView.h
|
||||
QCMakePreset.cxx
|
||||
QCMakePreset.h
|
||||
QCMakePresetComboBox.cxx
|
||||
QCMakePresetComboBox.h
|
||||
QCMakePresetItemModel.cxx
|
||||
QCMakePresetItemModel.h
|
||||
QCMakeWidgets.cxx
|
||||
QCMakeWidgets.h
|
||||
RegexExplorer.cxx
|
||||
@@ -116,6 +122,8 @@ qt5_wrap_cpp(MOC_SRCS
|
||||
FirstConfigure.h
|
||||
QCMake.h
|
||||
QCMakeCacheView.h
|
||||
QCMakePresetComboBox.h
|
||||
QCMakePresetItemModel.h
|
||||
QCMakeWidgets.h
|
||||
RegexExplorer.h
|
||||
WarningMessagesDialog.h
|
||||
|
||||
@@ -32,7 +32,8 @@ static const char* cmDocumentationUsage[][2] = {
|
||||
" cmake-gui [options]\n"
|
||||
" cmake-gui [options] <path-to-source>\n"
|
||||
" cmake-gui [options] <path-to-existing-build>\n"
|
||||
" cmake-gui [options] -S <path-to-source> -B <path-to-build>\n" },
|
||||
" cmake-gui [options] -S <path-to-source> -B <path-to-build>\n"
|
||||
" cmake-gui [options] -S <path-to-source> --preset=<preset-name>\n" },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
@@ -147,6 +148,7 @@ int main(int argc, char** argv)
|
||||
QStringList args = QApplication::arguments();
|
||||
std::string binaryDirectory;
|
||||
std::string sourceDirectory;
|
||||
std::string presetName;
|
||||
for (int i = 1; i < args.size(); ++i) {
|
||||
const QString& arg = args[i];
|
||||
if (arg.startsWith("-S")) {
|
||||
@@ -185,11 +187,28 @@ int main(int argc, char** argv)
|
||||
binaryDirectory =
|
||||
cmSystemTools::CollapseFullPath(path.toLocal8Bit().data());
|
||||
cmSystemTools::ConvertToUnixSlashes(binaryDirectory);
|
||||
} else if (arg.startsWith("--preset=")) {
|
||||
QString preset = arg.mid(cmStrLen("--preset="));
|
||||
if (preset.isEmpty()) {
|
||||
std::cerr << "No preset specified for --preset" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
presetName = preset.toLocal8Bit().data();
|
||||
}
|
||||
}
|
||||
if (!sourceDirectory.empty() && !binaryDirectory.empty()) {
|
||||
if (!sourceDirectory.empty() &&
|
||||
(!binaryDirectory.empty() || !presetName.empty())) {
|
||||
dialog.setSourceDirectory(QString::fromLocal8Bit(sourceDirectory.c_str()));
|
||||
dialog.setBinaryDirectory(QString::fromLocal8Bit(binaryDirectory.c_str()));
|
||||
if (!binaryDirectory.empty()) {
|
||||
dialog.setBinaryDirectory(
|
||||
QString::fromLocal8Bit(binaryDirectory.c_str()));
|
||||
if (!presetName.empty()) {
|
||||
dialog.setStartupBinaryDirectory(true);
|
||||
}
|
||||
}
|
||||
if (!presetName.empty()) {
|
||||
dialog.setDeferredPreset(QString::fromLocal8Bit(presetName.c_str()));
|
||||
}
|
||||
} else {
|
||||
if (args.count() == 2) {
|
||||
std::string filePath =
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
#include <QSettings>
|
||||
#include <QShortcut>
|
||||
#include <QStatusBar>
|
||||
#include <QString>
|
||||
#include <QToolButton>
|
||||
#include <QUrl>
|
||||
#include <QVector>
|
||||
|
||||
#ifdef QT_WINEXTRAS
|
||||
# include <QWinTaskbarButton>
|
||||
@@ -263,6 +265,8 @@ void CMakeSetupDialog::initialize()
|
||||
&CMakeSetupDialog::onBinaryDirectoryChanged);
|
||||
QObject::connect(this->SourceDirectory, &QLineEdit::textChanged, this,
|
||||
&CMakeSetupDialog::onSourceDirectoryChanged);
|
||||
QObject::connect(this->Preset, &QCMakePresetComboBox::presetChanged, this,
|
||||
&CMakeSetupDialog::onBuildPresetChanged);
|
||||
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
&QCMake::sourceDirChanged, this,
|
||||
@@ -270,6 +274,13 @@ void CMakeSetupDialog::initialize()
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
&QCMake::binaryDirChanged, this,
|
||||
&CMakeSetupDialog::updateBinaryDirectory);
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::presetsChanged,
|
||||
this, &CMakeSetupDialog::updatePresets);
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::presetChanged,
|
||||
this, &CMakeSetupDialog::updatePreset);
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
&QCMake::presetLoadError, this,
|
||||
&CMakeSetupDialog::showPresetLoadError);
|
||||
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
&QCMake::progressChanged, this,
|
||||
@@ -314,9 +325,15 @@ void CMakeSetupDialog::initialize()
|
||||
QObject::connect(this->WarnUninitializedAction, &QAction::triggered,
|
||||
this->CMakeThread->cmakeInstance(),
|
||||
&QCMake::setWarnUninitializedMode);
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
&QCMake::warnUninitializedModeChanged,
|
||||
this->WarnUninitializedAction, &QAction::setChecked);
|
||||
|
||||
if (!this->SourceDirectory->text().isEmpty() ||
|
||||
!this->BinaryDirectory->lineEdit()->text().isEmpty()) {
|
||||
if (!this->SourceDirectory->text().isEmpty() &&
|
||||
!this->DeferredPreset.isNull()) {
|
||||
this->onSourceDirectoryChanged(this->SourceDirectory->text());
|
||||
} else if (!this->SourceDirectory->text().isEmpty() ||
|
||||
!this->BinaryDirectory->lineEdit()->text().isEmpty()) {
|
||||
this->onSourceDirectoryChanged(this->SourceDirectory->text());
|
||||
this->onBinaryDirectoryChanged(this->BinaryDirectory->lineEdit()->text());
|
||||
} else {
|
||||
@@ -671,6 +688,41 @@ void CMakeSetupDialog::updateBinaryDirectory(const QString& dir)
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::updatePresets(const QVector<QCMakePreset>& presets)
|
||||
{
|
||||
if (this->Preset->presets() != presets) {
|
||||
this->Preset->blockSignals(true);
|
||||
this->Preset->setPresets(presets);
|
||||
this->Preset->blockSignals(false);
|
||||
}
|
||||
|
||||
this->Preset->setHidden(presets.isEmpty());
|
||||
this->PresetLabel->setHidden(presets.isEmpty());
|
||||
|
||||
if (!this->DeferredPreset.isNull()) {
|
||||
this->Preset->setPresetName(this->DeferredPreset);
|
||||
this->DeferredPreset = QString{};
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::updatePreset(const QString& name)
|
||||
{
|
||||
if (this->Preset->presetName() != name) {
|
||||
this->Preset->blockSignals(true);
|
||||
this->Preset->setPresetName(name);
|
||||
this->Preset->blockSignals(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::showPresetLoadError(
|
||||
const QString& dir, cmCMakePresetsFile::ReadFileResult result)
|
||||
{
|
||||
QMessageBox::warning(
|
||||
this, "Error Reading CMake Presets",
|
||||
QString::fromLocal8Bit("Could not read presets from %1: %2")
|
||||
.arg(dir, cmCMakePresetsFile::ResultToString(result)));
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::doBinaryBrowse()
|
||||
{
|
||||
QString dir = QFileDialog::getExistingDirectory(
|
||||
@@ -686,6 +738,11 @@ void CMakeSetupDialog::setBinaryDirectory(const QString& dir)
|
||||
this->BinaryDirectory->setEditText(dir);
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::setStartupBinaryDirectory(bool startup)
|
||||
{
|
||||
this->StartupBinaryDirectory = startup;
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::onSourceDirectoryChanged(const QString& dir)
|
||||
{
|
||||
this->Output->clear();
|
||||
@@ -711,11 +768,24 @@ void CMakeSetupDialog::onBinaryDirectoryChanged(const QString& dir)
|
||||
Q_ARG(QString, dir));
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::onBuildPresetChanged(const QString& name)
|
||||
{
|
||||
QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(), "setPreset",
|
||||
Qt::QueuedConnection, Q_ARG(QString, name),
|
||||
Q_ARG(bool, !this->StartupBinaryDirectory));
|
||||
this->StartupBinaryDirectory = false;
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::setSourceDirectory(const QString& dir)
|
||||
{
|
||||
this->SourceDirectory->setText(dir);
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::setDeferredPreset(const QString& preset)
|
||||
{
|
||||
this->DeferredPreset = preset;
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::showProgress(const QString& /*msg*/, float percent)
|
||||
{
|
||||
percent = (percent * ProgressFactor) + ProgressOffset;
|
||||
@@ -753,6 +823,7 @@ void CMakeSetupDialog::setEnabledState(bool enabled)
|
||||
this->CacheValues->cacheModel()->setEditEnabled(enabled);
|
||||
this->SourceDirectory->setEnabled(enabled);
|
||||
this->BrowseSourceDirectoryButton->setEnabled(enabled);
|
||||
this->Preset->setEnabled(enabled);
|
||||
this->BinaryDirectory->setEnabled(enabled);
|
||||
this->BrowseBinaryDirectoryButton->setEnabled(enabled);
|
||||
this->ReloadCacheAction->setEnabled(enabled);
|
||||
@@ -777,6 +848,17 @@ bool CMakeSetupDialog::setupFirstConfigure()
|
||||
// restore from settings
|
||||
dialog.loadFromSettings();
|
||||
|
||||
auto presetData = this->Preset->currentData();
|
||||
if (presetData.isValid()) {
|
||||
auto preset = presetData.value<QCMakePreset>();
|
||||
dialog.setCurrentGenerator(preset.generator);
|
||||
if (preset.setGenConfig) {
|
||||
dialog.setPlatform(preset.architecture);
|
||||
dialog.setToolset(preset.toolset);
|
||||
}
|
||||
dialog.setCompilerOption(CompilerOption::DefaultNative);
|
||||
}
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
dialog.saveToSettings();
|
||||
this->CMakeThread->cmakeInstance()->setGenerator(dialog.getGenerator());
|
||||
|
||||
@@ -5,12 +5,15 @@
|
||||
#include <memory>
|
||||
|
||||
#include "QCMake.h"
|
||||
#include "QCMakePreset.h"
|
||||
#include <QEventLoop>
|
||||
#include <QMainWindow>
|
||||
#include <QThread>
|
||||
#include <QVector>
|
||||
|
||||
#include "ui_CMakeSetupDialog.h"
|
||||
|
||||
class QCMakePresetItemModel;
|
||||
class QCMakeThread;
|
||||
class CMakeCacheModel;
|
||||
class QProgressBar;
|
||||
@@ -33,6 +36,8 @@ public:
|
||||
public slots:
|
||||
void setBinaryDirectory(const QString& dir);
|
||||
void setSourceDirectory(const QString& dir);
|
||||
void setDeferredPreset(const QString& preset);
|
||||
void setStartupBinaryDirectory(bool startup);
|
||||
|
||||
protected slots:
|
||||
void initialize();
|
||||
@@ -52,6 +57,10 @@ protected slots:
|
||||
void doDeleteCache();
|
||||
void updateSourceDirectory(const QString& dir);
|
||||
void updateBinaryDirectory(const QString& dir);
|
||||
void updatePresets(const QVector<QCMakePreset>& presets);
|
||||
void updatePreset(const QString& name);
|
||||
void showPresetLoadError(const QString& dir,
|
||||
cmCMakePresetsFile::ReadFileResult result);
|
||||
void showProgress(const QString& msg, float percent);
|
||||
void setEnabledState(bool);
|
||||
bool setupFirstConfigure();
|
||||
@@ -62,6 +71,7 @@ protected slots:
|
||||
void saveBuildPaths(const QStringList&);
|
||||
void onBinaryDirectoryChanged(const QString& dir);
|
||||
void onSourceDirectoryChanged(const QString& dir);
|
||||
void onBuildPresetChanged(const QString& name);
|
||||
void setCacheModified();
|
||||
void removeSelectedCacheEntries();
|
||||
void selectionChanged();
|
||||
@@ -113,6 +123,8 @@ protected:
|
||||
QAction* WarnUninitializedAction;
|
||||
QAction* InstallForCommandLineAction;
|
||||
State CurrentState;
|
||||
QString DeferredPreset;
|
||||
bool StartupBinaryDirectory = false;
|
||||
|
||||
QTextCharFormat ErrorFormat;
|
||||
QTextCharFormat MessageFormat;
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<widget class="QLabel" name="SourceLabel">
|
||||
<property name="text">
|
||||
<string>Where is the source code:</string>
|
||||
</property>
|
||||
@@ -61,13 +61,23 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<widget class="QLabel" name="PresetLabel">
|
||||
<property name="text">
|
||||
<string>Preset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCMakePresetComboBox" name="Preset"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="BinaryLabel">
|
||||
<property name="text">
|
||||
<string>Where to build the binaries:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="BinaryDirectory">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
@@ -83,7 +93,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="BrowseBinaryDirectoryButton">
|
||||
<property name="text">
|
||||
<string>Browse &Build...</string>
|
||||
@@ -367,6 +377,11 @@
|
||||
<extends>QTreeView</extends>
|
||||
<header>QCMakeCacheView.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QCMakePresetComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>QCMakePresetComboBox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="CMakeSetup.qrc"/>
|
||||
|
||||
@@ -145,6 +145,36 @@ void StartCompilerSetup::setCurrentGenerator(const QString& gen)
|
||||
}
|
||||
}
|
||||
|
||||
void StartCompilerSetup::setPlatform(const QString& platform)
|
||||
{
|
||||
this->PlatformOptions->setCurrentText(platform);
|
||||
}
|
||||
|
||||
void StartCompilerSetup::setToolset(const QString& toolset)
|
||||
{
|
||||
this->Toolset->setText(toolset);
|
||||
}
|
||||
|
||||
void StartCompilerSetup::setCompilerOption(CompilerOption option)
|
||||
{
|
||||
std::size_t index = 0;
|
||||
switch (option) {
|
||||
case CompilerOption::DefaultNative:
|
||||
index = 0;
|
||||
break;
|
||||
case CompilerOption::SpecifyNative:
|
||||
index = 1;
|
||||
break;
|
||||
case CompilerOption::ToolchainFile:
|
||||
index = 2;
|
||||
break;
|
||||
case CompilerOption::Options:
|
||||
index = 3;
|
||||
break;
|
||||
}
|
||||
this->CompilerSetupOptions[index]->setChecked(true);
|
||||
}
|
||||
|
||||
QString StartCompilerSetup::getGenerator() const
|
||||
{
|
||||
return this->GeneratorOptions->currentText();
|
||||
@@ -482,6 +512,26 @@ void FirstConfigure::setGenerators(
|
||||
this->mStartCompilerSetupPage->setGenerators(gens);
|
||||
}
|
||||
|
||||
void FirstConfigure::setCurrentGenerator(const QString& gen)
|
||||
{
|
||||
this->mStartCompilerSetupPage->setCurrentGenerator(gen);
|
||||
}
|
||||
|
||||
void FirstConfigure::setPlatform(const QString& platform)
|
||||
{
|
||||
this->mStartCompilerSetupPage->setPlatform(platform);
|
||||
}
|
||||
|
||||
void FirstConfigure::setToolset(const QString& toolset)
|
||||
{
|
||||
this->mStartCompilerSetupPage->setToolset(toolset);
|
||||
}
|
||||
|
||||
void FirstConfigure::setCompilerOption(CompilerOption option)
|
||||
{
|
||||
this->mStartCompilerSetupPage->setCompilerOption(option);
|
||||
}
|
||||
|
||||
QString FirstConfigure::getGenerator() const
|
||||
{
|
||||
return this->mStartCompilerSetupPage->getGenerator();
|
||||
@@ -503,7 +553,7 @@ void FirstConfigure::loadFromSettings()
|
||||
// restore generator
|
||||
settings.beginGroup("Settings/StartPath");
|
||||
QString lastGen = settings.value("LastGenerator").toString();
|
||||
this->mStartCompilerSetupPage->setCurrentGenerator(lastGen);
|
||||
this->setCurrentGenerator(lastGen);
|
||||
settings.endGroup();
|
||||
|
||||
// restore compiler setup
|
||||
@@ -550,7 +600,7 @@ void FirstConfigure::loadFromSettings()
|
||||
// this prevents them from being taken from environment, while the
|
||||
// generator is taken from application settings
|
||||
if (!mDefaultGenerator.isEmpty()) {
|
||||
this->mStartCompilerSetupPage->setCurrentGenerator(mDefaultGenerator);
|
||||
this->setCurrentGenerator(mDefaultGenerator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,14 @@ enum FirstConfigurePages
|
||||
Done
|
||||
};
|
||||
|
||||
enum class CompilerOption
|
||||
{
|
||||
DefaultNative,
|
||||
SpecifyNative,
|
||||
ToolchainFile,
|
||||
Options,
|
||||
};
|
||||
|
||||
//! the first page that gives basic options for what compilers setup to choose
|
||||
//! from
|
||||
class StartCompilerSetup : public QWizardPage
|
||||
@@ -33,6 +41,9 @@ public:
|
||||
~StartCompilerSetup();
|
||||
void setGenerators(std::vector<cmake::GeneratorInfo> const& gens);
|
||||
void setCurrentGenerator(const QString& gen);
|
||||
void setToolset(const QString& toolset);
|
||||
void setPlatform(const QString& platform);
|
||||
void setCompilerOption(CompilerOption option);
|
||||
QString getGenerator() const;
|
||||
QString getToolset() const;
|
||||
QString getPlatform() const;
|
||||
@@ -167,6 +178,10 @@ public:
|
||||
~FirstConfigure();
|
||||
|
||||
void setGenerators(std::vector<cmake::GeneratorInfo> const& gens);
|
||||
void setCurrentGenerator(const QString& gen);
|
||||
void setToolset(const QString& toolset);
|
||||
void setPlatform(const QString& platform);
|
||||
void setCompilerOption(CompilerOption option);
|
||||
QString getGenerator() const;
|
||||
QString getPlatform() const;
|
||||
QString getToolset() const;
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "QCMake.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <cm/memory>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
#include "cmExternalMakefileProjectGenerator.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
@@ -19,12 +23,15 @@
|
||||
|
||||
QCMake::QCMake(QObject* p)
|
||||
: QObject(p)
|
||||
, StartEnvironment(QProcessEnvironment::systemEnvironment())
|
||||
, Environment(QProcessEnvironment::systemEnvironment())
|
||||
{
|
||||
this->WarnUninitializedMode = false;
|
||||
qRegisterMetaType<QCMakeProperty>();
|
||||
qRegisterMetaType<QCMakePropertyList>();
|
||||
qRegisterMetaType<QProcessEnvironment>();
|
||||
qRegisterMetaType<QVector<QCMakePreset>>();
|
||||
qRegisterMetaType<cmCMakePresetsFile::ReadFileResult>();
|
||||
|
||||
cmSystemTools::DisableRunCommandOutput();
|
||||
cmSystemTools::SetRunCommandHideConsole(true);
|
||||
@@ -57,6 +64,17 @@ QCMake::QCMake(QObject* p)
|
||||
for (cmake::GeneratorInfo const& gen : generators) {
|
||||
this->AvailableGenerators.push_back(gen);
|
||||
}
|
||||
|
||||
connect(&this->LoadPresetsTimer, &QTimer::timeout, this, [this]() {
|
||||
this->loadPresets();
|
||||
if (!this->PresetName.isEmpty() &&
|
||||
this->CMakePresetsFile.Presets.find(
|
||||
std::string(this->PresetName.toLocal8Bit())) ==
|
||||
this->CMakePresetsFile.Presets.end()) {
|
||||
this->setPreset(QString{});
|
||||
}
|
||||
});
|
||||
this->LoadPresetsTimer.start(1000);
|
||||
}
|
||||
|
||||
QCMake::~QCMake() = default;
|
||||
@@ -73,6 +91,8 @@ void QCMake::setSourceDirectory(const QString& _dir)
|
||||
if (this->SourceDirectory != dir) {
|
||||
this->SourceDirectory = QDir::fromNativeSeparators(dir);
|
||||
emit this->sourceDirChanged(this->SourceDirectory);
|
||||
this->loadPresets();
|
||||
this->setPreset(QString{});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +149,56 @@ void QCMake::setBinaryDirectory(const QString& _dir)
|
||||
}
|
||||
}
|
||||
|
||||
void QCMake::setPreset(const QString& name, bool setBinary)
|
||||
{
|
||||
if (this->PresetName != name) {
|
||||
this->PresetName = name;
|
||||
emit this->presetChanged(this->PresetName);
|
||||
|
||||
if (!name.isNull()) {
|
||||
std::string presetName(name.toLocal8Bit());
|
||||
auto const& preset = this->CMakePresetsFile.Presets[presetName];
|
||||
auto expandedPreset = this->CMakePresetsFile.ExpandMacros(preset);
|
||||
if (expandedPreset) {
|
||||
if (setBinary) {
|
||||
QString binaryDir =
|
||||
QString::fromLocal8Bit(expandedPreset->BinaryDir.data());
|
||||
this->setBinaryDirectory(binaryDir);
|
||||
}
|
||||
if (expandedPreset->WarnDev) {
|
||||
this->CMakeInstance->SetSuppressDevWarnings(
|
||||
!*expandedPreset->WarnDev);
|
||||
}
|
||||
if (expandedPreset->ErrorDev) {
|
||||
this->CMakeInstance->SetDevWarningsAsErrors(
|
||||
*expandedPreset->ErrorDev);
|
||||
}
|
||||
if (expandedPreset->WarnDeprecated) {
|
||||
this->CMakeInstance->SetSuppressDeprecatedWarnings(
|
||||
!*expandedPreset->WarnDeprecated);
|
||||
}
|
||||
if (expandedPreset->ErrorDeprecated) {
|
||||
this->CMakeInstance->SetDeprecatedWarningsAsErrors(
|
||||
*expandedPreset->ErrorDeprecated);
|
||||
}
|
||||
if (expandedPreset->WarnUninitialized) {
|
||||
this->WarnUninitializedMode = *expandedPreset->WarnUninitialized;
|
||||
emit this->warnUninitializedModeChanged(
|
||||
*expandedPreset->WarnUninitialized);
|
||||
}
|
||||
this->Environment = this->StartEnvironment;
|
||||
for (auto const& v : expandedPreset->Environment) {
|
||||
if (v.second) {
|
||||
this->Environment.insert(QString::fromLocal8Bit(v.first.data()),
|
||||
QString::fromLocal8Bit(v.second->data()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
emit this->propertiesChanged(this->properties());
|
||||
}
|
||||
}
|
||||
|
||||
void QCMake::setGenerator(const QString& gen)
|
||||
{
|
||||
if (this->Generator != gen) {
|
||||
@@ -348,6 +418,56 @@ QCMakePropertyList QCMake::properties() const
|
||||
ret.append(prop);
|
||||
}
|
||||
|
||||
if (!this->PresetName.isNull()) {
|
||||
std::string presetName(this->PresetName.toLocal8Bit());
|
||||
auto p = this->CMakePresetsFile.ExpandMacros(
|
||||
this->CMakePresetsFile.Presets.at(presetName));
|
||||
if (p) {
|
||||
for (auto const& v : p->CacheVariables) {
|
||||
if (!v.second) {
|
||||
continue;
|
||||
}
|
||||
QCMakeProperty prop;
|
||||
prop.Key = QString::fromLocal8Bit(v.first.data());
|
||||
prop.Value = QString::fromLocal8Bit(v.second->Value.data());
|
||||
prop.Type = QCMakeProperty::STRING;
|
||||
if (!v.second->Type.empty()) {
|
||||
auto type = cmState::StringToCacheEntryType(v.second->Type);
|
||||
switch (type) {
|
||||
case cmStateEnums::BOOL:
|
||||
prop.Type = QCMakeProperty::BOOL;
|
||||
prop.Value = cmIsOn(v.second->Value);
|
||||
break;
|
||||
case cmStateEnums::PATH:
|
||||
prop.Type = QCMakeProperty::PATH;
|
||||
break;
|
||||
case cmStateEnums::FILEPATH:
|
||||
prop.Type = QCMakeProperty::FILEPATH;
|
||||
break;
|
||||
default:
|
||||
prop.Type = QCMakeProperty::STRING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// QCMakeCacheModel prefers variables earlier in the list rather than
|
||||
// later, so overwrite them if they already exist rather than simply
|
||||
// appending
|
||||
bool found = false;
|
||||
for (auto& orig : ret) {
|
||||
if (orig.Key == prop.Key) {
|
||||
orig = prop;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
ret.append(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -405,6 +525,46 @@ void QCMake::setUpEnvironment() const
|
||||
}
|
||||
}
|
||||
|
||||
void QCMake::loadPresets()
|
||||
{
|
||||
auto result = this->CMakePresetsFile.ReadProjectPresets(
|
||||
this->SourceDirectory.toLocal8Bit().data(), true);
|
||||
if (result != this->LastLoadPresetsResult &&
|
||||
result != cmCMakePresetsFile::ReadFileResult::READ_OK) {
|
||||
emit this->presetLoadError(this->SourceDirectory, result);
|
||||
}
|
||||
this->LastLoadPresetsResult = result;
|
||||
|
||||
QVector<QCMakePreset> presets;
|
||||
for (auto const& name : this->CMakePresetsFile.PresetOrder) {
|
||||
auto const& p = this->CMakePresetsFile.Presets[name];
|
||||
if (p.Hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QCMakePreset preset;
|
||||
preset.name = std::move(QString::fromLocal8Bit(p.Name.data()));
|
||||
preset.displayName =
|
||||
std::move(QString::fromLocal8Bit(p.DisplayName.data()));
|
||||
preset.description =
|
||||
std::move(QString::fromLocal8Bit(p.Description.data()));
|
||||
preset.generator = std::move(QString::fromLocal8Bit(p.Generator.data()));
|
||||
preset.architecture =
|
||||
std::move(QString::fromLocal8Bit(p.Architecture.data()));
|
||||
preset.toolset = std::move(QString::fromLocal8Bit(p.Toolset.data()));
|
||||
preset.setGenConfig = !p.GeneratorConfig ||
|
||||
p.GeneratorConfig == cmCMakePresetsFile::CMakeGeneratorConfig::Default;
|
||||
preset.enabled = std::find_if(this->AvailableGenerators.begin(),
|
||||
this->AvailableGenerators.end(),
|
||||
[&p](const cmake::GeneratorInfo& g) {
|
||||
return g.name == p.Generator;
|
||||
}) != this->AvailableGenerators.end() &&
|
||||
this->CMakePresetsFile.ExpandMacros(p);
|
||||
presets.push_back(preset);
|
||||
}
|
||||
emit this->presetsChanged(presets);
|
||||
}
|
||||
|
||||
QString QCMake::binaryDirectory() const
|
||||
{
|
||||
return this->BinaryDirectory;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include "cmCMakePresetsFile.h"
|
||||
#include "cmake.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -14,6 +15,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "QCMakePreset.h"
|
||||
#include <QAtomicInt>
|
||||
#include <QList>
|
||||
#include <QMetaType>
|
||||
@@ -21,6 +23,7 @@
|
||||
#include <QProcessEnvironment>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QTimer>
|
||||
#include <QVariant>
|
||||
|
||||
/// struct to represent cmake properties in Qt
|
||||
@@ -57,6 +60,7 @@ using QCMakePropertyList = QList<QCMakeProperty>;
|
||||
Q_DECLARE_METATYPE(QCMakeProperty)
|
||||
Q_DECLARE_METATYPE(QCMakePropertyList)
|
||||
Q_DECLARE_METATYPE(QProcessEnvironment)
|
||||
Q_DECLARE_METATYPE(cmCMakePresetsFile::ReadFileResult)
|
||||
|
||||
/// Qt API for CMake library.
|
||||
/// Wrapper like class allows for easier integration with
|
||||
@@ -74,6 +78,8 @@ public slots:
|
||||
void setSourceDirectory(const QString& dir);
|
||||
/// set the binary directory to build in
|
||||
void setBinaryDirectory(const QString& dir);
|
||||
/// set the preset name to use
|
||||
void setPreset(const QString& name, bool setBinary = true);
|
||||
/// set the desired generator to use
|
||||
void setGenerator(const QString& generator);
|
||||
/// set the desired generator to use
|
||||
@@ -147,6 +153,15 @@ signals:
|
||||
void sourceDirChanged(const QString& dir);
|
||||
/// signal when the binary directory changes
|
||||
void binaryDirChanged(const QString& dir);
|
||||
/// signal when the preset list changes
|
||||
void presetsChanged(const QVector<QCMakePreset>& presets);
|
||||
/// signal when the selected preset changes
|
||||
void presetChanged(const QString& name);
|
||||
/// signal when there's an error reading the presets files
|
||||
void presetLoadError(const QString& dir,
|
||||
cmCMakePresetsFile::ReadFileResult error);
|
||||
/// signal when uninitialized warning changes
|
||||
void warnUninitializedModeChanged(bool value);
|
||||
/// signal for progress events
|
||||
void progressChanged(const QString& msg, float percent);
|
||||
/// signal when configure is done
|
||||
@@ -178,6 +193,8 @@ protected:
|
||||
void stderrCallback(std::string const& msg);
|
||||
void setUpEnvironment() const;
|
||||
|
||||
void loadPresets();
|
||||
|
||||
bool WarnUninitializedMode;
|
||||
QString SourceDirectory;
|
||||
QString BinaryDirectory;
|
||||
@@ -185,7 +202,13 @@ protected:
|
||||
QString Platform;
|
||||
QString Toolset;
|
||||
std::vector<cmake::GeneratorInfo> AvailableGenerators;
|
||||
cmCMakePresetsFile CMakePresetsFile;
|
||||
cmCMakePresetsFile::ReadFileResult LastLoadPresetsResult =
|
||||
cmCMakePresetsFile::ReadFileResult::READ_OK;
|
||||
QString PresetName;
|
||||
QString CMakeExecutable;
|
||||
QAtomicInt InterruptFlag;
|
||||
QProcessEnvironment StartEnvironment;
|
||||
QProcessEnvironment Environment;
|
||||
QTimer LoadPresetsTimer;
|
||||
};
|
||||
|
||||
50
Source/QtDialog/QCMakePreset.cxx
Normal file
50
Source/QtDialog/QCMakePreset.cxx
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "QCMakePreset.h"
|
||||
|
||||
bool operator==(const QCMakePreset& lhs, const QCMakePreset& rhs)
|
||||
{
|
||||
return lhs.name == rhs.name && lhs.displayName == rhs.displayName &&
|
||||
lhs.description == rhs.description && lhs.generator == rhs.generator &&
|
||||
lhs.architecture == rhs.architecture && lhs.toolset == rhs.toolset &&
|
||||
lhs.setGenConfig == rhs.setGenConfig && lhs.enabled == rhs.enabled;
|
||||
}
|
||||
|
||||
bool operator!=(const QCMakePreset& lhs, const QCMakePreset& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator<(const QCMakePreset& lhs, const QCMakePreset& rhs)
|
||||
{
|
||||
return lhs.name < rhs.name ||
|
||||
(lhs.name == rhs.name &&
|
||||
(lhs.displayName < rhs.displayName ||
|
||||
(lhs.displayName == rhs.displayName &&
|
||||
(lhs.description < rhs.description ||
|
||||
(lhs.description == rhs.description &&
|
||||
(lhs.generator < rhs.generator ||
|
||||
(lhs.generator == rhs.generator &&
|
||||
(lhs.architecture < rhs.architecture ||
|
||||
(lhs.architecture == rhs.architecture &&
|
||||
(lhs.toolset < rhs.toolset ||
|
||||
(lhs.toolset == rhs.toolset &&
|
||||
(lhs.setGenConfig < rhs.setGenConfig ||
|
||||
(lhs.setGenConfig == rhs.setGenConfig &&
|
||||
(lhs.enabled < rhs.enabled))))))))))))));
|
||||
}
|
||||
|
||||
bool operator<=(const QCMakePreset& lhs, const QCMakePreset& rhs)
|
||||
{
|
||||
return rhs >= lhs;
|
||||
}
|
||||
|
||||
bool operator>(const QCMakePreset& lhs, const QCMakePreset& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
bool operator>=(const QCMakePreset& lhs, const QCMakePreset& rhs)
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
30
Source/QtDialog/QCMakePreset.h
Normal file
30
Source/QtDialog/QCMakePreset.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
#include "cmCMakePresetsFile.h"
|
||||
|
||||
class QCMakePreset
|
||||
{
|
||||
public:
|
||||
QString name;
|
||||
QString displayName;
|
||||
QString description;
|
||||
QString generator;
|
||||
QString architecture;
|
||||
QString toolset;
|
||||
bool setGenConfig;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
bool operator==(const QCMakePreset& lhs, const QCMakePreset& rhs);
|
||||
bool operator!=(const QCMakePreset& lhs, const QCMakePreset& rhs);
|
||||
bool operator<(const QCMakePreset& lhs, const QCMakePreset& rhs);
|
||||
bool operator<=(const QCMakePreset& lhs, const QCMakePreset& rhs);
|
||||
bool operator>(const QCMakePreset& lhs, const QCMakePreset& rhs);
|
||||
bool operator>=(const QCMakePreset& lhs, const QCMakePreset& rhs);
|
||||
|
||||
Q_DECLARE_METATYPE(QCMakePreset)
|
||||
64
Source/QtDialog/QCMakePresetComboBox.cxx
Normal file
64
Source/QtDialog/QCMakePresetComboBox.cxx
Normal file
@@ -0,0 +1,64 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "QCMakePresetComboBox.h"
|
||||
|
||||
#include "QCMakePresetItemModel.h"
|
||||
|
||||
QCMakePresetComboBox::QCMakePresetComboBox(QWidget* parent)
|
||||
: QComboBox(parent)
|
||||
{
|
||||
this->m_model = new QCMakePresetItemModel(this);
|
||||
this->setModel(this->m_model);
|
||||
|
||||
QObject::connect(this->m_model, &QCMakePresetItemModel::modelAboutToBeReset,
|
||||
this, [this]() { this->m_resetting = true; });
|
||||
QObject::connect(this->m_model, &QCMakePresetItemModel::modelReset, this,
|
||||
[this]() {
|
||||
this->setPresetName(this->m_lastPreset);
|
||||
this->m_resetting = false;
|
||||
this->emitPresetChanged();
|
||||
});
|
||||
QObject::connect(
|
||||
this,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, [this](int /*row*/) {
|
||||
if (!this->m_resetting) {
|
||||
this->emitPresetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const QVector<QCMakePreset>& QCMakePresetComboBox::presets() const
|
||||
{
|
||||
return this->m_model->presets();
|
||||
}
|
||||
|
||||
QString QCMakePresetComboBox::presetName() const
|
||||
{
|
||||
auto preset = this->currentData();
|
||||
if (preset.canConvert<QCMakePreset>()) {
|
||||
return preset.value<QCMakePreset>().name;
|
||||
}
|
||||
return QString{};
|
||||
}
|
||||
|
||||
void QCMakePresetComboBox::setPresets(const QVector<QCMakePreset>& presets)
|
||||
{
|
||||
this->m_model->setPresets(presets);
|
||||
}
|
||||
|
||||
void QCMakePresetComboBox::setPresetName(const QString& name)
|
||||
{
|
||||
this->setCurrentIndex(this->m_model->presetNameToRow(name));
|
||||
if (this->signalsBlocked()) {
|
||||
this->m_lastPreset = this->presetName();
|
||||
}
|
||||
}
|
||||
|
||||
void QCMakePresetComboBox::emitPresetChanged()
|
||||
{
|
||||
if (this->presetName() != this->m_lastPreset) {
|
||||
emit this->presetChanged(this->presetName());
|
||||
this->m_lastPreset = this->presetName();
|
||||
}
|
||||
}
|
||||
35
Source/QtDialog/QCMakePresetComboBox.h
Normal file
35
Source/QtDialog/QCMakePresetComboBox.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "QCMakePreset.h"
|
||||
#include <QComboBox>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
class QCMakePresetItemModel;
|
||||
|
||||
class QCMakePresetComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCMakePresetComboBox(QWidget* parent = nullptr);
|
||||
|
||||
const QVector<QCMakePreset>& presets() const;
|
||||
QString presetName() const;
|
||||
|
||||
public slots:
|
||||
void setPresets(const QVector<QCMakePreset>& presets);
|
||||
void setPresetName(const QString& name);
|
||||
|
||||
signals:
|
||||
void presetChanged(const QString& name);
|
||||
|
||||
private:
|
||||
QCMakePresetItemModel* m_model;
|
||||
bool m_resetting = false;
|
||||
QString m_lastPreset;
|
||||
|
||||
void emitPresetChanged();
|
||||
};
|
||||
143
Source/QtDialog/QCMakePresetItemModel.cxx
Normal file
143
Source/QtDialog/QCMakePresetItemModel.cxx
Normal file
@@ -0,0 +1,143 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "QCMakePresetItemModel.h"
|
||||
|
||||
#include <QFont>
|
||||
|
||||
QCMakePresetItemModel::QCMakePresetItemModel(QObject* parent)
|
||||
: QAbstractItemModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant QCMakePresetItemModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::AccessibleDescriptionRole:
|
||||
// Separators have to return "separator" for the
|
||||
// AccessibleDescriptionRole. This was determined by looking at
|
||||
// QComboBoxDelegate::isSeparator() (located in qcombobox_p.h.)
|
||||
if (index.internalId() == SEPARATOR_INDEX) {
|
||||
return QString::fromLocal8Bit("separator");
|
||||
}
|
||||
return QString{};
|
||||
case Qt::DisplayRole: {
|
||||
if (index.internalId() == CUSTOM_INDEX) {
|
||||
return QString::fromLocal8Bit("<custom>");
|
||||
}
|
||||
if (index.internalId() == SEPARATOR_INDEX) {
|
||||
return QVariant{};
|
||||
}
|
||||
auto const& preset = this->m_presets[index.internalId()];
|
||||
return preset.displayName.isEmpty() ? preset.name : preset.displayName;
|
||||
}
|
||||
case Qt::ToolTipRole:
|
||||
if (index.internalId() == CUSTOM_INDEX) {
|
||||
return QString::fromLocal8Bit("Specify all settings manually");
|
||||
}
|
||||
if (index.internalId() == SEPARATOR_INDEX) {
|
||||
return QVariant{};
|
||||
}
|
||||
return this->m_presets[index.internalId()].description;
|
||||
case Qt::UserRole:
|
||||
if (index.internalId() == CUSTOM_INDEX) {
|
||||
return QVariant{};
|
||||
}
|
||||
if (index.internalId() == SEPARATOR_INDEX) {
|
||||
return QVariant{};
|
||||
}
|
||||
return QVariant::fromValue(this->m_presets[index.internalId()]);
|
||||
case Qt::FontRole:
|
||||
if (index.internalId() == CUSTOM_INDEX) {
|
||||
QFont font;
|
||||
font.setItalic(true);
|
||||
return font;
|
||||
}
|
||||
return QFont{};
|
||||
default:
|
||||
return QVariant{};
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ItemFlags QCMakePresetItemModel::flags(const QModelIndex& index) const
|
||||
{
|
||||
Qt::ItemFlags flags =
|
||||
Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
|
||||
if (index.internalId() != SEPARATOR_INDEX &&
|
||||
(index.internalId() == CUSTOM_INDEX ||
|
||||
this->m_presets[index.internalId()].enabled)) {
|
||||
flags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
int QCMakePresetItemModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
if (this->m_presets.empty()) {
|
||||
return 1;
|
||||
}
|
||||
return this->m_presets.size() + 2;
|
||||
}
|
||||
|
||||
int QCMakePresetItemModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
QModelIndex QCMakePresetItemModel::index(int row, int column,
|
||||
const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid() || column != 0 || row < 0 ||
|
||||
row >= this->rowCount(QModelIndex{})) {
|
||||
return QModelIndex{};
|
||||
}
|
||||
|
||||
if (this->m_presets.empty() || row == this->m_presets.size() + 1) {
|
||||
return this->createIndex(row, column, CUSTOM_INDEX);
|
||||
}
|
||||
|
||||
if (row == this->m_presets.size()) {
|
||||
return this->createIndex(row, column, SEPARATOR_INDEX);
|
||||
}
|
||||
|
||||
return this->createIndex(row, column, static_cast<quintptr>(row));
|
||||
}
|
||||
|
||||
QModelIndex QCMakePresetItemModel::parent(const QModelIndex& /*index*/) const
|
||||
{
|
||||
return QModelIndex{};
|
||||
}
|
||||
|
||||
QVector<QCMakePreset> const& QCMakePresetItemModel::presets() const
|
||||
{
|
||||
return this->m_presets;
|
||||
}
|
||||
|
||||
void QCMakePresetItemModel::setPresets(QVector<QCMakePreset> const& presets)
|
||||
{
|
||||
this->beginResetModel();
|
||||
this->m_presets = presets;
|
||||
this->endResetModel();
|
||||
}
|
||||
|
||||
int QCMakePresetItemModel::presetNameToRow(const QString& name) const
|
||||
{
|
||||
if (this->m_presets.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (auto const& preset : this->m_presets) {
|
||||
if (preset.name == name) {
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return this->m_presets.size() + 1;
|
||||
}
|
||||
45
Source/QtDialog/QCMakePresetItemModel.h
Normal file
45
Source/QtDialog/QCMakePresetItemModel.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
#include "QCMakePreset.h"
|
||||
#include <QAbstractItemModel>
|
||||
#include <QModelIndex>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
#include <QtGlobal>
|
||||
|
||||
class QObject;
|
||||
|
||||
class QCMakePresetItemModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCMakePresetItemModel(QObject* parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex& index, int role) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex{}) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex{}) const override;
|
||||
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex& parent = QModelIndex{}) const override;
|
||||
QModelIndex parent(const QModelIndex& index) const override;
|
||||
|
||||
QVector<QCMakePreset> const& presets() const;
|
||||
|
||||
int presetNameToRow(const QString& name) const;
|
||||
|
||||
public slots:
|
||||
void setPresets(QVector<QCMakePreset> const& presets);
|
||||
|
||||
private:
|
||||
QVector<QCMakePreset> m_presets;
|
||||
|
||||
static constexpr quintptr SEPARATOR_INDEX = static_cast<quintptr>(-2);
|
||||
static constexpr quintptr CUSTOM_INDEX = static_cast<quintptr>(-1);
|
||||
};
|
||||
@@ -27,6 +27,10 @@ function(run_cmake_gui_test name)
|
||||
if(EXISTS "${_cmakelists_in}")
|
||||
configure_file("${_cmakelists_in}" "${_workdir}/src/CMakeLists.txt" @ONLY)
|
||||
endif()
|
||||
set(_cmakepresets_in "${_srcdir}/CMakePresets.json.in")
|
||||
if(EXISTS "${_cmakepresets_in}")
|
||||
configure_file("${_cmakepresets_in}" "${_workdir}/src/CMakePresets.json" @ONLY)
|
||||
endif()
|
||||
if(_rcgt_DO_CONFIGURE)
|
||||
if(NOT _rcgt_GENERATOR)
|
||||
set(_rcgt_GENERATOR "${CMakeGUITest_GENERATOR}")
|
||||
@@ -118,3 +122,37 @@ set(ENV{KEPT_VARIABLE} "Kept variable")
|
||||
set(ENV{CHANGED_VARIABLE} "This variable will be changed")
|
||||
set(ENV{REMOVED_VARIABLE} "Removed variable")
|
||||
run_cmake_gui_test(environment)
|
||||
|
||||
run_cmake_gui_test(presetArg:preset
|
||||
ARGS
|
||||
-S "${CMakeGUITest_BINARY_DIR}/presetArg-preset/src"
|
||||
"--preset=ninja"
|
||||
)
|
||||
run_cmake_gui_test(presetArg:presetBinary
|
||||
ARGS
|
||||
-S "${CMakeGUITest_BINARY_DIR}/presetArg-presetBinary/src"
|
||||
-B "${CMakeGUITest_BINARY_DIR}/presetArg-presetBinary/build"
|
||||
"--preset=ninja"
|
||||
)
|
||||
run_cmake_gui_test(presetArg:presetBinaryChange
|
||||
ARGS
|
||||
-S "${CMakeGUITest_BINARY_DIR}/presetArg-presetBinaryChange/src"
|
||||
-B "${CMakeGUITest_BINARY_DIR}/presetArg-presetBinaryChange/build"
|
||||
"--preset=ninja"
|
||||
)
|
||||
run_cmake_gui_test(presetArg:noPresetBinaryChange
|
||||
ARGS
|
||||
-S "${CMakeGUITest_BINARY_DIR}/presetArg-noPresetBinaryChange/src"
|
||||
-B "${CMakeGUITest_BINARY_DIR}/presetArg-noPresetBinaryChange/build"
|
||||
)
|
||||
run_cmake_gui_test(presetArg:presetConfigExists
|
||||
ARGS
|
||||
-S "${CMakeGUITest_BINARY_DIR}/presetArg-presetConfigExists/src"
|
||||
"--preset=ninja"
|
||||
)
|
||||
run_cmake_gui_test(presetArg:noExist
|
||||
ARGS
|
||||
-S "${CMakeGUITest_BINARY_DIR}/presetArg-noExist/src"
|
||||
"--preset=noExist"
|
||||
)
|
||||
run_cmake_gui_test(changingPresets)
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#include "QCMake.h"
|
||||
#include <QApplication>
|
||||
#include <QEventLoop>
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QMessageBox>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
@@ -18,6 +22,9 @@
|
||||
#include "CatchShow.h"
|
||||
#include "FirstConfigure.h"
|
||||
|
||||
using WindowSetupHelper = std::function<void(CMakeSetupDialog*)>;
|
||||
Q_DECLARE_METATYPE(WindowSetupHelper)
|
||||
|
||||
namespace {
|
||||
void loopSleep(int msecs = 500)
|
||||
{
|
||||
@@ -172,6 +179,264 @@ void CMakeGUITest::environment()
|
||||
QCOMPARE(penv.value("REMOVED_VARIABLE"), "Removed variable");
|
||||
}
|
||||
|
||||
void CMakeGUITest::presetArg()
|
||||
{
|
||||
QFETCH(WindowSetupHelper, setupFunction);
|
||||
QFETCH(QString, presetName);
|
||||
QFETCH(QString, sourceDir);
|
||||
QFETCH(QString, binaryDir);
|
||||
QFETCH(QCMakePropertyList, properties);
|
||||
|
||||
if (setupFunction) {
|
||||
setupFunction(this->m_window);
|
||||
}
|
||||
|
||||
// Wait a bit for everything to update
|
||||
loopSleep();
|
||||
|
||||
QCOMPARE(this->m_window->Preset->presetName(), presetName);
|
||||
QCOMPARE(this->m_window->SourceDirectory->text(), sourceDir);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(), binaryDir);
|
||||
|
||||
auto actualProperties =
|
||||
this->m_window->CacheValues->cacheModel()->properties();
|
||||
QCOMPARE(actualProperties.size(), properties.size());
|
||||
for (int i = 0; i < actualProperties.size(); ++i) {
|
||||
// operator==() only compares Key, we need to compare Value and Type too
|
||||
QCOMPARE(actualProperties[i].Key, properties[i].Key);
|
||||
QCOMPARE(actualProperties[i].Value, properties[i].Value);
|
||||
QCOMPARE(actualProperties[i].Type, properties[i].Type);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
QCMakePropertyList makePresetProperties(const QString& name)
|
||||
{
|
||||
return QCMakePropertyList{
|
||||
QCMakeProperty{
|
||||
/*Key=*/"FALSE_VARIABLE",
|
||||
/*Value=*/false,
|
||||
/*Strings=*/{},
|
||||
/*Help=*/"",
|
||||
/*Type=*/QCMakeProperty::BOOL,
|
||||
/*Advanced=*/false,
|
||||
},
|
||||
QCMakeProperty{
|
||||
/*Key=*/"FILEPATH_VARIABLE",
|
||||
/*Value=*/
|
||||
QString::fromLocal8Bit(CMakeGUITest_BINARY_DIR "/%1/src/CMakeLists.txt")
|
||||
.arg(name),
|
||||
/*Strings=*/{},
|
||||
/*Help=*/"",
|
||||
/*Type=*/QCMakeProperty::FILEPATH,
|
||||
/*Advanced=*/false,
|
||||
},
|
||||
QCMakeProperty{
|
||||
/*Key=*/"ON_VARIABLE",
|
||||
/*Value=*/true,
|
||||
/*Strings=*/{},
|
||||
/*Help=*/"",
|
||||
/*Type=*/QCMakeProperty::BOOL,
|
||||
/*Advanced=*/false,
|
||||
},
|
||||
QCMakeProperty{
|
||||
/*Key=*/"PATH_VARIABLE",
|
||||
/*Value=*/
|
||||
QString::fromLocal8Bit(CMakeGUITest_BINARY_DIR "/%1/src").arg(name),
|
||||
/*Strings=*/{},
|
||||
/*Help=*/"",
|
||||
/*Type=*/QCMakeProperty::PATH,
|
||||
/*Advanced=*/false,
|
||||
},
|
||||
QCMakeProperty{
|
||||
/*Key=*/"STRING_VARIABLE",
|
||||
/*Value=*/"String value",
|
||||
/*Strings=*/{},
|
||||
/*Help=*/"",
|
||||
/*Type=*/QCMakeProperty::STRING,
|
||||
/*Advanced=*/false,
|
||||
},
|
||||
QCMakeProperty{
|
||||
/*Key=*/"UNINITIALIZED_VARIABLE",
|
||||
/*Value=*/"Uninitialized value",
|
||||
/*Strings=*/{},
|
||||
/*Help=*/"",
|
||||
/*Type=*/QCMakeProperty::STRING,
|
||||
/*Advanced=*/false,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeGUITest::presetArg_data()
|
||||
{
|
||||
QTest::addColumn<WindowSetupHelper>("setupFunction");
|
||||
QTest::addColumn<QString>("presetName");
|
||||
QTest::addColumn<QString>("sourceDir");
|
||||
QTest::addColumn<QString>("binaryDir");
|
||||
QTest::addColumn<QCMakePropertyList>("properties");
|
||||
|
||||
QTest::newRow("preset") << WindowSetupHelper{} << "ninja"
|
||||
<< CMakeGUITest_BINARY_DIR "/presetArg-preset/src"
|
||||
<< CMakeGUITest_BINARY_DIR
|
||||
"/presetArg-preset/src/build"
|
||||
<< makePresetProperties("presetArg-preset");
|
||||
QTest::newRow("presetBinary")
|
||||
<< WindowSetupHelper{} << "ninja"
|
||||
<< CMakeGUITest_BINARY_DIR "/presetArg-presetBinary/src"
|
||||
<< CMakeGUITest_BINARY_DIR "/presetArg-presetBinary/build"
|
||||
<< makePresetProperties("presetArg-presetBinary");
|
||||
QTest::newRow("presetBinaryChange")
|
||||
<< WindowSetupHelper{ [](CMakeSetupDialog* window) {
|
||||
loopSleep();
|
||||
window->Preset->setPresetName("ninja2");
|
||||
} }
|
||||
<< "ninja2" << CMakeGUITest_BINARY_DIR "/presetArg-presetBinaryChange/src"
|
||||
<< CMakeGUITest_BINARY_DIR "/presetArg-presetBinaryChange/src/build"
|
||||
<< makePresetProperties("presetArg-presetBinaryChange");
|
||||
QTest::newRow("noPresetBinaryChange")
|
||||
<< WindowSetupHelper{ [](CMakeSetupDialog* window) {
|
||||
loopSleep();
|
||||
window->Preset->setPresetName("ninja");
|
||||
} }
|
||||
<< "ninja" << CMakeGUITest_BINARY_DIR "/presetArg-noPresetBinaryChange/src"
|
||||
<< CMakeGUITest_BINARY_DIR "/presetArg-noPresetBinaryChange/src/build"
|
||||
<< makePresetProperties("presetArg-noPresetBinaryChange");
|
||||
QTest::newRow("presetConfigExists")
|
||||
<< WindowSetupHelper{} << "ninja"
|
||||
<< CMakeGUITest_BINARY_DIR "/presetArg-presetConfigExists/src"
|
||||
<< CMakeGUITest_BINARY_DIR "/presetArg-presetConfigExists/src/build"
|
||||
<< makePresetProperties("presetArg-presetConfigExists");
|
||||
QTest::newRow("noExist") << WindowSetupHelper{} << QString{}
|
||||
<< CMakeGUITest_BINARY_DIR "/presetArg-noExist/src"
|
||||
<< "" << QCMakePropertyList{};
|
||||
}
|
||||
|
||||
namespace {
|
||||
void writePresets(const QString& buildDir, const QStringList& names)
|
||||
{
|
||||
QJsonArray presets{
|
||||
QJsonObject{
|
||||
{ "name", "base" },
|
||||
{ "generator", "Ninja" },
|
||||
{ "binaryDir",
|
||||
QString::fromLocal8Bit("${sourceDir}/%1/${presetName}")
|
||||
.arg(buildDir) },
|
||||
{ "hidden", true },
|
||||
},
|
||||
};
|
||||
|
||||
for (auto const& name : names) {
|
||||
presets.append(QJsonObject{
|
||||
{ "name", name },
|
||||
{ "inherits", QJsonArray{ "base" } },
|
||||
});
|
||||
}
|
||||
|
||||
QJsonDocument doc{ QJsonObject{
|
||||
{ "version", 1 },
|
||||
{ "configurePresets", presets },
|
||||
} };
|
||||
|
||||
QFile presetsFile(CMakeGUITest_BINARY_DIR
|
||||
"/changingPresets/src/CMakePresets.json");
|
||||
bool open = presetsFile.open(QIODevice::WriteOnly);
|
||||
Q_ASSERT(open);
|
||||
presetsFile.write(doc.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeGUITest::changingPresets()
|
||||
{
|
||||
QDir::root().mkpath(CMakeGUITest_BINARY_DIR "/changingPresets/src");
|
||||
|
||||
this->m_window->SourceDirectory->setText(CMakeGUITest_BINARY_DIR
|
||||
"/changingPresets/src");
|
||||
loopSleep();
|
||||
QCOMPARE(this->m_window->Preset->presetName(), QString{});
|
||||
QCOMPARE(this->m_window->Preset->presets().size(), 0);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(), "");
|
||||
QCOMPARE(this->m_window->Preset->isHidden(), true);
|
||||
QCOMPARE(this->m_window->PresetLabel->isHidden(), true);
|
||||
|
||||
writePresets("build1", { "preset" });
|
||||
loopSleep(1500);
|
||||
QCOMPARE(this->m_window->Preset->presetName(), QString{});
|
||||
QCOMPARE(this->m_window->Preset->presets().size(), 1);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(), "");
|
||||
QCOMPARE(this->m_window->Preset->isHidden(), false);
|
||||
QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
|
||||
|
||||
this->m_window->Preset->setPresetName("preset");
|
||||
loopSleep();
|
||||
QCOMPARE(this->m_window->Preset->presetName(), "preset");
|
||||
QCOMPARE(this->m_window->Preset->presets().size(), 1);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(),
|
||||
CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset");
|
||||
QCOMPARE(this->m_window->Preset->isHidden(), false);
|
||||
QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
|
||||
|
||||
writePresets("build2", { "preset2", "preset" });
|
||||
loopSleep(1500);
|
||||
QCOMPARE(this->m_window->Preset->presetName(), "preset");
|
||||
QCOMPARE(this->m_window->Preset->presets().size(), 2);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(),
|
||||
CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset");
|
||||
QCOMPARE(this->m_window->Preset->isHidden(), false);
|
||||
QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
|
||||
|
||||
writePresets("build3", { "preset2" });
|
||||
loopSleep(1500);
|
||||
QCOMPARE(this->m_window->Preset->presetName(), QString{});
|
||||
QCOMPARE(this->m_window->Preset->presets().size(), 1);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(),
|
||||
CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset");
|
||||
QCOMPARE(this->m_window->Preset->isHidden(), false);
|
||||
QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
|
||||
|
||||
this->m_window->Preset->setPresetName("preset2");
|
||||
loopSleep();
|
||||
QCOMPARE(this->m_window->Preset->presetName(), "preset2");
|
||||
QCOMPARE(this->m_window->Preset->presets().size(), 1);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(),
|
||||
CMakeGUITest_BINARY_DIR "/changingPresets/src/build3/preset2");
|
||||
QCOMPARE(this->m_window->Preset->isHidden(), false);
|
||||
QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
|
||||
|
||||
QDir::root().mkpath(CMakeGUITest_BINARY_DIR "/changingPresets/src2");
|
||||
QFile::copy(CMakeGUITest_BINARY_DIR "/changingPresets/src/CMakePresets.json",
|
||||
CMakeGUITest_BINARY_DIR
|
||||
"/changingPresets/src2/CMakePresets.json");
|
||||
this->m_window->SourceDirectory->setText(CMakeGUITest_BINARY_DIR
|
||||
"/changingPresets/src2");
|
||||
loopSleep();
|
||||
QCOMPARE(this->m_window->Preset->presetName(), QString{});
|
||||
QCOMPARE(this->m_window->Preset->presets().size(), 1);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(),
|
||||
CMakeGUITest_BINARY_DIR "/changingPresets/src/build3/preset2");
|
||||
QCOMPARE(this->m_window->Preset->isHidden(), false);
|
||||
QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
|
||||
|
||||
this->m_window->Preset->setPresetName("preset2");
|
||||
loopSleep();
|
||||
QCOMPARE(this->m_window->Preset->presetName(), "preset2");
|
||||
QCOMPARE(this->m_window->Preset->presets().size(), 1);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(),
|
||||
CMakeGUITest_BINARY_DIR "/changingPresets/src2/build3/preset2");
|
||||
QCOMPARE(this->m_window->Preset->isHidden(), false);
|
||||
QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
|
||||
|
||||
QFile(CMakeGUITest_BINARY_DIR "/changingPresets/src2/CMakePresets.json")
|
||||
.remove();
|
||||
loopSleep(1500);
|
||||
QCOMPARE(this->m_window->Preset->presetName(), QString{});
|
||||
QCOMPARE(this->m_window->Preset->presets().size(), 0);
|
||||
QCOMPARE(this->m_window->BinaryDirectory->currentText(),
|
||||
CMakeGUITest_BINARY_DIR "/changingPresets/src2/build3/preset2");
|
||||
QCOMPARE(this->m_window->Preset->isHidden(), true);
|
||||
QCOMPARE(this->m_window->PresetLabel->isHidden(), true);
|
||||
}
|
||||
|
||||
void SetupDefaultQSettings()
|
||||
{
|
||||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
|
||||
@@ -23,4 +23,7 @@ private slots:
|
||||
void simpleConfigure();
|
||||
void simpleConfigure_data();
|
||||
void environment();
|
||||
void presetArg();
|
||||
void presetArg_data();
|
||||
void changingPresets();
|
||||
};
|
||||
|
||||
@@ -72,3 +72,24 @@ add_cmake_gui_lib_test(QCMakeCacheModel
|
||||
MOC_SOURCES
|
||||
QCMakeCacheModelTest.h
|
||||
)
|
||||
add_cmake_gui_lib_test(QCMakePreset
|
||||
SOURCES
|
||||
QCMakePresetTest.cxx
|
||||
QCMakePresetTest.h
|
||||
MOC_SOURCES
|
||||
QCMakePresetTest.h
|
||||
)
|
||||
add_cmake_gui_lib_test(QCMakePresetItemModel
|
||||
SOURCES
|
||||
QCMakePresetItemModelTest.cxx
|
||||
QCMakePresetItemModelTest.h
|
||||
MOC_SOURCES
|
||||
QCMakePresetItemModelTest.h
|
||||
)
|
||||
add_cmake_gui_lib_test(QCMakePresetComboBox
|
||||
SOURCES
|
||||
QCMakePresetComboBoxTest.cxx
|
||||
QCMakePresetComboBoxTest.h
|
||||
MOC_SOURCES
|
||||
QCMakePresetComboBoxTest.h
|
||||
)
|
||||
|
||||
80
Tests/CMakeGUI/QCMakePresetComboBoxTest.cxx
Normal file
80
Tests/CMakeGUI/QCMakePresetComboBoxTest.cxx
Normal file
@@ -0,0 +1,80 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "QCMakePresetComboBoxTest.h"
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
void QCMakePresetComboBoxTest::changePresets()
|
||||
{
|
||||
QCMakePresetComboBox box;
|
||||
QSignalSpy presetChanged(&box, &QCMakePresetComboBox::presetChanged);
|
||||
|
||||
QCOMPARE(presetChanged.size(), 0);
|
||||
|
||||
box.setPresets({});
|
||||
QCOMPARE(presetChanged.size(), 0);
|
||||
|
||||
box.setPresetName(QString{});
|
||||
QCOMPARE(presetChanged.size(), 0);
|
||||
|
||||
box.setPresets({
|
||||
{
|
||||
/*name=*/"preset",
|
||||
/*description=*/"",
|
||||
/*description=*/"",
|
||||
/*generator=*/"Ninja",
|
||||
/*architecture=*/"",
|
||||
/*toolset=*/"",
|
||||
/*setGenConfig=*/true,
|
||||
/*enabled=*/true,
|
||||
},
|
||||
});
|
||||
QCOMPARE(presetChanged.size(), 0);
|
||||
|
||||
box.setPresetName(QString{});
|
||||
QCOMPARE(presetChanged.size(), 0);
|
||||
|
||||
box.setPresetName("noexist");
|
||||
QCOMPARE(presetChanged.size(), 0);
|
||||
|
||||
box.setPresetName("preset");
|
||||
QCOMPARE(presetChanged.size(), 1);
|
||||
QCOMPARE(presetChanged.last(), QList<QVariant>{ "preset" });
|
||||
|
||||
box.setPresets({
|
||||
{
|
||||
/*name=*/"preset",
|
||||
/*description=*/"",
|
||||
/*description=*/"",
|
||||
/*generator=*/"Ninja Multi-Config",
|
||||
/*architecture=*/"",
|
||||
/*toolset=*/"",
|
||||
/*setGenConfig=*/true,
|
||||
/*enabled=*/true,
|
||||
},
|
||||
});
|
||||
QCOMPARE(presetChanged.size(), 1);
|
||||
|
||||
box.setPresetName("noexist");
|
||||
QCOMPARE(presetChanged.size(), 2);
|
||||
QCOMPARE(presetChanged.last(), QList<QVariant>{ QString{} });
|
||||
|
||||
box.setPresetName("preset");
|
||||
QCOMPARE(presetChanged.size(), 3);
|
||||
QCOMPARE(presetChanged.last(), QList<QVariant>{ "preset" });
|
||||
|
||||
box.blockSignals(true);
|
||||
box.setPresetName(QString{});
|
||||
box.blockSignals(false);
|
||||
QCOMPARE(presetChanged.size(), 3);
|
||||
|
||||
box.setPresetName("preset");
|
||||
QCOMPARE(presetChanged.size(), 4);
|
||||
QCOMPARE(presetChanged.last(), QList<QVariant>{ "preset" });
|
||||
|
||||
box.setPresets({});
|
||||
QCOMPARE(presetChanged.size(), 5);
|
||||
QCOMPARE(presetChanged.last(), QList<QVariant>{ QString{} });
|
||||
}
|
||||
|
||||
QTEST_MAIN(QCMakePresetComboBoxTest)
|
||||
13
Tests/CMakeGUI/QCMakePresetComboBoxTest.h
Normal file
13
Tests/CMakeGUI/QCMakePresetComboBoxTest.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "QCMakePresetComboBox.h"
|
||||
#include <QObject>
|
||||
|
||||
class QCMakePresetComboBoxTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void changePresets();
|
||||
};
|
||||
162
Tests/CMakeGUI/QCMakePresetItemModelTest.cxx
Normal file
162
Tests/CMakeGUI/QCMakePresetItemModelTest.cxx
Normal file
@@ -0,0 +1,162 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "QCMakePresetItemModelTest.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "QCMakePreset.h"
|
||||
#include "QCMakePresetItemModel.h"
|
||||
#include <QHash>
|
||||
#include <QMetaType>
|
||||
#include <QSignalSpy>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
#include <QtTest>
|
||||
|
||||
using QItemDataHash = QHash<Qt::ItemDataRole, QVariant>;
|
||||
|
||||
void QCMakePresetItemModelTest::initTestCase()
|
||||
{
|
||||
QMetaType::registerComparators<QCMakePreset>();
|
||||
}
|
||||
|
||||
void QCMakePresetItemModelTest::initTestCase_data()
|
||||
{
|
||||
QTest::addColumn<QVector<QCMakePreset>>("presets");
|
||||
QTest::addColumn<QVector<QItemDataHash>>("data");
|
||||
|
||||
QVector<QCMakePreset> presets{
|
||||
QCMakePreset{
|
||||
/*name=*/"no-description",
|
||||
/*description=*/"",
|
||||
/*description=*/"",
|
||||
/*generator=*/"",
|
||||
/*architecture=*/"",
|
||||
/*toolset=*/"",
|
||||
/*setGenConfig=*/true,
|
||||
/*enabled=*/true,
|
||||
},
|
||||
QCMakePreset{
|
||||
/*name=*/"short-description",
|
||||
/*description=*/"Short Description",
|
||||
/*description=*/"",
|
||||
/*generator=*/"",
|
||||
/*architecture=*/"",
|
||||
/*toolset=*/"",
|
||||
/*setGenConfig=*/true,
|
||||
/*enabled=*/true,
|
||||
},
|
||||
QCMakePreset{
|
||||
/*name=*/"long-description",
|
||||
/*description=*/"",
|
||||
/*description=*/"Long Description",
|
||||
/*generator=*/"",
|
||||
/*architecture=*/"",
|
||||
/*toolset=*/"",
|
||||
/*setGenConfig=*/true,
|
||||
/*enabled=*/true,
|
||||
},
|
||||
QCMakePreset{
|
||||
/*name=*/"disabled",
|
||||
/*description=*/"",
|
||||
/*description=*/"",
|
||||
/*generator=*/"",
|
||||
/*architecture=*/"",
|
||||
/*toolset=*/"",
|
||||
/*setGenConfig=*/true,
|
||||
/*enabled=*/false,
|
||||
},
|
||||
};
|
||||
QVector<QItemDataHash> data{
|
||||
QItemDataHash{
|
||||
{ Qt::AccessibleDescriptionRole, "" },
|
||||
{ Qt::DisplayRole, "no-description" },
|
||||
{ Qt::ToolTipRole, "" },
|
||||
{ Qt::UserRole, QVariant::fromValue(presets[0]) },
|
||||
{ Qt::FontRole, QFont{} },
|
||||
},
|
||||
QItemDataHash{
|
||||
{ Qt::AccessibleDescriptionRole, "" },
|
||||
{ Qt::DisplayRole, "Short Description" },
|
||||
{ Qt::ToolTipRole, "" },
|
||||
{ Qt::UserRole, QVariant::fromValue(presets[1]) },
|
||||
{ Qt::FontRole, QFont{} },
|
||||
},
|
||||
QItemDataHash{
|
||||
{ Qt::AccessibleDescriptionRole, "" },
|
||||
{ Qt::DisplayRole, "long-description" },
|
||||
{ Qt::ToolTipRole, "Long Description" },
|
||||
{ Qt::UserRole, QVariant::fromValue(presets[2]) },
|
||||
{ Qt::FontRole, QFont{} },
|
||||
},
|
||||
QItemDataHash{
|
||||
{ Qt::AccessibleDescriptionRole, "" },
|
||||
{ Qt::DisplayRole, "disabled" },
|
||||
{ Qt::ToolTipRole, "" },
|
||||
{ Qt::UserRole, QVariant::fromValue(presets[3]) },
|
||||
{ Qt::FontRole, QFont{} },
|
||||
},
|
||||
QItemDataHash{
|
||||
{ Qt::AccessibleDescriptionRole, "separator" },
|
||||
{ Qt::DisplayRole, QVariant{} },
|
||||
{ Qt::ToolTipRole, QVariant{} },
|
||||
{ Qt::UserRole, QVariant{} },
|
||||
{ Qt::FontRole, QFont{} },
|
||||
},
|
||||
QItemDataHash{
|
||||
{ Qt::AccessibleDescriptionRole, "" },
|
||||
{ Qt::DisplayRole, "<custom>" },
|
||||
{ Qt::ToolTipRole, "Specify all settings manually" },
|
||||
{ Qt::UserRole, QVariant{} },
|
||||
{ Qt::FontRole,
|
||||
[]() {
|
||||
QFont f;
|
||||
f.setItalic(true);
|
||||
return f;
|
||||
}() },
|
||||
},
|
||||
};
|
||||
QTest::newRow("many") << presets << data;
|
||||
QTest::newRow("none") << QVector<QCMakePreset>{}
|
||||
<< QVector<QItemDataHash>{ data.last() };
|
||||
}
|
||||
|
||||
void QCMakePresetItemModelTest::data()
|
||||
{
|
||||
QFETCH_GLOBAL(QVector<QCMakePreset>, presets);
|
||||
QFETCH_GLOBAL(QVector<QItemDataHash>, data);
|
||||
QFETCH(Qt::ItemDataRole, role);
|
||||
|
||||
QCMakePresetItemModel model;
|
||||
QSignalSpy spy1(&model, &QCMakePresetItemModel::modelAboutToBeReset);
|
||||
QSignalSpy spy2(&model, &QCMakePresetItemModel::modelReset);
|
||||
model.setPresets(presets);
|
||||
QCOMPARE(spy1.size(), 1);
|
||||
QCOMPARE(spy2.size(), 1);
|
||||
|
||||
QVector<QVariant> expectedData(data.size());
|
||||
for (int i = 0; i < data.size(); ++i) {
|
||||
expectedData[i] = data[i][role];
|
||||
}
|
||||
|
||||
auto rows = model.rowCount();
|
||||
QVector<QVariant> actualData(rows);
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
actualData[i] = model.data(model.index(i, 0), role);
|
||||
}
|
||||
|
||||
QCOMPARE(actualData, expectedData);
|
||||
}
|
||||
|
||||
void QCMakePresetItemModelTest::data_data()
|
||||
{
|
||||
QTest::addColumn<Qt::ItemDataRole>("role");
|
||||
|
||||
QTest::newRow("accessible") << Qt::AccessibleDescriptionRole;
|
||||
QTest::newRow("display") << Qt::DisplayRole;
|
||||
QTest::newRow("tooltip") << Qt::ToolTipRole;
|
||||
QTest::newRow("user") << Qt::UserRole;
|
||||
QTest::newRow("font") << Qt::FontRole;
|
||||
}
|
||||
|
||||
QTEST_MAIN(QCMakePresetItemModelTest)
|
||||
17
Tests/CMakeGUI/QCMakePresetItemModelTest.h
Normal file
17
Tests/CMakeGUI/QCMakePresetItemModelTest.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "QCMakePresetItemModel.h"
|
||||
#include <QObject>
|
||||
|
||||
class QCMakePresetItemModelTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void initTestCase_data();
|
||||
|
||||
void data();
|
||||
void data_data();
|
||||
};
|
||||
82
Tests/CMakeGUI/QCMakePresetTest.cxx
Normal file
82
Tests/CMakeGUI/QCMakePresetTest.cxx
Normal file
@@ -0,0 +1,82 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "QCMakePresetTest.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "QCMakePreset.h"
|
||||
#include <QtTest>
|
||||
|
||||
namespace {
|
||||
QCMakePreset makePreset()
|
||||
{
|
||||
return QCMakePreset{
|
||||
/*name=*/"name",
|
||||
/*displayName=*/"displayName",
|
||||
/*description=*/"description",
|
||||
/*generator=*/"generator",
|
||||
/*architecture=*/"architecture",
|
||||
/*toolset=*/"toolset",
|
||||
/*setGenConfig=*/true,
|
||||
/*enabled=*/true,
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
QCMakePreset makePreset(T QCMakePreset::*field, U&& value)
|
||||
{
|
||||
auto preset = makePreset();
|
||||
preset.*field = std::forward<U>(value);
|
||||
return preset;
|
||||
}
|
||||
}
|
||||
|
||||
void QCMakePresetTest::equality()
|
||||
{
|
||||
QFETCH(QCMakePreset, rhs);
|
||||
QFETCH(bool, equal);
|
||||
QFETCH(bool, lt);
|
||||
QFETCH(bool, gt);
|
||||
|
||||
auto lhs = makePreset();
|
||||
QVERIFY((lhs == rhs) == equal);
|
||||
QVERIFY((lhs != rhs) == !equal);
|
||||
QVERIFY((lhs < rhs) == lt);
|
||||
QVERIFY((lhs >= rhs) == !lt);
|
||||
QVERIFY((lhs > rhs) == gt);
|
||||
QVERIFY((lhs <= rhs) == !gt);
|
||||
}
|
||||
|
||||
void QCMakePresetTest::equality_data()
|
||||
{
|
||||
QTest::addColumn<QCMakePreset>("rhs");
|
||||
QTest::addColumn<bool>("equal");
|
||||
QTest::addColumn<bool>("lt");
|
||||
QTest::addColumn<bool>("gt");
|
||||
|
||||
QTest::newRow("equal") << makePreset() << true << false << false;
|
||||
QTest::newRow("name") << makePreset(&QCMakePreset::name, "other-name")
|
||||
<< false << true << false;
|
||||
QTest::newRow("displayName")
|
||||
<< makePreset(&QCMakePreset::displayName, "other-displayName") << false
|
||||
<< true << false;
|
||||
QTest::newRow("description")
|
||||
<< makePreset(&QCMakePreset::description, "other-description") << false
|
||||
<< true << false;
|
||||
QTest::newRow("generator")
|
||||
<< makePreset(&QCMakePreset::generator, "other-generator") << false << true
|
||||
<< false;
|
||||
QTest::newRow("architecture")
|
||||
<< makePreset(&QCMakePreset::architecture, "other-architecture") << false
|
||||
<< true << false;
|
||||
QTest::newRow("toolset") << makePreset(&QCMakePreset::toolset,
|
||||
"other-toolset")
|
||||
<< false << false << true;
|
||||
QTest::newRow("setGenConfig")
|
||||
<< makePreset(&QCMakePreset::setGenConfig, false) << false << false
|
||||
<< true;
|
||||
QTest::newRow("enabled") << makePreset(&QCMakePreset::enabled, false)
|
||||
<< false << false << true;
|
||||
}
|
||||
|
||||
QTEST_MAIN(QCMakePresetTest)
|
||||
14
Tests/CMakeGUI/QCMakePresetTest.h
Normal file
14
Tests/CMakeGUI/QCMakePresetTest.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "QCMakePreset.h"
|
||||
#include <QObject>
|
||||
|
||||
class QCMakePresetTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void equality();
|
||||
void equality_data();
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"version": 1,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"STRING_VARIABLE": {
|
||||
"type": "STRING",
|
||||
"value": "String value"
|
||||
},
|
||||
"PATH_VARIABLE": {
|
||||
"type": "PATH",
|
||||
"value": "${sourceDir}"
|
||||
},
|
||||
"FILEPATH_VARIABLE": {
|
||||
"type": "FILEPATH",
|
||||
"value": "${sourceDir}/CMakeLists.txt"
|
||||
},
|
||||
"ON_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"FALSE_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "FALSE"
|
||||
},
|
||||
"UNINITIALIZED_VARIABLE": "Uninitialized value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
33
Tests/CMakeGUI/presetArg-preset/CMakePresets.json.in
Normal file
33
Tests/CMakeGUI/presetArg-preset/CMakePresets.json.in
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"version": 1,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"STRING_VARIABLE": {
|
||||
"type": "STRING",
|
||||
"value": "String value"
|
||||
},
|
||||
"PATH_VARIABLE": {
|
||||
"type": "PATH",
|
||||
"value": "${sourceDir}"
|
||||
},
|
||||
"FILEPATH_VARIABLE": {
|
||||
"type": "FILEPATH",
|
||||
"value": "${sourceDir}/CMakeLists.txt"
|
||||
},
|
||||
"ON_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"FALSE_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "FALSE"
|
||||
},
|
||||
"UNINITIALIZED_VARIABLE": "Uninitialized value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
33
Tests/CMakeGUI/presetArg-presetBinary/CMakePresets.json.in
Normal file
33
Tests/CMakeGUI/presetArg-presetBinary/CMakePresets.json.in
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"version": 1,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"STRING_VARIABLE": {
|
||||
"type": "STRING",
|
||||
"value": "String value"
|
||||
},
|
||||
"PATH_VARIABLE": {
|
||||
"type": "PATH",
|
||||
"value": "${sourceDir}"
|
||||
},
|
||||
"FILEPATH_VARIABLE": {
|
||||
"type": "FILEPATH",
|
||||
"value": "${sourceDir}/CMakeLists.txt"
|
||||
},
|
||||
"ON_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"FALSE_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "FALSE"
|
||||
},
|
||||
"UNINITIALIZED_VARIABLE": "Uninitialized value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"version": 1,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"STRING_VARIABLE": {
|
||||
"type": "STRING",
|
||||
"value": "String value"
|
||||
},
|
||||
"PATH_VARIABLE": {
|
||||
"type": "PATH",
|
||||
"value": "${sourceDir}"
|
||||
},
|
||||
"FILEPATH_VARIABLE": {
|
||||
"type": "FILEPATH",
|
||||
"value": "${sourceDir}/CMakeLists.txt"
|
||||
},
|
||||
"ON_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"FALSE_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "FALSE"
|
||||
},
|
||||
"UNINITIALIZED_VARIABLE": "Uninitialized value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ninja2",
|
||||
"inherits": [
|
||||
"ninja"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
project(sourceBinaryArgs-sourceDir NONE)
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"version": 1,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"STRING_VARIABLE": {
|
||||
"type": "STRING",
|
||||
"value": "String value"
|
||||
},
|
||||
"PATH_VARIABLE": {
|
||||
"type": "PATH",
|
||||
"value": "${sourceDir}"
|
||||
},
|
||||
"FILEPATH_VARIABLE": {
|
||||
"type": "FILEPATH",
|
||||
"value": "${sourceDir}/CMakeLists.txt"
|
||||
},
|
||||
"ON_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"FALSE_VARIABLE": {
|
||||
"type": "BOOL",
|
||||
"value": "FALSE"
|
||||
},
|
||||
"UNINITIALIZED_VARIABLE": "Uninitialized value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
[Settings]
|
||||
StartPath\WhereBuild0=@CMake_BINARY_DIR@
|
||||
Reference in New Issue
Block a user