EnvironmentDialog.cxx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "EnvironmentDialog.h"
  4. #include <QDialogButtonBox>
  5. #include <QGridLayout>
  6. #include <QItemSelectionModel>
  7. #include <QLabel>
  8. #include <QLineEdit>
  9. #include <QMessageBox>
  10. #include <QStandardItem>
  11. EnvironmentItemModel::EnvironmentItemModel(
  12. const QProcessEnvironment& environment, QObject* parent)
  13. : QStandardItemModel(parent)
  14. {
  15. this->clear();
  16. for (auto const& key : environment.keys()) {
  17. auto value = environment.value(key);
  18. this->appendVariable(key, value);
  19. }
  20. }
  21. QProcessEnvironment EnvironmentItemModel::environment() const
  22. {
  23. QProcessEnvironment env;
  24. for (int i = 0; i < this->rowCount(); ++i) {
  25. auto name = this->data(this->index(i, 0), Qt::DisplayRole).toString();
  26. auto value = this->data(this->index(i, 1), Qt::DisplayRole).toString();
  27. env.insert(name, value);
  28. }
  29. return env;
  30. }
  31. void EnvironmentItemModel::clear()
  32. {
  33. this->QStandardItemModel::clear();
  34. QStringList labels;
  35. labels << tr("Name") << tr("Value");
  36. this->setHorizontalHeaderLabels(labels);
  37. }
  38. QModelIndex EnvironmentItemModel::buddy(const QModelIndex& index) const
  39. {
  40. if (index.column() == 0) {
  41. return this->index(index.row(), index.column() + 1, index.parent());
  42. }
  43. return index;
  44. }
  45. void EnvironmentItemModel::appendVariable(const QString& key,
  46. const QString& value)
  47. {
  48. this->insertVariable(this->rowCount(), key, value);
  49. }
  50. void EnvironmentItemModel::insertVariable(int row, const QString& key,
  51. const QString& value)
  52. {
  53. for (int i = 0; i < this->rowCount(); ++i) {
  54. if (this->data(this->index(i, 0), Qt::DisplayRole) == key) {
  55. this->setData(this->index(i, 1), value, Qt::DisplayRole);
  56. return;
  57. }
  58. }
  59. auto* keyItem = new QStandardItem(key);
  60. auto* valueItem = new QStandardItem(value);
  61. this->insertRow(row, { keyItem, valueItem });
  62. }
  63. EnvironmentSearchFilter::EnvironmentSearchFilter(QObject* parent)
  64. : QSortFilterProxyModel(parent)
  65. {
  66. }
  67. bool EnvironmentSearchFilter::filterAcceptsRow(int row,
  68. const QModelIndex& parent) const
  69. {
  70. auto* model = this->sourceModel();
  71. auto key =
  72. model->data(model->index(row, 0, parent), Qt::DisplayRole).toString();
  73. return key.contains(this->filterRegExp());
  74. }
  75. EnvironmentDialog::EnvironmentDialog(const QProcessEnvironment& environment,
  76. QWidget* parent)
  77. : QDialog(parent)
  78. {
  79. this->setupUi(this);
  80. this->RemoveEntry->setEnabled(false);
  81. this->m_model = new EnvironmentItemModel(environment, this);
  82. this->m_filter = new EnvironmentSearchFilter(this);
  83. this->m_filter->setSourceModel(this->m_model);
  84. this->Environment->setModel(this->m_filter);
  85. this->Environment->setUniformRowHeights(true);
  86. this->Environment->setRootIsDecorated(false);
  87. this->Environment->setSelectionMode(QAbstractItemView::ExtendedSelection);
  88. this->Environment->setSelectionBehavior(QAbstractItemView::SelectRows);
  89. QObject::connect(this->AddEntry, &QToolButton::clicked, this,
  90. &EnvironmentDialog::addEntry);
  91. QObject::connect(this->RemoveEntry, &QToolButton::clicked, this,
  92. &EnvironmentDialog::removeSelectedEntries);
  93. QObject::connect(this->Search, &QLineEdit::textChanged, this->m_filter,
  94. &EnvironmentSearchFilter::setFilterFixedString);
  95. QObject::connect(this->Environment->selectionModel(),
  96. &QItemSelectionModel::selectionChanged, this,
  97. &EnvironmentDialog::selectionChanged);
  98. }
  99. QProcessEnvironment EnvironmentDialog::environment() const
  100. {
  101. return this->m_model->environment();
  102. }
  103. void EnvironmentDialog::addEntry()
  104. {
  105. // Build the dialog manually because it's simple enough
  106. QDialog dialog(this);
  107. dialog.setWindowTitle("Add Environment Variable");
  108. auto* layout = new QGridLayout;
  109. dialog.setLayout(layout);
  110. auto* nameLabel = new QLabel;
  111. nameLabel->setText("Name:");
  112. layout->addWidget(nameLabel, 0, 0);
  113. auto* nameEdit = new QLineEdit;
  114. nameEdit->setObjectName("name");
  115. layout->addWidget(nameEdit, 0, 1);
  116. auto* valueLabel = new QLabel;
  117. valueLabel->setText("Value:");
  118. layout->addWidget(valueLabel, 1, 0);
  119. auto* valueEdit = new QLineEdit;
  120. valueEdit->setObjectName("value");
  121. layout->addWidget(valueEdit, 1, 1);
  122. auto* buttons = new QDialogButtonBox;
  123. buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  124. QObject::connect(
  125. buttons, &QDialogButtonBox::accepted, &dialog,
  126. [this, &dialog, nameEdit]() {
  127. auto text = nameEdit->text();
  128. if (text.isEmpty()) {
  129. QMessageBox::critical(&dialog, "Error", "Name must be non-empty.");
  130. return;
  131. }
  132. auto* model = this->Environment->model();
  133. for (int i = 0; i < model->rowCount(); ++i) {
  134. if (model->data(model->index(i, 0), Qt::DisplayRole) == text) {
  135. QMessageBox::critical(
  136. &dialog, "Error",
  137. tr("Environment variable \"%1\" already exists.").arg(text));
  138. return;
  139. }
  140. }
  141. dialog.accept();
  142. });
  143. QObject::connect(buttons, &QDialogButtonBox::rejected, &dialog,
  144. &QDialog::reject);
  145. layout->addWidget(buttons, 2, 0, 1, 2);
  146. if (dialog.exec() == QDialog::Accepted) {
  147. this->m_model->insertVariable(0, nameEdit->text(), valueEdit->text());
  148. }
  149. }
  150. void EnvironmentDialog::removeSelectedEntries()
  151. {
  152. QModelIndexList idxs = this->Environment->selectionModel()->selectedRows();
  153. QList<QPersistentModelIndex> pidxs;
  154. foreach (QModelIndex const& i, idxs) {
  155. pidxs.append(i);
  156. }
  157. foreach (QPersistentModelIndex const& pi, pidxs) {
  158. this->Environment->model()->removeRow(pi.row(), pi.parent());
  159. }
  160. }
  161. void EnvironmentDialog::selectionChanged()
  162. {
  163. auto selected = this->Environment->selectionModel()->selectedRows();
  164. this->RemoveEntry->setEnabled(!selected.isEmpty());
  165. }