mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-09 15:20:56 -06:00
CMake GUI: Add environment editor
This commit is contained in:
4
Help/release/dev/cmake-gui-environment.rst
Normal file
4
Help/release/dev/cmake-gui-environment.rst
Normal file
@@ -0,0 +1,4 @@
|
||||
cmake-gui-environment
|
||||
---------------------
|
||||
|
||||
* The :manual:`CMake GUI <cmake-gui(1)>` now has an environment variable editor.
|
||||
@@ -84,6 +84,8 @@ set(SRCS
|
||||
CMakeSetupDialog.cxx
|
||||
CMakeSetupDialog.h
|
||||
Compilers.h
|
||||
EnvironmentDialog.cxx
|
||||
EnvironmentDialog.h
|
||||
FirstConfigure.cxx
|
||||
FirstConfigure.h
|
||||
QCMake.cxx
|
||||
@@ -102,6 +104,7 @@ qt5_wrap_ui(UI_SRCS
|
||||
Compilers.ui
|
||||
CrossCompiler.ui
|
||||
AddCacheEntry.ui
|
||||
EnvironmentDialog.ui
|
||||
RegexExplorer.ui
|
||||
WarningMessagesDialog.ui
|
||||
)
|
||||
@@ -109,6 +112,7 @@ qt5_wrap_cpp(MOC_SRCS
|
||||
AddCacheEntry.h
|
||||
Compilers.h
|
||||
CMakeSetupDialog.h
|
||||
EnvironmentDialog.h
|
||||
FirstConfigure.h
|
||||
QCMake.h
|
||||
QCMakeCacheView.h
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QMimeData>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QProgressBar>
|
||||
#include <QSettings>
|
||||
#include <QShortcut>
|
||||
@@ -35,6 +36,7 @@
|
||||
#include "cmVersion.h"
|
||||
|
||||
#include "AddCacheEntry.h"
|
||||
#include "EnvironmentDialog.h"
|
||||
#include "FirstConfigure.h"
|
||||
#include "RegexExplorer.h"
|
||||
#include "WarningMessagesDialog.h"
|
||||
@@ -292,6 +294,9 @@ void CMakeSetupDialog::initialize()
|
||||
QObject::connect(this->AddEntry, &QToolButton::clicked, this,
|
||||
&CMakeSetupDialog::addCacheEntry);
|
||||
|
||||
QObject::connect(this->Environment, &QToolButton::clicked, this,
|
||||
&CMakeSetupDialog::editEnvironment);
|
||||
|
||||
QObject::connect(this->WarnUninitializedAction, &QAction::triggered,
|
||||
this->CMakeThread->cmakeInstance(),
|
||||
&QCMake::setWarnUninitializedMode);
|
||||
@@ -742,6 +747,7 @@ void CMakeSetupDialog::setEnabledState(bool enabled)
|
||||
this->ConfigureAction->setEnabled(enabled);
|
||||
this->AddEntry->setEnabled(enabled);
|
||||
this->RemoveEntry->setEnabled(false); // let selection re-enable it
|
||||
this->Environment->setEnabled(enabled);
|
||||
}
|
||||
|
||||
bool CMakeSetupDialog::setupFirstConfigure()
|
||||
@@ -1075,6 +1081,17 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s)
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::editEnvironment()
|
||||
{
|
||||
EnvironmentDialog dialog(this->CMakeThread->cmakeInstance()->environment(),
|
||||
this);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
QMetaObject::invokeMethod(
|
||||
this->CMakeThread->cmakeInstance(), "setEnvironment",
|
||||
Q_ARG(QProcessEnvironment, dialog.environment()));
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::addCacheEntry()
|
||||
{
|
||||
QDialog dialog(this);
|
||||
|
||||
@@ -65,6 +65,7 @@ protected slots:
|
||||
void setCacheModified();
|
||||
void removeSelectedCacheEntries();
|
||||
void selectionChanged();
|
||||
void editEnvironment();
|
||||
void addCacheEntry();
|
||||
void startSearch();
|
||||
void setDebugOutput(bool);
|
||||
|
||||
@@ -11,7 +11,16 @@
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
@@ -19,7 +28,16 @@
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
@@ -90,7 +108,16 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -98,7 +125,16 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -191,6 +227,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="Environment">
|
||||
<property name="text">
|
||||
<string>E&nvironment...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -224,7 +267,16 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -241,13 +293,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="OpenProjectButton">
|
||||
<property name="text">
|
||||
<string>Open &Project</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="OpenProjectButton">
|
||||
<property name="text">
|
||||
<string>Open &Project</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="Generator">
|
||||
<property name="text">
|
||||
|
||||
194
Source/QtDialog/EnvironmentDialog.cxx
Normal file
194
Source/QtDialog/EnvironmentDialog.cxx
Normal file
@@ -0,0 +1,194 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "EnvironmentDialog.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QStandardItem>
|
||||
|
||||
EnvironmentItemModel::EnvironmentItemModel(
|
||||
const QProcessEnvironment& environment, QObject* parent)
|
||||
: QStandardItemModel(parent)
|
||||
{
|
||||
this->clear();
|
||||
for (auto const& key : environment.keys()) {
|
||||
auto value = environment.value(key);
|
||||
this->appendVariable(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
QProcessEnvironment EnvironmentItemModel::environment() const
|
||||
{
|
||||
QProcessEnvironment env;
|
||||
for (int i = 0; i < this->rowCount(); ++i) {
|
||||
auto name = this->data(this->index(i, 0), Qt::DisplayRole).toString();
|
||||
auto value = this->data(this->index(i, 1), Qt::DisplayRole).toString();
|
||||
env.insert(name, value);
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
void EnvironmentItemModel::clear()
|
||||
{
|
||||
this->QStandardItemModel::clear();
|
||||
|
||||
QStringList labels;
|
||||
labels << tr("Name") << tr("Value");
|
||||
this->setHorizontalHeaderLabels(labels);
|
||||
}
|
||||
|
||||
QModelIndex EnvironmentItemModel::buddy(const QModelIndex& index) const
|
||||
{
|
||||
if (index.column() == 0) {
|
||||
return this->index(index.row(), index.column() + 1, index.parent());
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void EnvironmentItemModel::appendVariable(const QString& key,
|
||||
const QString& value)
|
||||
{
|
||||
this->insertVariable(this->rowCount(), key, value);
|
||||
}
|
||||
|
||||
void EnvironmentItemModel::insertVariable(int row, const QString& key,
|
||||
const QString& value)
|
||||
{
|
||||
for (int i = 0; i < this->rowCount(); ++i) {
|
||||
if (this->data(this->index(i, 0), Qt::DisplayRole) == key) {
|
||||
this->setData(this->index(i, 1), value, Qt::DisplayRole);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto* keyItem = new QStandardItem(key);
|
||||
auto* valueItem = new QStandardItem(value);
|
||||
this->insertRow(row, { keyItem, valueItem });
|
||||
}
|
||||
|
||||
EnvironmentSearchFilter::EnvironmentSearchFilter(QObject* parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool EnvironmentSearchFilter::filterAcceptsRow(int row,
|
||||
const QModelIndex& parent) const
|
||||
{
|
||||
auto* model = this->sourceModel();
|
||||
auto key =
|
||||
model->data(model->index(row, 0, parent), Qt::DisplayRole).toString();
|
||||
return key.contains(this->filterRegExp());
|
||||
}
|
||||
|
||||
EnvironmentDialog::EnvironmentDialog(const QProcessEnvironment& environment,
|
||||
QWidget* parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
this->RemoveEntry->setEnabled(false);
|
||||
|
||||
this->m_model = new EnvironmentItemModel(environment, this);
|
||||
this->m_filter = new EnvironmentSearchFilter(this);
|
||||
this->m_filter->setSourceModel(this->m_model);
|
||||
this->Environment->setModel(this->m_filter);
|
||||
|
||||
this->Environment->setUniformRowHeights(true);
|
||||
this->Environment->setRootIsDecorated(false);
|
||||
this->Environment->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
this->Environment->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
|
||||
QObject::connect(this->AddEntry, &QToolButton::clicked, this,
|
||||
&EnvironmentDialog::addEntry);
|
||||
QObject::connect(this->RemoveEntry, &QToolButton::clicked, this,
|
||||
&EnvironmentDialog::removeSelectedEntries);
|
||||
QObject::connect(this->Search, &QLineEdit::textChanged, this->m_filter,
|
||||
&EnvironmentSearchFilter::setFilterFixedString);
|
||||
QObject::connect(this->Environment->selectionModel(),
|
||||
&QItemSelectionModel::selectionChanged, this,
|
||||
&EnvironmentDialog::selectionChanged);
|
||||
}
|
||||
|
||||
QProcessEnvironment EnvironmentDialog::environment() const
|
||||
{
|
||||
return this->m_model->environment();
|
||||
}
|
||||
|
||||
void EnvironmentDialog::addEntry()
|
||||
{
|
||||
// Build the dialog manually because it's simple enough
|
||||
QDialog dialog(this);
|
||||
dialog.setWindowTitle("Add Environment Variable");
|
||||
|
||||
auto* layout = new QGridLayout;
|
||||
dialog.setLayout(layout);
|
||||
|
||||
auto* nameLabel = new QLabel;
|
||||
nameLabel->setText("Name:");
|
||||
layout->addWidget(nameLabel, 0, 0);
|
||||
|
||||
auto* nameEdit = new QLineEdit;
|
||||
nameEdit->setObjectName("name");
|
||||
layout->addWidget(nameEdit, 0, 1);
|
||||
|
||||
auto* valueLabel = new QLabel;
|
||||
valueLabel->setText("Value:");
|
||||
layout->addWidget(valueLabel, 1, 0);
|
||||
|
||||
auto* valueEdit = new QLineEdit;
|
||||
valueEdit->setObjectName("value");
|
||||
layout->addWidget(valueEdit, 1, 1);
|
||||
|
||||
auto* buttons = new QDialogButtonBox;
|
||||
buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
QObject::connect(
|
||||
buttons, &QDialogButtonBox::accepted, &dialog,
|
||||
[this, &dialog, nameEdit]() {
|
||||
auto text = nameEdit->text();
|
||||
if (text.isEmpty()) {
|
||||
QMessageBox::critical(&dialog, "Error", "Name must be non-empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* model = this->Environment->model();
|
||||
for (int i = 0; i < model->rowCount(); ++i) {
|
||||
if (model->data(model->index(i, 0), Qt::DisplayRole) == text) {
|
||||
QMessageBox::critical(
|
||||
&dialog, "Error",
|
||||
tr("Environment variable \"%1\" already exists.").arg(text));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dialog.accept();
|
||||
});
|
||||
QObject::connect(buttons, &QDialogButtonBox::rejected, &dialog,
|
||||
&QDialog::reject);
|
||||
layout->addWidget(buttons, 2, 0, 1, 2);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
this->m_model->insertVariable(0, nameEdit->text(), valueEdit->text());
|
||||
}
|
||||
}
|
||||
|
||||
void EnvironmentDialog::removeSelectedEntries()
|
||||
{
|
||||
QModelIndexList idxs = this->Environment->selectionModel()->selectedRows();
|
||||
QList<QPersistentModelIndex> pidxs;
|
||||
foreach (QModelIndex const& i, idxs) {
|
||||
pidxs.append(i);
|
||||
}
|
||||
foreach (QPersistentModelIndex const& pi, pidxs) {
|
||||
this->Environment->model()->removeRow(pi.row(), pi.parent());
|
||||
}
|
||||
}
|
||||
|
||||
void EnvironmentDialog::selectionChanged()
|
||||
{
|
||||
auto selected = this->Environment->selectionModel()->selectedRows();
|
||||
this->RemoveEntry->setEnabled(!selected.isEmpty());
|
||||
}
|
||||
59
Source/QtDialog/EnvironmentDialog.h
Normal file
59
Source/QtDialog/EnvironmentDialog.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QObject>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include "ui_EnvironmentDialog.h"
|
||||
|
||||
class EnvironmentItemModel : public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EnvironmentItemModel(const QProcessEnvironment& environment,
|
||||
QObject* parent = nullptr);
|
||||
|
||||
QProcessEnvironment environment() const;
|
||||
void clear();
|
||||
|
||||
QModelIndex buddy(const QModelIndex& index) const override;
|
||||
|
||||
public slots:
|
||||
void appendVariable(const QString& key, const QString& value);
|
||||
void insertVariable(int row, const QString& key, const QString& value);
|
||||
};
|
||||
|
||||
class EnvironmentSearchFilter : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EnvironmentSearchFilter(QObject* parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int row, const QModelIndex& parent) const override;
|
||||
};
|
||||
|
||||
class EnvironmentDialog
|
||||
: public QDialog
|
||||
, public Ui::EnvironmentDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EnvironmentDialog(const QProcessEnvironment& environment,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
QProcessEnvironment environment() const;
|
||||
|
||||
protected slots:
|
||||
void addEntry();
|
||||
void removeSelectedEntries();
|
||||
void selectionChanged();
|
||||
|
||||
private:
|
||||
EnvironmentItemModel* m_model;
|
||||
EnvironmentSearchFilter* m_filter;
|
||||
};
|
||||
130
Source/QtDialog/EnvironmentDialog.ui
Normal file
130
Source/QtDialog/EnvironmentDialog.ui
Normal file
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EnvironmentDialog</class>
|
||||
<widget class="QDialog" name="EnvironmentDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Environment Editor</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>S&earch:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>Search</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="Search"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>12</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="AddEntry">
|
||||
<property name="text">
|
||||
<string>&Add Entry</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="CMakeSetup.qrc">
|
||||
<normaloff>:/Icons/Plus16.png</normaloff>:/Icons/Plus16.png</iconset>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="RemoveEntry">
|
||||
<property name="text">
|
||||
<string>&Remove Entry</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="CMakeSetup.qrc">
|
||||
<normaloff>:/Icons/Delete16.png</normaloff>:/Icons/Delete16.png</iconset>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="Environment"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="CMakeSetup.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>EnvironmentDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>EnvironmentDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -19,10 +19,12 @@
|
||||
|
||||
QCMake::QCMake(QObject* p)
|
||||
: QObject(p)
|
||||
, Environment(QProcessEnvironment::systemEnvironment())
|
||||
{
|
||||
this->WarnUninitializedMode = false;
|
||||
qRegisterMetaType<QCMakeProperty>();
|
||||
qRegisterMetaType<QCMakePropertyList>();
|
||||
qRegisterMetaType<QProcessEnvironment>();
|
||||
|
||||
cmSystemTools::DisableRunCommandOutput();
|
||||
cmSystemTools::SetRunCommandHideConsole(true);
|
||||
@@ -151,54 +153,72 @@ void QCMake::setToolset(const QString& toolset)
|
||||
}
|
||||
}
|
||||
|
||||
void QCMake::setEnvironment(const QProcessEnvironment& environment)
|
||||
{
|
||||
this->Environment = environment;
|
||||
}
|
||||
|
||||
void QCMake::configure()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
UINT lastErrorMode = SetErrorMode(0);
|
||||
#endif
|
||||
|
||||
this->CMakeInstance->SetHomeDirectory(
|
||||
this->SourceDirectory.toLocal8Bit().data());
|
||||
this->CMakeInstance->SetHomeOutputDirectory(
|
||||
this->BinaryDirectory.toLocal8Bit().data());
|
||||
this->CMakeInstance->SetGlobalGenerator(
|
||||
this->CMakeInstance->CreateGlobalGenerator(
|
||||
this->Generator.toLocal8Bit().data()));
|
||||
this->CMakeInstance->SetGeneratorPlatform(
|
||||
this->Platform.toLocal8Bit().data());
|
||||
this->CMakeInstance->SetGeneratorToolset(this->Toolset.toLocal8Bit().data());
|
||||
this->CMakeInstance->LoadCache();
|
||||
this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
|
||||
this->CMakeInstance->PreLoadCMakeFiles();
|
||||
|
||||
InterruptFlag = 0;
|
||||
cmSystemTools::ResetErrorOccuredFlag();
|
||||
|
||||
int err = this->CMakeInstance->Configure();
|
||||
int err;
|
||||
{
|
||||
cmSystemTools::SaveRestoreEnvironment restoreEnv;
|
||||
this->setUpEnvironment();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
SetErrorMode(lastErrorMode);
|
||||
UINT lastErrorMode = SetErrorMode(0);
|
||||
#endif
|
||||
|
||||
this->CMakeInstance->SetHomeDirectory(
|
||||
this->SourceDirectory.toLocal8Bit().data());
|
||||
this->CMakeInstance->SetHomeOutputDirectory(
|
||||
this->BinaryDirectory.toLocal8Bit().data());
|
||||
this->CMakeInstance->SetGlobalGenerator(
|
||||
this->CMakeInstance->CreateGlobalGenerator(
|
||||
this->Generator.toLocal8Bit().data()));
|
||||
this->CMakeInstance->SetGeneratorPlatform(
|
||||
this->Platform.toLocal8Bit().data());
|
||||
this->CMakeInstance->SetGeneratorToolset(
|
||||
this->Toolset.toLocal8Bit().data());
|
||||
this->CMakeInstance->LoadCache();
|
||||
this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
|
||||
this->CMakeInstance->PreLoadCMakeFiles();
|
||||
|
||||
InterruptFlag = 0;
|
||||
cmSystemTools::ResetErrorOccuredFlag();
|
||||
|
||||
err = this->CMakeInstance->Configure();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
SetErrorMode(lastErrorMode);
|
||||
#endif
|
||||
}
|
||||
|
||||
emit this->propertiesChanged(this->properties());
|
||||
emit this->configureDone(err);
|
||||
}
|
||||
|
||||
void QCMake::generate()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
UINT lastErrorMode = SetErrorMode(0);
|
||||
#endif
|
||||
|
||||
InterruptFlag = 0;
|
||||
cmSystemTools::ResetErrorOccuredFlag();
|
||||
|
||||
int err = this->CMakeInstance->Generate();
|
||||
int err;
|
||||
{
|
||||
cmSystemTools::SaveRestoreEnvironment restoreEnv;
|
||||
this->setUpEnvironment();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
SetErrorMode(lastErrorMode);
|
||||
UINT lastErrorMode = SetErrorMode(0);
|
||||
#endif
|
||||
|
||||
InterruptFlag = 0;
|
||||
cmSystemTools::ResetErrorOccuredFlag();
|
||||
|
||||
err = this->CMakeInstance->Generate();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
SetErrorMode(lastErrorMode);
|
||||
#endif
|
||||
}
|
||||
|
||||
emit this->generateDone(err);
|
||||
checkOpenPossible();
|
||||
}
|
||||
@@ -373,6 +393,18 @@ void QCMake::stderrCallback(std::string const& msg)
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
void QCMake::setUpEnvironment() const
|
||||
{
|
||||
auto env = QProcessEnvironment::systemEnvironment();
|
||||
for (auto const& key : env.keys()) {
|
||||
cmSystemTools::UnsetEnv(key.toLocal8Bit().data());
|
||||
}
|
||||
|
||||
for (auto const& var : this->Environment.toStringList()) {
|
||||
cmSystemTools::PutEnv(var.toLocal8Bit().data());
|
||||
}
|
||||
}
|
||||
|
||||
QString QCMake::binaryDirectory() const
|
||||
{
|
||||
return this->BinaryDirectory;
|
||||
@@ -388,6 +420,11 @@ QString QCMake::generator() const
|
||||
return this->Generator;
|
||||
}
|
||||
|
||||
QProcessEnvironment QCMake::environment() const
|
||||
{
|
||||
return this->Environment;
|
||||
}
|
||||
|
||||
std::vector<cmake::GeneratorInfo> const& QCMake::availableGenerators() const
|
||||
{
|
||||
return AvailableGenerators;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <QList>
|
||||
#include <QMetaType>
|
||||
#include <QObject>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
@@ -55,6 +56,7 @@ using QCMakePropertyList = QList<QCMakeProperty>;
|
||||
// allow QVariant to be a property or list of properties
|
||||
Q_DECLARE_METATYPE(QCMakeProperty)
|
||||
Q_DECLARE_METATYPE(QCMakePropertyList)
|
||||
Q_DECLARE_METATYPE(QProcessEnvironment)
|
||||
|
||||
/// Qt API for CMake library.
|
||||
/// Wrapper like class allows for easier integration with
|
||||
@@ -78,6 +80,8 @@ public slots:
|
||||
void setPlatform(const QString& platform);
|
||||
/// set the desired generator to use
|
||||
void setToolset(const QString& toolset);
|
||||
/// set the configure and generate environment
|
||||
void setEnvironment(const QProcessEnvironment& environment);
|
||||
/// do the configure step
|
||||
void configure();
|
||||
/// generate the files
|
||||
@@ -125,6 +129,8 @@ public:
|
||||
QString sourceDirectory() const;
|
||||
/// get the current generator
|
||||
QString generator() const;
|
||||
/// get the configure and generate environment
|
||||
QProcessEnvironment environment() const;
|
||||
/// get the available generators
|
||||
std::vector<cmake::GeneratorInfo> const& availableGenerators() const;
|
||||
/// get whether to do debug output
|
||||
@@ -170,6 +176,7 @@ protected:
|
||||
void messageCallback(std::string const& msg, const char* title);
|
||||
void stdoutCallback(std::string const& msg);
|
||||
void stderrCallback(std::string const& msg);
|
||||
void setUpEnvironment() const;
|
||||
|
||||
bool WarnUninitializedMode;
|
||||
QString SourceDirectory;
|
||||
@@ -180,4 +187,5 @@ protected:
|
||||
std::vector<cmake::GeneratorInfo> AvailableGenerators;
|
||||
QString CMakeExecutable;
|
||||
QAtomicInt InterruptFlag;
|
||||
QProcessEnvironment Environment;
|
||||
};
|
||||
|
||||
@@ -112,3 +112,9 @@ run_cmake_gui_test(sourceBinaryArgs:noExistConfigExists
|
||||
|
||||
run_cmake_gui_test(simpleConfigure:success)
|
||||
run_cmake_gui_test(simpleConfigure:fail)
|
||||
|
||||
unset(ENV{ADDED_VARIABLE})
|
||||
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)
|
||||
|
||||
@@ -143,6 +143,35 @@ void CMakeGUITest::simpleConfigure_data()
|
||||
<< -1;
|
||||
}
|
||||
|
||||
void CMakeGUITest::environment()
|
||||
{
|
||||
auto* cmake = this->m_window->findChild<QCMakeThread*>()->cmakeInstance();
|
||||
|
||||
this->m_window->SourceDirectory->setText(CMakeGUITest_BINARY_DIR
|
||||
"/environment/src");
|
||||
this->m_window->BinaryDirectory->setCurrentText(CMakeGUITest_BINARY_DIR
|
||||
"/environment/build");
|
||||
|
||||
// We are already testing EnvironmentDialog, so just trust that it's
|
||||
// connected correctly and modify the environment directly.
|
||||
auto env = cmake->environment();
|
||||
env.insert("ADDED_VARIABLE", "Added variable");
|
||||
env.insert("CHANGED_VARIABLE", "Changed variable");
|
||||
env.remove("REMOVED_VARIABLE");
|
||||
cmake->setEnvironment(env);
|
||||
|
||||
// Wait a bit for everything to update
|
||||
loopSleep();
|
||||
|
||||
this->tryConfigure();
|
||||
|
||||
auto penv = QProcessEnvironment::systemEnvironment();
|
||||
QVERIFY(!penv.contains("ADDED_VARIABLE"));
|
||||
QCOMPARE(penv.value("KEPT_VARIABLE"), "Kept variable");
|
||||
QCOMPARE(penv.value("CHANGED_VARIABLE"), "This variable will be changed");
|
||||
QCOMPARE(penv.value("REMOVED_VARIABLE"), "Removed variable");
|
||||
}
|
||||
|
||||
void SetupDefaultQSettings()
|
||||
{
|
||||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
|
||||
@@ -22,4 +22,5 @@ private slots:
|
||||
void sourceBinaryArgs_data();
|
||||
void simpleConfigure();
|
||||
void simpleConfigure_data();
|
||||
void environment();
|
||||
};
|
||||
|
||||
@@ -58,6 +58,13 @@ add_cmake_gui_lib_test(CatchShow
|
||||
MOC_SOURCES
|
||||
CatchShowTest.h
|
||||
)
|
||||
add_cmake_gui_lib_test(EnvironmentDialog
|
||||
SOURCES
|
||||
EnvironmentDialogTest.cxx
|
||||
EnvironmentDialogTest.h
|
||||
MOC_SOURCES
|
||||
EnvironmentDialogTest.h
|
||||
)
|
||||
add_cmake_gui_lib_test(QCMakeCacheModel
|
||||
SOURCES
|
||||
QCMakeCacheModelTest.cxx
|
||||
|
||||
142
Tests/CMakeGUI/EnvironmentDialogTest.cxx
Normal file
142
Tests/CMakeGUI/EnvironmentDialogTest.cxx
Normal file
@@ -0,0 +1,142 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "EnvironmentDialogTest.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QMessageBox>
|
||||
#include <QObject>
|
||||
#include <QPushButton>
|
||||
#include <QString>
|
||||
#include <QtTest>
|
||||
|
||||
#include "CatchShow.h"
|
||||
#include "EnvironmentDialog.h"
|
||||
|
||||
EnvironmentDialogTest::EnvironmentDialogTest(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void EnvironmentDialogTest::environmentDialog()
|
||||
{
|
||||
CatchShow catcher;
|
||||
catcher.setCallback<QMessageBox>([](QMessageBox* box) { box->accept(); });
|
||||
|
||||
QProcessEnvironment env;
|
||||
env.insert("DELETED_VARIABLE_1", "Deleted variable 1");
|
||||
env.insert("DELETED_VARIABLE_2", "Deleted variable 2");
|
||||
env.insert("KEPT_VARIABLE", "Kept variable");
|
||||
env.insert("CHANGED_VARIABLE", "This will be changed");
|
||||
|
||||
EnvironmentDialog dialog(env);
|
||||
|
||||
{
|
||||
QStringList expected{
|
||||
"CHANGED_VARIABLE=This will be changed",
|
||||
"DELETED_VARIABLE_1=Deleted variable 1",
|
||||
"DELETED_VARIABLE_2=Deleted variable 2",
|
||||
"KEPT_VARIABLE=Kept variable",
|
||||
};
|
||||
QCOMPARE(dialog.environment().toStringList(), expected);
|
||||
QCOMPARE(catcher.count(), 0);
|
||||
}
|
||||
|
||||
{
|
||||
CatchShow catcher2;
|
||||
bool done = false;
|
||||
catcher2.setCallback<QDialog>([&catcher, &done](QDialog* box) {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
done = true;
|
||||
|
||||
auto name = box->findChild<QLineEdit*>("name");
|
||||
auto value = box->findChild<QLineEdit*>("value");
|
||||
auto acceptReject = box->findChild<QDialogButtonBox*>();
|
||||
|
||||
name->setText("");
|
||||
value->setText("");
|
||||
acceptReject->button(QDialogButtonBox::Ok)->click();
|
||||
QCOMPARE(catcher.count(), 1);
|
||||
|
||||
name->setText("KEPT_VARIABLE");
|
||||
value->setText("");
|
||||
acceptReject->button(QDialogButtonBox::Ok)->click();
|
||||
QCOMPARE(catcher.count(), 2);
|
||||
|
||||
name->setText("ADDED_VARIABLE");
|
||||
value->setText("Added variable");
|
||||
acceptReject->button(QDialogButtonBox::Ok)->click();
|
||||
QCOMPARE(catcher.count(), 2);
|
||||
});
|
||||
dialog.AddEntry->click();
|
||||
|
||||
QStringList expected{
|
||||
"ADDED_VARIABLE=Added variable",
|
||||
"CHANGED_VARIABLE=This will be changed",
|
||||
"DELETED_VARIABLE_1=Deleted variable 1",
|
||||
"DELETED_VARIABLE_2=Deleted variable 2",
|
||||
"KEPT_VARIABLE=Kept variable",
|
||||
};
|
||||
QCOMPARE(dialog.environment().toStringList(), expected);
|
||||
QCOMPARE(catcher.count(), 2);
|
||||
QVERIFY(done);
|
||||
}
|
||||
|
||||
{
|
||||
CatchShow catcher2;
|
||||
bool done = false;
|
||||
catcher2.setCallback<QDialog>([&done](QDialog* box) {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
done = true;
|
||||
|
||||
auto name = box->findChild<QLineEdit*>("name");
|
||||
auto value = box->findChild<QLineEdit*>("value");
|
||||
auto acceptReject = box->findChild<QDialogButtonBox*>();
|
||||
|
||||
name->setText("DISCARDED_VARIABLE");
|
||||
value->setText("Discarded variable");
|
||||
acceptReject->button(QDialogButtonBox::Cancel)->click();
|
||||
});
|
||||
dialog.AddEntry->click();
|
||||
|
||||
QStringList expected{
|
||||
"ADDED_VARIABLE=Added variable",
|
||||
"CHANGED_VARIABLE=This will be changed",
|
||||
"DELETED_VARIABLE_1=Deleted variable 1",
|
||||
"DELETED_VARIABLE_2=Deleted variable 2",
|
||||
"KEPT_VARIABLE=Kept variable",
|
||||
};
|
||||
QCOMPARE(dialog.environment().toStringList(), expected);
|
||||
QCOMPARE(catcher.count(), 2);
|
||||
QVERIFY(done);
|
||||
}
|
||||
|
||||
{
|
||||
auto* model = dialog.Environment->model();
|
||||
auto* selectionModel = dialog.Environment->selectionModel();
|
||||
for (int i = 0; i < model->rowCount(); ++i) {
|
||||
auto index1 = model->index(i, 0);
|
||||
auto index2 = model->buddy(index1);
|
||||
auto name = model->data(index1, Qt::DisplayRole).toString();
|
||||
if (name == "DELETED_VARIABLE_1" || name == "DELETED_VARIABLE_2") {
|
||||
selectionModel->select(index1, QItemSelectionModel::Select);
|
||||
selectionModel->select(index2, QItemSelectionModel::Select);
|
||||
} else if (name == "CHANGED_VARIABLE") {
|
||||
model->setData(index2, "Changed variable", Qt::DisplayRole);
|
||||
}
|
||||
}
|
||||
dialog.RemoveEntry->click();
|
||||
|
||||
QStringList expected{
|
||||
"ADDED_VARIABLE=Added variable",
|
||||
"CHANGED_VARIABLE=Changed variable",
|
||||
"KEPT_VARIABLE=Kept variable",
|
||||
};
|
||||
QCOMPARE(dialog.environment().toStringList(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(EnvironmentDialogTest)
|
||||
15
Tests/CMakeGUI/EnvironmentDialogTest.h
Normal file
15
Tests/CMakeGUI/EnvironmentDialogTest.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class EnvironmentDialogTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EnvironmentDialogTest(QObject* parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void environmentDialog();
|
||||
};
|
||||
18
Tests/CMakeGUI/environment/CMakeLists.txt.in
Normal file
18
Tests/CMakeGUI/environment/CMakeLists.txt.in
Normal file
@@ -0,0 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
project(environment NONE)
|
||||
|
||||
if(NOT "$ENV{KEPT_VARIABLE}" STREQUAL "Kept variable")
|
||||
message(SEND_ERROR "KEPT_VARIABLE is \"$ENV{KEPT_VARIABLE}\", should be \"Kept variable\"")
|
||||
endif()
|
||||
|
||||
if(NOT "$ENV{ADDED_VARIABLE}" STREQUAL "Added variable")
|
||||
message(SEND_ERROR "ADDED_VARIABLE is \"$ENV{ADDED_VARIABLE}\", should be \"Added variable\"")
|
||||
endif()
|
||||
|
||||
if(NOT "$ENV{CHANGED_VARIABLE}" STREQUAL "Changed variable")
|
||||
message(SEND_ERROR "CHANGED_VARIABLE is \"$ENV{CHANGED_VARIABLE}\", should be \"Changed variable\"")
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{REMOVED_VARIABLE})
|
||||
message(SEND_ERROR "REMOVED_VARIABLE should not be defined")
|
||||
endif()
|
||||
Reference in New Issue
Block a user