1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "codeportingmanager.h"
6#include "configwidget.h"
7#include "common/widget/outputpane.h"
8#include "services/window/windowservice.h"
9#include "services/project/projectservice.h"
10#include "reportpane.h"
11
12#include <QtConcurrent>
13
14#define AsynInvoke(Fun) \
15 QtConcurrent::run([=]() { \
16 Fun; \
17 });
18
19static const int kLineNumberAdaptation = 1;
20using namespace dpfservice;
21CodePortingManager *CodePortingManager::instance()
22{
23 static CodePortingManager ins;
24 return &ins;
25}
26
27OutputPane *CodePortingManager::getOutputPane() const
28{
29 return outputPane;
30}
31
32QWidget *CodePortingManager::getReportPane() const
33{
34 return reportPane;
35}
36
37void CodePortingManager::slotShowConfigWidget()
38{
39 if (cfgWidget) {
40 cfgWidget->setModal(true);
41 cfgWidget->show();
42 }
43}
44
45void CodePortingManager::slotPortingStart(const QString &project, const QString &srcCPU, const QString &destCPU)
46{
47 if (codeporting.isRunning())
48 return;
49
50 resetUI();
51
52 QString projectSrcPath;
53 QString buildDir;
54 auto &ctx = dpfInstance.serviceContext();
55 ProjectService *projectService = ctx.service<ProjectService>(ProjectService::name());
56 if (projectService && projectService->getAllProjectInfo) {
57 auto allInfo = projectService->getAllProjectInfo();
58 if (allInfo.isEmpty()) {
59 return;
60 } else {
61 for (auto projInfo : allInfo) {
62 QString path = projInfo.workspaceFolder();
63 QString dirName = path.split("/").back();
64 if (dirName == project) {
65 projectSrcPath = path;
66 buildDir = projInfo.buildFolder();
67 break;
68 }
69 }
70 }
71 }
72 AsynInvoke(codeporting.start(projectSrcPath, srcCPU, buildDir, destCPU));
73}
74
75void CodePortingManager::slotPortingStatus(CodePorting::PortingStatus status)
76{
77 if (status == CodePorting::kSuccessful) {
78 reportPane->refreshDispaly();
79 }
80}
81
82void CodePortingManager::slotSelectedChanged(const QString &filePath, const QString &suggestion, int startLine, int endLine)
83{
84 Q_UNUSED(endLine)
85
86 int startLineInEditor = startLine + kLineNumberAdaptation;
87 int endLineInEditor = endLine + kLineNumberAdaptation;
88 editor.jumpToLine(filePath, startLineInEditor);
89 AnnotationInfo annInfo{AnnotationInfo::Role::get()->Note, suggestion};
90 editor.setAnnotation(filePath, startLine, QString("CodePorting"), annInfo);
91 QColor backgroundColor(Qt::red);
92 backgroundColor.setAlpha(100);
93 for (int lineNumber = startLineInEditor; lineNumber <= endLineInEditor; ++lineNumber) {
94 editor.setLineBackground(filePath, lineNumber, backgroundColor);
95 }
96}
97
98void CodePortingManager::slotAppendOutput(const QString &content, OutputPane::OutputFormat format, OutputPane::AppendMode mode)
99{
100 if (outputPane) {
101 QString newContent = content;
102 if (OutputPane::OutputFormat::NormalMessage == format
103 || OutputPane::OutputFormat::ErrorMessage == format) {
104 QDateTime curDatetime = QDateTime::currentDateTime();
105 QString time = curDatetime.toString("hh:mm:ss");
106 newContent = time + ": " + newContent;
107 }
108 outputPane->appendText(newContent, format, mode);
109 }
110}
111
112CodePortingManager::CodePortingManager(QObject *parent)
113 : QObject(parent),
114 cfgWidget(new ConfigWidget),
115 outputPane(new OutputPane),
116 reportPane(new ReportPane(&codeporting))
117{
118 qRegisterMetaType<OutputPane::OutputFormat>("OutputPane::OutputFormat");
119 qRegisterMetaType<OutputPane::AppendMode>("OutputPane::AppendMode");
120 qRegisterMetaType<CodePorting::PortingStatus>("PortingStatus");
121
122 connect(cfgWidget, &ConfigWidget::sigStartPorting, this, &CodePortingManager::slotPortingStart);
123 connect(&codeporting, &CodePorting::outputInformation, this, &CodePortingManager::slotAppendOutput);
124 connect(&codeporting, &CodePorting::notifyPortingStatus, this, &CodePortingManager::slotPortingStatus);
125 connect(reportPane, &ReportPane::selectedChanged, this, &CodePortingManager::slotSelectedChanged);
126}
127
128CodePortingManager::~CodePortingManager()
129{
130 if (cfgWidget) {
131 // delete cfgWidget; mainwindow released
132 cfgWidget = nullptr;
133 }
134
135 if (outputPane) {
136 // delete outputPane; mainwindow released
137 outputPane = nullptr;
138 }
139
140 if (reportPane) {
141 // delete reportPane; mainwindow released
142 reportPane = nullptr;
143 }
144}
145
146void CodePortingManager::resetUI()
147{
148 outputPane->clearContents();
149 editor.switchContext(tr("C&ode Porting"));
150}
151