1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #include "stepspane.h" |
6 | |
7 | #include "services/project/projectservice.h" |
8 | |
9 | #include <QVBoxLayout> |
10 | #include <QHBoxLayout> |
11 | #include <QCheckBox> |
12 | #include <QHeaderView> |
13 | #include <QTableView> |
14 | #include <QLineEdit> |
15 | #include <QLabel> |
16 | |
17 | const QString ENABLE_ALL_ENV = StepsPane::tr("Enable All BuildSteps" ); |
18 | static const char *kBuildTitle = "Build:" ; |
19 | static const char *kBuildCommand = "cmake --build . --target " ; |
20 | |
21 | class StepsModelPrivate |
22 | { |
23 | friend class StepsModel; |
24 | |
25 | QMap<QString, bool> targets; |
26 | }; |
27 | |
28 | StepsModel::StepsModel(QObject *parent) |
29 | : QAbstractTableModel(parent) |
30 | , d (new StepsModelPrivate()) |
31 | { |
32 | |
33 | } |
34 | |
35 | StepsModel::~StepsModel() |
36 | { |
37 | |
38 | } |
39 | |
40 | int StepsModel::rowCount(const QModelIndex &) const |
41 | { |
42 | return d->targets.keys().size(); |
43 | } |
44 | |
45 | int StepsModel::columnCount(const QModelIndex &) const |
46 | { |
47 | return kColumnCount; |
48 | } |
49 | |
50 | QVariant StepsModel::data(const QModelIndex &index, int role) const |
51 | { |
52 | if (!index.isValid()) |
53 | return QVariant(); |
54 | |
55 | if (index.row() >= d->targets.size()) |
56 | return QVariant(); |
57 | |
58 | QString target = d->targets.keys().at(index.row()); |
59 | if (role == Qt::DisplayRole || role == Qt::EditRole) { |
60 | switch (index.column()) { |
61 | case kTarget: |
62 | return target; |
63 | case kPath: |
64 | return "" ; |
65 | default: |
66 | break; |
67 | } |
68 | } else if (role == Qt::CheckStateRole) { |
69 | int CHECK_BOX_COLUMN = 0; |
70 | if (index.column() == CHECK_BOX_COLUMN) { |
71 | if (d->targets.value(target)) { |
72 | return Qt::Checked; |
73 | } else { |
74 | return Qt::Unchecked; |
75 | } |
76 | } |
77 | } else if (role == Qt::TextAlignmentRole) { |
78 | return QVariant(Qt::AlignLeft | Qt::AlignVCenter); |
79 | } |
80 | return QVariant(); |
81 | } |
82 | |
83 | QVariant StepsModel::(int section, Qt::Orientation orientation, int role) const |
84 | { |
85 | switch (role) |
86 | { |
87 | case Qt::TextAlignmentRole: |
88 | return QVariant(Qt::AlignLeft | Qt::AlignVCenter); |
89 | case Qt::DisplayRole: |
90 | { |
91 | if (orientation == Qt::Horizontal) { |
92 | switch (section) { |
93 | case kTarget: |
94 | return "Target" ; |
95 | case kPath: |
96 | return "Path" ; |
97 | default: |
98 | break; |
99 | } |
100 | } |
101 | } |
102 | } |
103 | return QVariant(); |
104 | } |
105 | |
106 | Qt::ItemFlags StepsModel::flags(const QModelIndex &index) const |
107 | { |
108 | if (!index.isValid()) |
109 | return QAbstractItemModel::flags(index); |
110 | |
111 | Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; |
112 | int CHECK_BOX_COLUMN = 0; |
113 | if (index.column() == CHECK_BOX_COLUMN) |
114 | flags |= Qt::ItemIsUserCheckable; |
115 | |
116 | return flags; |
117 | } |
118 | |
119 | bool StepsModel::setData(const QModelIndex &index, const QVariant &value, int role) |
120 | { |
121 | if (!index.isValid()) |
122 | return false; |
123 | |
124 | if (index.row() >= d->targets.size()) |
125 | return false; |
126 | |
127 | int nColumn = index.column(); |
128 | QString target = d->targets.keys().at(index.row()); |
129 | switch (role) |
130 | { |
131 | case Qt::DisplayRole: |
132 | { |
133 | return QAbstractTableModel::setData(index, value, role); |
134 | } |
135 | case Qt::CheckStateRole: |
136 | { |
137 | int CHECK_BOX_COLUMN = 0; |
138 | if (nColumn == CHECK_BOX_COLUMN) { |
139 | beginResetModel(); |
140 | |
141 | bool bChecked = (value.toInt() == Qt::Checked); |
142 | d->targets[target] = bChecked; |
143 | |
144 | if (bChecked) { |
145 | foreach (auto key, d->targets.keys()) { |
146 | if(key != target) { |
147 | d->targets[key] = !bChecked; |
148 | } |
149 | } |
150 | } |
151 | |
152 | emit dataChanged(index, index); |
153 | |
154 | endResetModel(); |
155 | return true; |
156 | } |
157 | break; |
158 | } |
159 | default: |
160 | return false; |
161 | } |
162 | return false; |
163 | } |
164 | |
165 | void StepsModel::setData(const QMap<QString, bool> &data) |
166 | { |
167 | beginResetModel(); |
168 | d->targets = data; |
169 | endResetModel(); |
170 | } |
171 | |
172 | QString StepsModel::getSelectedTarget() |
173 | { |
174 | QString selectedTarget; |
175 | foreach (auto key, d->targets.keys()) { |
176 | if(d->targets.value(key)) { |
177 | selectedTarget = key; |
178 | } |
179 | } |
180 | |
181 | return selectedTarget; |
182 | } |
183 | |
184 | class StepsPanePrivate |
185 | { |
186 | friend class StepsPane; |
187 | |
188 | QLineEdit *toolArguments{nullptr}; |
189 | QLabel *buildLabel{nullptr}; |
190 | StepsModel *model{nullptr}; |
191 | }; |
192 | |
193 | StepsPane::StepsPane(QWidget *parent) |
194 | : QWidget(parent) |
195 | , d(new StepsPanePrivate) |
196 | { |
197 | setupUi(); |
198 | |
199 | updateSummaryText(); |
200 | } |
201 | |
202 | StepsPane::~StepsPane() |
203 | { |
204 | if(d) { |
205 | delete d; |
206 | } |
207 | } |
208 | |
209 | void StepsPane::setupUi() |
210 | { |
211 | setAutoFillBackground(true); |
212 | |
213 | QVBoxLayout *vLayout = new QVBoxLayout(this); |
214 | |
215 | d->buildLabel = new QLabel(this); |
216 | d->buildLabel->setText(QString("Build:" ).append(kBuildCommand)); |
217 | |
218 | QTableView *tableView = new QTableView(); |
219 | tableView->setShowGrid(false); |
220 | QHeaderView* = tableView->horizontalHeader(); |
221 | headerView->setSectionResizeMode(QHeaderView::ResizeToContents); |
222 | headerView->setSelectionMode(QAbstractItemView::SingleSelection); |
223 | tableView->verticalHeader()->hide(); |
224 | |
225 | d->model = new StepsModel(); |
226 | tableView->setModel(d->model); |
227 | |
228 | QHBoxLayout *hLayout = new QHBoxLayout(this); |
229 | d->toolArguments = new QLineEdit(this); |
230 | d->toolArguments->setPlaceholderText(tr("Input your arguments." )); |
231 | QLabel *label = new QLabel(tr("Tool arguments:" ), this); |
232 | hLayout->addWidget(label); |
233 | hLayout->addWidget(d->toolArguments); |
234 | |
235 | vLayout->setMargin(0); |
236 | vLayout->addWidget(d->buildLabel); |
237 | vLayout->addLayout(hLayout); |
238 | vLayout->addWidget(tableView); |
239 | |
240 | connect(d->toolArguments, &QLineEdit::textEdited, this, &StepsPane::toolArgumentsEdited); |
241 | connect(d->model, &StepsModel::dataChanged, this, &StepsPane::dataChanged); |
242 | |
243 | setLayout(vLayout); |
244 | } |
245 | |
246 | void StepsPane::toolArgumentsEdited() |
247 | { |
248 | updateSummaryText(); |
249 | } |
250 | |
251 | void StepsPane::dataChanged() |
252 | { |
253 | updateSummaryText(); |
254 | } |
255 | |
256 | QString StepsPane::getCombinedBuildText() |
257 | { |
258 | QString head = kBuildTitle; |
259 | QString defaultCommand = kBuildCommand; |
260 | QString arguments = d->toolArguments->text(); |
261 | |
262 | QString buildText = head + defaultCommand + d->model->getSelectedTarget() + (arguments.isEmpty() ? "" : " -- " + arguments); |
263 | return buildText; |
264 | } |
265 | |
266 | void StepsPane::updateSummaryText() |
267 | { |
268 | d->buildLabel->setText(getCombinedBuildText()); |
269 | } |
270 | |
271 | void StepsPane::setValues(const config::StepItem &item) |
272 | { |
273 | d->toolArguments->setText(item.arguments); |
274 | |
275 | QMap<QString, bool> data; |
276 | foreach (auto targetName, item.targetList) { |
277 | data.insert(targetName, targetName == item.targetName ? true : false); |
278 | } |
279 | |
280 | d->model->setData(data); |
281 | updateSummaryText(); |
282 | } |
283 | |
284 | void StepsPane::getValues(config::StepItem &item) |
285 | { |
286 | item.arguments = d->toolArguments->text(); |
287 | item.targetName = d->model->getSelectedTarget(); |
288 | } |
289 | |