1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #include "environmentview.h" |
6 | |
7 | #include <QVBoxLayout> |
8 | #include <QCheckBox> |
9 | #include <QHeaderView> |
10 | #include <QTableView> |
11 | #include <QProcessEnvironment> |
12 | |
13 | class EnvironmentModelPrivate |
14 | { |
15 | friend class EnvironmentModel; |
16 | QMap<QString, QVariant> envs; |
17 | }; |
18 | |
19 | EnvironmentModel::EnvironmentModel(QObject *parent) |
20 | : QAbstractTableModel(parent) |
21 | , d (new EnvironmentModelPrivate()) |
22 | { |
23 | |
24 | } |
25 | |
26 | EnvironmentModel::~EnvironmentModel() |
27 | { |
28 | if (d) |
29 | delete d; |
30 | } |
31 | |
32 | int EnvironmentModel::rowCount(const QModelIndex &) const |
33 | { |
34 | return d->envs.keys().size(); |
35 | } |
36 | |
37 | int EnvironmentModel::columnCount(const QModelIndex &) const |
38 | { |
39 | return ColumnCount; |
40 | } |
41 | |
42 | QVariant EnvironmentModel::data(const QModelIndex &index, int role) const |
43 | { |
44 | if (role == Qt::DisplayRole || role == Qt::EditRole) { |
45 | auto var = d->envs.keys()[index.row()]; |
46 | switch (index.column()) { |
47 | case Key: |
48 | return var; |
49 | case Value: |
50 | return d->envs.value(var); |
51 | default: |
52 | break; |
53 | } |
54 | } |
55 | return {}; |
56 | } |
57 | |
58 | bool EnvironmentModel::setData(const QModelIndex &index, const QVariant &value, int role) |
59 | { |
60 | if (!index.isValid() || role != Qt::EditRole) |
61 | return false; |
62 | |
63 | if (data(index, role) == value) |
64 | return true; |
65 | |
66 | const QString oldName = data(this->index(index.row(), 0, QModelIndex())).toString(); |
67 | const QString oldValue = data(this->index(index.row(), 1, QModelIndex()), Qt::EditRole).toString(); |
68 | QMap<QString, QVariant> map = d->envs; |
69 | if (index.column() == Key) { |
70 | const QString newName = value.toString(); |
71 | if (newName.isEmpty() || newName.contains("=" )) |
72 | return false; |
73 | if (map.contains(newName) || newName.isEmpty()) |
74 | return false; |
75 | map.remove(oldName); |
76 | map.insert(value.toString(), oldValue); |
77 | } else if (index.column() == Value) { |
78 | const QString stringValue = value.toString(); |
79 | auto var = map.keys()[index.row()]; |
80 | map[var] = stringValue; |
81 | } |
82 | update(map); |
83 | emit dataChanged(index, index); |
84 | return true; |
85 | } |
86 | |
87 | Qt::ItemFlags EnvironmentModel::flags(const QModelIndex &index) const |
88 | { |
89 | Q_UNUSED(index); |
90 | return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable; |
91 | } |
92 | |
93 | QVariant EnvironmentModel::(int section, Qt::Orientation orientation, int role) const |
94 | { |
95 | if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { |
96 | switch (section) { |
97 | case Key: |
98 | return QObject::tr("Variable" ); |
99 | case Value: |
100 | return QObject::tr("Value" ); |
101 | default: |
102 | break; |
103 | } |
104 | } |
105 | return {}; |
106 | } |
107 | |
108 | void EnvironmentModel::append(const QString &key, const QVariant &value) |
109 | { |
110 | beginInsertRows({}, d->envs.keys().count(), d->envs.keys().count()); |
111 | d->envs.insert(key, value); |
112 | endInsertRows(); |
113 | } |
114 | |
115 | void EnvironmentModel::remove(QModelIndex &index) |
116 | { |
117 | if (d->envs.keys().isEmpty() || index.row() < 0) |
118 | return; |
119 | |
120 | beginRemoveRows({}, d->envs.keys().count(), d->envs.keys().count()); |
121 | QString key = d->envs.keys()[index.row()]; |
122 | d->envs.remove(key); |
123 | endRemoveRows(); |
124 | } |
125 | |
126 | void EnvironmentModel::update(const QMap<QString, QVariant> &data) |
127 | { |
128 | beginResetModel(); |
129 | d->envs.clear(); |
130 | d->envs = data; |
131 | endResetModel(); |
132 | } |
133 | |
134 | const QMap<QString, QVariant> EnvironmentModel::getEnvironment() const |
135 | { |
136 | return d->envs; |
137 | } |
138 | |
139 | class EnvironmentViewPrivate |
140 | { |
141 | friend class EnvironmentView; |
142 | |
143 | QVBoxLayout *vLayout = nullptr; |
144 | QTableView *tableView = nullptr; |
145 | EnvironmentModel *model = nullptr; |
146 | }; |
147 | |
148 | EnvironmentView::EnvironmentView(QWidget *parent) |
149 | : QWidget(parent) |
150 | , d(new EnvironmentViewPrivate) |
151 | { |
152 | setAutoFillBackground(true); |
153 | |
154 | if (!d->vLayout) |
155 | d->vLayout = new QVBoxLayout(); |
156 | this->setLayout(d->vLayout); |
157 | |
158 | if (!d->tableView) { |
159 | d->tableView = new QTableView(); |
160 | d->tableView->setShowGrid(false); |
161 | QHeaderView* = d->tableView->horizontalHeader(); |
162 | headerView->setSectionResizeMode(QHeaderView::ResizeToContents); |
163 | d->tableView->verticalHeader()->hide(); |
164 | d->tableView->setSelectionMode(QAbstractItemView::SingleSelection); |
165 | d->tableView->setSelectionBehavior(QAbstractItemView::SelectItems); |
166 | } |
167 | |
168 | if (!d->model) |
169 | d->model = new EnvironmentModel(); |
170 | |
171 | d->tableView->setModel(d->model); |
172 | |
173 | d->vLayout->setSpacing(0); |
174 | d->vLayout->setMargin(0); |
175 | d->vLayout->addWidget(d->tableView); |
176 | |
177 | connect(d->tableView->selectionModel(), &QItemSelectionModel::currentChanged, [=](const QModelIndex ¤t){ |
178 | if (current.isValid() || d->tableView->selectionModel()->hasSelection()) { |
179 | emit deleteSignal(true); |
180 | } else { |
181 | emit deleteSignal(false); |
182 | } |
183 | }); |
184 | |
185 | initModel(); |
186 | } |
187 | |
188 | EnvironmentView::~EnvironmentView() |
189 | { |
190 | if(d) |
191 | delete d; |
192 | } |
193 | |
194 | const QMap<QString, QVariant> EnvironmentView::getEnvironment() |
195 | { |
196 | return d->model->getEnvironment(); |
197 | } |
198 | |
199 | void EnvironmentView::appendRow() |
200 | { |
201 | d->model->append("<KEY>" , "<VALUE>" ); |
202 | } |
203 | |
204 | void EnvironmentView::deleteRow() |
205 | { |
206 | QModelIndex index = d->tableView->currentIndex(); |
207 | d->model->remove(index); |
208 | } |
209 | |
210 | void EnvironmentView::initModel() |
211 | { |
212 | QMap<QString, QVariant> envs; |
213 | QStringList keys = QProcessEnvironment::systemEnvironment().keys(); |
214 | for (auto key : keys) { |
215 | QString value = QProcessEnvironment::systemEnvironment().value(key); |
216 | envs.insert(key, value); |
217 | } |
218 | |
219 | d->model->update(envs); |
220 | emit deleteSignal(false); |
221 | } |
222 | |
223 | void EnvironmentView::setValue(const QMap<QString, QVariant> &map) |
224 | { |
225 | d->model->update(map); |
226 | } |
227 | |
228 | |
229 | |
230 | |