1014 lines
40 KiB
C++
1014 lines
40 KiB
C++
// **************************************************************************
|
|
//
|
|
// (C) Copyright 2009 Swiss SIMTEC AG
|
|
//
|
|
// **************************************************************************
|
|
//
|
|
// $HeadURL$
|
|
// $LastChangedBy$
|
|
// $LastChangedDate$
|
|
// $LastChangedRevision$
|
|
//
|
|
// **************************************************************************
|
|
|
|
// manual class headers
|
|
#include "LogViewGui.hpp"
|
|
|
|
#include "LogViewTelegram.hpp"
|
|
#include "LogViewXdrParser.hpp"
|
|
#include "LogViewTelegramDialog.hpp"
|
|
#include "LogViewOptionDialog.hpp"
|
|
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QTimer>
|
|
#include <QAction>
|
|
#include <QApplication>
|
|
#include <QCheckBox>
|
|
#include <QDesktopWidget>
|
|
#include <QFileDialog>
|
|
#include <QGroupBox>
|
|
#include <QHeaderView>
|
|
#include <QJsonArray>
|
|
#include <QLabel>
|
|
#include <QMessageBox>
|
|
#include <QScreen>
|
|
#include <QSortFilterProxyModel>
|
|
#include <QSplitter>
|
|
#include <QStatusBar>
|
|
#include <QTableView>
|
|
#include <QToolBar>
|
|
#include <QToolBox>
|
|
#include <QDateTime>
|
|
#include <QVBoxLayout>
|
|
#include <nglapplication/nglapplication.h>
|
|
|
|
#include "LogViewInjectionThread.hpp"
|
|
#include "LogViewTelegramEdit.hpp"
|
|
#include "LogViewTetraTelegramsParser.hpp"
|
|
#include <TrainingAreaBase/training_area_telegrams.h>
|
|
|
|
namespace N_LogView
|
|
{
|
|
|
|
// static member initialization
|
|
const QLatin1String LogViewGui::WINDOW_GROUP("MainWindow");
|
|
const QLatin1String LogViewGui::SIZE("Size");
|
|
const QLatin1String LogViewGui::SCREEN("Screen");
|
|
const QLatin1String LogViewGui::POS("Pos");
|
|
const QLatin1String LogViewGui::SPLITTPOS("SplittPos");
|
|
const QLatin1String LogViewGui::TOOLBOXINDEX("ToolBoxIndex");
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
|
|
// ---------------------------------------------------------------
|
|
LogViewGui::LogViewGui(QWidget* a_parent)
|
|
: QMainWindow(a_parent)
|
|
, RADIO_BUTTON_ICON_SIZE(16, 16)
|
|
, m_LogfileSize(0)
|
|
, m_DoReload(false)
|
|
, m_EditTelegramController(new TelegramEdit(this))
|
|
, m_TailTimer(nullptr)
|
|
, m_InjectionThread(nullptr)
|
|
, m_replayTimer(new QTimer(this))
|
|
, m_currentReplayRow(-1)
|
|
, m_logger(getLogger("LogViewGui"))
|
|
{
|
|
setWindowIcon(QIcon(QLatin1String(":icons/16x16/rde_16x16.png")));
|
|
|
|
QSettings settings;
|
|
settings.beginGroup(WINDOW_GROUP);
|
|
|
|
// status-bar
|
|
m_InjectionStatus = new QLabel(this);
|
|
m_InjectionStatus->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
|
statusBar()->addPermanentWidget(m_InjectionStatus);
|
|
m_ParticipantStatus = new QLabel(this);
|
|
m_ParticipantStatus->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
|
statusBar()->addPermanentWidget(m_ParticipantStatus);
|
|
m_TelegramStatus = new QLabel(this);
|
|
m_TelegramStatus->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
|
statusBar()->addPermanentWidget(m_TelegramStatus);
|
|
|
|
// tool-bar
|
|
// --------
|
|
QToolBar* toolBar = addToolBar(tr("Datei"));
|
|
toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
|
// tool-bar: new logfile
|
|
QString tipText;
|
|
QAction* action = new QAction(tr("Neue Log-Datei"), this);
|
|
action->setIcon(QIcon(QLatin1String(":icons/16x16/document-new.png")));
|
|
action->setShortcut(tr("Ctrl+N"));
|
|
tipText = tr("Eine neue Telegram-Log-Datei anzeigen (Ctrl-N)");
|
|
action->setStatusTip(tipText);
|
|
action->setToolTip(tipText);
|
|
connect(action, &QAction::triggered, this, &LogViewGui::newTelegramFile);
|
|
toolBar->addAction(action);
|
|
// tool-bar: add logfile
|
|
action = new QAction(tr("Log-Datei hinzu"), this);
|
|
action->setIcon(QIcon(QLatin1String(":icons/16x16/document-import.png")));
|
|
action->setShortcut(tr("Ctrl+O"));
|
|
tipText = tr("Eine weitere Telegramm-Log-Datei anzeigen (Ctrl-O)");
|
|
action->setStatusTip(tipText);
|
|
action->setToolTip(tipText);
|
|
connect(action, &QAction::triggered, this, &LogViewGui::loadTelegramFile);
|
|
toolBar->addAction(action);
|
|
// tool-bar: reload
|
|
m_reloadAction = new QAction(tr("&Reload"), this);
|
|
m_reloadAction->setCheckable(true);
|
|
m_reloadAction->setChecked(m_DoReload);
|
|
m_reloadAction->setIcon(QIcon(QLatin1String(":icons/16x16/edit-redo.png")));
|
|
m_reloadAction->setShortcut(tr("Ctrl+R"));
|
|
tipText = tr("Reload des Logfiles ein-/ausschalten (Ctrl-R)");
|
|
m_reloadAction->setStatusTip(tipText);
|
|
m_reloadAction->setToolTip(tipText);
|
|
connect(m_reloadAction, &QAction::triggered, this, &LogViewGui::reloadOnOff);
|
|
toolBar->addAction(m_reloadAction);
|
|
// tool-bar: settings
|
|
action = new QAction(tr("&Einstellungen"), this);
|
|
action->setIcon(QIcon(QLatin1String(":icons/16x16/configure.png")));
|
|
action->setShortcut(tr("Ctrl+E"));
|
|
tipText = tr("Verhalten des Programmes einstellen (Ctrl-E)");
|
|
action->setStatusTip(tipText);
|
|
action->setToolTip(tipText);
|
|
connect(action, &QAction::triggered, this, &LogViewGui::changeSettings);
|
|
toolBar->addAction(action);
|
|
// tool-bar: exit
|
|
toolBar->addSeparator();
|
|
action = new QAction(tr("&Beenden"), this);
|
|
action->setIcon(QIcon(QLatin1String(":icons/16x16/edit-delete.png")));
|
|
action->setShortcut(tr("Alt-F4"));
|
|
tipText = tr("LogView beenden (Alt-F4)");
|
|
action->setStatusTip(tipText);
|
|
action->setToolTip(tipText);
|
|
connect(action, &QAction::triggered, this, &LogViewGui::close);
|
|
toolBar->addAction(action);
|
|
|
|
createCentralSelectionWidget();
|
|
createTetraSelectionWidget();
|
|
createWlsSelectionWidget();
|
|
|
|
// participant-selection
|
|
// ---------------------
|
|
m_ParticipantTableView = new QTableView(this);
|
|
m_participantProxyModel = new QSortFilterProxyModel(this);
|
|
m_participantModel = new ParticipantModel(this);
|
|
m_participantProxyModel->setSourceModel(m_participantModel);
|
|
m_ParticipantTableView->setModel(m_participantProxyModel);
|
|
m_ParticipantTableView->setAlternatingRowColors(true);
|
|
m_ParticipantTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
m_ParticipantTableView->setSelectionMode(QAbstractItemView::MultiSelection);
|
|
m_ParticipantTableView->setSortingEnabled(true);
|
|
m_ParticipantTableView->setTabKeyNavigation(false);
|
|
m_ParticipantTableView->verticalHeader()->hide();
|
|
m_ParticipantTableView->verticalHeader()->setMinimumSectionSize(QApplication::font().pointSize() * 2.5);
|
|
m_ParticipantTableView->verticalHeader()->setDefaultSectionSize(QApplication::font().pointSize() * 2.5);
|
|
m_ParticipantTableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
|
m_ParticipantTableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
|
connect(m_ParticipantTableView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
|
this, &LogViewGui::selectedParticipantChanged);
|
|
QVBoxLayout* participantBox = new QVBoxLayout;
|
|
participantBox->addWidget(m_ParticipantTableView);
|
|
m_ParticipantSelectionGroup = new QGroupBox(tr("Teilnehmer-Filter &aktivieren"), this);
|
|
m_ParticipantSelectionGroup->setCheckable(true);
|
|
m_ParticipantSelectionGroup->setChecked(false);
|
|
m_ParticipantSelectionGroup->setLayout(participantBox);
|
|
connect(m_ParticipantSelectionGroup, &QGroupBox::toggled, this, &LogViewGui::selectedParticipantChanged);
|
|
|
|
// left side (filters)
|
|
m_ToolBox = new QToolBox(this);
|
|
m_ToolBox->addItem(m_CentralSelectionGroup, QIcon(QLatin1String(":/image/Central.png")), tr("&Zentral-Telegramm-Filter"));
|
|
m_ToolBox->addItem(m_TetraSelectionGroup, QIcon(QLatin1String(":/image/Tetra.png")), tr("TET&RA-Telegramm-Filter"));
|
|
m_ToolBox->addItem(m_WlsSelectionGroup, QIcon(QLatin1String(":/image/Wls.png")), tr("&WLS-Telegramm-Filter"));
|
|
m_ToolBox->addItem(m_ParticipantSelectionGroup, QIcon(QLatin1String(":/image/TNE.png")), tr("Teilnehmer-&Filter"));
|
|
m_ToolBox->addItem(m_EditTelegramController->tableView(), QIcon(QLatin1String(":icons/16x16/document-edit.png")), tr("&Edit && Sende Telegramme"));
|
|
m_ToolBox->setCurrentIndex(settings.value(TOOLBOXINDEX).toInt());
|
|
|
|
// right side (logged telegrams)
|
|
// -----------------------------
|
|
m_logTelegramView = new QTableView(this);
|
|
m_logTelegramView->setAlternatingRowColors(true);
|
|
m_logTelegramView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
m_logTelegramView->setSelectionMode(QAbstractItemView::ContiguousSelection);
|
|
m_logTelegramView->verticalHeader()->hide();
|
|
m_logTelegramView->verticalHeader()->setMinimumSectionSize(QApplication::font().pointSize() * 2.5);
|
|
m_logTelegramView->verticalHeader()->setDefaultSectionSize(QApplication::font().pointSize() * 2.5);
|
|
m_logTelegramView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
|
m_logTelegramView->setContextMenuPolicy(Qt::CustomContextMenu); //Custom Contextmenu enabled
|
|
connect(m_logTelegramView, &QTableView::customContextMenuRequested,
|
|
this, &LogViewGui::customMenuRequested); //connect table to contextmenu
|
|
m_telegramModel = new TelegramModel(m_logTelegramView);
|
|
m_telegramProxyModel = new TelegramProxyModel(m_logTelegramView);
|
|
m_telegramProxyModel->setSourceModel(m_telegramModel);
|
|
m_logTelegramView->setModel(m_telegramProxyModel);
|
|
connect(m_logTelegramView, &QTableView::doubleClicked,
|
|
this, &LogViewGui::onLogTelegramViewDoubleClicked);
|
|
m_logTelegramView->horizontalHeader()->setSortIndicatorShown(true);
|
|
m_logTelegramView->horizontalHeader()->setSortIndicator(3, Qt::AscendingOrder);
|
|
m_logTelegramView->setSortingEnabled(true);
|
|
|
|
QVBoxLayout* telegramBox = new QVBoxLayout;
|
|
telegramBox->addWidget(m_logTelegramView);
|
|
QGroupBox* telegramGroup = new QGroupBox(tr("&Log-Telegramme"), this);
|
|
telegramGroup->setLayout(telegramBox);
|
|
|
|
// splitter between toolbox and log-telegram-list
|
|
m_Splitter = new QSplitter(Qt::Horizontal, this);
|
|
m_Splitter->addWidget(m_ToolBox);
|
|
m_Splitter->addWidget(telegramGroup);
|
|
const QList<QVariant> splitterSizesAsVariant = settings.value(SPLITTPOS).toList();
|
|
QList<int> splitterSizes;
|
|
splitterSizes.reserve(splitterSizesAsVariant.size());
|
|
if (splitterSizesAsVariant.isEmpty())
|
|
{
|
|
splitterSizes << 235 << 1000;
|
|
}
|
|
else
|
|
{
|
|
for (const QVariant &item : splitterSizesAsVariant)
|
|
splitterSizes << item.toInt();
|
|
}
|
|
m_Splitter->setSizes(splitterSizes);
|
|
setCentralWidget(m_Splitter);
|
|
|
|
// initialize the telegram-filters (this should be done before load of telegrams, otherwise the telegram-list
|
|
// will be shown several times and this could be slow when the telegram-list is slow)
|
|
m_CentralSelectionGroup->setChecked(true);
|
|
m_ackCentralTelCheckBox->setChecked(true);
|
|
m_ackCentralTelCheckBox->setChecked(false);
|
|
m_PosCentralTelCheckBox->setChecked(true);
|
|
m_PosCentralTelCheckBox->setChecked(false);
|
|
m_SentCentralTelCheckBox->setChecked(true);
|
|
m_ReceivedCentralTelCheckBox->setChecked(true);
|
|
|
|
m_TetraSelectionGroup->setChecked(true);
|
|
m_SentTetraTelCheckBox->setChecked(true);
|
|
m_ReceivedTetraTelCheckBox->setChecked(true);
|
|
m_PosTetraTelCheckBox->setChecked(true);
|
|
m_PosTetraTelCheckBox->setChecked(false);
|
|
m_FragmentedTetraTelCheckBox->setChecked(true);
|
|
m_LoginTetraTelCheckBox->setChecked(true);
|
|
m_RegisterTetraTelCheckBox->setChecked(true);
|
|
m_ReportTetraTelCheckBox->setChecked(false);
|
|
m_AirInterfaceLoadTetraTelCheckBox->setChecked(false);
|
|
|
|
m_WlsSelectionGroup->setChecked(true);
|
|
m_PosWlsTelCheckBox->setChecked(true);
|
|
m_PosWlsTelCheckBox->setChecked(false);
|
|
m_SentWlsTelCheckBox->setChecked(true);
|
|
m_ReceivedWlsTelCheckBox->setChecked(true);
|
|
|
|
// set the size and position of main-window
|
|
QSize size = settings.value(SIZE, sizeHint()).toSize();
|
|
resize(size.isNull() ? QSize(1280, 768) : size);
|
|
move(settings.value(POS, QPoint(0, 0)).toPoint());
|
|
settings.endGroup();
|
|
|
|
connect(m_replayTimer, &QTimer::timeout, this, &LogViewGui::onReplayTimerTimeout);
|
|
|
|
QTimer::singleShot(0, this, &LogViewGui::loadSpecificationFiles);
|
|
|
|
startInjectionThread();
|
|
}
|
|
|
|
void LogViewGui::createCentralSelectionWidget()
|
|
{
|
|
// send-checkbox
|
|
m_SentCentralTelCheckBox = createRadioButton(tr("&gesendete Telegramme"), QLatin1String(":/image/P2C.png"));
|
|
// received-checkbox
|
|
m_ReceivedCentralTelCheckBox = createRadioButton(tr("&empfangene Telegramme"), QLatin1String(":/image/C2P.png"));
|
|
// pos-checkbox
|
|
m_PosCentralTelCheckBox = createRadioButton(tr("&Positionsmeldungen"), QLatin1String(":/image/CentralPos.png"));
|
|
// ack-checkbox
|
|
m_ackCentralTelCheckBox = createRadioButton(tr("&Bestaetigungstelegramme"), QLatin1String(":/image/CentralAck.png"));
|
|
|
|
QVBoxLayout* centralFilterBox = new QVBoxLayout;
|
|
centralFilterBox->addWidget(m_SentCentralTelCheckBox);
|
|
centralFilterBox->addWidget(m_ReceivedCentralTelCheckBox);
|
|
centralFilterBox->addWidget(m_PosCentralTelCheckBox);
|
|
centralFilterBox->addWidget(m_ackCentralTelCheckBox);
|
|
centralFilterBox->addStretch(1);
|
|
|
|
m_CentralSelectionGroup = new QGroupBox(tr("Telegramme anzeigen"), this);
|
|
m_CentralSelectionGroup->setCheckable(true);
|
|
m_CentralSelectionGroup->setChecked(false);
|
|
m_CentralSelectionGroup->setLayout(centralFilterBox);
|
|
connect(m_CentralSelectionGroup, &QGroupBox::toggled, this, &LogViewGui::showTelegramTable);
|
|
}
|
|
|
|
void LogViewGui::createTetraSelectionWidget()
|
|
{
|
|
// sent-checkbox
|
|
m_SentTetraTelCheckBox = createRadioButton(tr("&gesendete Telegramme"), QLatin1String(":/image/T2P.png"));
|
|
// received-checkbox
|
|
m_ReceivedTetraTelCheckBox = createRadioButton(tr("&empfangene Telegramme"), QLatin1String(":/image/P2T.png"));
|
|
// pos-checkbox
|
|
m_PosTetraTelCheckBox = createRadioButton(tr("&Positionsmeldungen"), QLatin1String(":/image/TetraPos.png"));
|
|
// fragmented-checkbox
|
|
m_FragmentedTetraTelCheckBox = createRadioButton(tr("&Fragmentierte Meldungen"), QLatin1String(":/image/TetraFragmented.png"));
|
|
// login-checkbox
|
|
m_LoginTetraTelCheckBox = createRadioButton(tr("&Loginmeldungen"), QLatin1String(":/image/TetraLogin.png"));
|
|
// register-checkbox
|
|
m_RegisterTetraTelCheckBox = createRadioButton(tr("&Registermeldungen"), QLatin1String(":/image/TetraRegister.png"));
|
|
// report-checkbox
|
|
m_ReportTetraTelCheckBox = createRadioButton(tr("&Reportmeldungen"), QLatin1String(":/image/TetraReport.png"));
|
|
// air-interface-load-checkbox
|
|
m_AirInterfaceLoadTetraTelCheckBox = createRadioButton(tr("&Air-Load Meldungen"), QLatin1String(":/image/TetraAirInterface.png"));
|
|
|
|
QVBoxLayout* tetraFilterBox = new QVBoxLayout;
|
|
tetraFilterBox->addWidget(m_SentTetraTelCheckBox);
|
|
tetraFilterBox->addWidget(m_ReceivedTetraTelCheckBox);
|
|
tetraFilterBox->addWidget(m_PosTetraTelCheckBox);
|
|
tetraFilterBox->addWidget(m_FragmentedTetraTelCheckBox);
|
|
tetraFilterBox->addWidget(m_LoginTetraTelCheckBox);
|
|
tetraFilterBox->addWidget(m_RegisterTetraTelCheckBox);
|
|
tetraFilterBox->addWidget(m_ReportTetraTelCheckBox);
|
|
tetraFilterBox->addWidget(m_AirInterfaceLoadTetraTelCheckBox);
|
|
tetraFilterBox->addStretch(1);
|
|
|
|
m_TetraSelectionGroup = new QGroupBox(tr("Telegramme anzeigen"), this);
|
|
m_TetraSelectionGroup->setCheckable(true);
|
|
m_TetraSelectionGroup->setChecked(false);
|
|
m_TetraSelectionGroup->setLayout(tetraFilterBox);
|
|
connect(m_TetraSelectionGroup, &QGroupBox::toggled, this, &LogViewGui::showTelegramTable);
|
|
}
|
|
|
|
void LogViewGui::createWlsSelectionWidget()
|
|
{
|
|
// send-checkbox
|
|
m_SentWlsTelCheckBox = createRadioButton(tr("&gesendete Telegramme"), QLatin1String(":/image/P2W.png"));
|
|
// received-checkbox
|
|
m_ReceivedWlsTelCheckBox = createRadioButton(tr("&empfangene Telegramme"), QLatin1String(":/image/W2P.png"));
|
|
// pos-checkbox
|
|
m_PosWlsTelCheckBox = createRadioButton(tr("&Positionsmeldungen"), QLatin1String(":/image/WlsPos.png"));
|
|
|
|
QVBoxLayout* wlsFilterBox = new QVBoxLayout;
|
|
wlsFilterBox->addWidget(m_SentWlsTelCheckBox);
|
|
wlsFilterBox->addWidget(m_ReceivedWlsTelCheckBox);
|
|
wlsFilterBox->addWidget(m_PosWlsTelCheckBox);
|
|
wlsFilterBox->addStretch(1);
|
|
|
|
m_WlsSelectionGroup = new QGroupBox(tr("Telegramme anzeigen"), this);
|
|
m_WlsSelectionGroup->setCheckable(true);
|
|
m_WlsSelectionGroup->setChecked(false);
|
|
m_WlsSelectionGroup->setLayout(wlsFilterBox);
|
|
connect(m_WlsSelectionGroup, &QGroupBox::toggled, this, &LogViewGui::showTelegramTable);
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::customMenuRequested(const QPoint &pos)
|
|
{
|
|
//create Menu with Actions
|
|
QMenu menu(this);
|
|
menu.addAction(tr("Add Telegram to EditList"), this, &LogViewGui::addTelegramToEdit);
|
|
menu.addAction(tr("Show HexData"), this, &LogViewGui::showHexData);
|
|
menu.addAction(tr("Export as CSV file"), this, &LogViewGui::exportAsCsv);
|
|
menu.addAction(tr("Export as JSon file"), this, &LogViewGui::exportAsJson);
|
|
#ifdef LTS_DEBUG
|
|
if (m_EditTelegramController && m_EditTelegramController->isInjectionPossible())
|
|
{
|
|
const QString str = m_replayTimer->isActive() ? tr("Stop replay") : tr("Start Replay from here");
|
|
menu.addAction(str, this, &LogViewGui::onStartLogReplay);
|
|
}
|
|
#endif
|
|
menu.exec(m_logTelegramView->viewport()->mapToGlobal(pos));
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::addTelegramToEdit()
|
|
{
|
|
for (const QModelIndex &orig: m_logTelegramView->selectionModel()->selectedRows())
|
|
{
|
|
const QModelIndex idx = m_telegramProxyModel->mapToSource(orig);
|
|
QSharedPointer<LogViewTelegram> tele = m_telegramModel->telegram(idx.row());
|
|
if (!tele)
|
|
continue;
|
|
m_EditTelegramController->appendTelegram(tele);
|
|
}
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::showHexData()
|
|
{
|
|
const QModelIndex idx = m_telegramProxyModel->mapToSource(m_logTelegramView->currentIndex());
|
|
QSharedPointer<LogViewTelegram> tele = m_telegramModel->telegram(idx.row());
|
|
if (!tele)
|
|
return;
|
|
|
|
LogViewTelegramDialog* showTelegramDialog = new LogViewTelegramDialog(this, true);
|
|
showTelegramDialog->showDataDump(tele, false);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::exportAsCsv()
|
|
{
|
|
const int idx = m_ActualLogfile.lastIndexOf(QLatin1Char('.'));
|
|
const QString suggestion = m_ActualLogfile.left(idx) + QLatin1String(".csv");
|
|
const QString fn = QFileDialog::getSaveFileName(this, tr("Export logdata as CSV"), suggestion, tr("CSV file (*.csv)"));
|
|
if (fn.isEmpty())
|
|
return;
|
|
QFile f(fn);
|
|
if (!f.open(QIODevice::WriteOnly))
|
|
return;
|
|
for (int c = 0; c < m_telegramProxyModel->columnCount(); ++c)
|
|
{
|
|
f.write(m_telegramProxyModel->headerData(c, Qt::Horizontal).toString().toUtf8());
|
|
f.write(";");
|
|
}
|
|
f.write("ISSI\n");
|
|
const int rc = m_telegramProxyModel->rowCount();
|
|
for (int r = 0; r < rc; ++r)
|
|
{
|
|
QSharedPointer<LogViewTelegram> tele = m_telegramProxyModel->telegram(r);
|
|
if (!tele)
|
|
continue;
|
|
f.write(QByteArray::number(tele->getDestination()));
|
|
f.write(";");
|
|
f.write(tele->getName().toUtf8());
|
|
f.write(";");
|
|
f.write(QByteArray::number(tele->getParticipantId()));
|
|
f.write(";");
|
|
f.write(QByteArray::number(tele->getLogTimeMsec()));
|
|
f.write(";");
|
|
f.write(QByteArray::number(tele->getGpsTime()));
|
|
f.write(";");
|
|
f.write(QByteArray::number(tele->getDelay()));
|
|
f.write(";");
|
|
f.write(QByteArray::number(tele->getISSI()));
|
|
f.write("\n");
|
|
}
|
|
f.close();
|
|
}// ---------------------------------------------------------------
|
|
|
|
void LogViewGui::exportAsJson()
|
|
{
|
|
const int idx = m_ActualLogfile.lastIndexOf(QLatin1Char('.'));
|
|
const QString suggestion = m_ActualLogfile.left(idx) + QLatin1String(".csv");
|
|
const QString fn = QFileDialog::getSaveFileName(this, tr("Export logdata as Json"), suggestion, tr("JSon file (*.json)"));
|
|
if (fn.isEmpty())
|
|
return;
|
|
QFile f(fn);
|
|
if (!f.open(QIODevice::WriteOnly))
|
|
return;
|
|
QJsonArray arr;
|
|
const int rc = m_telegramProxyModel->rowCount();
|
|
for (int r = 0; r < rc; ++r)
|
|
{
|
|
QSharedPointer<LogViewTelegram> tele = m_telegramProxyModel->telegram(r);
|
|
if (!tele)
|
|
continue;
|
|
if (tele->jsonData().isEmpty())
|
|
continue;
|
|
arr += tele->jsonData();
|
|
}
|
|
f.write(QJsonDocument(arr).toJson(QJsonDocument::Indented));
|
|
f.close();
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::onStartLogReplay()
|
|
{
|
|
#ifndef LTS_DEBUG
|
|
return;
|
|
#endif
|
|
if (m_replayTimer->isActive())
|
|
{
|
|
m_replayTimer->stop();
|
|
return;
|
|
}
|
|
m_reloadAction->setChecked(false);
|
|
m_PosCentralTelCheckBox->setChecked(true);
|
|
if (!m_EditTelegramController || !m_EditTelegramController->isInjectionPossible())
|
|
return;
|
|
m_currentReplayRow = m_telegramProxyModel->mapToSource(m_logTelegramView->currentIndex()).row();
|
|
if (m_currentReplayRow < 0)
|
|
return;
|
|
m_replayTimer->start(0);
|
|
}
|
|
|
|
void LogViewGui::onReplayTimerTimeout()
|
|
{
|
|
auto findNextCentralTelegram = [&]()
|
|
{
|
|
static constexpr auto sendToCentralBits = N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral |
|
|
N_CoPrtCnv::CoPrtCnvLogHeader::e_DestSend;
|
|
auto tele = m_telegramModel->telegram(m_currentReplayRow);
|
|
while (tele && (tele->getDestination() != sendToCentralBits ||
|
|
tele->getTelId() == GEF_BESTAETIGUNG))
|
|
tele = m_telegramModel->telegram(++m_currentReplayRow);
|
|
return tele;
|
|
};
|
|
|
|
QSharedPointer<LogViewTelegram> tele = findNextCentralTelegram();
|
|
auto checkTele = [&]()
|
|
{
|
|
if (!tele)
|
|
{
|
|
m_replayTimer->stop();
|
|
m_currentReplayRow = -1;
|
|
QMessageBox::information(this, tr("Sending finished"), tr("No more telegrams to send - stopping"));
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
if (!checkTele())
|
|
return;
|
|
const uint64_t curSendTime = tele->getLogTimeMsec();
|
|
auto teleCopy = QSharedPointer<LogViewTelegram>(new LogViewTelegram(*(tele.data())));
|
|
teleCopy->actualizeGpsTime();
|
|
m_InjectionThread->sendTelegram(teleCopy.data(), true);
|
|
++m_currentReplayRow;
|
|
tele = findNextCentralTelegram();
|
|
if (!checkTele())
|
|
return;
|
|
|
|
uint64_t nextSendTime = (tele->getLogTimeMsec() - curSendTime); // micro -> milli
|
|
DEBUG_LOG(m_logger) << "Next SendTime: " << nextSendTime
|
|
<< ", telId: " << tele->getTelId()
|
|
<< ", next row: " << m_currentReplayRow
|
|
<< ", equipNo: " << tele->getParticipantId();
|
|
QModelIndex idx = m_telegramModel->index(m_currentReplayRow, 0, QModelIndex());
|
|
m_logTelegramView->setCurrentIndex(m_telegramProxyModel->mapFromSource(idx));
|
|
m_replayTimer->start(nextSendTime);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::loadSpecificationFiles()
|
|
{
|
|
QSettings settings;
|
|
settings.beginGroup(LogViewOptionDialog::SPEC_FILES_GROUP);
|
|
|
|
// load central-protocol spezification
|
|
QString defString = QCoreApplication::applicationDirPath() + QLatin1String("/training_area_telegrams.h");
|
|
QString filename = settings.value(LogViewOptionDialog::P0_FILENAME, defString).toString();
|
|
INFO_LOG(m_logger) << "Load central-protocol spezification-file: " << filename.toStdString();
|
|
if (!QFile::exists(filename))
|
|
{
|
|
QMessageBox::warning(this, tr("LogView"), tr("Die Spezifikations-Datei \'%1\' fuer Zentral-Telegramme existiert nicht!<br><br>Werde die Default-Datei verwenden...").arg(filename));
|
|
filename = defString;
|
|
}
|
|
LogViewTelegram::jsonParser()->parse(filename);
|
|
|
|
// load tetra-protocol spezification
|
|
defString = QCoreApplication::applicationDirPath() + QLatin1String("/zsksxd_tetraForLogView.x");
|
|
filename = settings.value(LogViewOptionDialog::P5_FILENAME, defString).toString();
|
|
INFO_LOG(m_logger) << "Load tetra-protocol spezification-file: " << filename.toStdString();
|
|
if (!QFile::exists(filename))
|
|
{
|
|
QMessageBox::warning(this, tr("LogView"), tr("Die Spezifikations-Datei \'%1\' fuer TETRA-Telegramme existiert nicht!<br><br>Werde die Default-Datei verwenden...").arg(filename));
|
|
filename = defString;
|
|
}
|
|
|
|
LogViewTelegram::tetraParser()->parseX_File(filename);
|
|
|
|
INFO_LOG(m_logger) << "Browse telegram-log-file";
|
|
newTelegramFile();
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::newTelegramFile()
|
|
{
|
|
if (m_TailTimer) m_TailTimer->stop();
|
|
// delete all participants
|
|
m_participantModel->clearParticipants();
|
|
m_telegramModel->clearTelegrams();
|
|
m_participantListTelCount.clear();
|
|
m_participantListIssi.clear();
|
|
m_ParticipantStatus->setText(tr("0 Teilnehmer"));
|
|
// load a telegram-file
|
|
loadTelegramFile();
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::loadTelegramFile()
|
|
{
|
|
const QLatin1String DIR("Dir");
|
|
QSettings settings;
|
|
settings.beginGroup(QLatin1String("LogFiles"));
|
|
|
|
QString filename = QFileDialog::getOpenFileName(this, tr("Bitte eine Log-Datei auswaehlen"), settings.value(DIR).toString(), LogViewOptionDialog::KRLOG_FILES/*tr("Log-Dateien (*.krlog)")*/);
|
|
if (filename.isEmpty())
|
|
return;
|
|
|
|
QDir dir;
|
|
settings.setValue(DIR, dir.filePath(filename));
|
|
|
|
readTelegramsFromLogFile(filename);
|
|
showTelegramTable();
|
|
startInjectionThread();
|
|
m_logTelegramView->resizeColumnsToContents();
|
|
m_ParticipantTableView->resizeColumnsToContents();
|
|
|
|
// start the time for checking whether new entries were added to the log-file
|
|
if (!m_TailTimer)
|
|
m_TailTimer = new QTimer(this);
|
|
connect(m_TailTimer, &QTimer::timeout, this, &LogViewGui::updateLogfile, Qt::QueuedConnection);
|
|
m_TailTimer->setInterval(1000);
|
|
m_TailTimer->start();
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
// Checks whether the size of actual logfile has changed. If
|
|
// yes, the new log-entries will be read and shown within
|
|
// table.
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::updateLogfile()
|
|
{
|
|
if(!m_DoReload)
|
|
return;
|
|
m_TailTimer->stop();
|
|
QFileInfo fileInfo = QFileInfo(m_ActualLogfile);
|
|
if (fileInfo.exists())
|
|
{
|
|
if (fileInfo.size() > m_LogfileSize)
|
|
{
|
|
try
|
|
{
|
|
readTelegramsFromLogFile(m_ActualLogfile, m_LogfileSize);
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
WARNING_LOG(m_logger) << "Error: " << e.what();
|
|
// simply read the telegram in the next update
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//check if one newer file exists and load it
|
|
QString dateFromFile;
|
|
const QString format = QStringLiteral("yyMMdd_hh");
|
|
for (int iterator = fileInfo.baseName().size() - format.size(); iterator < fileInfo.baseName().size(); ++iterator)
|
|
dateFromFile.append(fileInfo.baseName().at(iterator));
|
|
|
|
QDateTime nextDateCalc = QDateTime::fromString(dateFromFile, format);
|
|
nextDateCalc = nextDateCalc.addYears(100);
|
|
nextDateCalc = nextDateCalc.addSecs(3600);
|
|
QString nextDate = nextDateCalc.toString(format);
|
|
nextDateCalc = nextDateCalc.addSecs(3600);
|
|
QString checkDate = nextDateCalc.toString(format);
|
|
|
|
QString filePath(fileInfo.absolutePath() + QLatin1Char('/'));
|
|
const QString baseName = fileInfo.baseName();
|
|
const QVector<QStringRef> parts = baseName.splitRef(QLatin1Char('_'));
|
|
|
|
for (int iterator = 0; iterator < parts.size() - 2; ++iterator) // ...ex_42_<date>...
|
|
filePath += parts.at(iterator).toString() + QLatin1Char('_');
|
|
|
|
QString nextFile(filePath + nextDate + QLatin1Char('.') + fileInfo.completeSuffix());
|
|
QString checkFile(filePath + checkDate + QLatin1Char('.') + fileInfo.completeSuffix());
|
|
|
|
QFileInfo infoNextFile(nextFile);
|
|
QFileInfo infoCheckFile(checkFile);
|
|
if (infoNextFile.exists() && infoNextFile.isFile() && !infoCheckFile.exists())
|
|
{
|
|
m_LogfileSize = 0;
|
|
readTelegramsFromLogFile(nextFile, m_LogfileSize);
|
|
}
|
|
}
|
|
}
|
|
m_TailTimer->start();
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::readTelegramsFromLogFile(const QString& a_fileName, const qint64 a_filePos)
|
|
{
|
|
// open the log-file
|
|
QFile telegramFile(a_fileName);
|
|
if (telegramFile.open(QIODevice::ReadOnly))
|
|
{
|
|
m_ActualLogfile = a_fileName;
|
|
telegramFile.seek(a_filePos);
|
|
setWindowTitle(QFileInfo(m_ActualLogfile).baseName());
|
|
m_logTelegramView->blockSignals(true);
|
|
m_logTelegramView->setUpdatesEnabled(false);
|
|
QVector<QSharedPointer<LogViewTelegram> > newTelegrams;
|
|
// read the header of telegram-entry
|
|
N_CoPrtCnv::CoPrtCnvLogHeader lh;
|
|
while (true)
|
|
{
|
|
if (sizeof(lh) == telegramFile.read((char*)&lh, sizeof(lh)))
|
|
{
|
|
if (lh.m_Version == 3 || lh.m_Version == 4)
|
|
{
|
|
// read the telegram itself
|
|
qint64 telegramLength = lh.m_Length - sizeof(lh);
|
|
QByteArray buf(telegramLength, Qt::Uninitialized);
|
|
if (telegramLength == telegramFile.read(buf.data(), telegramLength))
|
|
{
|
|
m_LogfileSize = telegramFile.pos();
|
|
|
|
if (lh.m_Version == 4)
|
|
buf = qUncompress(buf);
|
|
|
|
// add the telegram to telegram-list
|
|
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol protocol =
|
|
static_cast<N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol>(lh.m_Protocol);
|
|
QSharedPointer<LogViewTelegram> telegram(new LogViewTelegram(protocol, lh.m_Time, buf));
|
|
// this checks the telegram and raises a messagebox if the telegram is wrong
|
|
if (!telegram->isValid())
|
|
{
|
|
ERROR_LOG(m_logger) << "Trying to read/parse unknown data from logfile '" << a_fileName
|
|
<< "' at position " << telegramFile.pos() - (telegramLength + sizeof(lh));
|
|
continue;
|
|
}
|
|
newTelegrams.push_back(telegram);
|
|
|
|
// add the pariticipant to the participant-list
|
|
addToParticipantList(telegram);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QMessageBox::warning(this, tr("Falsche Version"), tr("LogViewer kann Telegramm-Logs der Version %1 nicht einlesen").arg(lh.m_Version));
|
|
ERROR_LOG(m_logger) << "Trying to read/parse unknown data from logfile '" << a_fileName
|
|
<< "' at position " << telegramFile.pos() - sizeof(lh);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
syncParticipantList();
|
|
|
|
m_telegramModel->appendTelegrams(newTelegrams);
|
|
m_ParticipantStatus->setText(tr("%1 Teilnehmer").arg(m_participantModel->rowCount()));
|
|
m_logTelegramView->setUpdatesEnabled(true);
|
|
m_logTelegramView->blockSignals(false);
|
|
|
|
statusBar()->showMessage(tr("%1 Telegramme eingelesen").arg(m_telegramModel->rowCount()));
|
|
}
|
|
else
|
|
{
|
|
QMessageBox::warning(this, tr("Dateifehler"), tr("Konnte die Datei <b>%1</b> nicht oeffnen").arg(a_fileName));
|
|
}
|
|
telegramFile.close();
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::selectedParticipantChanged()
|
|
{
|
|
std::set<int> selectedParticipantIds;
|
|
|
|
const QModelIndexList selectedParticipants = m_ParticipantTableView->selectionModel()->selectedRows(0);
|
|
for (const QModelIndex &participantIdx : selectedParticipants)
|
|
{
|
|
// row 0 -> eqId
|
|
const QModelIndex idx = m_participantProxyModel->mapToSource(participantIdx);
|
|
selectedParticipantIds.insert(m_participantModel->data(idx).toInt());
|
|
}
|
|
m_telegramProxyModel->setAllowedEquipmentIds(selectedParticipantIds);
|
|
showTelegramTable();
|
|
}
|
|
|
|
static void updateFilteredPosTelegramIds(std::set<int> &teleIds, bool bEnable)
|
|
{
|
|
if (bEnable)
|
|
{
|
|
teleIds.erase(TrainingAreaBase::TetraIcd::POSITIONS_MELDUNG);
|
|
teleIds.erase(TrainingAreaBase::TetraIcd::POSITIONS_MELDUNG_LFZ);
|
|
teleIds.erase(TrainingAreaBase::TetraIcd::POSITIONS_MELDUNG_MIT_TEILNEHMER);
|
|
teleIds.erase(TrainingAreaBase::TetraIcd::IPS_POSITIONSDATEN);
|
|
}
|
|
else
|
|
{
|
|
teleIds.insert(TrainingAreaBase::TetraIcd::POSITIONS_MELDUNG);
|
|
teleIds.insert(TrainingAreaBase::TetraIcd::POSITIONS_MELDUNG_LFZ);
|
|
teleIds.insert(TrainingAreaBase::TetraIcd::POSITIONS_MELDUNG_MIT_TEILNEHMER);
|
|
teleIds.insert(TrainingAreaBase::TetraIcd::IPS_POSITIONSDATEN);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::showTelegramTable()
|
|
{
|
|
updateFilteredPosTelegramIds(m_CentralTelegramFilterList, m_PosCentralTelCheckBox->isChecked());
|
|
updateFilteredPosTelegramIds(m_TetraTelegramFilterList, m_PosTetraTelCheckBox->isChecked());
|
|
updateFilteredPosTelegramIds(m_WlsTelegramFilterList, m_PosWlsTelCheckBox->isChecked());
|
|
if (m_ackCentralTelCheckBox->isChecked())
|
|
m_CentralTelegramFilterList.erase(TrainingAreaBase::TetraIcd::BESTAETIGUNG);
|
|
else
|
|
m_CentralTelegramFilterList.insert(TrainingAreaBase::TetraIcd::BESTAETIGUNG);
|
|
m_telegramProxyModel->setFilteredCentralTelegramIds(m_CentralTelegramFilterList);
|
|
m_telegramProxyModel->setFilteredTetraTelegramIds(m_TetraTelegramFilterList);
|
|
m_telegramProxyModel->setFilteredWlsTelegramIds(m_WlsTelegramFilterList);
|
|
|
|
m_telegramProxyModel->setFilterByEquipmentIds(m_ParticipantSelectionGroup->isChecked());
|
|
|
|
m_PosCentralTelCheckBox->setEnabled(m_SentCentralTelCheckBox->isChecked() && m_CentralSelectionGroup->isChecked());
|
|
m_PosTetraTelCheckBox->setEnabled(m_SentTetraTelCheckBox->isChecked() && m_TetraSelectionGroup->isChecked());
|
|
m_PosWlsTelCheckBox->setEnabled(m_ReceivedWlsTelCheckBox->isChecked() && m_WlsSelectionGroup->isChecked());
|
|
|
|
const bool bShowCentralTelegrams = m_CentralSelectionGroup->isChecked();
|
|
m_telegramProxyModel->setFilterCentralTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestSend,
|
|
!m_SentCentralTelCheckBox->isChecked() || !bShowCentralTelegrams);
|
|
m_telegramProxyModel->setFilterCentralTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestReceive,
|
|
!m_ReceivedCentralTelCheckBox->isChecked() || !bShowCentralTelegrams);
|
|
|
|
const bool bShowTetraTelegrams = m_TetraSelectionGroup->isChecked();
|
|
m_telegramProxyModel->setFilterTetraTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestSend,
|
|
!m_SentTetraTelCheckBox->isChecked() || !bShowTetraTelegrams);
|
|
m_telegramProxyModel->setFilterTetraTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestReceive,
|
|
!m_ReceivedTetraTelCheckBox->isChecked() || !bShowTetraTelegrams);
|
|
m_telegramProxyModel->setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::e_RegisterInd,
|
|
!m_RegisterTetraTelCheckBox->isChecked() || !bShowTetraTelegrams);
|
|
m_telegramProxyModel->setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::e_RegisterRsp,
|
|
!m_RegisterTetraTelCheckBox->isChecked() || !bShowTetraTelegrams);
|
|
m_telegramProxyModel->setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::e_DataIndReq,
|
|
!bShowTetraTelegrams);
|
|
m_telegramProxyModel->setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::e_ReportIndReq,
|
|
!m_ReportTetraTelCheckBox->isChecked() || !bShowTetraTelegrams);
|
|
m_telegramProxyModel->setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::e_AirInterfaceLoadReq,
|
|
!m_AirInterfaceLoadTetraTelCheckBox->isChecked() || !bShowTetraTelegrams);
|
|
m_telegramProxyModel->setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::e_AirLoadHyterra,
|
|
!m_AirInterfaceLoadTetraTelCheckBox->isChecked() || !bShowTetraTelegrams);
|
|
m_telegramProxyModel->setFilterTetraLogin(!m_LoginTetraTelCheckBox->isChecked() || !bShowTetraTelegrams);
|
|
m_telegramProxyModel->setFilterTetraFragmented(!m_FragmentedTetraTelCheckBox->isChecked() || !bShowTetraTelegrams);
|
|
|
|
const bool bShowWlsTelegrams = m_WlsSelectionGroup->isChecked();
|
|
m_telegramProxyModel->setFilterWlsTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestSend,
|
|
!m_SentWlsTelCheckBox->isChecked() || !bShowWlsTelegrams);
|
|
m_telegramProxyModel->setFilterWlsTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestReceive,
|
|
!m_ReceivedWlsTelCheckBox->isChecked() || !bShowWlsTelegrams);
|
|
|
|
m_TelegramStatus->setText(tr("%1 telegrams (unfiltered: %2)")
|
|
.arg(m_telegramProxyModel->rowCount())
|
|
.arg(m_telegramModel->rowCount()));
|
|
}
|
|
|
|
|
|
void LogViewGui::addToParticipantList(const QSharedPointer<LogViewTelegram> &a_telegram)
|
|
{
|
|
int partId = a_telegram->getParticipantId();
|
|
m_participantListTelCount[partId]++;
|
|
auto &issi = m_participantListIssi[partId];
|
|
if (issi == 0)
|
|
issi = a_telegram->getISSI();
|
|
}
|
|
|
|
void LogViewGui::syncParticipantList()
|
|
{
|
|
QVector<int> eqIds;
|
|
QVector<int> issis;
|
|
QVector<int> numberOfTelegrams;
|
|
eqIds.reserve(m_participantListTelCount.size());
|
|
issis.reserve(m_participantListTelCount.size());
|
|
numberOfTelegrams.reserve(m_participantListTelCount.size());
|
|
for (auto it = m_participantListTelCount.constBegin(); it != m_participantListTelCount.constEnd(); ++it)
|
|
{
|
|
eqIds.push_back(it.key());
|
|
issis.push_back(m_participantListIssi.value(it.key()));
|
|
numberOfTelegrams.push_back(it.value());
|
|
}
|
|
m_participantModel->addUpdateParticipants(eqIds, issis, numberOfTelegrams);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::changeSettings()
|
|
{
|
|
LogViewOptionDialog optionDialog(this);
|
|
|
|
connect(&optionDialog, &LogViewOptionDialog::settingsChanged, this, &LogViewGui::onSettingsChanged);
|
|
|
|
optionDialog.exec();
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
QCheckBox* LogViewGui::createRadioButton(const QString& a_buttonName, const QString& a_iconName)
|
|
{
|
|
QCheckBox* checkBox = new QCheckBox(a_buttonName, this);
|
|
checkBox->setIcon(QIcon(a_iconName));
|
|
checkBox->setIconSize(RADIO_BUTTON_ICON_SIZE);
|
|
connect(checkBox, &QCheckBox::toggled, this, &LogViewGui::showTelegramTable);
|
|
return checkBox;
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
// starts the thread, which trys to connect to the injection-
|
|
// server of PrtCnv
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::startInjectionThread()
|
|
{
|
|
if (m_InjectionThread)
|
|
{
|
|
m_InjectionThread->quit();
|
|
m_InjectionThread->wait();
|
|
delete m_InjectionThread;
|
|
}
|
|
|
|
m_InjectionThread = new LogViewInjectionThread();
|
|
|
|
QSettings settings;
|
|
settings.beginGroup(QLatin1String("LogFiles"));
|
|
QString filePath = settings.value(QLatin1String("Dir")).toString();
|
|
QString exerciseName;
|
|
QVector<QStringRef> parts = filePath.splitRef(QLatin1Char('/'));
|
|
if (parts.size() >= 2)
|
|
exerciseName = QLatin1Char('_') + parts.at(parts.size() - 2).toString();
|
|
|
|
QString portFilePath = QCoreApplication::applicationDirPath() + QDir::separator() + QLatin1String("PrtCnv") + exerciseName + QLatin1String(".dat");
|
|
QFileInfo checkPortFile(portFilePath);
|
|
if(checkPortFile.exists() && checkPortFile.isFile())
|
|
{
|
|
QSettings portSetting(portFilePath, QSettings::IniFormat);
|
|
m_InjectionThread->setPort(portSetting.value(QLatin1String("Injection/Port")).toInt());
|
|
}
|
|
|
|
m_EditTelegramController->setInjectionThread(m_InjectionThread);
|
|
connect(m_InjectionThread, &LogViewInjectionThread::updateStatus,
|
|
this, &LogViewGui::updateInjectionStatus);
|
|
|
|
m_InjectionThread->start();
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
// Toggles whether the logfile must be periodically checked
|
|
// for changes
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::reloadOnOff()
|
|
{
|
|
m_DoReload = !m_DoReload;
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::closeEvent(QCloseEvent* a_closeEvent)
|
|
{
|
|
QSettings settings;
|
|
settings.beginGroup(WINDOW_GROUP);
|
|
|
|
// store the actual toolbox selection
|
|
settings.setValue(TOOLBOXINDEX, m_ToolBox->currentIndex());
|
|
|
|
// store the actual size
|
|
settings.setValue(SIZE, size());
|
|
QPoint position = pos();
|
|
settings.setValue(POS, position);
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
|
int screenNbr = QApplication::desktop()->screenNumber(position);
|
|
#else
|
|
QScreen *scr = QGuiApplication::screenAt(position);
|
|
int screenNbr = QGuiApplication::screens().indexOf(scr);
|
|
#endif
|
|
settings.setValue(SCREEN, screenNbr);
|
|
|
|
// store the splitter-position
|
|
const QList<int> splitterSizes = m_Splitter->sizes();
|
|
QList<QVariant> splitterSizesAsVariant;
|
|
splitterSizesAsVariant.reserve(splitterSizes.size());
|
|
for (int item : splitterSizes)
|
|
splitterSizesAsVariant << QVariant(item);
|
|
|
|
settings.setValue(SPLITTPOS, splitterSizesAsVariant);
|
|
|
|
settings.endGroup();
|
|
|
|
QMainWindow::closeEvent(a_closeEvent);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::updateInjectionStatus(const QString& a_picName, const QString& a_toopTipText)
|
|
{
|
|
m_InjectionStatus->setPixmap(QPixmap(a_picName));
|
|
m_InjectionStatus->setToolTip(a_toopTipText);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
void LogViewGui::onLogTelegramViewDoubleClicked(const QModelIndex &index)
|
|
{
|
|
if (!m_telegramProxyModel || !m_telegramModel)
|
|
return;
|
|
QModelIndex idx = m_telegramProxyModel->mapToSource(index);
|
|
if (!idx.isValid())
|
|
return;
|
|
QSharedPointer<LogViewTelegram> telegram = m_telegramModel->telegram(idx.row());
|
|
if (!telegram)
|
|
return;
|
|
LogViewTelegramDialog* showTelegramDialog = new LogViewTelegramDialog(this, true);
|
|
showTelegramDialog->showDialog(telegram);
|
|
}
|
|
|
|
void LogViewGui::onSettingsChanged(uint32_t changedFlags)
|
|
{
|
|
if ((changedFlags & LogViewOptionDialog::SpecFilesGroup) == LogViewOptionDialog::SpecFilesGroup)
|
|
loadSpecificationFiles();
|
|
|
|
if ((changedFlags & LogViewOptionDialog::InjectionGroup) == LogViewOptionDialog::InjectionGroup)
|
|
startInjectionThread();
|
|
}
|
|
|
|
} // namespace N_LogView
|