mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 21:31:08 -06:00
Don't use subclasses to connect to QAbstractButton::clicked. This is slightly dodgy, but of more immediate importance, tweaking it will allow us to change the widget type of some QToolButton instances that should be QPushButton.
199 lines
6.0 KiB
C++
199 lines
6.0 KiB
C++
/* 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();
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
|
return key.contains(this->filterRegularExpression());
|
|
#else
|
|
return key.contains(this->filterRegExp());
|
|
#endif
|
|
}
|
|
|
|
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, &QAbstractButton::clicked, this,
|
|
&EnvironmentDialog::addEntry);
|
|
QObject::connect(this->RemoveEntry, &QAbstractButton::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());
|
|
}
|