Skip to content

Commit fa9e2a3

Browse files
committed
feat: 添加终端颜色主题支持和日志格式化功能
1 parent 6d279b9 commit fa9e2a3

2 files changed

Lines changed: 105 additions & 0 deletions

File tree

docs/images/show.png

-12.5 KB
Loading

src/app/view/workbench_page.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <FluentQtWidgets/Dialogs/FolderListDialog.h>
77
#include <FluentQtWidgets/Settings/SettingCard.h>
88
#include <FluentQtWidgets/StyleSheet.h>
9+
#include <FluentQtWidgets/Theme.h>
910

1011
#include <QtCore/QDir>
1112
#include <QtCore/QFileInfo>
@@ -51,6 +52,64 @@ constexpr int CompactControlHeight = 32;
5152
constexpr int DefaultFileChunkSize = 256;
5253
constexpr int DefaultFileChunkIntervalMs = 10;
5354

55+
QColor terminalTimestampColor()
56+
{
57+
return ThemeManager::instance()->effectiveTheme() == Theme::Dark ? QColor(132, 192, 214) : QColor(75, 103, 128);
58+
}
59+
60+
QColor terminalDirectionMarkerColor(bool tx)
61+
{
62+
const bool dark = ThemeManager::instance()->effectiveTheme() == Theme::Dark;
63+
if(tx) {
64+
return dark ? QColor(255, 185, 115) : QColor(177, 86, 15);
65+
}
66+
return dark ? QColor(79, 214, 191) : QColor(0, 121, 107);
67+
}
68+
69+
QColor terminalEspIdfLogLevelColor(QChar level)
70+
{
71+
const bool dark = ThemeManager::instance()->effectiveTheme() == Theme::Dark;
72+
switch(level.toUpper().toLatin1()) {
73+
case 'V':
74+
return dark ? QColor(187, 154, 255) : QColor(108, 84, 190);
75+
case 'D':
76+
return dark ? QColor(117, 190, 255) : QColor(33, 118, 188);
77+
case 'I':
78+
return dark ? QColor(103, 219, 123) : QColor(0, 126, 67);
79+
case 'W':
80+
return dark ? QColor(255, 209, 102) : QColor(171, 103, 0);
81+
case 'E':
82+
return dark ? QColor(255, 132, 132) : QColor(190, 35, 35);
83+
default:
84+
return QColor();
85+
}
86+
}
87+
88+
int espIdfLogPrefixEnd(const QString &line, int prefixStart)
89+
{
90+
if(prefixStart + 4 >= line.size()) {
91+
return -1;
92+
}
93+
94+
const QColor levelColor = terminalEspIdfLogLevelColor(line.at(prefixStart));
95+
if(!levelColor.isValid() || line.at(prefixStart + 1) != QLatin1Char(' ') ||
96+
line.at(prefixStart + 2) != QLatin1Char('(')) {
97+
return -1;
98+
}
99+
100+
int cursor = prefixStart + 3;
101+
const int digitStart = cursor;
102+
while(cursor < line.size() && line.at(cursor).isDigit()) {
103+
++cursor;
104+
}
105+
106+
if(cursor == digitStart || cursor >= line.size() || line.at(cursor) != QLatin1Char(')')) {
107+
return -1;
108+
}
109+
110+
return cursor + 1;
111+
}
112+
54113
void setFixedControlWidth(QWidget *widget, int width)
55114
{
56115
widget->setMinimumWidth(width);
@@ -315,6 +374,9 @@ WorkbenchPage::WorkbenchPage(QWidget *parent)
315374
connect(&m_statsTimer, &QTimer::timeout, this, &WorkbenchPage::updateRateStats);
316375
m_fileSendTimer.setSingleShot(true);
317376
connect(&m_fileSendTimer, &QTimer::timeout, this, &WorkbenchPage::sendNextFileChunk);
377+
connect(ThemeManager::instance(), &ThemeManager::effectiveThemeChanged, this, [this]() {
378+
renderTerminal();
379+
});
318380

319381
refreshPorts();
320382
loadSendHistory();
@@ -1790,6 +1852,49 @@ bool WorkbenchPage::appendRecordToTerminal(QTextCursor &cursor, const SessionRec
17901852
if(!searchText.isEmpty() && line.contains(searchText, Qt::CaseInsensitive)) {
17911853
format.setBackground(QColor(255, 214, 10, 72));
17921854
}
1855+
1856+
const bool showTimestamp = m_timestampCheck && m_timestampCheck->isChecked();
1857+
const QString timestamp = record.timestamp.toString(QStringLiteral("HH:mm:ss.zzz"));
1858+
const QString marker = record.direction == RecordDirection::Tx ? QStringLiteral("»") : QStringLiteral("«");
1859+
int position = 0;
1860+
if(showTimestamp && line.startsWith(timestamp)) {
1861+
QTextCharFormat timestampFormat = format;
1862+
timestampFormat.setForeground(terminalTimestampColor());
1863+
cursor.insertText(timestamp, timestampFormat);
1864+
position = timestamp.size();
1865+
}
1866+
1867+
const int markerIndex = line.indexOf(marker, position);
1868+
if(markerIndex >= position) {
1869+
QTextCharFormat markerFormat = format;
1870+
markerFormat.setForeground(terminalDirectionMarkerColor(record.direction == RecordDirection::Tx));
1871+
cursor.insertText(line.mid(position, markerIndex - position), format);
1872+
cursor.insertText(marker, markerFormat);
1873+
1874+
const int afterMarker = markerIndex + marker.size();
1875+
int prefixStart = afterMarker;
1876+
while(prefixStart < line.size() && line.at(prefixStart).isSpace()) {
1877+
++prefixStart;
1878+
}
1879+
1880+
const int prefixEnd = espIdfLogPrefixEnd(line, prefixStart);
1881+
if(prefixEnd > prefixStart) {
1882+
QTextCharFormat levelFormat = format;
1883+
levelFormat.setForeground(terminalEspIdfLogLevelColor(line.at(prefixStart)));
1884+
cursor.insertText(line.mid(afterMarker, prefixStart - afterMarker), format);
1885+
cursor.insertText(line.mid(prefixStart, prefixEnd - prefixStart), levelFormat);
1886+
cursor.insertText(line.mid(prefixEnd), format);
1887+
} else {
1888+
cursor.insertText(line.mid(afterMarker), format);
1889+
}
1890+
return true;
1891+
}
1892+
1893+
if(position > 0) {
1894+
cursor.insertText(line.mid(position), format);
1895+
return true;
1896+
}
1897+
17931898
cursor.insertText(line, format);
17941899
return true;
17951900
}

0 commit comments

Comments
 (0)