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
17const QString ENABLE_ALL_ENV = StepsPane::tr("Enable All BuildSteps");
18static const char *kBuildTitle = "Build:";
19static const char *kBuildCommand = "cmake --build . --target ";
20
21class StepsModelPrivate
22{
23 friend class StepsModel;
24
25 QMap<QString, bool> targets;
26};
27
28StepsModel::StepsModel(QObject *parent)
29 : QAbstractTableModel(parent)
30 , d (new StepsModelPrivate())
31{
32
33}
34
35StepsModel::~StepsModel()
36{
37
38}
39
40int StepsModel::rowCount(const QModelIndex &) const
41{
42 return d->targets.keys().size();
43}
44
45int StepsModel::columnCount(const QModelIndex &) const
46{
47 return kColumnCount;
48}
49
50QVariant 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
83QVariant StepsModel::headerData(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
106Qt::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
119bool 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
165void StepsModel::setData(const QMap<QString, bool> &data)
166{
167 beginResetModel();
168 d->targets = data;
169 endResetModel();
170}
171
172QString 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
184class StepsPanePrivate
185{
186 friend class StepsPane;
187
188 QLineEdit *toolArguments{nullptr};
189 QLabel *buildLabel{nullptr};
190 StepsModel *model{nullptr};
191};
192
193StepsPane::StepsPane(QWidget *parent)
194 : QWidget(parent)
195 , d(new StepsPanePrivate)
196{
197 setupUi();
198
199 updateSummaryText();
200}
201
202StepsPane::~StepsPane()
203{
204 if(d) {
205 delete d;
206 }
207}
208
209void 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* headerView = 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
246void StepsPane::toolArgumentsEdited()
247{
248 updateSummaryText();
249}
250
251void StepsPane::dataChanged()
252{
253 updateSummaryText();
254}
255
256QString 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
266void StepsPane::updateSummaryText()
267{
268 d->buildLabel->setText(getCombinedBuildText());
269}
270
271void 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
284void StepsPane::getValues(config::StepItem &item)
285{
286 item.arguments = d->toolArguments->text();
287 item.targetName = d->model->getSelectedTarget();
288}
289