4#include "G4UImanager.hh"
5#include "G4coutDestination.hh"
16 G4UImanager::GetUIpointer()->SetCoutDestination(
this);
17 G4coutDestination::masterG4coutDestination =
this;
26 QString fullQString = QString::fromStdString(coutString);
28 fullQString.replace(
"\r\n",
"\n");
29 fullQString.replace(
'\r',
'\n');
30 fullQString.replace(QChar(0x2028),
'\n');
31 QStringList lines = fullQString.split(
'\n', Qt::KeepEmptyParts);
34 QStringList htmlLines;
35 htmlLines.reserve(lines.size());
36 for (
const QString&
line : lines) { htmlLines << ansiToHtml(
line); }
42 QMetaObject::invokeMethod(b, [b, htmlLines]() {
43 for (
const QString& htmlLine : htmlLines) { b->appendLog(htmlLine); }
53 QString fullQString = QString::fromStdString(cerrString);
54 fullQString.replace(
"\r\n",
"\n");
55 fullQString.replace(
'\r',
'\n');
56 fullQString.replace(QChar(0x2028),
'\n');
57 QStringList lines = fullQString.split(
'\n', Qt::KeepEmptyParts);
59 QStringList htmlLines;
60 htmlLines.reserve(lines.size());
61 for (
const QString&
line : lines) { htmlLines << ansiToHtml(
line); }
64 QMetaObject::invokeMethod(b, [b, htmlLines]() {
65 for (
const QString& htmlLine : htmlLines) { b->appendLog(htmlLine); }
78QString GUI_Session::ansiToHtml(
const QString& ansiText) {
80 htmlText.reserve(ansiText.length() * 1.2);
84 bool isUnderlined =
false;
85 QString currentColor =
"";
88 QMap<int, QString> colorMap;
89 colorMap[30] =
"black";
91 colorMap[32] =
"green";
92 colorMap[33] =
"darkorange";
93 colorMap[34] =
"blue";
94 colorMap[35] =
"magenta";
95 colorMap[36] =
"cyan";
96 colorMap[37] =
"grey";
99 QRegularExpression ansiRegex(
"\x1B\\[([0-9;]*)m");
102 QRegularExpressionMatchIterator i = ansiRegex.globalMatch(ansiText);
104 while (i.hasNext()) {
105 QRegularExpressionMatch match = i.next();
106 int currentPos = match.capturedStart();
109 if (currentPos > lastPos) {
110 QString textSegment = ansiText.mid(lastPos, currentPos - lastPos);
112 htmlText += textSegment.toHtmlEscaped();
116 QString codesStr = match.captured(1);
117 QStringList codes = codesStr.split(
';', Qt::SkipEmptyParts);
119 if (codes.isEmpty()) {
125 bool nextBold = isBold;
126 bool nextUnderlined = isUnderlined;
127 QString nextColor = currentColor;
128 bool resetDetected =
false;
130 for (
const QString& codeStr : codes) {
132 int code = codeStr.toInt(&ok);
137 resetDetected =
true;
139 nextUnderlined =
false;
145 else if (code == 1) {
149 else if (code == 4) {
151 nextUnderlined =
true;
153 else if (code == 22) {
157 else if (code == 24) {
159 nextUnderlined =
false;
161 else if (code >= 30 && code <= 37) {
163 nextColor = colorMap.value(code,
"");
165 else if (code == 39) {
175 if (isUnderlined && !nextUnderlined) { htmlText +=
"</u>"; }
176 if (isBold && !nextBold) { htmlText +=
"</b>"; }
177 if (!currentColor.isEmpty() && currentColor != nextColor) { htmlText +=
"</font>"; }
181 if (isUnderlined) htmlText +=
"</u>";
182 if (isBold) htmlText +=
"</b>";
183 if (!currentColor.isEmpty()) htmlText +=
"</font>";
187 if (!currentColor.isEmpty() && currentColor != nextColor) {
189 if (!nextColor.isEmpty()) { htmlText += QString(
"<font color=\"%1\">").arg(nextColor); }
191 else if (currentColor.isEmpty() && !nextColor.isEmpty()) {
193 htmlText += QString(
"<font color=\"%1\">").arg(nextColor);
196 if (!isBold && nextBold) { htmlText +=
"<b>"; }
197 if (!isUnderlined && nextUnderlined) { htmlText +=
"<u>"; }
201 isUnderlined = nextUnderlined;
202 currentColor = nextColor;
205 lastPos = match.capturedEnd();
209 if (lastPos < ansiText.length()) {
210 QString textSegment = ansiText.mid(lastPos);
211 htmlText += textSegment.toHtmlEscaped();
215 if (isUnderlined) { htmlText +=
"</u>"; }
216 if (isBold) { htmlText +=
"</b>"; }
217 if (!currentColor.isEmpty()) { htmlText +=
"</font>"; }
226 if (
auto* UIM = G4UImanager::GetUIpointer()) {
227 UIM->SetCoutDestination(
nullptr);
232 if (G4coutDestination::masterG4coutDestination ==
this) {
233 G4coutDestination::masterG4coutDestination =
nullptr;
std::shared_ptr< GLogger > log
A Qt widget that displays read-only log text with a compact "top bar" UI.
void info(int level, Args &&... args) const
GUI_Session(const std::shared_ptr< GOptions > &gopt, GBoard *board)
Constructs a GUI_Session.
G4int ReceiveG4cerr(const G4String &cerrString) override
Receives error output from Geant4 and forwards it to the board.
~GUI_Session() override
Destructor.
G4int ReceiveG4cout(const G4String &coutString) override
Receives standard output from Geant4 and forwards it to the board.
constexpr const char * GBOARD_LOGGER