| 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 | |