149 lines
5.9 KiB
C++
149 lines
5.9 KiB
C++
#include "qlogviewer.h"
|
|
#include <QDateTime>
|
|
#include <QFileDialog>
|
|
#include <QFile>
|
|
#include <QTextStream>
|
|
#include <QScrollBar>
|
|
QLogViewer::QLogViewer(QWidget *parent) : QWidget(parent)
|
|
{
|
|
QVBoxLayout* layout = new QVBoxLayout(this);
|
|
layout->setContentsMargins(5, 5, 5, 5);
|
|
QHBoxLayout* toolbarLayout = new QHBoxLayout;
|
|
toolbarLayout->setSpacing(10);
|
|
QLabel* levelLabel = new QLabel("Log Level:");
|
|
levelLabel->setStyleSheet("color: #000;");
|
|
levelCombo = new QComboBox;
|
|
levelCombo->setStyleSheet("background-color: #333; color: #EEE;");
|
|
levelCombo->addItem("All", QVariant(-1));
|
|
levelCombo->addItem("DEBUG", QLogManager::LogLevel::SQ_DEBUG);
|
|
levelCombo->addItem("INFO", QLogManager::LogLevel::SQ_INFO);
|
|
levelCombo->addItem("WARNING", QLogManager::LogLevel::SQ_WARNING);
|
|
levelCombo->addItem("ERROR", QLogManager::LogLevel::SQ_ERROR);
|
|
levelCombo->addItem("FATAL", QLogManager::LogLevel::SQ_FATAL);
|
|
levelCombo->setCurrentIndex(2);
|
|
QLabel* searchLabel = new QLabel("Search:");
|
|
searchLabel->setStyleSheet("color: #000;");
|
|
searchEdit = new QLineEdit;
|
|
searchEdit->setStyleSheet("background-color: #333; color: #EEE;");
|
|
searchEdit->setPlaceholderText("Filter logs...");
|
|
clearBtn = new QPushButton("Clear Logs");
|
|
clearBtn->setStyleSheet("background-color: #444; color: #EEE;");
|
|
saveBtn = new QPushButton("Save Logs");
|
|
saveBtn->setStyleSheet("background-color: #444; color: #EEE;");
|
|
logText = new QTextEdit;
|
|
logText->setReadOnly(true);
|
|
logText->setFontFamily("Consolas");
|
|
logText->setFontPointSize(9);
|
|
logText->setStyleSheet(R"(
|
|
QTextEdit {
|
|
background-color: #222;
|
|
color: #CCC;
|
|
border: 1px solid #444;
|
|
border-radius: 2px;
|
|
}
|
|
)");
|
|
connect(levelCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
|
this, &QLogViewer::filterLogs);
|
|
connect(searchEdit, &QLineEdit::textChanged,
|
|
this, &QLogViewer::filterLogs);
|
|
connect(clearBtn, &QPushButton::clicked, this, [this](){
|
|
logCache.clear();
|
|
logText->clear();
|
|
});
|
|
connect(saveBtn, &QPushButton::clicked,
|
|
this, &QLogViewer::saveLogs);
|
|
layout->addLayout(toolbarLayout);
|
|
layout->addWidget(logText);
|
|
QLogManager* logManager = QLogManager::Instance();
|
|
connect(logManager, &QLogManager::newLog,
|
|
this, &QLogViewer::appendLog);
|
|
}
|
|
void QLogViewer::appendLog(QLogManager::LogLevel level, const QString& logLine)
|
|
{
|
|
logCache.append(qMakePair(level, logLine));
|
|
applyFilter();
|
|
QScrollBar* scrollbar = logText->verticalScrollBar();
|
|
scrollbar->setValue(scrollbar->maximum());
|
|
}
|
|
void QLogViewer::filterLogs()
|
|
{
|
|
QScrollBar* scrollbar = logText->verticalScrollBar();
|
|
int scrollPos = scrollbar->value();
|
|
double scrollRatio = scrollPos / (double)scrollbar->maximum();
|
|
logText->clear();
|
|
applyFilter();
|
|
if (scrollbar->maximum() > 0) {
|
|
scrollbar->setValue(scrollbar->maximum() * scrollRatio);
|
|
}
|
|
}
|
|
void QLogViewer::applyFilter()
|
|
{
|
|
int levelFilter = levelCombo->currentData().toInt();
|
|
QString searchText = searchEdit->text().toLower();
|
|
QString selectedText = logText->textCursor().selectedText();
|
|
logText->clear();
|
|
for (const auto& log : logCache) {
|
|
QLogManager::LogLevel level = log.first;
|
|
const QString& logLine = log.second;
|
|
if (levelFilter != -1 && (int)level < levelFilter) {
|
|
continue;
|
|
}
|
|
if (!searchText.isEmpty() && !logLine.toLower().contains(searchText)) {
|
|
continue;
|
|
}
|
|
QString formattedLog;
|
|
switch (level) {
|
|
case QLogManager::LogLevel::SQ_DEBUG: formattedLog = "<span style='color:#88AACC'>" + logLine + "</span>"; break;
|
|
case QLogManager::LogLevel::SQ_INFO: formattedLog = "<span style='color:#CCCCCC'>" + logLine + "</span>"; break;
|
|
case QLogManager::LogLevel::SQ_WARNING: formattedLog = "<span style='color:#FFAA55'>" + logLine + "</span>"; break;
|
|
case QLogManager::LogLevel::SQ_ERROR: formattedLog = "<span style='color:#FF5555'>" + logLine + "</span>"; break;
|
|
case QLogManager::LogLevel::SQ_FATAL: formattedLog = "<span style='color:#FF3333; font-weight:bold'>" + logLine + "</span>"; break;
|
|
}
|
|
logText->append(formattedLog);
|
|
}
|
|
if (!selectedText.isEmpty()) {
|
|
QTextCursor cursor = logText->textCursor();
|
|
cursor.movePosition(QTextCursor::Start);
|
|
if (cursor.document()->find(selectedText, cursor).isNull()) {
|
|
cursor.clearSelection();
|
|
logText->setTextCursor(cursor);
|
|
}
|
|
}
|
|
}
|
|
void QLogViewer::saveLogs()
|
|
{
|
|
QString fileName = QFileDialog::getSaveFileName(
|
|
this,
|
|
"Save Logs",
|
|
QString("quant_logs_%1.txt")
|
|
.arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")),
|
|
"Text Files (*.txt);;All Files (*)"
|
|
);
|
|
if (fileName.isEmpty()) {
|
|
return;
|
|
}
|
|
QFile file(fileName);
|
|
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
QTextStream out(&file);
|
|
out << "Quant Trading System Logs\n";
|
|
out << "Generated: " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << "\n";
|
|
out << "========================================\n\n";
|
|
for (const auto& log : logCache) {
|
|
out << log.second << "\n";
|
|
}
|
|
file.close();
|
|
QLogManager::Instance()->log(
|
|
QLogManager::LogLevel::SQ_INFO,
|
|
QString("Logs saved to: %1 (%2 entries)")
|
|
.arg(fileName)
|
|
.arg(logCache.size())
|
|
);
|
|
logText->append("<span style='color:#55FF55'>Logs saved successfully</span>");
|
|
} else {
|
|
QLogManager::Instance()->log(
|
|
QLogManager::LogLevel::SQ_ERROR,
|
|
QString("Failed to save logs: %1").arg(file.errorString())
|
|
);
|
|
logText->append("<span style='color:#FF5555'>Failed to save logs: " + file.errorString() + "</span>");
|
|
}
|
|
} |