1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "buildpropertywidget.h"
6
7#include "environmentwidget.h"
8#include "stepspane.h"
9#include "targetsmanager.h"
10
11#include <QComboBox>
12#include <QVBoxLayout>
13#include <QPushButton>
14#include <QFileDialog>
15#include <QStackedWidget>
16
17#include "common/common.h"
18
19using namespace config;
20
21class DetailPropertyWidgetPrivate
22{
23 friend class DetailPropertyWidget;
24
25 StepsPane *buildStepsPane{nullptr};
26 StepsPane *cleanStepsPane{nullptr};
27 EnvironmentWidget *envWidget{nullptr};
28};
29
30DetailPropertyWidget::DetailPropertyWidget(QWidget *parent)
31 : ConfigureWidget(parent)
32 , d(new DetailPropertyWidgetPrivate())
33{
34 d->buildStepsPane = new StepsPane(this);
35 d->cleanStepsPane = new StepsPane(this);
36 d->envWidget = new EnvironmentWidget(this);
37
38 CollapseWidget *buildStep = new CollapseWidget(QObject::tr("Build Steps"), d->buildStepsPane, this);
39 CollapseWidget *cleanStep = new CollapseWidget(QObject::tr("Clean Steps"), d->cleanStepsPane, this);
40 CollapseWidget *envStep = new CollapseWidget(QObject::tr("Runtime Env"), d->envWidget, this);
41
42 addCollapseWidget(buildStep);
43 addCollapseWidget(cleanStep);
44 addCollapseWidget(envStep);
45
46 buildStep->setChecked(false);
47}
48
49DetailPropertyWidget::~DetailPropertyWidget()
50{
51 if (d)
52 delete d;
53}
54
55void DetailPropertyWidget::setValues(const BuildConfigure &configure)
56{
57 for(auto iter = configure.steps.begin(); iter != configure.steps.end(); ++iter) {
58 if (iter->type == Build)
59 d->buildStepsPane->setValues(*iter);
60 else if (iter->type == Clean)
61 d->cleanStepsPane->setValues(*iter);
62 }
63
64 d->envWidget->setValues(configure.env);
65}
66
67void DetailPropertyWidget::getValues(BuildConfigure &configure)
68{
69 for(auto iter = configure.steps.begin(); iter != configure.steps.end(); ++iter) {
70 if (iter->type == Build)
71 d->buildStepsPane->getValues(*iter);
72 else if (iter->type == Clean)
73 d->cleanStepsPane->getValues(*iter);
74 }
75
76 d->envWidget->getValues(configure.env);
77}
78
79class BuildPropertyWidgetPrivate
80{
81 friend class BuildPropertyWidget;
82
83 QComboBox *configureComboBox{nullptr};
84 QLineEdit *outputDirEdit{nullptr};
85
86 QStackedWidget* stackWidget{nullptr};
87 dpfservice::ProjectInfo projectInfo;
88
89 QMap<StepType, dpfservice::TargetType> typeMap = {{StepType::Build, dpfservice::TargetType::kBuildTarget},
90 {StepType::Build, dpfservice::TargetType::kBuildTarget}};
91};
92
93BuildPropertyWidget::BuildPropertyWidget(const dpfservice::ProjectInfo &projectInfo, QWidget *parent)
94 : PageWidget(parent)
95 , d(new BuildPropertyWidgetPrivate())
96{
97 d->projectInfo = projectInfo;
98 setupOverviewUI();
99 initData(projectInfo);
100
101 QObject::connect(TargetsManager::instance(), &TargetsManager::initialized,
102 this, &BuildPropertyWidget::updateDetail);
103}
104
105BuildPropertyWidget::~BuildPropertyWidget()
106{
107 if (d)
108 delete d;
109}
110
111void BuildPropertyWidget::setupOverviewUI()
112{
113 QVBoxLayout *vLayout = new QVBoxLayout();
114 ConfigureWidget *buildCfgWidget = new ConfigureWidget();
115 vLayout->addWidget(buildCfgWidget);
116 setLayout(vLayout);
117
118 QVBoxLayout *overviewLayout = new QVBoxLayout();
119 QWidget *overviewWidget = new QWidget();
120 overviewWidget->setLayout(overviewLayout);
121
122 QHBoxLayout *configureLayout = new QHBoxLayout();
123 QLabel *configureLabel = new QLabel(QLabel::tr("Build configuration:"));
124 configureLabel->setFixedWidth(150);
125 d->configureComboBox = new QComboBox();
126 configureLayout->addWidget(configureLabel);
127 configureLayout->addWidget(d->configureComboBox);
128 configureLayout->setSpacing(10);
129 configureLayout->addStretch();
130 QObject::connect(d->configureComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index){
131 QVariant var = d->configureComboBox->itemData(index, Qt::UserRole + 1);
132 if (var.isValid()) {
133 QString directory = var.value<QString>();
134 if (d->outputDirEdit) {
135 d->outputDirEdit->setText(directory);
136 }
137 }
138
139 var = d->configureComboBox->itemData(index, Qt::UserRole + 2);
140 if (var.isValid()) {
141 DetailPropertyWidget *detail = var.value<DetailPropertyWidget *>();
142 if (detail && d->stackWidget) {
143 d->stackWidget->setCurrentWidget(detail);
144 }
145 }
146
147 ConfigureParam *param = ConfigUtil::instance()->getConfigureParamPointer();
148 param->tempSelType = ConfigUtil::instance()->getTypeFromName(d->configureComboBox->currentText());
149 ConfigUtil::instance()->checkConfigInfo(d->configureComboBox->currentText(), d->outputDirEdit->text());
150 });
151
152 QHBoxLayout *hLayout = new QHBoxLayout(this);
153 QLabel *label = new QLabel(this);
154 label->setText(tr("Output direcotry:"));
155 label->setFixedWidth(150);
156 d->outputDirEdit = new QLineEdit(this);
157 d->outputDirEdit->setReadOnly(true);
158 auto button = new QPushButton(this);
159 button->setText(tr("Browse..."));
160 connect(button, &QPushButton::clicked, [this](){
161 QString outputDirectory = QFileDialog::getExistingDirectory(this, "Output directory", d->outputDirEdit->text());
162 if (!outputDirectory.isEmpty()) {
163 QString oldDir = d->outputDirEdit->text();
164 d->outputDirEdit->setText(outputDirectory.toUtf8());
165 int index = d->configureComboBox->currentIndex();
166 d->configureComboBox->setItemData(index, QVariant::fromValue(outputDirectory.toUtf8()), Qt::UserRole + 1);
167
168 if (outputDirectory != oldDir) {
169 ConfigUtil::instance()->checkConfigInfo(d->configureComboBox->currentText(), d->outputDirEdit->text());
170 }
171 }
172 });
173
174 hLayout->addWidget(label);
175 hLayout->addWidget(d->outputDirEdit);
176 hLayout->addWidget(button);
177 hLayout->setSpacing(10);
178
179 overviewLayout->setSpacing(0);
180 overviewLayout->setMargin(0);
181 overviewLayout->addLayout(configureLayout);
182 overviewLayout->setSpacing(5);
183 overviewLayout->addLayout(hLayout);
184
185 buildCfgWidget->addWidget(overviewWidget);
186 d->stackWidget = new QStackedWidget();
187 buildCfgWidget->addWidget(d->stackWidget);
188}
189
190void BuildPropertyWidget::initData(const dpfservice::ProjectInfo &projectInfo)
191{
192 d->configureComboBox->clear();
193
194 ConfigureParam *param = ConfigUtil::instance()->getConfigureParamPointer();
195 ConfigUtil::instance()->readConfig(ConfigUtil::instance()->getConfigPath(projectInfo.workspaceFolder()), *param);
196
197 auto iter = param->buildConfigures.begin();
198 int index = 0;
199 for (; iter != param->buildConfigures.end(); ++iter, index++) {
200 for (auto iterStep = iter->steps.begin(); iterStep != iter->steps.end(); ++iterStep) {
201 if (iterStep->targetList.isEmpty()) {
202 iterStep->targetList = TargetsManager::instance()->getTargetNamesList();
203 dpfservice::TargetType targetType = dpfservice::TargetType::kUnknown;
204 if (iterStep->type == Build) {
205 targetType = dpfservice::TargetType::kBuildTarget;
206 } else if (iterStep->type == Clean) {
207 targetType = dpfservice::TargetType::kCleanTarget;
208 }
209 dpfservice::Target target = TargetsManager::instance()->getActivedTargetByTargetType(targetType);
210 iterStep->targetName = target.buildTarget;
211 }
212 }
213
214 DetailPropertyWidget *detailWidget = new DetailPropertyWidget();
215 detailWidget->setValues(*iter);
216 d->stackWidget->insertWidget(index, detailWidget);
217
218 d->configureComboBox->insertItem(index, ConfigUtil::instance()->getNameFromType(iter->type));
219 d->configureComboBox->setItemData(index, QVariant::fromValue(iter->directory), Qt::UserRole + 1);
220 d->configureComboBox->setItemData(index, QVariant::fromValue(detailWidget), Qt::UserRole + 2);
221 if (param->defaultType == iter->type) {
222 d->configureComboBox->setCurrentIndex(index);
223 d->outputDirEdit->setText(iter->directory);
224 d->stackWidget->setCurrentWidget(detailWidget);
225 }
226
227 initRunConfig(iter->directory, iter->runConfigure);
228 }
229
230}
231
232void BuildPropertyWidget::updateDetail()
233{
234 ConfigureParam *param = ConfigUtil::instance()->getConfigureParamPointer();
235
236 QString currentTypeString = d->configureComboBox->currentText();
237 auto iter = param->buildConfigures.begin();
238 for (; iter != param->buildConfigures.end(); ++iter) {
239 if (iter->type == ConfigUtil::instance()->getTypeFromName(currentTypeString)) {
240 for (auto iterStep = iter->steps.begin(); iterStep != iter->steps.end(); ++iterStep) {
241 iterStep->targetList = TargetsManager::instance()->getTargetNamesList();
242 dpfservice::Target target = TargetsManager::instance()->getActivedTargetByTargetType(d->typeMap.value(iterStep->type));
243 iterStep->targetName = target.buildTarget;
244 }
245
246 DetailPropertyWidget *detail = dynamic_cast<DetailPropertyWidget *>(d->stackWidget->currentWidget());
247 if (detail) {
248 detail->setValues(*iter);
249 }
250
251 break;
252 }
253
254 initRunConfig(iter->directory, iter->runConfigure);
255 }
256}
257
258void BuildPropertyWidget::initRunConfig(const QString &workDirectory, RunConfigure &runConfigure)
259{
260 if (runConfigure.params.isEmpty()) {
261 QStringList exeTargetList = TargetsManager::instance()->getExeTargetNamesList();
262 foreach (auto targetName, exeTargetList) {
263 RunParam param;
264 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
265 foreach (auto key, env.keys()) {
266 param.env.environments.insert(key, env.value(key));
267 }
268 param.targetName = targetName;
269 dpfservice::Target target = TargetsManager::instance()->getTargetByName(targetName);
270 param.targetPath = target.output;
271
272 runConfigure.params.push_back(param);
273 }
274
275 dpfservice::Target target = TargetsManager::instance()->getActivedTargetByTargetType(dpfservice::TargetType::kActiveExecTarget);
276 runConfigure.defaultTargetName = target.buildTarget;
277 }
278}
279
280void BuildPropertyWidget::readConfig()
281{
282
283}
284
285void BuildPropertyWidget::saveConfig()
286{
287 ConfigureParam *param = ConfigUtil::instance()->getConfigureParamPointer();
288 auto iter = param->buildConfigures.begin();
289 int index = 0;
290 for (; iter != param->buildConfigures.end(); ++iter) {
291 DetailPropertyWidget *detailWidget = dynamic_cast<DetailPropertyWidget *>(d->stackWidget->widget(index));
292 if (detailWidget) {
293 detailWidget->getValues(*iter);
294 }
295
296 for (int i = 0; i < d->configureComboBox->count(); i++) {
297 ConfigType type = ConfigUtil::instance()->getTypeFromName(d->configureComboBox->itemText(i));
298 if (type == iter->type) {
299 QVariant var = d->configureComboBox->itemData(index, Qt::UserRole + 1);
300 if (var.isValid()) {
301 iter->directory = var.value<QString>();
302 }
303
304 if (d->configureComboBox->currentIndex() == i)
305 param->defaultType = type;
306
307 break;
308 }
309 }
310
311 index++;
312 }
313}
314