1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #include "configwidget.h" |
6 | #include "services/project/projectservice.h" |
7 | #include "common/util/custompaths.h" |
8 | |
9 | #include <QtCore/QVariant> |
10 | #include <QtWidgets/QApplication> |
11 | #include <QtWidgets/QComboBox> |
12 | #include <QtWidgets/QGridLayout> |
13 | #include <QtWidgets/QHBoxLayout> |
14 | #include <QtWidgets/QLabel> |
15 | #include <QtWidgets/QPushButton> |
16 | #include <QtWidgets/QSpacerItem> |
17 | #include <QtWidgets/QVBoxLayout> |
18 | #include <QtWidgets/QWidget> |
19 | |
20 | static const char *kConfigFileName = "codeporting.cfg" ; |
21 | static const char *kSrcCPU = "Src CPU" ; |
22 | static const char *kTargetCPU = "Target CPU" ; |
23 | |
24 | // TODO(mozart):These value should get from backend later. |
25 | static const char *kX86_64 = "x86_64" ; |
26 | static const char *kArm = "arm64" ; |
27 | static const char *kMips = "mips64el" ; |
28 | static const char *kSW_64 = "sw_64" ; |
29 | static const char *kLoongarch64 = "loongarch64" ; |
30 | |
31 | static const char *kSupportKit [] = {"cmake" }; |
32 | |
33 | using namespace dpfservice; |
34 | |
35 | struct ConfigParameter |
36 | { |
37 | QString project; |
38 | QString srcCPU; |
39 | QString targetCPU; |
40 | QString reserve; |
41 | }; |
42 | |
43 | class ConfigWidgetPrivate |
44 | { |
45 | friend ConfigWidget; |
46 | QVBoxLayout *verticalLayout = nullptr; |
47 | QGridLayout *gridLayout = nullptr; |
48 | QLabel *lbProject = nullptr; |
49 | QComboBox *combProject = nullptr; |
50 | QLabel *lbSrc = nullptr; |
51 | QComboBox *combSrc = nullptr; |
52 | QLabel *lbTarget = nullptr; |
53 | QComboBox *combTarget = nullptr; |
54 | QSpacerItem *verticalSpacer = nullptr; |
55 | QHBoxLayout *horizontalLayout = nullptr; |
56 | QSpacerItem *horizontalSpacer = nullptr; |
57 | QPushButton *btnPoting = nullptr; |
58 | QPushButton *btnCancel = nullptr; |
59 | QLabel *lbWarning = nullptr; |
60 | |
61 | ConfigParameter cfgParam; |
62 | }; |
63 | |
64 | ConfigWidget::ConfigWidget(QWidget *parent) |
65 | : QDialog(parent) |
66 | , d(new ConfigWidgetPrivate) |
67 | { |
68 | setupUi(this); |
69 | |
70 | initializeUi(); |
71 | |
72 | if (!restore()) { |
73 | setDefaultValue(); |
74 | } |
75 | |
76 | connect(d->btnPoting, &QPushButton::clicked, this, &ConfigWidget::configDone); |
77 | connect(d->btnCancel, &QPushButton::clicked, this, &ConfigWidget::reject); |
78 | } |
79 | |
80 | void ConfigWidget::configDone() |
81 | { |
82 | d->cfgParam.project = d->combProject->currentText(); |
83 | d->cfgParam.srcCPU = d->combSrc->currentText(); |
84 | d->cfgParam.targetCPU = d->combTarget->currentText(); |
85 | |
86 | // empty parameter check. |
87 | if (d->cfgParam.project.isEmpty() |
88 | || d->cfgParam.srcCPU.isEmpty() |
89 | || d->cfgParam.targetCPU.isEmpty()) { |
90 | d->lbWarning->setText(tr("Warning: parameter is empty!" )); |
91 | return; |
92 | } |
93 | |
94 | // repeat paramter check. |
95 | if (d->cfgParam.srcCPU == d->cfgParam.targetCPU) { |
96 | d->lbWarning->setText(tr("Warning: source cpu and target cpu should not be the same!" )); |
97 | return; |
98 | } |
99 | |
100 | saveCfg(); |
101 | |
102 | accept(); |
103 | |
104 | d->lbWarning->clear(); |
105 | |
106 | emit sigStartPorting(d->cfgParam.project, d->cfgParam.srcCPU, d->cfgParam.targetCPU); |
107 | } |
108 | |
109 | void ConfigWidget::showEvent(QShowEvent *e) |
110 | { |
111 | refreshUi(); |
112 | |
113 | QDialog::showEvent(e); |
114 | } |
115 | |
116 | void ConfigWidget::initializeUi() |
117 | { |
118 | d->combSrc->addItem(kX86_64); |
119 | d->combSrc->addItem(kArm); |
120 | d->combSrc->addItem(kMips); |
121 | d->combSrc->addItem(kSW_64); |
122 | d->combSrc->addItem(kLoongarch64); |
123 | |
124 | d->combTarget->addItem(kX86_64); |
125 | d->combTarget->addItem(kArm); |
126 | d->combTarget->addItem(kMips); |
127 | d->combTarget->addItem(kSW_64); |
128 | d->combTarget->addItem(kLoongarch64); |
129 | } |
130 | |
131 | void ConfigWidget::setDefaultValue() |
132 | { |
133 | d->cfgParam.srcCPU = "x86_64" ; |
134 | d->cfgParam.targetCPU = "arm64" ; |
135 | } |
136 | |
137 | void ConfigWidget::setupUi(QWidget *Widget) |
138 | { |
139 | Widget->setWindowTitle(tr("CodePorting config" )); |
140 | Widget->resize(500, 200); |
141 | d->verticalLayout = new QVBoxLayout(Widget); |
142 | d->verticalLayout->setSpacing(6); |
143 | d->verticalLayout->setContentsMargins(11, 11, 11, 11); |
144 | d->verticalLayout->setContentsMargins(40, 20, 40, 20); |
145 | d->gridLayout = new QGridLayout(); |
146 | d->gridLayout->setSpacing(6); |
147 | d->lbProject = new QLabel(Widget); |
148 | d->lbProject->setText(tr("Project:" )); |
149 | |
150 | d->gridLayout->addWidget(d->lbProject, 0, 0, 1, 1); |
151 | |
152 | d->combProject = new QComboBox(Widget); |
153 | |
154 | d->gridLayout->addWidget(d->combProject, 0, 1, 1, 1); |
155 | |
156 | d->lbSrc = new QLabel(Widget); |
157 | d->lbSrc->setText(tr("Source CPU Architecture:" )); |
158 | |
159 | d->gridLayout->addWidget(d->lbSrc, 1, 0, 1, 1); |
160 | |
161 | d->combSrc = new QComboBox(Widget); |
162 | |
163 | d->gridLayout->addWidget(d->combSrc, 1, 1, 1, 1); |
164 | |
165 | d->lbTarget = new QLabel(Widget); |
166 | d->lbTarget->setText(tr("Target CPU Architecture:" )); |
167 | |
168 | d->gridLayout->addWidget(d->lbTarget, 2, 0, 1, 1); |
169 | |
170 | d->combTarget = new QComboBox(Widget); |
171 | |
172 | d->gridLayout->addWidget(d->combTarget, 2, 1, 1, 1); |
173 | |
174 | d->verticalLayout->addLayout(d->gridLayout); |
175 | |
176 | d->lbWarning = new QLabel(Widget); |
177 | QPalette pe; |
178 | pe.setColor(QPalette::Text, Qt::yellow); |
179 | d->lbWarning->setPalette(pe); |
180 | |
181 | d->verticalLayout->addWidget(d->lbWarning); |
182 | |
183 | d->verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); |
184 | |
185 | d->verticalLayout->addItem(d->verticalSpacer); |
186 | |
187 | d->horizontalLayout = new QHBoxLayout(); |
188 | d->horizontalSpacer = new QSpacerItem(40, 30, QSizePolicy::Expanding, QSizePolicy::Minimum); |
189 | |
190 | d->horizontalLayout->addItem(d->horizontalSpacer); |
191 | |
192 | d->btnPoting = new QPushButton(Widget); |
193 | d->btnPoting->setText(tr("Porting" )); |
194 | d->btnPoting->setDefault(true); |
195 | |
196 | d->horizontalLayout->addWidget(d->btnPoting); |
197 | |
198 | d->btnCancel = new QPushButton(Widget); |
199 | d->btnCancel->setText(tr("Cancel" )); |
200 | |
201 | d->horizontalLayout->addWidget(d->btnCancel); |
202 | |
203 | d->verticalLayout->addLayout(d->horizontalLayout); |
204 | } |
205 | |
206 | void ConfigWidget::resetUi() |
207 | { |
208 | int emptyIndex = -1; |
209 | d->combProject->setCurrentIndex(emptyIndex); |
210 | d->combSrc->setCurrentIndex(emptyIndex); |
211 | d->combTarget->setCurrentIndex(emptyIndex); |
212 | } |
213 | |
214 | void ConfigWidget::refreshDetail() |
215 | { |
216 | d->combSrc->setCurrentText(d->cfgParam.srcCPU); |
217 | d->combTarget->setCurrentText(d->cfgParam.targetCPU); |
218 | } |
219 | |
220 | bool ConfigWidget::saveCfg() |
221 | { |
222 | QString cfgFilePath = configFilePath(); |
223 | |
224 | QJsonArray paramsArray; |
225 | |
226 | QJsonObject valueObj; |
227 | valueObj.insert(kSrcCPU, d->cfgParam.srcCPU); |
228 | valueObj.insert(kTargetCPU, d->cfgParam.targetCPU); |
229 | |
230 | paramsArray.append(valueObj); |
231 | |
232 | QJsonObject rootObject; |
233 | rootObject.insert("Configure" , paramsArray); |
234 | QJsonDocument doc; |
235 | doc.setObject(rootObject); |
236 | QString jsonStr(doc.toJson(QJsonDocument::Indented)); |
237 | |
238 | QFile file(cfgFilePath); |
239 | if (!file.open(QIODevice::WriteOnly)) |
240 | return false; |
241 | |
242 | file.write(jsonStr.toUtf8()); |
243 | file.close(); |
244 | |
245 | return true; |
246 | } |
247 | |
248 | bool ConfigWidget::restore() |
249 | { |
250 | QString cfgFilePath = configFilePath(); |
251 | |
252 | QFile file(cfgFilePath); |
253 | if (!file.open(QIODevice::ReadOnly)) |
254 | return false; |
255 | |
256 | QByteArray data = file.readAll(); |
257 | file.close(); |
258 | |
259 | QJsonParseError parseError; |
260 | QJsonDocument doc = QJsonDocument::fromJson(data, &parseError); |
261 | if (QJsonParseError::NoError != parseError.error) { |
262 | return false; |
263 | } |
264 | |
265 | if (!doc.isObject()) |
266 | return false; |
267 | |
268 | QJsonObject rootObject = doc.object(); |
269 | for (auto key : rootObject.keys()) { |
270 | if (!rootObject.value(key).isArray() || !rootObject.keys().contains("Configure" )) |
271 | continue; |
272 | |
273 | if (rootObject.keys().contains("Configure" )) { |
274 | QJsonArray valueArray = rootObject.value("Configure" ).toArray(); |
275 | |
276 | for (QJsonValue value : valueArray) { |
277 | QJsonObject obj = value.toObject(); |
278 | d->cfgParam.srcCPU = obj.value(kSrcCPU).toString(); |
279 | d->cfgParam.targetCPU = obj.value(kTargetCPU).toString(); |
280 | } |
281 | } |
282 | } |
283 | return true; |
284 | } |
285 | |
286 | QString ConfigWidget::configFilePath() |
287 | { |
288 | return CustomPaths::endSeparator(CustomPaths::user(CustomPaths::Configures)) + kConfigFileName; |
289 | } |
290 | |
291 | void ConfigWidget::refreshUi() |
292 | { |
293 | auto &ctx = dpfInstance.serviceContext(); |
294 | ProjectService *projectService = ctx.service<ProjectService>(ProjectService::name()); |
295 | d->combProject->clear(); |
296 | if (projectService && projectService->getAllProjectInfo) { |
297 | auto allInfo = projectService->getAllProjectInfo(); |
298 | if (allInfo.isEmpty()) { |
299 | resetUi(); |
300 | return; |
301 | } else { |
302 | for (auto projInfo : allInfo) { |
303 | QString path = projInfo.workspaceFolder(); |
304 | QString dirName = path.split("/" ).back(); |
305 | QString kitName = projInfo.kitName(); |
306 | int supportkitCount = sizeof(kSupportKit)/sizeof(kSupportKit[0]); |
307 | for (int i = 0; i < supportkitCount; ++i) { |
308 | if (kSupportKit[i] == projInfo.kitName()) { |
309 | d->combProject->addItem(dirName); |
310 | break; |
311 | } |
312 | } |
313 | } |
314 | } |
315 | } |
316 | refreshDetail(); |
317 | } |
318 | |