1
0
forked from BRT/arc
arc/views/log/LogWindow.cpp
trnsmkot 4b502450bd Add EventWindow, database migrations, and enhanced DAO methods
Implemented `EventWindow` for viewing events with pagination and table-based UI. Added database migration to remove `UNIQUE` constraint on `external_id` in `events`. Enhanced DAO methods for event retrieval, pagination, and transaction updates. Integrated OCR recognition in transaction scripts and streamlined event handling in services.
2026-03-04 22:56:47 +07:00

155 lines
6.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "LogWindow.h"
#include <QHBoxLayout>
#include <QHeaderView>
#include <QPixmap>
#include <QResizeEvent>
#include <QScrollArea>
#include <QSplitter>
#include <QVBoxLayout>
#include "dao/AppLogDAO.h"
static constexpr int COL_ID = 0;
static constexpr int COL_TIME = 1;
static constexpr int COL_SOURCE = 2;
static constexpr int COL_DEVICE = 3;
static constexpr int COL_MESSAGE = 4;
LogWindow::LogWindow(QWidget *parent) : QDialog(parent) {
setWindowTitle("Логи ошибок");
resize(1100, 650);
// ── Таблица ───────────────────────────────────────────────────────────────
m_table = new QTableWidget(this);
m_table->setColumnCount(5);
m_table->setHorizontalHeaderLabels({"#", "Время", "Источник", "Устройство", "Сообщение"});
m_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
m_table->setSelectionMode(QAbstractItemView::SingleSelection);
m_table->verticalHeader()->hide();
m_table->horizontalHeader()->setStretchLastSection(true);
m_table->setColumnWidth(COL_ID, 45);
m_table->setColumnWidth(COL_TIME, 145);
m_table->setColumnWidth(COL_SOURCE, 170);
m_table->setColumnWidth(COL_DEVICE, 120);
// ── Панель скриншота ──────────────────────────────────────────────────────
m_screenshotLabel = new QLabel("Выберите строку для просмотра скриншота");
m_screenshotLabel->setAlignment(Qt::AlignCenter);
m_screenshotLabel->setMinimumWidth(320);
m_screenshotLabel->setWordWrap(true);
m_screenshotLabel->setStyleSheet("background: #1a1a1a; color: #888; border-radius: 4px;");
auto *scrollArea = new QScrollArea(this);
scrollArea->setWidget(m_screenshotLabel);
scrollArea->setWidgetResizable(true);
scrollArea->setMinimumWidth(320);
// ── Сплиттер ─────────────────────────────────────────────────────────────
auto *splitter = new QSplitter(Qt::Horizontal, this);
splitter->addWidget(m_table);
splitter->addWidget(scrollArea);
splitter->setStretchFactor(0, 7);
splitter->setStretchFactor(1, 3);
// ── Пагинация ─────────────────────────────────────────────────────────────
m_prevBtn = new QPushButton("", this);
m_nextBtn = new QPushButton("", this);
m_pageLabel = new QLabel(this);
m_pageLabel->setAlignment(Qt::AlignCenter);
m_pageLabel->setMinimumWidth(140);
auto *refreshBtn = new QPushButton("Обновить", this);
auto *paginationLayout = new QHBoxLayout;
paginationLayout->addWidget(m_prevBtn);
paginationLayout->addWidget(m_pageLabel);
paginationLayout->addWidget(m_nextBtn);
paginationLayout->addStretch();
paginationLayout->addWidget(refreshBtn);
auto *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(splitter, 1);
mainLayout->addLayout(paginationLayout);
// ── Сигналы ───────────────────────────────────────────────────────────────
connect(m_prevBtn, &QPushButton::clicked, this, [this]() {
if (m_page > 0) { --m_page; loadPage(); }
});
connect(m_nextBtn, &QPushButton::clicked, this, [this]() {
if (m_page < m_totalPages - 1) { ++m_page; loadPage(); }
});
connect(refreshBtn, &QPushButton::clicked, this, [this]() {
m_page = 0;
loadPage();
});
connect(m_table, &QTableWidget::currentCellChanged, this,
[this](int row, int, int, int) {
if (row < 0) return;
const int logId = m_table->item(row, COL_ID)->text().toInt();
showScreenshot(logId);
});
loadPage();
}
void LogWindow::loadPage() {
const int total = AppLogDAO::getTotalCount();
m_totalPages = qMax(1, (total + m_pageSize - 1) / m_pageSize);
m_page = qBound(0, m_page, m_totalPages - 1);
const QList<AppLogEntry> entries = AppLogDAO::getLogs(m_page, m_pageSize);
m_table->setRowCount(static_cast<int>(entries.size()));
for (int i = 0; i < entries.size(); ++i) {
const auto &e = entries[i];
m_table->setItem(i, COL_ID, new QTableWidgetItem(QString::number(e.id)));
m_table->setItem(i, COL_TIME, new QTableWidgetItem(
e.timestamp.toLocalTime().toString("dd.MM.yy HH:mm:ss")));
m_table->setItem(i, COL_SOURCE, new QTableWidgetItem(e.source));
m_table->setItem(i, COL_DEVICE, new QTableWidgetItem(e.deviceId));
m_table->setItem(i, COL_MESSAGE, new QTableWidgetItem(e.message));
}
// Сбрасываем скриншот при смене страницы
m_screenshotLabel->setPixmap({});
m_screenshotLabel->setText("Выберите строку для просмотра скриншота");
updatePagination();
}
void LogWindow::updatePagination() {
m_pageLabel->setText(QString("Страница %1 из %2").arg(m_page + 1).arg(m_totalPages));
m_prevBtn->setEnabled(m_page > 0);
m_nextBtn->setEnabled(m_page < m_totalPages - 1);
}
void LogWindow::showScreenshot(int logId) {
const QByteArray bytes = AppLogDAO::getScreenshot(logId);
if (bytes.isEmpty()) {
m_originalPixmap = {};
m_screenshotLabel->setPixmap({});
m_screenshotLabel->setText("Скриншот отсутствует");
return;
}
if (!m_originalPixmap.loadFromData(bytes)) {
m_originalPixmap = {};
m_screenshotLabel->setText("Не удалось загрузить скриншот");
return;
}
rescaleScreenshot();
}
void LogWindow::rescaleScreenshot() {
if (m_originalPixmap.isNull()) return;
m_screenshotLabel->setPixmap(
m_originalPixmap.scaled(m_screenshotLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)
);
}
void LogWindow::resizeEvent(QResizeEvent *event) {
QDialog::resizeEvent(event);
rescaleScreenshot();
}