mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-06-05 22:55:04 -06:00
UI: colored ANSI logs fix-ups
This commit is contained in:
parent
b2768bbd61
commit
484d97caf1
@ -132,8 +132,6 @@ log_frame::log_frame(std::shared_ptr<gui_settings> _gui_settings, QWidget* paren
|
|||||||
m_tty->setContextMenuPolicy(Qt::CustomContextMenu);
|
m_tty->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
m_tty->document()->setMaximumBlockCount(max_block_count_tty);
|
m_tty->document()->setMaximumBlockCount(max_block_count_tty);
|
||||||
m_tty->installEventFilter(this);
|
m_tty->installEventFilter(this);
|
||||||
|
|
||||||
m_tty_ansi_highlighter = new AnsiHighlighter(m_tty->document());
|
|
||||||
|
|
||||||
m_tty_input = new QLineEdit();
|
m_tty_input = new QLineEdit();
|
||||||
if (m_tty_channel >= 0)
|
if (m_tty_channel >= 0)
|
||||||
@ -164,6 +162,11 @@ log_frame::log_frame(std::shared_ptr<gui_settings> _gui_settings, QWidget* paren
|
|||||||
CreateAndConnectActions();
|
CreateAndConnectActions();
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
|
|
||||||
|
if (m_ansi_tty)
|
||||||
|
{
|
||||||
|
m_tty_ansi_highlighter = new AnsiHighlighter(m_tty->document());
|
||||||
|
}
|
||||||
|
|
||||||
m_timer = new QTimer(this);
|
m_timer = new QTimer(this);
|
||||||
connect(m_timer, &QTimer::timeout, this, &log_frame::UpdateUI);
|
connect(m_timer, &QTimer::timeout, this, &log_frame::UpdateUI);
|
||||||
}
|
}
|
||||||
@ -291,6 +294,16 @@ void log_frame::CreateAndConnectActions()
|
|||||||
{
|
{
|
||||||
m_gui_settings->SetValue(gui::l_ansi_code, checked);
|
m_gui_settings->SetValue(gui::l_ansi_code, checked);
|
||||||
m_ansi_tty = checked;
|
m_ansi_tty = checked;
|
||||||
|
|
||||||
|
if (!m_tty_ansi_highlighter)
|
||||||
|
{
|
||||||
|
m_tty_ansi_highlighter = new AnsiHighlighter(m_tty->document());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete m_tty_ansi_highlighter;
|
||||||
|
m_tty_ansi_highlighter = nullptr;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
m_tty_channel_acts = new QActionGroup(this);
|
m_tty_channel_acts = new QActionGroup(this);
|
||||||
@ -602,13 +615,15 @@ void log_frame::UpdateUI()
|
|||||||
buf_line.assign(std::string_view(m_tty_buf).substr(str_index, m_tty_buf.find_first_of('\n', str_index) - str_index));
|
buf_line.assign(std::string_view(m_tty_buf).substr(str_index, m_tty_buf.find_first_of('\n', str_index) - str_index));
|
||||||
str_index += buf_line.size() + 1;
|
str_index += buf_line.size() + 1;
|
||||||
|
|
||||||
// Ignore control characters and greater/equal to 0x80, but preserve ESC (0x1B) if ANSI mode is enabled
|
buf_line.erase(std::remove_if(buf_line.begin(), buf_line.end(), [this](s8 c)
|
||||||
buf_line.erase(std::remove_if(buf_line.begin(), buf_line.end(), [this](s8 c) {
|
{
|
||||||
|
// If ANSI TTY is enabled, preserve ESC (0x1B) for ANSI sequences
|
||||||
if (m_ansi_tty)
|
if (m_ansi_tty)
|
||||||
{
|
{
|
||||||
// Keep ESC (0x1B) so ANSI sequences remain intact
|
|
||||||
return c <= 0x8 || c == 0x7F || (c >= 0xE && c <= 0x1F && c != 0x1B);
|
return c <= 0x8 || c == 0x7F || (c >= 0xE && c <= 0x1F && c != 0x1B);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove all control characters so output is clean
|
||||||
return c <= 0x8 || c == 0x7F || (c >= 0xE && c <= 0x1F);
|
return c <= 0x8 || c == 0x7F || (c >= 0xE && c <= 0x1F);
|
||||||
}), buf_line.end());
|
}), buf_line.end());
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Utilities/File.h"
|
#include "Utilities/File.h"
|
||||||
|
#include "rpcs3qt/syntax_highlighter.h"
|
||||||
#include "util/logs.hpp"
|
#include "util/logs.hpp"
|
||||||
|
|
||||||
#include "custom_dock_widget.h"
|
#include "custom_dock_widget.h"
|
||||||
#include "find_dialog.h"
|
#include "find_dialog.h"
|
||||||
#include "syntax_highlighter.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -13,6 +13,8 @@
|
|||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
|
|
||||||
|
class AnsiHighlighter;
|
||||||
|
|
||||||
class gui_settings;
|
class gui_settings;
|
||||||
|
|
||||||
class log_frame : public custom_dock_widget
|
class log_frame : public custom_dock_widget
|
||||||
|
|||||||
@ -34,7 +34,6 @@ private:
|
|||||||
QString m_full_log;
|
QString m_full_log;
|
||||||
QPlainTextEdit* m_log_text;
|
QPlainTextEdit* m_log_text;
|
||||||
LogHighlighter* m_log_highlighter;
|
LogHighlighter* m_log_highlighter;
|
||||||
AnsiHighlighter* m_ansi_highlighter;
|
|
||||||
std::unique_ptr<find_dialog> m_find_dialog;
|
std::unique_ptr<find_dialog> m_find_dialog;
|
||||||
std::bitset<32> m_log_levels = std::bitset<32>(0b11111111u);
|
std::bitset<32> m_log_levels = std::bitset<32>(0b11111111u);
|
||||||
bool m_show_timestamps = true;
|
bool m_show_timestamps = true;
|
||||||
|
|||||||
@ -186,48 +186,49 @@ GlslHighlighter::GlslHighlighter(QTextDocument* parent) : Highlighter(parent)
|
|||||||
|
|
||||||
AnsiHighlighter::AnsiHighlighter(QTextDocument* parent) : Highlighter(parent)
|
AnsiHighlighter::AnsiHighlighter(QTextDocument* parent) : Highlighter(parent)
|
||||||
{
|
{
|
||||||
|
m_foreground_color = gui::utils::get_foreground_color();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnsiHighlighter::highlightBlock(const QString &text)
|
void AnsiHighlighter::highlightBlock(const QString& text)
|
||||||
{
|
{
|
||||||
// Match ANSI SGR sequences, e.g. "\x1b[31m" or "\x1b[1;32m"
|
// Match ANSI SGR sequences, e.g. "\x1b[31m" or "\x1b[1;32m"
|
||||||
const QRegularExpression ansi_re("\x1b\\[[0-9;]*m");
|
static const QRegularExpression ansi_re("\x1b\\[[0-9;]*m");
|
||||||
const QRegularExpression param_re("\x1b\\[([0-9;]*)m");
|
static const QRegularExpression param_re("\x1b\\[([0-9;]*)m");
|
||||||
|
|
||||||
QTextCharFormat escapeFormat;
|
static QTextCharFormat escape_format;
|
||||||
escapeFormat.setForeground(Qt::darkGray);
|
escape_format.setForeground(Qt::darkGray);
|
||||||
escapeFormat.setFontItalic(true);
|
escape_format.setFontItalic(true);
|
||||||
|
|
||||||
QTextCharFormat currentFormat;
|
static QTextCharFormat current_format;
|
||||||
currentFormat.setForeground(gui::utils::get_foreground_color());
|
current_format.setForeground(m_foreground_color);
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
auto it = ansi_re.globalMatch(text);
|
auto it = ansi_re.globalMatch(text);
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
auto match = it.next();
|
const auto match = it.next();
|
||||||
int start = match.capturedStart();
|
const int start = match.capturedStart();
|
||||||
int length = match.capturedLength();
|
const int length = match.capturedLength();
|
||||||
|
|
||||||
// Apply current format to the chunk before this escape sequence
|
// Apply current format to the chunk before this escape sequence
|
||||||
if (start > pos)
|
if (start > pos)
|
||||||
{
|
{
|
||||||
setFormat(pos, start - pos, currentFormat);
|
setFormat(pos, start - pos, current_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Highlight the escape sequence itself
|
// Highlight the escape sequence itself
|
||||||
setFormat(start, length, escapeFormat);
|
setFormat(start, length, escape_format);
|
||||||
|
|
||||||
// Parse SGR parameters and update currentFormat
|
// Parse SGR parameters and update currentFormat
|
||||||
QRegularExpressionMatch pm = param_re.match(match.captured());
|
const QRegularExpressionMatch pm = param_re.match(match.captured());
|
||||||
if (pm.hasMatch())
|
if (pm.hasMatch())
|
||||||
{
|
{
|
||||||
QString params = pm.captured(1);
|
const QString params = pm.captured(1);
|
||||||
if (params.isEmpty())
|
if (params.isEmpty())
|
||||||
{
|
{
|
||||||
// empty or just \x1b[m = reset
|
// empty or just \x1b[m = reset
|
||||||
currentFormat = QTextCharFormat();
|
current_format = QTextCharFormat();
|
||||||
currentFormat.setForeground(gui::utils::get_foreground_color());
|
current_format.setForeground(m_foreground_color);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -240,35 +241,35 @@ void AnsiHighlighter::highlightBlock(const QString &text)
|
|||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
currentFormat = QTextCharFormat();
|
current_format = QTextCharFormat();
|
||||||
currentFormat.setForeground(gui::utils::get_foreground_color());
|
current_format.setForeground(m_foreground_color);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
currentFormat.setFontWeight(QFont::Bold);
|
current_format.setFontWeight(QFont::Bold);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
currentFormat.setFontItalic(true);
|
current_format.setFontItalic(true);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
currentFormat.setFontUnderline(true);
|
current_format.setFontUnderline(true);
|
||||||
break;
|
break;
|
||||||
case 30: currentFormat.setForeground(Qt::black); break;
|
case 30: current_format.setForeground(Qt::black); break;
|
||||||
case 31: currentFormat.setForeground(Qt::red); break;
|
case 31: current_format.setForeground(Qt::red); break;
|
||||||
case 32: currentFormat.setForeground(Qt::darkGreen); break;
|
case 32: current_format.setForeground(Qt::darkGreen); break;
|
||||||
case 33: currentFormat.setForeground(Qt::darkYellow); break;
|
case 33: current_format.setForeground(Qt::darkYellow); break;
|
||||||
case 34: currentFormat.setForeground(Qt::darkBlue); break;
|
case 34: current_format.setForeground(Qt::darkBlue); break;
|
||||||
case 35: currentFormat.setForeground(Qt::darkMagenta); break;
|
case 35: current_format.setForeground(Qt::darkMagenta); break;
|
||||||
case 36: currentFormat.setForeground(Qt::darkCyan); break;
|
case 36: current_format.setForeground(Qt::darkCyan); break;
|
||||||
case 37: currentFormat.setForeground(Qt::lightGray); break;
|
case 37: current_format.setForeground(Qt::lightGray); break;
|
||||||
case 39: currentFormat.setForeground(gui::utils::get_foreground_color()); break;
|
case 39: current_format.setForeground(m_foreground_color); break;
|
||||||
case 90: currentFormat.setForeground(Qt::darkGray); break;
|
case 90: current_format.setForeground(Qt::darkGray); break;
|
||||||
case 91: currentFormat.setForeground(Qt::red); break;
|
case 91: current_format.setForeground(Qt::red); break;
|
||||||
case 92: currentFormat.setForeground(Qt::green); break;
|
case 92: current_format.setForeground(Qt::green); break;
|
||||||
case 93: currentFormat.setForeground(Qt::yellow); break;
|
case 93: current_format.setForeground(Qt::yellow); break;
|
||||||
case 94: currentFormat.setForeground(Qt::blue); break;
|
case 94: current_format.setForeground(Qt::blue); break;
|
||||||
case 95: currentFormat.setForeground(Qt::magenta); break;
|
case 95: current_format.setForeground(Qt::magenta); break;
|
||||||
case 96: currentFormat.setForeground(Qt::cyan); break;
|
case 96: current_format.setForeground(Qt::cyan); break;
|
||||||
case 97: currentFormat.setForeground(Qt::white); break;
|
case 97: current_format.setForeground(Qt::white); break;
|
||||||
// Background and extended colors not yet handled
|
// Background and extended colors not yet handled
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -282,5 +283,5 @@ void AnsiHighlighter::highlightBlock(const QString &text)
|
|||||||
|
|
||||||
// Apply remaining format
|
// Apply remaining format
|
||||||
if (pos < text.length())
|
if (pos < text.length())
|
||||||
setFormat(pos, text.length() - pos, currentFormat);
|
setFormat(pos, text.length() - pos, current_format);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <QSyntaxHighlighter>
|
#include <QSyntaxHighlighter>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <qbrush.h>
|
||||||
|
|
||||||
// Inspired by https://doc.qt.io/qt-5/qtwidgets-richtext-syntaxhighlighter-example.html
|
// Inspired by https://doc.qt.io/qt-5/qtwidgets-richtext-syntaxhighlighter-example.html
|
||||||
|
|
||||||
@ -61,5 +62,7 @@ public:
|
|||||||
explicit AnsiHighlighter(QTextDocument* parent = nullptr);
|
explicit AnsiHighlighter(QTextDocument* parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void highlightBlock(const QString &text) override;
|
QColor m_foreground_color;
|
||||||
|
|
||||||
|
void highlightBlock(const QString& text) override;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user