1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #include "binarytoolsdialog.h" |
6 | #include "binarytoolsconfigview.h" |
7 | #include "common/util/eventdefinitions.h" |
8 | |
9 | #include <QPushButton> |
10 | #include <QDialogButtonBox> |
11 | #include <QProcess> |
12 | #include <QBoxLayout> |
13 | #include <QTextBlock> |
14 | |
15 | class BinaryToolsDialogPrivate |
16 | { |
17 | friend class BinaryToolsDialog; |
18 | BinaryToolsConfigView *configView = nullptr; |
19 | QDialogButtonBox *buttons = nullptr; |
20 | }; |
21 | |
22 | BinaryToolsDialog::BinaryToolsDialog(QDialog *parent) |
23 | : QDialog(parent) |
24 | , d (new BinaryToolsDialogPrivate) |
25 | { |
26 | setWindowTitle(tr("Binary Tools" )); |
27 | |
28 | QVBoxLayout *vLayout = new QVBoxLayout(this); |
29 | vLayout->setContentsMargins(20, 20, 20, 20); |
30 | vLayout->setSpacing(6); |
31 | |
32 | d->configView = new BinaryToolsConfigView; |
33 | vLayout->addWidget(d->configView); |
34 | vLayout->addStretch(); |
35 | |
36 | QHBoxLayout * buttonLayout = new QHBoxLayout(); |
37 | d->buttons = new QDialogButtonBox(this); |
38 | d->buttons->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Save | QDialogButtonBox::Cancel); |
39 | d->buttons->button(QDialogButtonBox::Apply)->setText(tr("Use Tool" )); |
40 | d->buttons->button(QDialogButtonBox::Save)->setText(tr("Save" )); |
41 | d->buttons->button(QDialogButtonBox::Cancel)->setText(tr("Cancel" )); |
42 | d->buttons->button(QDialogButtonBox::Apply)->setDefault(true); |
43 | buttonLayout->addWidget(d->buttons); |
44 | vLayout->addLayout(buttonLayout); |
45 | |
46 | connect(d->configView, &BinaryToolsConfigView::useCombinationCommand, [=](){ |
47 | QtConcurrent::run([=](){ |
48 | useClicked(); |
49 | }); |
50 | }); |
51 | connect(d->buttons->button(QDialogButtonBox::Apply), &QPushButton::clicked, [=](){ |
52 | QtConcurrent::run([=](){ |
53 | useClicked(); |
54 | }); |
55 | }); |
56 | connect(d->buttons->button(QDialogButtonBox::Save), &QPushButton::clicked, this, &BinaryToolsDialog::saveClicked); |
57 | connect(d->buttons, &QDialogButtonBox::rejected, this, &BinaryToolsDialog::reject); |
58 | connect(d->buttons, &QDialogButtonBox::accepted, this, &BinaryToolsDialog::accept); |
59 | } |
60 | |
61 | BinaryToolsDialog::~BinaryToolsDialog() |
62 | { |
63 | if (d) |
64 | delete d; |
65 | } |
66 | |
67 | void BinaryToolsDialog::printOutput(const QString &content, OutputPane::OutputFormat format) |
68 | { |
69 | editor.switchContext(tr("&Application Output" )); |
70 | auto outputPane = OutputPane::instance(); |
71 | QString outputContent = content; |
72 | if (format == OutputPane::OutputFormat::NormalMessage) { |
73 | QTextDocument *doc = outputPane->document(); |
74 | QTextBlock tb = doc->lastBlock(); |
75 | QString lastLineText = tb.text(); |
76 | QString prefix = "\n" ; |
77 | if (lastLineText.isEmpty()) { |
78 | prefix = "" ; |
79 | } |
80 | QDateTime curDatetime = QDateTime::currentDateTime(); |
81 | QString time = curDatetime.toString("hh:mm:ss" ); |
82 | outputContent = prefix + time + ":" + content; |
83 | } |
84 | outputContent += "\n" ; |
85 | OutputPane::AppendMode mode = OutputPane::AppendMode::Normal; |
86 | outputPane->appendText(outputContent, format, mode); |
87 | } |
88 | |
89 | void BinaryToolsDialog::saveClicked() |
90 | { |
91 | d->configView->saveConfig(); |
92 | } |
93 | |
94 | void BinaryToolsDialog::useClicked() |
95 | { |
96 | d->configView->saveConfig(); |
97 | |
98 | QProcess proc; |
99 | QString retMsg = tr("Error: execute command error! The reason is unknown.\n" );; |
100 | connect(&proc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), |
101 | [&](int exitcode, QProcess::ExitStatus exitStatus) { |
102 | if (0 == exitcode && exitStatus == QProcess::ExitStatus::NormalExit) { |
103 | retMsg = tr("The process \"%1\" exited normally.\n" ).arg(proc.program()); |
104 | } else if (exitStatus == QProcess::NormalExit) { |
105 | retMsg = tr("The process \"%1\" exited with code %2.\n" ) |
106 | .arg(proc.program(), QString::number(exitcode)); |
107 | } else { |
108 | retMsg = tr("The process \"%1\" crashed.\n" ).arg(proc.program()); |
109 | } |
110 | }); |
111 | |
112 | connect(&proc, &QProcess::readyReadStandardError, [&]() { |
113 | proc.setReadChannel(QProcess::StandardError); |
114 | while (proc.canReadLine()) { |
115 | QString line = QString::fromUtf8(proc.readLine()); |
116 | qInfo() << line; |
117 | outputMsg(line, OutputPane::OutputFormat::StdErr); |
118 | } |
119 | }); |
120 | |
121 | connect(&proc, &QProcess::readyReadStandardOutput, [&]() { |
122 | proc.setReadChannel(QProcess::StandardOutput); |
123 | while (proc.canReadLine()) { |
124 | QString line = QString::fromUtf8(proc.readLine()); |
125 | qInfo() << line; |
126 | outputMsg(line, OutputPane::OutputFormat::StdOut); |
127 | } |
128 | }); |
129 | |
130 | QList<QString> programList = d->configView->getProgramList(); |
131 | QList<QStringList> argsList = d->configView->getArgumentsList(); |
132 | QList<QString> workingDirList = d->configView->getWorkingDirList(); |
133 | QList<QMap<QString, QVariant>> envList = d->configView->getEnvironmentList(); |
134 | |
135 | for (int i =0; i < programList.size(); i++) { |
136 | proc.setProgram(programList.at(i)); |
137 | if (!argsList.at(i).at(0).isEmpty()) { |
138 | proc.setArguments(argsList.at(i)); |
139 | } else { |
140 | proc.setArguments({}); |
141 | } |
142 | proc.setWorkingDirectory(workingDirList.at(i)); |
143 | QProcessEnvironment env; |
144 | auto iterator = envList.at(i).begin(); |
145 | while (iterator != envList.at(i).end()) { |
146 | env.insert(iterator.key(), iterator.value().toString()); |
147 | ++iterator; |
148 | } |
149 | proc.setProcessEnvironment(env); |
150 | QString startMsg = tr("Start execute command: \"%1\" \"%2\" in workspace \"%3\".\n" ) |
151 | .arg(programList.at(i), argsList.at(i).join(" " ), workingDirList.at(i)); |
152 | outputMsg(startMsg, OutputPane::OutputFormat::NormalMessage); |
153 | proc.start(); |
154 | proc.waitForFinished(-1); |
155 | |
156 | outputMsg(retMsg, OutputPane::OutputFormat::NormalMessage); |
157 | QString endMsg = tr("Execute command finished.\n" ); |
158 | outputMsg(endMsg, OutputPane::OutputFormat::NormalMessage); |
159 | } |
160 | QDialog::reject(); |
161 | } |
162 | |
163 | void BinaryToolsDialog::outputMsg(const QString &content, OutputPane::OutputFormat format) |
164 | { |
165 | QMetaObject::invokeMethod(this, "printOutput" , Q_ARG(QString, content), Q_ARG(OutputPane::OutputFormat, format)); |
166 | } |
167 | |