Adds initial intermediate qt6 porting state
This commit is contained in:
11247 files changed
+1891537
No files matched your search
Executable
+135
@@ -0,0 +1,135 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLSE, 2017-02-10
|
||||
#
|
||||
|
||||
|
||||
# EventFilter
|
||||
SET(EventFilter_SRCS
|
||||
EventFilter/AttributeEditingModeUI.h
|
||||
EventFilter/AttributeEditingModeUI.cpp
|
||||
EventFilter/AttributeSelectionModeUI.h
|
||||
EventFilter/AttributeSelectionModeUI.cpp
|
||||
|
||||
EventFilter/FilterWindow.h
|
||||
EventFilter/FilterWindow.cpp
|
||||
EventFilter/FilterTableEntry.h
|
||||
EventFilter/FilterTableEntry.cpp
|
||||
EventFilter/FilterTableEntryAttribute.h
|
||||
EventFilter/FilterTableEntryAttribute.cpp
|
||||
|
||||
EventFilter/interpreter/FilterWorker.h
|
||||
EventFilter/interpreter/FilterWorker.cpp
|
||||
|
||||
EventFilter/widgets/AbstractAttributeWidget.cpp
|
||||
EventFilter/widgets/ComboBox.cpp
|
||||
EventFilter/widgets/TimeRangeWidget.cpp
|
||||
EventFilter/widgets/AreaWidget.cpp
|
||||
EventFilter/widgets/DefaultRangeWidget.cpp
|
||||
EventFilter/widgets/CheckBoxWidget.cpp
|
||||
EventFilter/widgets/RadiusWidget.cpp
|
||||
|
||||
EventFilter/interpreter/InfoWindow.h
|
||||
EventFilter/interpreter/InfoWindow.cpp
|
||||
EventFilter/interpreter/FilterEquationFunctions.cpp
|
||||
EventFilter/interpreter/FilterValueInterpreter.cpp
|
||||
|
||||
EventFilter/widgets/AbstractAttributeWidget.h
|
||||
EventFilter/widgets/ComboBox.h
|
||||
EventFilter/widgets/TimeRangeWidget.h
|
||||
EventFilter/widgets/AreaWidget.h
|
||||
EventFilter/widgets/DefaultRangeWidget.h
|
||||
EventFilter/widgets/CheckBoxWidget.h
|
||||
EventFilter/widgets/RadiusWidget.h
|
||||
|
||||
EventFilter/interpreter/FilterEquationFunctions.h
|
||||
EventFilter/interpreter/FilterValueInterpreter.h
|
||||
|
||||
detail_data.h
|
||||
detail_data.cpp
|
||||
excon_filter.h
|
||||
excon_filter.cpp
|
||||
logger.h
|
||||
logger.cpp
|
||||
)
|
||||
|
||||
SET(EventFilter_UICS
|
||||
EventFilter/ui/FilterWindowUi.ui
|
||||
)
|
||||
|
||||
|
||||
# Timeline
|
||||
SET(tln_view_gui_SRCS
|
||||
attribute_value_lookup.cpp
|
||||
attribute_value_lookup.h
|
||||
tln_view_gui_plugin.cpp
|
||||
tln_view_gui_plugin.h
|
||||
tln_dialog.cpp
|
||||
tln_dialog.h
|
||||
tln_dialog_model.cpp
|
||||
tln_dialog_model.h
|
||||
tln_cache_dialog.cpp
|
||||
tln_cache_dialog.h
|
||||
tln_show_details.cpp
|
||||
tln_show_details.h
|
||||
tln_event_list.h
|
||||
tln_event_list.cpp
|
||||
tln_event_list_model.h
|
||||
tln_event_list_model.cpp
|
||||
tln_event_list_columns.h
|
||||
tln_event_list_columns.cpp
|
||||
tln_legend.h
|
||||
tln_legend.cpp
|
||||
|
||||
${EventFilter_SRCS}
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(tln_view_gui_SRCS
|
||||
tln_dialog.ui
|
||||
tln_cache_dialog.ui
|
||||
tln_show_details.ui
|
||||
tln_event_list.ui
|
||||
tln_event_list_columns.ui
|
||||
tln_legend.ui
|
||||
|
||||
${EventFilter_UICS}
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS TlnViewGuiPlugin MODULE ${tln_view_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(TlnViewGuiPlugin
|
||||
Qt5::Widgets
|
||||
Qt5::WebSockets
|
||||
|
||||
LtsAppManager
|
||||
LtsDataView
|
||||
LtsTimelineClassic
|
||||
LtsPrinting
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsUtilsCore # data mod
|
||||
LtsUtilsGuiDds
|
||||
LtsUtilsSettings
|
||||
LtsWidgets
|
||||
NGLLogger
|
||||
ngltools # dtg
|
||||
|
||||
AvmDataPluginInterface
|
||||
ExmDataPluginInterface
|
||||
IsmDataPluginInterface
|
||||
MrkDataPluginInterface
|
||||
OpmDataPluginInterface
|
||||
PdmDataPluginInterface
|
||||
PpmDataPluginInterface
|
||||
|
||||
FlmExplorerGuiPluginInterface
|
||||
FltAesGuiPluginInterface # SitMap Filter
|
||||
TlnDataPluginInterface
|
||||
TlnViewGuiPluginInterface
|
||||
|
||||
MrkCommon # SitMap Filter Helper
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(TlnViewGuiPlugin)
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "AttributeEditingModeUI.h"
|
||||
#include "../detail_data.h"
|
||||
|
||||
#include "widgets/TimeRangeWidget.h"
|
||||
#include "widgets/DefaultRangeWidget.h"
|
||||
#include "widgets/ComboBox.h"
|
||||
#include "widgets/CheckBoxWidget.h"
|
||||
#include "widgets/AreaWidget.h"
|
||||
#include "widgets/RadiusWidget.h"
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
AbstractAttributeWidget *EditingModeUI::createAttributeUIWidget(DetailData *detailData, const QString &attributeType,
|
||||
int eventType, const QString &initialValue)
|
||||
{
|
||||
AbstractAttributeWidget *resultWidget = nullptr;
|
||||
QString concreteAttributeType = detailData->attributeRedirectionLookup.getRedirection(attributeType);
|
||||
int attributeUIType = detailData->attributeUITypeLookup.getUIType(concreteAttributeType);
|
||||
|
||||
if (attributeUIType == -1)
|
||||
return nullptr;
|
||||
|
||||
|
||||
|
||||
const DetailData::AttributeParameterLookup::ParameterMap &pm = detailData->attributeParameterLookup.getParameterMap(concreteAttributeType);
|
||||
|
||||
switch (attributeUIType)
|
||||
{
|
||||
case DetailData::ATTRIBUTE_UI_TYPE_COMBO_BOX:
|
||||
{
|
||||
resultWidget = new ComboBox(detailData, concreteAttributeType, eventType, initialValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case DetailData::ATTRIBUTE_UI_TYPE_DEFAULT_RANGE_WIDGET:
|
||||
{
|
||||
bool minb = false;
|
||||
unsigned int min = pm.value(DetailData::UI_PARAM_TYPE_MIN).toUInt(&minb);
|
||||
|
||||
bool maxb = false;
|
||||
unsigned int max = pm.value(DetailData::UI_PARAM_TYPE_MAX).toUInt(&maxb);
|
||||
|
||||
QString prefix = pm.value(DetailData::UI_PARAM_TYPE_PREFIX).toString();
|
||||
|
||||
QString suffix = pm.value(DetailData::UI_PARAM_TYPE_SUFFIX).toString();
|
||||
|
||||
|
||||
if (!minb || !maxb)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "createAttributeUIWidget: !minb (" << minb << ") || !maxb (" << maxb << ")";
|
||||
break;
|
||||
}
|
||||
|
||||
resultWidget = new DefaultRangeWidget(min, max, prefix, suffix, initialValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case DetailData::ATTRIBUTE_UI_TYPE_RAD_RANGE_WIDGET:
|
||||
{
|
||||
bool n1k = false;
|
||||
int n1 = pm.value(DetailData::UI_PARAM_TYPE_N1).toUInt(&n1k);
|
||||
|
||||
bool n2k = false;
|
||||
int n2 = pm.value(DetailData::UI_PARAM_TYPE_N2).toUInt(&n2k);
|
||||
|
||||
bool o1k = false;
|
||||
int o1 = pm.value(DetailData::UI_PARAM_TYPE_O1).toUInt(&o1k);
|
||||
|
||||
bool o2k = false;
|
||||
int o2 = pm.value(DetailData::UI_PARAM_TYPE_O2).toUInt(&o2k);
|
||||
|
||||
bool rk = false;
|
||||
int r = pm.value(DetailData::UI_PARAM_TYPE_RAD).toUInt(&rk);
|
||||
|
||||
if (n1k && n2k && o1k && o2k && rk)
|
||||
{
|
||||
resultWidget = new RadiusWidget(n1, n2, o1, o2, r);
|
||||
break;
|
||||
}
|
||||
|
||||
WARNING_LOG(m_logger) << "DetailData::ATTRIBUTE_UI_TYPE_RAD_RANGE_WIDGET: errorious values!";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DetailData::ATTRIBUTE_UI_TYPE_AREA_RANGE_WIDGET:
|
||||
{
|
||||
bool n1k = false;
|
||||
int n1 = pm.value(DetailData::UI_PARAM_TYPE_N1).toUInt(&n1k);
|
||||
|
||||
bool n2k = false;
|
||||
int n2 = pm.value(DetailData::UI_PARAM_TYPE_N2).toUInt(&n2k);
|
||||
|
||||
bool o1k = false;
|
||||
int o1 = pm.value(DetailData::UI_PARAM_TYPE_O1).toUInt(&o1k);
|
||||
|
||||
bool o2k = false;
|
||||
int o2 = pm.value(DetailData::UI_PARAM_TYPE_O2).toUInt(&o2k);
|
||||
|
||||
if (n1k && n2k && o1k && o2k)
|
||||
{
|
||||
resultWidget = new AreaWidget(n1, n2, o1, o2);
|
||||
break;
|
||||
}
|
||||
|
||||
WARNING_LOG(m_logger) << "DetailData::ATTRIBUTE_UI_TYPE_AREA_RANGE_WIDGET: errorious values!";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DetailData::ATTRIBUTE_UI_TYPE_CHECKBOX:
|
||||
{
|
||||
resultWidget = new CheckBoxWidget(detailData, concreteAttributeType, initialValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case DetailData::ATTRIBUTE_UI_TYPE_TIME_RANGE_WIDGET:
|
||||
{
|
||||
TimeRangeWidget *trw = new TimeRangeWidget(detailData, initialValue);
|
||||
detailData->createRetrieveCurrentTimeCallback(trw->m_edit1);
|
||||
detailData->createRetrieveCurrentTimeCallback(trw->m_edit2);
|
||||
resultWidget = trw;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
WARNING_LOG(m_logger) << "createAttributeUIWidget: invalid attribute type #" << attributeUIType << "!";
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return resultWidget;
|
||||
}
|
||||
|
||||
void EditingModeUI::addAttributeContainer(int eventType, const QString &initialValue)
|
||||
{
|
||||
|
||||
|
||||
AbstractAttributeWidget *attributeUIWidget = createAttributeUIWidget(m_detailData, attributeType, eventType, initialValue);
|
||||
|
||||
if (attributeUIWidget == nullptr)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "addAttributeContainer: !attributeUIWidget";
|
||||
return;
|
||||
}
|
||||
|
||||
connect(attributeUIWidget, &AbstractAttributeWidget::destroyed, this, &EditingModeUI::signalChanges);
|
||||
connect(attributeUIWidget, &AbstractAttributeWidget::signalChanges, this, &EditingModeUI::signalChanges);
|
||||
|
||||
attributeValuesLayout->insertWidget(0, attributeUIWidget, 0, Qt::AlignTop);
|
||||
attributeUIWidget->setFocus();
|
||||
}
|
||||
|
||||
EditingModeUI::EditingModeUI(DetailData *detailData, const QString &attributeType, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, attributeType(attributeType)
|
||||
, m_detailData(detailData)
|
||||
, m_logger(getLogger("EventFilter.EditingModeUI"))
|
||||
{
|
||||
QVBoxLayout *editingModeLayout = new QVBoxLayout;
|
||||
|
||||
QWidget *filterTextWidget = new QWidget;
|
||||
QHBoxLayout *filterTextLayout = new QHBoxLayout;
|
||||
filterTextWidget->setLayout(filterTextLayout);
|
||||
|
||||
pbDelete = new QPushButton(QStringLiteral("-"));
|
||||
pbDelete->setToolTip(tr("Delete this attribute and all its values"));
|
||||
pbDelete->setPalette(QPalette(QColor("red")));
|
||||
pbDelete->setMaximumWidth(30);
|
||||
|
||||
lbFilterText = new QLabel;
|
||||
|
||||
filterTextLayout->addWidget(lbFilterText, 0, Qt::AlignLeft);
|
||||
filterTextLayout->addWidget(pbDelete, 1, Qt::AlignLeft);
|
||||
|
||||
|
||||
QWidget *attributeValuesWidget = new QWidget;
|
||||
attributeValuesLayout = new QVBoxLayout();
|
||||
attributeValuesWidget->setLayout(attributeValuesLayout);
|
||||
pbAddAttributeContainer = new QPushButton(tr("Add Value"));
|
||||
pbAddAttributeContainer->setPalette(QPalette(QColor("green")));
|
||||
|
||||
|
||||
setLayout(editingModeLayout);
|
||||
editingModeLayout->addWidget(filterTextWidget, 0, Qt::AlignTop);
|
||||
|
||||
|
||||
QWidget *horizontalLineWidget = new QWidget;
|
||||
horizontalLineWidget->setFixedHeight(2);
|
||||
horizontalLineWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
horizontalLineWidget->setStyleSheet(QStringLiteral("background-color: #c0c0c0;"));
|
||||
editingModeLayout->addWidget(horizontalLineWidget, 0, Qt::AlignTop);
|
||||
|
||||
editingModeLayout->addWidget(pbAddAttributeContainer, 0, Qt::AlignTop | Qt::AlignLeft);
|
||||
editingModeLayout->addWidget(attributeValuesWidget, 0, Qt::AlignTop);
|
||||
}
|
||||
|
||||
EditingModeUI::~EditingModeUI()
|
||||
{
|
||||
const auto children = findChildren<AbstractAttributeWidget*>();
|
||||
for (auto child : children)
|
||||
child->disconnect(this);
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QVBoxLayout;
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
class AbstractAttributeWidget;
|
||||
|
||||
|
||||
class EditingModeUI : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EditingModeUI(DetailData *detailData, const QString &attributeType, QWidget *parent);
|
||||
~EditingModeUI();
|
||||
|
||||
void addAttributeContainer(int eventType, const QString &initialValue = QString());
|
||||
|
||||
QLabel *lbFilterText;
|
||||
QPushButton *pbDelete;
|
||||
QVBoxLayout *attributeValuesLayout;
|
||||
QPushButton *pbAddAttributeContainer;
|
||||
|
||||
private:
|
||||
Timeline::AbstractAttributeWidget *createAttributeUIWidget(DetailData *detailData, const QString &attributeType,
|
||||
int eventType, const QString &initialValue);
|
||||
|
||||
signals:
|
||||
void signalChanges();
|
||||
private:
|
||||
QString attributeType;
|
||||
DetailData *m_detailData;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "../detail_data.h"
|
||||
#include "AttributeSelectionModeUI.h"
|
||||
#include "logger.h"
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
QComboBox *SelectionModeUI::createAttributesComboBox(int eventType)
|
||||
{
|
||||
QComboBox *cbAttributes = new QComboBox();
|
||||
|
||||
|
||||
|
||||
|
||||
DetailData::AttributeEventLookup::AttributeList attributeList = m_detailData->attributeEventLookup.getEventsAttributeList(eventType);
|
||||
|
||||
for (auto i = attributeList.constBegin(); i != attributeList.constEnd(); ++i)
|
||||
{
|
||||
const QString &attributeKey = m_detailData->attributeRedirectionLookup.getRedirection(*i);
|
||||
|
||||
|
||||
if (m_detailData->attributeInterpreterLookup.getInterpreterType(attributeKey) == DetailData::INTERPRETER_TYPE_NONE)
|
||||
continue;
|
||||
|
||||
QString cbAttribute = m_detailData->attributeTypeLookup.getAttributeText(attributeKey);
|
||||
|
||||
if (cbAttribute.isEmpty())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "SelectionModeUI::createAttributesComboBox: event type " << eventType << " has no attribute text for attribute " << attributeKey << " for attribute event lookup - not added";
|
||||
}
|
||||
else
|
||||
{
|
||||
cbAttributes->addItem(cbAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
return cbAttributes;
|
||||
}
|
||||
|
||||
|
||||
SelectionModeUI::SelectionModeUI(DetailData *detailData, const int eventType)
|
||||
: eventType(eventType)
|
||||
, m_detailData(detailData)
|
||||
, m_logger(getLogger("EventFilter.AttributeEditingModeUI"))
|
||||
{
|
||||
selectionModeWidget = new QWidget();
|
||||
selectionModeLayout = new QHBoxLayout();
|
||||
|
||||
lbFilterText = new QLabel(tr("Select attribute type to filter:"));
|
||||
cbAttributeType = createAttributesComboBox(eventType);
|
||||
|
||||
pbAddEditingMode = new QPushButton(tr("OK"));
|
||||
pbAddEditingMode->setToolTip(tr("Add this attribute and start adding values"));
|
||||
pbAddEditingMode->setPalette(QPalette(QColor("green")));
|
||||
pbAddEditingMode->setMaximumWidth(30);
|
||||
|
||||
pbDeleteFilter = new QPushButton(QStringLiteral("-"));
|
||||
pbDeleteFilter->setPalette(QPalette(QColor("red")));
|
||||
pbDeleteFilter->setToolTip(tr("Delete this attribute and all its values"));
|
||||
pbDeleteFilter->setMaximumWidth(30);
|
||||
|
||||
selectionModeLayout->addWidget(lbFilterText, 0, Qt::AlignCenter);
|
||||
selectionModeLayout->addWidget(cbAttributeType, 0, Qt::AlignTop);
|
||||
selectionModeLayout->addWidget(pbAddEditingMode, 0, Qt::AlignTop);
|
||||
selectionModeLayout->addWidget(pbDeleteFilter, 1, Qt::AlignTop);
|
||||
|
||||
selectionModeWidget->setLayout(selectionModeLayout);
|
||||
}
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
|
||||
class SelectionModeUI : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
SelectionModeUI &operator=(const SelectionModeUI &);
|
||||
|
||||
public:
|
||||
QComboBox *createAttributesComboBox(int eventType);
|
||||
|
||||
|
||||
|
||||
explicit SelectionModeUI(DetailData *detailData, const int eventType);
|
||||
|
||||
~SelectionModeUI()
|
||||
{
|
||||
delete lbFilterText;
|
||||
delete cbAttributeType;
|
||||
delete pbAddEditingMode;
|
||||
delete selectionModeLayout;
|
||||
delete selectionModeWidget;
|
||||
}
|
||||
|
||||
int eventType;
|
||||
QWidget *selectionModeWidget;
|
||||
QHBoxLayout *selectionModeLayout;
|
||||
QLabel *lbFilterText;
|
||||
QComboBox *cbAttributeType;
|
||||
QPushButton *pbAddEditingMode;
|
||||
QPushButton *pbDeleteFilter;
|
||||
DetailData *m_detailData;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "FilterTableEntry.h"
|
||||
#include "FilterTableEntryAttribute.h"
|
||||
#include "interpreter/FilterWorker.h"
|
||||
#include "../detail_data.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QSizePolicy>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
FilterTableEntry::FilterTableEntry(DetailData *detailData, const int &eventType, const bool &active, QWidget *parent)
|
||||
: QGroupBox(parent)
|
||||
, m_logger(getLogger("EventFilter.FilterTableEntry"))
|
||||
, m_eventType(eventType)
|
||||
|
||||
|
||||
, m_mainLayout(new QVBoxLayout())
|
||||
, m_topLayout(new QHBoxLayout())
|
||||
, m_centerLayout(new QHBoxLayout())
|
||||
, m_cbEventSelector(nullptr)
|
||||
, m_pbDelete(new QPushButton(QStringLiteral("-")))
|
||||
, m_pbFoundEvents(new QPushButton(tr("Show Events")))
|
||||
, m_pbFilterActive(new QPushButton(tr("Active")))
|
||||
, m_pbOK(new QPushButton(tr("OK")))
|
||||
, m_lbSelectText(new QLabel(tr("Select event type to filter:")))
|
||||
, m_detailData(detailData)
|
||||
{
|
||||
m_cbEventSelector = getEventTypesComboBox();
|
||||
|
||||
m_pbDelete->setPalette(QPalette(QColor("red")));
|
||||
m_pbDelete->setToolTip(tr("Delete this filter and all its attributes"));
|
||||
|
||||
m_pbFilterActive->setPalette(QPalette(QColor("orange")));
|
||||
m_pbFoundEvents->setPalette(QPalette(QColor("orange")));
|
||||
m_pbOK->setPalette(QPalette(QColor("green")));
|
||||
|
||||
m_pbOK->setToolTip(tr("Add this filter and start adding attributes (when needed)"));
|
||||
connect(m_pbFilterActive, &QPushButton::clicked, this, &FilterTableEntry::signalChanges);
|
||||
|
||||
|
||||
|
||||
|
||||
setLayout(m_mainLayout);
|
||||
|
||||
|
||||
|
||||
QWidget *topLayoutWidget = new QWidget(this);
|
||||
|
||||
|
||||
topLayoutWidget->setLayout(m_topLayout);
|
||||
|
||||
m_mainLayout->addWidget(topLayoutWidget, 0, Qt::AlignTop);
|
||||
|
||||
|
||||
|
||||
m_topLayout->addWidget(m_lbSelectText, 0, Qt::AlignLeft);
|
||||
m_topLayout->addWidget(m_cbEventSelector, 0, Qt::AlignLeft);
|
||||
|
||||
m_pbOK->setMinimumWidth(30);
|
||||
m_pbOK->setMaximumWidth(30);
|
||||
m_topLayout->addWidget(m_pbOK, 0, Qt::AlignLeft);
|
||||
connect(m_pbOK, &QPushButton::clicked, this, &FilterTableEntry::slotSelectEventType);
|
||||
|
||||
connect(m_pbDelete, &QPushButton::clicked, this, &FilterTableEntry::deleteLater);
|
||||
m_pbDelete->setMinimumWidth(30);
|
||||
m_pbDelete->setMaximumWidth(30);
|
||||
m_topLayout->addWidget(m_pbDelete, 1, Qt::AlignLeft);
|
||||
|
||||
QWidget *centerLayoutWidget = new QWidget(this);
|
||||
centerLayoutWidget->setStyleSheet(topLayoutWidget->styleSheet());
|
||||
centerLayoutWidget->setLayout(m_centerLayout);
|
||||
m_mainLayout->addWidget(centerLayoutWidget, 0);
|
||||
|
||||
if (m_eventType > -1)
|
||||
slotSelectEventType();
|
||||
|
||||
m_pbFoundEvents->setEnabled(active);
|
||||
m_pbFilterActive->setCheckable(true);
|
||||
m_pbFilterActive->setChecked(active);
|
||||
m_pbFilterActive->setToolTip(m_pbFilterActive->isChecked() ? tr("Filter is active") : tr("Filter is inactive"));
|
||||
}
|
||||
|
||||
FilterTableEntry::~FilterTableEntry()
|
||||
{
|
||||
const auto children = findChildren<FilterTableEntryAttribute *>();
|
||||
for (auto child : children)
|
||||
child->disconnect(this);
|
||||
}
|
||||
|
||||
void FilterTableEntry::updateData()
|
||||
{
|
||||
for (int i = 0; i < m_centerLayout->count(); i++)
|
||||
{
|
||||
FilterTableEntryAttribute *ftec = dynamic_cast<FilterTableEntryAttribute *>(m_centerLayout->itemAt(i)->widget());
|
||||
|
||||
if (!ftec)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "FilterTableEntry::filterText(): !ftec";
|
||||
continue;
|
||||
}
|
||||
|
||||
ftec->updateData(m_detailData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QComboBox *FilterTableEntry::getEventTypesComboBox()
|
||||
{
|
||||
QComboBox *cbEventTypes = new QComboBox();
|
||||
cbEventTypes->addItems(m_detailData->eventTypeLookup.getEventTexts());
|
||||
cbEventTypes->model()->sort(0);
|
||||
connect(cbEventTypes, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &FilterTableEntry::signalChanges);
|
||||
|
||||
return cbEventTypes;
|
||||
}
|
||||
|
||||
|
||||
const QJsonObject FilterTableEntry::filter(bool typeSafe) const
|
||||
{
|
||||
|
||||
|
||||
if (m_eventType == -1)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "FilterTableEntry has no event type.";
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!m_centerLayout->count())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
QJsonObject result;
|
||||
|
||||
QString eventTypeString;
|
||||
|
||||
if (typeSafe)
|
||||
eventTypeString = QString::number(m_eventType);
|
||||
else
|
||||
eventTypeString = m_detailData->eventTypeLookup.getEventText(m_eventType);
|
||||
|
||||
if (!eventTypeString.length())
|
||||
return QJsonObject();
|
||||
|
||||
|
||||
|
||||
|
||||
result[QStringLiteral("EventType")] = eventTypeString;
|
||||
|
||||
QJsonArray attributes;
|
||||
for (int i = 0; i < m_centerLayout->count(); i++)
|
||||
{
|
||||
FilterTableEntryAttribute *ftec = dynamic_cast<FilterTableEntryAttribute *>(m_centerLayout->itemAt(i)->widget());
|
||||
|
||||
if (!ftec)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "FilterTableEntry::filterText(): !ftec";
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QJsonObject filterTile = ftec->filter(typeSafe);
|
||||
|
||||
if (filterTile.isEmpty())
|
||||
continue;
|
||||
|
||||
attributes.append(filterTile);
|
||||
}
|
||||
|
||||
result[QStringLiteral("Attributes")] = attributes;
|
||||
result[QStringLiteral("Active")] = m_pbFilterActive->isChecked();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void FilterTableEntry::slotSelectEventType()
|
||||
{
|
||||
delete m_lbSelectText;
|
||||
|
||||
|
||||
if (m_cbEventSelector)
|
||||
{
|
||||
if (m_eventType == -1)
|
||||
{
|
||||
m_eventType = m_detailData->eventTypeLookup.getEventType(m_cbEventSelector->currentText());
|
||||
}
|
||||
|
||||
m_lbEventName = new QLabel(QString(tr("Filter by event type: <b>%1</b>")).arg(m_detailData->eventTypeLookup.getEventText(m_eventType)));
|
||||
m_lbEventName->setMinimumWidth(m_cbEventSelector->width());
|
||||
|
||||
delete m_cbEventSelector;
|
||||
m_cbEventSelector = nullptr;
|
||||
|
||||
m_topLayout->insertWidget(0, m_lbEventName);
|
||||
}
|
||||
|
||||
if (m_eventType == -1)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "slotSelectEventType: m_eventType == -1";
|
||||
return;
|
||||
}
|
||||
|
||||
delete m_pbOK;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QWidget *horizontalLineWidget = new QWidget();
|
||||
horizontalLineWidget->setFixedHeight(2);
|
||||
horizontalLineWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
horizontalLineWidget->setStyleSheet(QStringLiteral("background-color: #c0c0c0;"));
|
||||
m_mainLayout->insertWidget(1, horizontalLineWidget, 0, Qt::AlignTop);
|
||||
|
||||
delete m_pbDelete;
|
||||
m_pbDelete = new QPushButton(QStringLiteral("-"));
|
||||
m_pbDelete->setToolTip(tr("Delete this filter and all its attributes"));
|
||||
m_pbDelete->setPalette(QPalette(QColor("red")));
|
||||
connect(m_pbDelete, &QPushButton::clicked, this, &FilterTableEntry::deleteLater);
|
||||
m_pbDelete->setMinimumWidth(30);
|
||||
m_pbDelete->setMaximumWidth(30);
|
||||
m_topLayout->addWidget(m_pbDelete, 0, Qt::AlignLeft);
|
||||
|
||||
m_topLayout->addWidget(m_pbFilterActive, 0, Qt::AlignLeft);
|
||||
connect(m_pbFilterActive, &QPushButton::clicked, this, &FilterTableEntry::slotFilterActiveClicked);
|
||||
|
||||
connect(m_pbFoundEvents, &QPushButton::clicked, this, &FilterTableEntry::slotShowEvents);
|
||||
m_pbFoundEvents->setToolTip(tr("Show all events that fit to this filter"));
|
||||
m_topLayout->addWidget(m_pbFoundEvents, 1, Qt::AlignLeft);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DetailData::AttributeEventLookup::AttributeList attributeList = m_detailData->attributeEventLookup.getEventsAttributeList(m_eventType);
|
||||
|
||||
|
||||
|
||||
QMutableListIterator<QString> it(attributeList);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
const QString attributeType = it.next();
|
||||
|
||||
if (m_detailData->attributeInterpreterLookup.getInterpreterType(attributeType) == DetailData::INTERPRETER_TYPE_NONE)
|
||||
it.remove();
|
||||
}
|
||||
|
||||
if (attributeList.isEmpty())
|
||||
return;
|
||||
|
||||
|
||||
QPushButton *pbAddAttribute = new QPushButton(tr("Add Attribute"));
|
||||
pbAddAttribute->setPalette(QPalette(QColor("green")));
|
||||
connect(pbAddAttribute, &QPushButton::clicked, this, &FilterTableEntry::slotAddAttribute);
|
||||
|
||||
|
||||
m_mainLayout->insertWidget(2, pbAddAttribute, 0, Qt::AlignLeft);
|
||||
}
|
||||
|
||||
|
||||
void FilterTableEntry::slotShowEvents()
|
||||
{
|
||||
QJsonArray a;
|
||||
a.append(filter(true ));
|
||||
emit signalShowEvents(a);
|
||||
}
|
||||
|
||||
|
||||
void FilterTableEntry::slotFilterActiveClicked()
|
||||
{
|
||||
if (m_pbFilterActive->isChecked())
|
||||
{
|
||||
m_pbFilterActive->setPalette(QPalette(QColor("orange")));
|
||||
m_pbFilterActive->setToolTip(tr("Filter is active"));
|
||||
m_pbFoundEvents->setPalette(QPalette(QColor("orange")));
|
||||
m_pbFoundEvents->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pbFilterActive->setPalette(QPalette(QColor("grey")));
|
||||
m_pbFilterActive->setToolTip(tr("Filter is inactive"));
|
||||
m_pbFoundEvents->setPalette(QPalette(QColor("grey")));
|
||||
m_pbFoundEvents->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FilterTableEntry::slotAddAttribute()
|
||||
{
|
||||
addAttribute();
|
||||
}
|
||||
|
||||
|
||||
bool FilterTableEntry::hasAttributes() const
|
||||
{
|
||||
qWarning() << "hasAttributes? children: " << m_centerLayout->children().count();
|
||||
return !!m_centerLayout->children().count();
|
||||
}
|
||||
|
||||
|
||||
FilterTableEntryAttribute *FilterTableEntry::addAttribute(const QString &attributeType)
|
||||
{
|
||||
FilterTableEntryAttribute *ftec = new FilterTableEntryAttribute(m_detailData, m_eventType, attributeType, this);
|
||||
connect(ftec, &FilterTableEntryAttribute::signalChanges, this, &FilterTableEntry::signalChanges);
|
||||
connect(ftec, &FilterTableEntryAttribute::destroyed, this, &FilterTableEntry::signalChanges);
|
||||
m_centerLayout->insertWidget(0, ftec, 1, Qt::AlignLeft);
|
||||
|
||||
return ftec;
|
||||
}
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FilterTableEntryAttribute.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QComboBox>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QList>
|
||||
#include <QGroupBox>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
|
||||
class FilterTableEntry : public QGroupBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FilterTableEntry(DetailData *detailData, const int &eventType = -1, const bool &active = true, QWidget *parent = nullptr);
|
||||
~FilterTableEntry();
|
||||
const QJsonObject filter(bool typeSafe = false) const;
|
||||
|
||||
|
||||
FilterTableEntryAttribute *addAttribute(const QString &attributeType = QString());
|
||||
bool hasAttributes() const;
|
||||
void updateData();
|
||||
|
||||
|
||||
private:
|
||||
NGL::INGLLogger &m_logger;
|
||||
QComboBox *getEventTypesComboBox();
|
||||
|
||||
int m_eventType;
|
||||
|
||||
|
||||
QVBoxLayout *m_mainLayout{nullptr};
|
||||
QHBoxLayout *m_topLayout{nullptr};
|
||||
QHBoxLayout *m_centerLayout{nullptr};
|
||||
QComboBox *m_cbEventSelector{nullptr};
|
||||
QLabel *m_lbEventName{nullptr};
|
||||
QPushButton *m_pbDelete{nullptr};
|
||||
QPushButton *m_pbFoundEvents{nullptr};
|
||||
QPushButton *m_pbFilterActive{nullptr};
|
||||
QPushButton *m_pbOK{nullptr};
|
||||
QLabel *m_lbSelectText{nullptr};
|
||||
DetailData *m_detailData{nullptr};
|
||||
|
||||
signals:
|
||||
void signalShowEvents(const QJsonArray &filter);
|
||||
void signalChanges();
|
||||
|
||||
private slots:
|
||||
void slotAddAttribute();
|
||||
void slotFilterActiveClicked();
|
||||
void slotSelectEventType();
|
||||
void slotShowEvents();
|
||||
|
||||
public slots:
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "interpreter/FilterWorker.h"
|
||||
#include "FilterTableEntryAttribute.h"
|
||||
#include "widgets/AbstractAttributeWidget.h"
|
||||
#include "logger.h"
|
||||
#include "../detail_data.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
FilterTableEntryAttribute::FilterTableEntryAttribute(DetailData *detailData, int eventType, const QString &attributeType, QWidget *parent)
|
||||
: QGroupBox(parent)
|
||||
, m_eventType(eventType)
|
||||
, m_attributeType(attributeType)
|
||||
, m_selectionModeUI(nullptr)
|
||||
, m_editionModeUI(nullptr)
|
||||
, m_attributesLayout(new QVBoxLayout())
|
||||
, m_detailData(detailData)
|
||||
, m_logger(getLogger("EventFilter.FilterTableEntryAttribute"))
|
||||
{
|
||||
|
||||
this->setTitle(QString());
|
||||
|
||||
setLayout(m_attributesLayout);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
slotAddSelectionMode();
|
||||
|
||||
if (!attributeType.isEmpty())
|
||||
{
|
||||
m_selectionModeUI->cbAttributeType->setCurrentIndex(m_selectionModeUI->cbAttributeType->findData(QVariant::fromValue<QString>(attributeType)));
|
||||
slotAddEditingMode(false);
|
||||
}
|
||||
}
|
||||
|
||||
FilterTableEntryAttribute::~FilterTableEntryAttribute()
|
||||
{
|
||||
delete m_editionModeUI;
|
||||
}
|
||||
|
||||
void FilterTableEntryAttribute::updateData(DetailData *detailData)
|
||||
{
|
||||
if (!m_editionModeUI)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < m_editionModeUI->attributeValuesLayout->count(); i++)
|
||||
{
|
||||
AbstractAttributeWidget *aaw = dynamic_cast<AbstractAttributeWidget *>(m_editionModeUI->attributeValuesLayout->itemAt(i)->widget());
|
||||
|
||||
if (!aaw)
|
||||
continue;
|
||||
|
||||
aaw->updateData(detailData);
|
||||
connect(aaw, &AbstractAttributeWidget::deleteClicked, this, [this]()
|
||||
{
|
||||
emit attributeChanged(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const QJsonObject FilterTableEntryAttribute::filter(bool typeSafe) const
|
||||
{
|
||||
if (m_attributeType.isEmpty())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "filterText: m_attributeType == -1";
|
||||
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
|
||||
QString attributeTypeName;
|
||||
|
||||
if (typeSafe)
|
||||
attributeTypeName = m_attributeType;
|
||||
else
|
||||
{
|
||||
attributeTypeName = m_detailData->attributeTypeLookup.getAttributeText(m_attributeType);
|
||||
}
|
||||
|
||||
if (attributeTypeName.isEmpty())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "filterText: !attributeTypeName.length()";
|
||||
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
|
||||
QJsonObject result;
|
||||
result[QStringLiteral("AttributeType")] = attributeTypeName;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QJsonArray values;
|
||||
|
||||
if (m_editionModeUI)
|
||||
{
|
||||
for (int i = 0; i < m_editionModeUI->attributeValuesLayout->count(); i++)
|
||||
{
|
||||
AbstractAttributeWidget *aaw = dynamic_cast<AbstractAttributeWidget *>(m_editionModeUI->attributeValuesLayout->itemAt(i)->widget());
|
||||
|
||||
if (!aaw)
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
QString value = aaw->filterText(typeSafe);
|
||||
|
||||
if (value.isEmpty())
|
||||
continue;
|
||||
|
||||
values.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result[QStringLiteral("AttributeValues")] = values;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FilterTableEntryAttribute::slotAddSelectionMode()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
m_selectionModeUI = new SelectionModeUI(m_detailData, m_eventType);
|
||||
|
||||
connect(m_selectionModeUI->pbAddEditingMode, &QPushButton::clicked, this, &FilterTableEntryAttribute::slotAddEditingMode);
|
||||
connect(m_selectionModeUI->pbDeleteFilter, &QPushButton::clicked, this, &FilterTableEntryAttribute::slotDeleteAttributeContainer);
|
||||
|
||||
m_attributesLayout->addWidget(m_selectionModeUI->selectionModeWidget, 0, Qt::AlignTop);
|
||||
}
|
||||
|
||||
void FilterTableEntryAttribute::slotAddEditingMode(bool createBlankContainer)
|
||||
{
|
||||
|
||||
if (!m_selectionModeUI)
|
||||
return;
|
||||
|
||||
|
||||
QString attributeTypeString;
|
||||
|
||||
if (m_attributeType.isEmpty())
|
||||
{
|
||||
attributeTypeString = m_selectionModeUI->cbAttributeType->currentText();
|
||||
m_attributeType = m_detailData->attributeTypeLookup.getAttributeType(attributeTypeString);
|
||||
}
|
||||
else
|
||||
{
|
||||
attributeTypeString = m_detailData->attributeTypeLookup.getAttributeText(m_attributeType);
|
||||
|
||||
}
|
||||
|
||||
delete m_selectionModeUI;
|
||||
m_selectionModeUI = nullptr;
|
||||
|
||||
if (m_attributeType.isEmpty())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "slotAddEditingMode: invalid attribute type string!";
|
||||
return;
|
||||
}
|
||||
|
||||
m_editionModeUI = new EditingModeUI(m_detailData, m_attributeType, nullptr);
|
||||
|
||||
connect(m_editionModeUI, &EditingModeUI::signalChanges, this, &FilterTableEntryAttribute::signalChanges);
|
||||
connect(m_editionModeUI, &EditingModeUI::destroyed, this, &FilterTableEntryAttribute::signalChanges);
|
||||
|
||||
connect(m_editionModeUI->pbAddAttributeContainer, &QPushButton::clicked, this, &FilterTableEntryAttribute::slotAddAttributeContainer);
|
||||
connect(m_editionModeUI->pbDelete, &QPushButton::clicked, this, &FilterTableEntryAttribute::slotDeleteAttributeContainer);
|
||||
m_editionModeUI->lbFilterText->setText(tr("Filter by attribute type: <b>%1</b>").arg(attributeTypeString));
|
||||
|
||||
m_attributesLayout->addWidget(m_editionModeUI, 0, Qt::AlignTop);
|
||||
|
||||
|
||||
if (createBlankContainer)
|
||||
slotAddAttributeContainer();
|
||||
}
|
||||
|
||||
void FilterTableEntryAttribute::slotDeleteAttributeContainer()
|
||||
{
|
||||
emit attributeChanged(false);
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void FilterTableEntryAttribute::slotAddAttributeContainer()
|
||||
{
|
||||
emit signalChanges();
|
||||
emit attributeChanged(true);
|
||||
if (m_editionModeUI != nullptr)
|
||||
m_editionModeUI->addAttributeContainer(m_eventType);
|
||||
}
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AttributeEditingModeUI.h"
|
||||
#include "AttributeSelectionModeUI.h"
|
||||
#include <QGroupBox>
|
||||
|
||||
class QLabel;
|
||||
class QVBoxLayout;
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
|
||||
class FilterTableEntryAttribute : public QGroupBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FilterTableEntryAttribute(DetailData *detailData, int eventType, const QString &attributeType, QWidget *parent = nullptr);
|
||||
~FilterTableEntryAttribute();
|
||||
const QJsonObject filter(bool typeSafe = false) const;
|
||||
void updateData(DetailData *detailData);
|
||||
|
||||
int m_eventType;
|
||||
QString m_attributeType;
|
||||
|
||||
|
||||
|
||||
SelectionModeUI *m_selectionModeUI;
|
||||
EditingModeUI *m_editionModeUI;
|
||||
|
||||
QVBoxLayout *m_attributesLayout;
|
||||
QLabel *m_lbSelectText;
|
||||
DetailData *m_detailData;
|
||||
|
||||
signals:
|
||||
void signalChanges();
|
||||
void attributeChanged(const bool &hasAttribute);
|
||||
|
||||
private:
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
private slots:
|
||||
void slotAddAttributeContainer();
|
||||
void slotDeleteAttributeContainer();
|
||||
void slotAddSelectionMode();
|
||||
void slotAddEditingMode(bool createBlankContainer = true);
|
||||
};
|
||||
|
||||
}
|
||||
+320
@@ -0,0 +1,320 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "FilterWindow.h"
|
||||
#include "ui_FilterWindowUi.h"
|
||||
#include "FilterTableEntry.h"
|
||||
#include "interpreter/FilterWorker.h"
|
||||
#include "../detail_data.h"
|
||||
#include "logger.h"
|
||||
#include <FileManagement/flm_translation.h>
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonParseError>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
|
||||
#include <QScopeGuard>
|
||||
#endif
|
||||
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
FilterWindow::FilterWindow(DetailData *detailData,
|
||||
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmIfc,
|
||||
LtsSession::LtsSession *session,
|
||||
QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_flmIfc(flmIfc)
|
||||
, m_ui(new Ui::FilterWindow)
|
||||
, updateTimer(new QTimer(this))
|
||||
, m_detailData(detailData)
|
||||
|
||||
, m_logger(getLogger("EventFilter.FilterWindow"))
|
||||
, m_session(session)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
setMinimumSize(1500, 800);
|
||||
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->hide();
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add,
|
||||
this, &FilterWindow::slotAddNewFilter);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Show,
|
||||
this, &FilterWindow::slotShowEvents);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Save,
|
||||
this, &FilterWindow::slotSave);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load,
|
||||
this, &FilterWindow::slotLoad);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
connect(updateTimer, &QTimer::timeout, this, &FilterWindow::slotUpdate);
|
||||
updateTimer->setInterval(5000);
|
||||
updateTimer->start();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Timeline-Filter_Functions"));
|
||||
}
|
||||
|
||||
|
||||
FilterWindow::~FilterWindow()
|
||||
{
|
||||
const QList<FilterTableEntry*> lst = findChildren<FilterTableEntry*>();
|
||||
for (FilterTableEntry *fte : lst)
|
||||
fte->disconnect(this);
|
||||
updateTimer->stop();
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void FilterWindow::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Filters"));
|
||||
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Add)->setText(tr("Add Filter"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setText(tr("Show Events"));
|
||||
}
|
||||
|
||||
|
||||
void FilterWindow::slotSave()
|
||||
{
|
||||
int fileId = m_flmIfc->saveFileContent(this, FileManagement::FileType::Xml, m_session->exerciseId(),
|
||||
filterToDoc(exportFilter()));
|
||||
if (fileId > 0)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Saved file with id = " << fileId;
|
||||
__unchange__();
|
||||
}
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Could not save file in library ";
|
||||
}
|
||||
|
||||
|
||||
void FilterWindow::slotUpdate()
|
||||
{
|
||||
for (int i = 0; i < m_ui->filterContainer->count(); i++)
|
||||
{
|
||||
FilterTableEntry *fte = qobject_cast<FilterTableEntry *>(m_ui->filterContainer->itemAt(i)->widget());
|
||||
|
||||
if (!fte)
|
||||
continue;
|
||||
|
||||
fte->updateData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FilterTableEntry *FilterWindow::addNewFilter(const int eventType, bool active)
|
||||
{
|
||||
FilterTableEntry *fte = new FilterTableEntry(m_detailData, eventType, active, this);
|
||||
|
||||
connect(fte, &FilterTableEntry::signalChanges, this, &FilterWindow::slotChangesMade);
|
||||
connect(fte, &FilterTableEntry::destroyed, this, &FilterWindow::slotChangesMade);
|
||||
connect(fte, &FilterTableEntry::signalShowEvents, this, &FilterWindow::signalShowEvents);
|
||||
|
||||
m_ui->filterContainer->addWidget(fte);
|
||||
|
||||
slotChangesMade();
|
||||
|
||||
return fte;
|
||||
}
|
||||
|
||||
|
||||
void FilterWindow::slotAddNewFilter()
|
||||
{
|
||||
addNewFilter();
|
||||
}
|
||||
|
||||
|
||||
const QJsonArray FilterWindow::exportFilter() const
|
||||
{
|
||||
if (!m_ui->filterContainer->count())
|
||||
return QJsonArray();
|
||||
|
||||
QJsonArray result;
|
||||
|
||||
for (int i = 0; i < m_ui->filterContainer->count(); i++)
|
||||
{
|
||||
FilterTableEntry *fte = qobject_cast<FilterTableEntry *>(m_ui->filterContainer->itemAt(i)->widget());
|
||||
|
||||
if (!fte)
|
||||
continue;
|
||||
|
||||
const QJsonObject filterTile = fte->filter(true );
|
||||
if (filterTile.isEmpty())
|
||||
continue;
|
||||
|
||||
result.append(filterTile);
|
||||
}
|
||||
|
||||
|
||||
qWarning() << "filter text:" << result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
const QByteArray FilterWindow::filterToDoc(const QJsonArray &flt)
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj[QStringLiteral("XmlType")] = FileManagement::toString(FileManagement::XmlType::TLNTimelineFilter);
|
||||
obj[QStringLiteral("Filter")] = flt;
|
||||
|
||||
QJsonDocument doc(obj);
|
||||
return doc.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
bool FilterWindow::apply()
|
||||
{
|
||||
slotApplyFilter();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void FilterWindow::aboutToClose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FilterWindow::slotApplyFilter()
|
||||
{
|
||||
emit signalApplyFilter(exportFilter());
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FilterWindow::slotShowEvents()
|
||||
{
|
||||
emit signalShowEvents(exportFilter());
|
||||
}
|
||||
|
||||
|
||||
void FilterWindow::slotLoad()
|
||||
{
|
||||
QByteArray content;
|
||||
int fileId = m_flmIfc->loadFileContent(this, content, {FileManagement::FileType::Xml}, m_session->exerciseId(), FileManagement::toString(FileManagement::XmlType::TLNTimelineFilter));
|
||||
if (fileId > 0)
|
||||
{
|
||||
|
||||
int msgResult = QMessageBox::question(this,
|
||||
tr("Load filter set"),
|
||||
tr("Do you really want to discard current filter set to load the requested filter set?\n"
|
||||
"\n"
|
||||
"Yes, discard current filter set and load a filter set.\n"
|
||||
"No, do not make any changes."),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No);
|
||||
|
||||
if (msgResult != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
if (!m_flmIfc->isXmlType(content, FileManagement::toString(FileManagement::XmlType::TLNTimelineFilter)))
|
||||
{
|
||||
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Invalid xml file content"),
|
||||
windowTitle(),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes,
|
||||
texts);
|
||||
}
|
||||
else
|
||||
{
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(content));
|
||||
const QJsonObject obj(doc.object());
|
||||
const QJsonArray tlnFilter(obj.value(QStringLiteral("Filter")).toArray());
|
||||
|
||||
loadFilters(tlnFilter);
|
||||
slotChangesMade();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FilterWindow::loadFilters(const QJsonArray &filter)
|
||||
{
|
||||
setUnchangeable();
|
||||
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
|
||||
auto unchangableReset = qScopeGuard([this] { setUnchangeable(false); });
|
||||
#else
|
||||
std::shared_ptr<int> unchangeableReset(nullptr, [this](int *) { setUnchangeable(false); });
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
FilterWorker::GetModelFilterListResult result = FilterWorker::getModelFilterList(m_detailData, filter, true);
|
||||
if (!FilterWorker::getInstance()->handleResultValues(result.resultValueList, this, true))
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("The selected filter set is invalid and cannot be loaded."), tr("Cannot load filter"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
while (m_ui->filterContainer->count())
|
||||
{
|
||||
delete m_ui->filterContainer->itemAt(0)->widget();
|
||||
}
|
||||
|
||||
|
||||
const ModelFilterList &modelFilterList = result.result;
|
||||
|
||||
|
||||
int lastEventType = -1;
|
||||
FilterTableEntry *lastFTW = nullptr;
|
||||
|
||||
QString lastAttributeType;
|
||||
FilterTableEntryAttribute *lastFTEA = nullptr;
|
||||
|
||||
for (const FilterWorker::ModelFilter &mf : modelFilterList)
|
||||
{
|
||||
if (lastEventType != mf.eventType || lastEventType == -1 || !lastFTW)
|
||||
{
|
||||
lastEventType = mf.eventType;
|
||||
lastFTW = addNewFilter(mf.eventType, mf.active);
|
||||
}
|
||||
|
||||
if (mf.attributeType == QString())
|
||||
continue;
|
||||
|
||||
if (lastAttributeType != mf.attributeType || lastAttributeType.isEmpty() || !lastFTEA)
|
||||
{
|
||||
lastAttributeType = mf.attributeType;
|
||||
lastFTEA = lastFTW->addAttribute(mf.attributeType);
|
||||
}
|
||||
|
||||
EditingModeUI *emui = lastFTEA->m_editionModeUI;
|
||||
|
||||
if (!emui)
|
||||
continue;
|
||||
|
||||
emui->addAttributeContainer(mf.eventType, mf.attributeValue);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QJsonArray>
|
||||
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FilterWindow;
|
||||
}
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
class FilterTableEntry;
|
||||
class FilterWorker;
|
||||
|
||||
class FilterWindow : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FilterWindow(DetailData *detailData,
|
||||
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmIfc,
|
||||
LtsSession::LtsSession *session,
|
||||
QWidget *parent = nullptr);
|
||||
~FilterWindow();
|
||||
FilterTableEntry *addNewFilter(const int eventType = -1, bool active = true);
|
||||
|
||||
|
||||
void clearSavedFiltersList();
|
||||
void updateData();
|
||||
const QJsonArray exportFilter() const;
|
||||
const QByteArray filterToDoc(const QJsonArray &flt);
|
||||
bool loadFilters(const QJsonArray &filter);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
bool apply() override;
|
||||
void aboutToClose() override;
|
||||
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmIfc;
|
||||
Ui::FilterWindow *m_ui;
|
||||
QTimer *updateTimer;
|
||||
DetailData *m_detailData;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
LtsSession::LtsSession *m_session;
|
||||
|
||||
signals:
|
||||
void signalConvertFilterText(const QString &);
|
||||
void signalShowEvents(const QJsonArray &events);
|
||||
void signalApplyFilter(const QJsonArray &filter);
|
||||
void signalReloadSavedFiltersList();
|
||||
void signalDeleteFilter(int);
|
||||
void signalReplaceFilter(int);
|
||||
void signalReplaceFilterNow(int, const QString &);
|
||||
|
||||
|
||||
|
||||
public slots:
|
||||
void slotLoad();
|
||||
void slotSave();
|
||||
void slotUpdate();
|
||||
void slotAddNewFilter();
|
||||
|
||||
private slots:
|
||||
void slotApplyFilter();
|
||||
void slotShowEvents();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+291
@@ -0,0 +1,291 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
#include "FilterEquationFunctions.h"
|
||||
#include "FilterValueInterpreter.h"
|
||||
#include "../../detail_data.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QRect>
|
||||
#include <QVariant>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
static bool inTime(DetailData *detailData, const QVariant &value, const QString &interpreterText)
|
||||
{
|
||||
NGL::INGLLogger &logger(getLogger("FilterEquationFunctions"));
|
||||
bool ok = false;
|
||||
|
||||
unsigned int time = value.toUInt(&ok);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
WARNING_LOG(logger) << "inTime: value error!" << value.toString();
|
||||
return false;
|
||||
}
|
||||
|
||||
InterpreterResult ir = interpretValue(detailData, DetailData::INTERPRETER_TYPE_RANGE, interpreterText);
|
||||
|
||||
if (ir.resultType == InterpreterResult::InterpreterResultTypes::RESULT_SUCCESS && ir.resultList.count() == 2)
|
||||
{
|
||||
bool ok1 = false;
|
||||
bool ok2 = false;
|
||||
|
||||
unsigned int t1 = ir.resultList.at(0).toUInt(&ok1);
|
||||
unsigned int t2 = ir.resultList.at(1).toUInt(&ok2);
|
||||
|
||||
if (ok1 && ok2 && t1 <= time && t2 >= time)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool inArea(DetailData *detailData, const QVariant &value, const QString &interpreterText)
|
||||
{
|
||||
NGL::INGLLogger &logger(getLogger("FilterEquationFunctions"));
|
||||
(void)detailData;
|
||||
|
||||
QStringList areaValuesList = value.toString().split(QLatin1Char('x'));
|
||||
|
||||
if (areaValuesList.count() != 2)
|
||||
{
|
||||
WARNING_LOG(logger) << "inArea: areaValuesList.count() != 2 (" << areaValuesList.count() << ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList interpreterValuesList = interpreterText.split(QLatin1Char('x'));
|
||||
|
||||
if (interpreterValuesList.count() != 4)
|
||||
{
|
||||
WARNING_LOG(logger) << "inArea: interpreterValuesList.count() != 4 (" << interpreterValuesList.count() << ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nb = false;
|
||||
int n = areaValuesList.at(0).toInt(&nb);
|
||||
|
||||
bool ob = false;
|
||||
int o = areaValuesList.at(1).toInt(&ob);
|
||||
|
||||
|
||||
bool n1b = false;
|
||||
int n1 = interpreterValuesList.at(0).toInt(&n1b);
|
||||
|
||||
bool n2b = false;
|
||||
int n2 = interpreterValuesList.at(1).toInt(&n2b);
|
||||
|
||||
bool o1b = false;
|
||||
int o1 = interpreterValuesList.at(2).toInt(&o1b);
|
||||
|
||||
bool o2b = false;
|
||||
int o2 = interpreterValuesList.at(3).toInt(&o2b);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!nb || !ob || !n1b || !n2b || !o1b || !o2b)
|
||||
{
|
||||
WARNING_LOG(logger) << "inArea: !nb || !ob || !n1b || !n2b || !o1b || !o2b";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QRect range;
|
||||
range.adjust(o1, n1, o2, n2);
|
||||
|
||||
if (range.contains(o, n))
|
||||
{
|
||||
WARNING_LOG(logger) << "inArea: in area!";
|
||||
return true;
|
||||
}
|
||||
|
||||
WARNING_LOG(logger) << "inArea: not in area";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool inRad(DetailData *detailData, const QVariant &value, const QString &interpreterText)
|
||||
{
|
||||
NGL::INGLLogger &logger(getLogger("FilterEquationFunctions"));
|
||||
(void)detailData;
|
||||
|
||||
QStringList radValuesList = value.toString().split(QLatin1Char('x'));
|
||||
|
||||
if (radValuesList.count() != 2)
|
||||
{
|
||||
WARNING_LOG(logger) << "inRad: radValuesList.count() != 2 (" << radValuesList.count() << ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList interpreterValuesList = interpreterText.split(QLatin1Char('x'));
|
||||
|
||||
if (interpreterValuesList.count() != 3)
|
||||
{
|
||||
WARNING_LOG(logger) << "inArea: interpreterValuesList.count() != 3 (" << interpreterValuesList.count() << ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nb = false;
|
||||
int n = radValuesList.at(0).toInt(&nb);
|
||||
|
||||
bool ob = false;
|
||||
int o = radValuesList.at(1).toInt(&ob);
|
||||
|
||||
|
||||
bool n1b = false;
|
||||
int n1 = interpreterValuesList.at(0).toInt(&n1b);
|
||||
|
||||
bool o1b = false;
|
||||
int o1 = interpreterValuesList.at(1).toInt(&o1b);
|
||||
|
||||
bool r1b = false;
|
||||
int r1 = interpreterValuesList.at(2).toInt(&r1b);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!nb || !ob || !n1b || !o1b || !r1b)
|
||||
{
|
||||
WARNING_LOG(logger) << "inRad: !nb || !ob || !n1b || !o1b || !r1b";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QRect range;
|
||||
range.adjust(o1 - r1, n1 - r1, o1 + r1, n1 + r1);
|
||||
|
||||
if (range.contains(o, n))
|
||||
{
|
||||
WARNING_LOG(logger) << "inRad: in radius!";
|
||||
return true;
|
||||
}
|
||||
|
||||
WARNING_LOG(logger) << "inRad: not in radius";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool isIntEqual(DetailData *detailData, const QVariant &value, const QString &interpreterText)
|
||||
{
|
||||
NGL::INGLLogger &logger(getLogger("FilterEquationFunctions"));
|
||||
(void)detailData;
|
||||
|
||||
bool ok1 = false;
|
||||
bool ok2 = false;
|
||||
|
||||
|
||||
|
||||
int i1 = value.toInt(&ok1);
|
||||
int i2 = interpreterText.toInt(&ok2);
|
||||
|
||||
if (!ok1 || !ok2)
|
||||
{
|
||||
WARNING_LOG(logger) << "isIntEqual: STR to INT conversion error! ok1 (" << ok1 << ") ok2 (" << ok2 << ") value (" << value.toString() << ") intTxt (" << interpreterText << ")";
|
||||
}
|
||||
|
||||
if (ok1 && ok2 && i1 == i2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool checkValue(DetailData *detailData, int attributeInterpreterType, const QVariant &value, const QString &interpreterText)
|
||||
{
|
||||
switch(attributeInterpreterType)
|
||||
{
|
||||
case DetailData::INTERPRETER_TYPE_TIME:
|
||||
{
|
||||
return inTime(detailData, value, interpreterText);
|
||||
}
|
||||
|
||||
case DetailData::INTERPRETER_TYPE_AREA:
|
||||
{
|
||||
return inArea(detailData, value, interpreterText);
|
||||
}
|
||||
|
||||
case DetailData::INTERPRETER_TYPE_RAD:
|
||||
{
|
||||
return inRad(detailData, value, interpreterText);
|
||||
}
|
||||
|
||||
case DetailData::INTERPRETER_TYPE_STR_COMPARE:
|
||||
{
|
||||
|
||||
|
||||
if (value.toString() == interpreterText)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
case DetailData::INTERPRETER_TYPE_ID_COMPARE:
|
||||
{
|
||||
bool tryIt = isIntEqual(detailData, value, interpreterText);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return tryIt;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FilterEquationFunctions::checkValue(DetailData *detailData, const QString &attributeType, const QVariant &value, const QString &interpreterText)
|
||||
{
|
||||
int attributeInterpreterType = detailData->attributeInterpreterLookup.getInterpreterType(attributeType);
|
||||
return checkValue(detailData, attributeInterpreterType, value, interpreterText);
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
class QVariant;
|
||||
class QString;
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
|
||||
namespace FilterEquationFunctions
|
||||
{
|
||||
bool checkValue(DetailData *detailData, const QString &attributeType, const QVariant &value, const QString &interpreterText);
|
||||
}
|
||||
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "FilterValueInterpreter.h"
|
||||
#include "../../detail_data.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QRect>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
static InterpreterResult interpretAreaText(const QString &areaText)
|
||||
{
|
||||
QStringList areaList = areaText.split(QLatin1Char('x'));
|
||||
|
||||
if (areaList.count() != 4)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_AREATEXT_COUNT_NOT_FOUR);
|
||||
}
|
||||
|
||||
bool ok1 = false;
|
||||
bool ok2 = false;
|
||||
bool ok3 = false;
|
||||
bool ok4 = false;
|
||||
|
||||
int n1 = areaList.at(0).toInt(&ok1);
|
||||
int n2 = areaList.at(1).toInt(&ok2);
|
||||
int o1 = areaList.at(2).toInt(&ok3);
|
||||
int o2 = areaList.at(3).toInt(&ok4);
|
||||
|
||||
|
||||
|
||||
|
||||
if (!ok1)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_AREATEXT_CANNOT_INTERPRET_N1);
|
||||
}
|
||||
|
||||
if (!ok2)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_AREATEXT_CANNOT_INTERPRET_N2);
|
||||
}
|
||||
|
||||
if (!ok3)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_AREATEXT_CANNOT_INTERPRET_O1);
|
||||
}
|
||||
|
||||
if (!ok4)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_AREATEXT_CANNOT_INTERPRET_O2);
|
||||
}
|
||||
|
||||
InterpreterResult ir(InterpreterResult::InterpreterResultTypes::RESULT_SUCCESS);
|
||||
ir.resultList.append(QRect(o1, n1, o2, n2));
|
||||
return ir;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static InterpreterResult interpretToInt(const QString &text)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
int result = text.toInt(&ok);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_TOINT_CANNOT_INTERPRET_VALUE);
|
||||
}
|
||||
|
||||
InterpreterResult ir(InterpreterResult::InterpreterResultTypes::RESULT_SUCCESS);
|
||||
ir.resultList.append(result);
|
||||
return ir;
|
||||
}
|
||||
|
||||
static InterpreterResult interpretRangeText(const QString &rangeText)
|
||||
{
|
||||
QStringList rangeList = rangeText.split(QLatin1Char('-'));
|
||||
|
||||
if (rangeList.count() != 2)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_RANGETEXT_COUNT_NOT_TWO);
|
||||
}
|
||||
|
||||
bool ok1 = false;
|
||||
bool ok2 = false;
|
||||
|
||||
unsigned int t1 = rangeList.at(0).toUInt(&ok1);
|
||||
unsigned int t2 = rangeList.at(1).toUInt(&ok2);
|
||||
|
||||
if (!ok1)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_RANGETEXT_CANNOT_INTERPRET_T1);
|
||||
}
|
||||
|
||||
if (!ok2)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_RANGETEXT_CANNOT_INTERPRET_T2);
|
||||
}
|
||||
|
||||
if (t1 > t2)
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_RANGETEXT_BEGIN_GREATER_THAN_END);
|
||||
}
|
||||
|
||||
InterpreterResult ir(InterpreterResult::InterpreterResultTypes::RESULT_SUCCESS);
|
||||
ir.resultList.append(t1);
|
||||
ir.resultList.append(t2);
|
||||
|
||||
return ir;
|
||||
}
|
||||
|
||||
|
||||
InterpreterResult interpretValue(DetailData *detailData, int attributeInterpreterType, const QString &value)
|
||||
{
|
||||
(void)detailData;
|
||||
|
||||
switch (attributeInterpreterType)
|
||||
{
|
||||
case DetailData::INTERPRETER_TYPE_ID_COMPARE:
|
||||
{
|
||||
return interpretToInt(value);
|
||||
}
|
||||
|
||||
case DetailData::INTERPRETER_TYPE_RANGE:
|
||||
{
|
||||
return interpretRangeText(value);
|
||||
}
|
||||
|
||||
case DetailData::INTERPRETER_TYPE_AREA:
|
||||
{
|
||||
return interpretAreaText(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
case DetailData::INTERPRETER_TYPE_STR_COMPARE:
|
||||
{
|
||||
InterpreterResult ir(InterpreterResult::InterpreterResultTypes::RESULT_SUCCESS);
|
||||
ir.resultList.append(value);
|
||||
return ir;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return InterpreterResult(InterpreterResult::InterpreterResultTypes::RESULT_ATTRIBUTE_HAS_NO_INTERPRETER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
InterpreterResult interpretValue(DetailData *detailData, const QString &attributeType, const QString &value)
|
||||
{
|
||||
int interpreterType = detailData->attributeInterpreterLookup.getInterpreterType(attributeType);
|
||||
return interpretValue(detailData, interpreterType, value);
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
|
||||
class InterpreterResult
|
||||
{
|
||||
public:
|
||||
enum class InterpreterResultTypes
|
||||
{
|
||||
RESULT_UNKNOWN,
|
||||
RESULT_SUCCESS,
|
||||
|
||||
RESULT_ATTRIBUTE_HAS_NO_INTERPRETER,
|
||||
|
||||
RESULT_RANGETEXT_COUNT_NOT_TWO,
|
||||
RESULT_RANGETEXT_BEGIN_GREATER_THAN_END,
|
||||
RESULT_RANGETEXT_CANNOT_INTERPRET_T1,
|
||||
RESULT_RANGETEXT_CANNOT_INTERPRET_T2,
|
||||
|
||||
RESULT_AREATEXT_COUNT_NOT_FOUR,
|
||||
RESULT_AREATEXT_CANNOT_INTERPRET_N1,
|
||||
RESULT_AREATEXT_CANNOT_INTERPRET_N2,
|
||||
RESULT_AREATEXT_CANNOT_INTERPRET_O1,
|
||||
RESULT_AREATEXT_CANNOT_INTERPRET_O2,
|
||||
|
||||
RESULT_TOINT_CANNOT_INTERPRET_VALUE
|
||||
};
|
||||
|
||||
explicit InterpreterResult(const InterpreterResult::InterpreterResultTypes &res)
|
||||
: resultType(res)
|
||||
{
|
||||
}
|
||||
|
||||
InterpreterResult()
|
||||
: resultType(InterpreterResultTypes::RESULT_UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
InterpreterResultTypes resultType;
|
||||
QList<QVariant> additionalInformation;
|
||||
|
||||
QList<QVariant> resultList;
|
||||
};
|
||||
|
||||
InterpreterResult interpretValue(DetailData *detailData, int attributeInterpreterType, const QString &value);
|
||||
InterpreterResult interpretValue(DetailData *detailData, const QString &attributeType, const QString &value);
|
||||
|
||||
}
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "FilterWorker.h"
|
||||
#include "InfoWindow.h"
|
||||
#include "../../detail_data.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QApplication>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
FilterWorker* FilterWorker::s_instance = nullptr;
|
||||
FilterWorker* FilterWorker::getInstance()
|
||||
{
|
||||
if (!s_instance)
|
||||
{
|
||||
s_instance = new FilterWorker();
|
||||
}
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
|
||||
FilterWorker::~FilterWorker()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FilterWorker::deleteInstance()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
FilterWorker::FilterWorker()
|
||||
{
|
||||
#define addErrorHandler(x,y) { FilterWorker::ErrorHandler eh; eh.errorText = y; eh.errorParamCount = eh.errorText.split(QLatin1Char('%'), QString::SkipEmptyParts).count(); m_errorHandlerLookupMap.insert(x, eh); }(void)this
|
||||
|
||||
|
||||
|
||||
addErrorHandler(GetModelFilterListResult::ERR_ATTRIBUTE_BLOCK_NOT_CLOSED, tr("Attribute block not closed: \n\'%1'"));
|
||||
addErrorHandler(GetModelFilterListResult::ERR_ATTRIBUTE_HAS_NO_VALUES, tr("Attribute '%1' has no values"));
|
||||
addErrorHandler(GetModelFilterListResult::ERR_COLON_MISUSE, tr("Colon misuse: \n\'%1'"));
|
||||
addErrorHandler(GetModelFilterListResult::ERR_EVENT_HAS_NOT_ATTRIBUTE, tr("Attribute type '%1' does not belong to event type '%2': \n'%3'"));
|
||||
addErrorHandler(GetModelFilterListResult::ERR_NO_EVENT_NAME, tr("No event name given for filter '%1'"));
|
||||
addErrorHandler(GetModelFilterListResult::ERR_UNKNOWN_ATTRIBUTE_TYPE_BY_STRING, tr("Attribute type for '%1' does not exist"));
|
||||
addErrorHandler(GetModelFilterListResult::ERR_UNKNOWN_EVENT_TYPE, tr("Event type '%1' does not exist"));
|
||||
|
||||
|
||||
addErrorHandler(GetModelFilterListResult::ERR_VALUE_NOT_FOUND, tr("The attribute value '%1' is not a value of attribute type '%2'"));
|
||||
addErrorHandler(GetModelFilterListResult::ERR_NO_VALUE_GIVEN, tr("There are no values given inside the brackets: \n'%1'"));
|
||||
addErrorHandler(GetModelFilterListResult::ERR_TOO_MUCH_BRACKETS, tr("Too much brackets: \n'%1'"));
|
||||
}
|
||||
|
||||
|
||||
FilterWorker::Result makeResult(const int resultValue, const QString& additionalInformation = QString())
|
||||
{
|
||||
FilterWorker::Result result;
|
||||
|
||||
result.resultValue = resultValue;
|
||||
|
||||
if (!additionalInformation.isEmpty())
|
||||
{
|
||||
result.additionalInformation.append(additionalInformation);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FilterWorker::Result makeResult(const int resultValue, const QStringList& additionalInformationList)
|
||||
{
|
||||
FilterWorker::Result result;
|
||||
|
||||
result.resultValue = resultValue;
|
||||
result.additionalInformation.append(additionalInformationList);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FilterWorker::GetModelFilterListResult FilterWorker::getModelFilterList(DetailData *detailData, const QJsonArray &filter, bool fromTypeSafe)
|
||||
{
|
||||
GetModelFilterListResult result;
|
||||
|
||||
if (filter.isEmpty())
|
||||
{
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
for (auto i1 = filter.constBegin(); i1 != filter.constEnd(); ++i1)
|
||||
{
|
||||
const QJsonObject ¤tFilter = (*i1).toObject();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QString eventTypeString = currentFilter[QStringLiteral("EventType")].toString();
|
||||
int eventType = -1;
|
||||
|
||||
if (fromTypeSafe)
|
||||
{
|
||||
bool ok = false;
|
||||
eventType = eventTypeString.toInt(&ok);
|
||||
if (!ok)
|
||||
{
|
||||
eventType = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eventType = detailData->eventTypeLookup.getEventType(eventTypeString);
|
||||
}
|
||||
|
||||
|
||||
QString eventTypeName = detailData->eventTypeLookup.getEventText(eventType);
|
||||
if (!eventTypeName.isEmpty())
|
||||
eventTypeString = eventTypeName;
|
||||
|
||||
|
||||
if (eventType == -1)
|
||||
{
|
||||
result.resultValueList.append(makeResult(GetModelFilterListResult::ResultValues::ERR_UNKNOWN_EVENT_TYPE,
|
||||
eventTypeString));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
bool active = currentFilter[QStringLiteral("Active")].toBool(false);
|
||||
const QJsonArray &attributes = currentFilter[QStringLiteral("Attributes")].toArray();
|
||||
|
||||
if (attributes.isEmpty())
|
||||
{
|
||||
ModelFilter mf;
|
||||
mf.eventType = eventType;
|
||||
mf.attributeType = QString();
|
||||
mf.active = active;
|
||||
|
||||
result.result.append(mf);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (auto i2 = attributes.constBegin(); i2 != attributes.constEnd(); i2++)
|
||||
{
|
||||
const QJsonObject &attribute = (*i2).toObject();
|
||||
QString attributeType = attribute[QStringLiteral("AttributeType")].toString();
|
||||
|
||||
if (!fromTypeSafe)
|
||||
{
|
||||
attributeType = detailData->attributeTypeLookup.getAttributeType(attributeType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
attributeType = detailData->attributeRedirectionLookup.getRedirection(attributeType);
|
||||
|
||||
|
||||
if (attributeType.isEmpty())
|
||||
{
|
||||
result.resultValueList.append(makeResult(GetModelFilterListResult::ResultValues::ERR_UNKNOWN_ATTRIBUTE_TYPE_BY_STRING,
|
||||
attributeType));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int interpreterType = detailData->attributeInterpreterLookup.getInterpreterType(attributeType);
|
||||
|
||||
if (interpreterType == DetailData::INTERPRETER_TYPE_NONE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const QJsonArray &attributeValues = attribute[QStringLiteral("AttributeValues")].toArray();
|
||||
for (auto i3 = attributeValues.constBegin(); i3 != attributeValues.constEnd(); ++i3)
|
||||
{
|
||||
QString attributeValueString = (*i3).toString();
|
||||
|
||||
|
||||
|
||||
ModelFilter mf;
|
||||
mf.eventType = eventType;
|
||||
mf.attributeType = attributeType;
|
||||
mf.active = active;
|
||||
mf.attributeValue = attributeValueString;
|
||||
result.result.append(mf);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool FilterWorker::handleResultValues(const QVector<Result> &resultList, QWidget* parentWidget, bool ignoreInfos)
|
||||
{
|
||||
bool errorOccured = false;
|
||||
InfoWindowEntryList iwel;
|
||||
|
||||
for (int i = 0; i < resultList.count(); i++)
|
||||
{
|
||||
FilterWorker::Result result = resultList.at(i);
|
||||
int resultValue = result.resultValue;
|
||||
|
||||
if (!errorOccured && (resultValue & GetModelFilterListResult::ERR) == GetModelFilterListResult::ERR)
|
||||
{
|
||||
errorOccured = true;
|
||||
}
|
||||
|
||||
if (ignoreInfos && (resultValue & GetModelFilterListResult::INFO) == GetModelFilterListResult::INFO)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
InfoWindowEntry iwe;
|
||||
const ErrorHandler& eh = m_errorHandlerLookupMap.value(result.resultValue);
|
||||
if (!eh.isValid())
|
||||
{
|
||||
iwe.text = tr("Unhandled error (%1)");
|
||||
iwe.infoType = InfoWindowEntry::InfoTypes::Error;
|
||||
iwel.append(iwe);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int additionalInformationCount = result.additionalInformation.count();
|
||||
QString iweText = eh.errorText;
|
||||
|
||||
if (eh.errorParamCount)
|
||||
{
|
||||
for (int i2 = 0; i2 < eh.errorParamCount; i2++)
|
||||
{
|
||||
if (additionalInformationCount >= eh.errorParamCount)
|
||||
{
|
||||
iweText = iweText.arg(result.additionalInformation.at(i2));
|
||||
}
|
||||
else
|
||||
{
|
||||
iweText = iweText.arg(QStringLiteral("???"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iwe.text = iweText;
|
||||
iwel.append(iwe);
|
||||
}
|
||||
|
||||
|
||||
if (iwel.count())
|
||||
{
|
||||
InfoWindow* iw = new InfoWindow(iwel, parentWidget);
|
||||
iw->show();
|
||||
}
|
||||
|
||||
return !errorOccured;
|
||||
}
|
||||
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QVector>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QMap>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
|
||||
class FilterWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
FilterWorker();
|
||||
~FilterWorker();
|
||||
static FilterWorker* s_instance;
|
||||
|
||||
public:
|
||||
static FilterWorker* getInstance();
|
||||
static void deleteInstance();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct ModelFilter
|
||||
{
|
||||
int eventType = -1;
|
||||
QString attributeType;
|
||||
bool active = false;
|
||||
QString attributeValue;
|
||||
};
|
||||
|
||||
struct Result
|
||||
{
|
||||
int resultValue = -1;
|
||||
QStringList additionalInformation;
|
||||
};
|
||||
|
||||
struct GetModelFilterListResult
|
||||
{
|
||||
|
||||
|
||||
enum ResultType
|
||||
{
|
||||
ERR = 0x80,
|
||||
WARN = 0x40,
|
||||
INFO = 0x20,
|
||||
};
|
||||
|
||||
enum ResultValues
|
||||
{
|
||||
|
||||
|
||||
|
||||
ERR_NO_EVENT_NAME = ERR | 0,
|
||||
ERR_COLON_MISUSE = ERR | 1,
|
||||
ERR_UNKNOWN_EVENT_TYPE = ERR | 2,
|
||||
ERR_ATTRIBUTE_HAS_NO_VALUES = ERR | 3,
|
||||
ERR_ATTRIBUTE_BLOCK_NOT_CLOSED = ERR | 4,
|
||||
ERR_UNKNOWN_ATTRIBUTE_TYPE_BY_STRING = ERR | 5,
|
||||
|
||||
ERR_EVENT_HAS_NOT_ATTRIBUTE = ERR | 7,
|
||||
ERR_VALUE_NOT_FOUND = ERR | 8,
|
||||
ERR_NO_VALUE_GIVEN = ERR | 9,
|
||||
ERR_TOO_MUCH_BRACKETS = ERR | 10,
|
||||
};
|
||||
|
||||
QVector<Result> resultValueList;
|
||||
QVector<ModelFilter> result;
|
||||
};
|
||||
|
||||
static GetModelFilterListResult getModelFilterList(DetailData *detailData, const QJsonArray &filter, bool fromTypeSafe = false);
|
||||
bool handleResultValues(const QVector<Result> &resultList, QWidget* parentWidget = nullptr, bool ignoreInfos = false);
|
||||
|
||||
private:
|
||||
class ErrorHandler
|
||||
{
|
||||
public:
|
||||
ErrorHandler(const QString& errorText = QString(), const int errorParamCount = 0)
|
||||
: errorText(errorText)
|
||||
, errorParamCount(errorParamCount)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
if (errorText.isEmpty() && !errorParamCount)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString errorText;
|
||||
int errorParamCount;
|
||||
};
|
||||
|
||||
using ErrorHandlerLookupMap = QMap<int, ErrorHandler>;
|
||||
ErrorHandlerLookupMap m_errorHandlerLookupMap;
|
||||
};
|
||||
|
||||
using ModelFilterList = QVector<FilterWorker::ModelFilter>;
|
||||
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "InfoWindow.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
InfoWindow::InfoWindow(const InfoWindowEntryList &infoWindowEntryList, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, infoWindowEntryList(infoWindowEntryList)
|
||||
|
||||
|
||||
|
||||
, mainLayout(new QVBoxLayout())
|
||||
, pbPrev(new QPushButton(tr("< Previous")))
|
||||
, lbIndicator(new QLabel())
|
||||
, pbNext(new QPushButton(tr("Next >")))
|
||||
, pbOK(new QPushButton(tr("OK")))
|
||||
, teText(new QTextEdit(tr("Missing Message")))
|
||||
|
||||
, listPosition(-1)
|
||||
{
|
||||
if (!infoWindowEntryList.count())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
connect(pbPrev, &QPushButton::clicked, this, &InfoWindow::slotPrev);
|
||||
connect(pbNext, &QPushButton::clicked, this, &InfoWindow::slotNext);
|
||||
connect(pbOK , &QPushButton::clicked, this, &InfoWindow::deleteLater);
|
||||
|
||||
|
||||
|
||||
QHBoxLayout* topButtonsLayout = new QHBoxLayout();
|
||||
pbPrev->setEnabled(false);
|
||||
topButtonsLayout->addWidget(pbPrev);
|
||||
topButtonsLayout->addWidget(lbIndicator);
|
||||
topButtonsLayout->addWidget(pbNext);
|
||||
pbNext->setEnabled(false);
|
||||
QWidget* topButtonsWidget = new QWidget();
|
||||
topButtonsWidget->setLayout(topButtonsLayout);
|
||||
mainLayout->addWidget(topButtonsWidget);
|
||||
|
||||
|
||||
|
||||
mainLayout->addWidget(teText);
|
||||
|
||||
|
||||
|
||||
QHBoxLayout* bottomButtonsLayout = new QHBoxLayout();
|
||||
bottomButtonsLayout->addWidget(pbOK);
|
||||
QWidget* bottomButtonsWidget = new QWidget();
|
||||
bottomButtonsWidget->setLayout(bottomButtonsLayout);
|
||||
mainLayout->addWidget(bottomButtonsWidget);
|
||||
|
||||
|
||||
|
||||
slotNext();
|
||||
|
||||
this->setLayout(mainLayout);
|
||||
}
|
||||
|
||||
void InfoWindow::checkNavigationButtons(int newPosition)
|
||||
{
|
||||
int listCount = infoWindowEntryList.count();
|
||||
|
||||
if (newPosition -1 >= 0)
|
||||
{
|
||||
pbPrev->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
pbPrev->setEnabled(false);
|
||||
}
|
||||
|
||||
if (newPosition +2 > listCount)
|
||||
{
|
||||
pbNext->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
pbNext->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void InfoWindow::slotPrev()
|
||||
{
|
||||
int listCount = infoWindowEntryList.count();
|
||||
int prevListPosition = listPosition - 1 ;
|
||||
|
||||
checkNavigationButtons(prevListPosition);
|
||||
|
||||
if (prevListPosition >= 0 && prevListPosition < listCount)
|
||||
{
|
||||
teText->setText(infoWindowEntryList.at(prevListPosition).text);
|
||||
|
||||
QString indicatorString = QStringLiteral("%1/%2");
|
||||
lbIndicator->setText(indicatorString.arg(prevListPosition + 1 ).arg(listCount));
|
||||
|
||||
listPosition = prevListPosition;
|
||||
}
|
||||
}
|
||||
|
||||
void InfoWindow::slotNext()
|
||||
{
|
||||
int listCount = infoWindowEntryList.count();
|
||||
int nextListPosition = listPosition + 1 ;
|
||||
|
||||
checkNavigationButtons(nextListPosition);
|
||||
|
||||
if (nextListPosition >= 0 && nextListPosition < listCount)
|
||||
{
|
||||
teText->setText(infoWindowEntryList.at(nextListPosition).text);
|
||||
|
||||
QString indicatorString = QStringLiteral("%1/%2");
|
||||
lbIndicator->setText(indicatorString.arg(nextListPosition + 1 ).arg(listCount));
|
||||
|
||||
listPosition = nextListPosition;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QTextEdit>
|
||||
#include <QLabel>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
struct InfoWindowEntry
|
||||
{
|
||||
enum class InfoTypes
|
||||
{
|
||||
Error,
|
||||
Info,
|
||||
Warning
|
||||
};
|
||||
|
||||
QString title;
|
||||
QString text;
|
||||
InfoTypes infoType = InfoTypes::Info;
|
||||
};
|
||||
|
||||
typedef QVector<InfoWindowEntry> InfoWindowEntryList;
|
||||
|
||||
|
||||
class InfoWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InfoWindow(const InfoWindowEntryList &infoWindowEntryList, QWidget* parent = nullptr);
|
||||
~InfoWindow() = default;
|
||||
|
||||
private:
|
||||
InfoWindowEntryList infoWindowEntryList;
|
||||
QVBoxLayout* mainLayout;
|
||||
QPushButton* pbPrev;
|
||||
QLabel* lbIndicator;
|
||||
QPushButton* pbNext;
|
||||
QPushButton* pbOK;
|
||||
QTextEdit* teText;
|
||||
int listPosition;
|
||||
|
||||
void checkNavigationButtons(int newPosition);
|
||||
|
||||
|
||||
public slots:
|
||||
void slotPrev();
|
||||
void slotNext();
|
||||
};
|
||||
|
||||
}
|
||||
+1357
File diff suppressed because it is too large.
Load diff
+81
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FilterWindow</class>
|
||||
<widget class="QWidget" name="FilterWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>628</width>
|
||||
<height>393</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Filter Table</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Closing this window will reset all filters for the timeline.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaContent">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>610</width>
|
||||
<height>358</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="filterContainer"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "AbstractAttributeWidget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
AbstractAttributeWidget::AbstractAttributeWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_abstractMainLayout(new QHBoxLayout(this))
|
||||
{
|
||||
QPushButton *pbDelete(new QPushButton(QStringLiteral("-")));
|
||||
pbDelete->setPalette(QPalette(QColor("red")));
|
||||
pbDelete->setToolTip(tr("Delete this value"));
|
||||
|
||||
m_abstractMainLayout->addWidget(pbDelete);
|
||||
connect(pbDelete, &QPushButton::clicked, this, &AbstractAttributeWidget::slotDelete);
|
||||
}
|
||||
|
||||
void AbstractAttributeWidget::slotDelete()
|
||||
{
|
||||
|
||||
emit deleteClicked();
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void AbstractAttributeWidget::addCustomWidget(QWidget* widget)
|
||||
{
|
||||
m_abstractMainLayout->insertWidget(0, widget, 1, Qt::AlignLeft);
|
||||
}
|
||||
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QHBoxLayout;
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
|
||||
class AbstractAttributeWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AbstractAttributeWidget(QWidget *parent = nullptr);
|
||||
virtual QString filterText(bool typeSafe = false) const = 0;
|
||||
virtual void updateData(DetailData *detailData) = 0;
|
||||
|
||||
protected:
|
||||
void addCustomWidget(QWidget* widget);
|
||||
protected:
|
||||
QHBoxLayout *m_abstractMainLayout;
|
||||
|
||||
private slots:
|
||||
void slotDelete();
|
||||
|
||||
signals:
|
||||
void signalChanges();
|
||||
void deleteClicked();
|
||||
};
|
||||
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "AreaWidget.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QSpinBox>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
AreaWidget::AreaWidget(int n1, int n2, int o1, int o2, QWidget *parent)
|
||||
: AbstractAttributeWidget(parent)
|
||||
, sbN1(new QSpinBox())
|
||||
, sbN2(new QSpinBox())
|
||||
, sbO1(new QSpinBox())
|
||||
, sbO2(new QSpinBox())
|
||||
{
|
||||
connect(sbN1, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &AreaWidget::signalChanges);
|
||||
connect(sbN2, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &AreaWidget::signalChanges);
|
||||
connect(sbO1, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &AreaWidget::signalChanges);
|
||||
connect(sbO2, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &AreaWidget::signalChanges);
|
||||
|
||||
QString sbNPrefix = tr("N ");
|
||||
QString sbOPrefix = tr("O ");
|
||||
|
||||
sbN1->setPrefix(sbNPrefix);
|
||||
sbN2->setPrefix(sbNPrefix);
|
||||
sbO1->setPrefix(sbOPrefix);
|
||||
sbO2->setPrefix(sbOPrefix);
|
||||
|
||||
sbN1->setRange(n1, n2);
|
||||
sbN2->setRange(n1, n2);
|
||||
sbO1->setRange(o1, o2);
|
||||
sbO2->setRange(o1, o2);
|
||||
|
||||
sbN1->setValue(n1);
|
||||
sbN2->setValue(n2);
|
||||
sbO1->setValue(o1);
|
||||
sbO2->setValue(o2);
|
||||
|
||||
|
||||
QGridLayout* mainLayout = new QGridLayout();
|
||||
|
||||
mainLayout->addWidget(sbN1, 0, 1);
|
||||
mainLayout->addWidget(sbN2, 2, 1);
|
||||
mainLayout->addWidget(sbO1, 1, 0);
|
||||
mainLayout->addWidget(sbO2, 1, 2);
|
||||
|
||||
QWidget* mainLayoutWidget = new QWidget();
|
||||
mainLayoutWidget->setLayout(mainLayout);
|
||||
|
||||
this->addCustomWidget(mainLayoutWidget);
|
||||
}
|
||||
|
||||
QString AreaWidget::filterText(bool typeSafe) const
|
||||
{
|
||||
Q_UNUSED(typeSafe);
|
||||
return QStringLiteral("%1x%2x%3x%4").arg(sbN1->cleanText(), sbN2->cleanText(), sbO1->cleanText(), sbO2->cleanText());
|
||||
}
|
||||
|
||||
void AreaWidget::updateData(DetailData *detailData)
|
||||
{
|
||||
|
||||
Q_UNUSED(detailData);
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AbstractAttributeWidget.h"
|
||||
|
||||
|
||||
class QSpinBox;
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class AreaWidget : public AbstractAttributeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AreaWidget(int n1, int n2, int o1, int o2, QWidget *parent = nullptr);
|
||||
QString filterText(bool typeSafe = false) const override;
|
||||
void updateData(DetailData *detailData) override;
|
||||
|
||||
private:
|
||||
QSpinBox* sbN1;
|
||||
QSpinBox* sbN2;
|
||||
QSpinBox* sbO1;
|
||||
QSpinBox* sbO2;
|
||||
};
|
||||
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
|
||||
#include "CheckBoxWidget.h"
|
||||
#include "../../detail_data.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
CheckBoxWidget::CheckBoxWidget(DetailData *detailData, const QString &attributeType, const QString &initialValue, QWidget* parent)
|
||||
: AbstractAttributeWidget(parent)
|
||||
, cbCheck(new QCheckBox(this))
|
||||
{
|
||||
connect(cbCheck, &QCheckBox::stateChanged, this, &CheckBoxWidget::signalChanges);
|
||||
|
||||
trueValue = detailData->attributeValueLookup.getValueStringFromValueId(attributeType, 1);
|
||||
falseValue = detailData->attributeValueLookup.getValueStringFromValueId(attributeType, 0);
|
||||
|
||||
cbCheck->setText(trueValue);
|
||||
|
||||
addCustomWidget(cbCheck);
|
||||
|
||||
if (initialValue.isEmpty())
|
||||
return;
|
||||
|
||||
cbCheck->setChecked(initialValue != QStringLiteral("0"));
|
||||
}
|
||||
|
||||
|
||||
void CheckBoxWidget::setText(const QString &text)
|
||||
{
|
||||
cbCheck->setText(text);
|
||||
}
|
||||
|
||||
|
||||
QString CheckBoxWidget::filterText(bool typeSafe) const
|
||||
{
|
||||
QString filterText;
|
||||
|
||||
if (cbCheck->isChecked())
|
||||
{
|
||||
if (typeSafe)
|
||||
filterText += QStringLiteral("1");
|
||||
else
|
||||
filterText += trueValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeSafe)
|
||||
filterText += QStringLiteral("0");
|
||||
else
|
||||
filterText += falseValue;
|
||||
}
|
||||
|
||||
return filterText;
|
||||
}
|
||||
|
||||
|
||||
void CheckBoxWidget::updateData(DetailData *)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AbstractAttributeWidget.h"
|
||||
#include "../../detail_data.h"
|
||||
|
||||
|
||||
class QCheckBox;
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class CheckBoxWidget : public AbstractAttributeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CheckBoxWidget(DetailData *detailData, const QString &attributeType, const QString &initialValue, QWidget *parent = nullptr);
|
||||
QString filterText(bool typeSafe = false) const override;
|
||||
void updateData(DetailData *) override;
|
||||
void setText(const QString &text);
|
||||
|
||||
private:
|
||||
QCheckBox* cbCheck;
|
||||
QString trueValue;
|
||||
QString falseValue;
|
||||
};
|
||||
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "ComboBox.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
|
||||
ComboBox::ComboBox(DetailData *detailData, const QString &attributeType, int eventType, const QString &initialValue, QWidget* parent)
|
||||
: AbstractAttributeWidget(parent)
|
||||
, m_cbValues(new QComboBox())
|
||||
, m_eventType(eventType)
|
||||
, m_logger(getLogger("EventFilter.ComboBox"))
|
||||
{
|
||||
connect(m_cbValues, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ComboBox::signalChanges);
|
||||
|
||||
addCustomWidget(m_cbValues);
|
||||
|
||||
m_concreteAttributeType = detailData->attributeRedirectionLookup.getRedirection(attributeType);
|
||||
|
||||
updateData(detailData);
|
||||
|
||||
if (initialValue.isEmpty())
|
||||
return;
|
||||
|
||||
bool k = false;
|
||||
int initialValueKey = initialValue.toInt(&k);
|
||||
|
||||
if (initialValueKey < 0 || !k)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "ComboBox::c_tor: initialValueKey < 0 (" << initialValueKey << ")" << "initialValue: " << initialValue;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_cbValues->setCurrentIndex(m_cbValues->findData(initialValueKey, Qt::UserRole));
|
||||
}
|
||||
|
||||
|
||||
void ComboBox::updateData(DetailData *detailData)
|
||||
{
|
||||
int lastSelectedKey = -1;
|
||||
|
||||
if (m_cbValues->currentIndex() > 0)
|
||||
lastSelectedKey = m_cbValues->itemData(m_cbValues->currentIndex()).toInt();
|
||||
|
||||
|
||||
QSignalBlocker blocker(m_cbValues);
|
||||
m_cbValues->clear();
|
||||
m_avm = detailData->m_attributeValueLookupDtc.getAttributeValueMap(m_eventType, m_concreteAttributeType);
|
||||
if (m_avm.isEmpty())
|
||||
m_avm = detailData->attributeValueLookup.getAttributeValueMap(m_concreteAttributeType);
|
||||
|
||||
for (auto i = m_avm.constBegin(); i != m_avm.constEnd(); ++i)
|
||||
{
|
||||
m_cbValues->addItem(i.value()
|
||||
#ifdef DEBUG
|
||||
+ " (" + QString::number(i.key()) + ")"
|
||||
#endif
|
||||
, i.key());
|
||||
}
|
||||
|
||||
if (lastSelectedKey < 0)
|
||||
{
|
||||
m_cbValues->setCurrentIndex(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_cbValues->setCurrentIndex(m_cbValues->findData(lastSelectedKey, Qt::UserRole));
|
||||
|
||||
DEBUG_LOG(m_logger) << "ComboBox: no initial item index found for value id" << lastSelectedKey;
|
||||
}
|
||||
|
||||
|
||||
QString ComboBox::filterText(bool typeSafe) const
|
||||
{
|
||||
QString resultFilterText;
|
||||
|
||||
bool ok = false;
|
||||
int key = m_cbValues->itemData(m_cbValues->currentIndex()).toInt(&ok);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
return resultFilterText;
|
||||
}
|
||||
|
||||
if (typeSafe)
|
||||
resultFilterText = QString::number(key);
|
||||
else
|
||||
resultFilterText = m_avm.value(key);
|
||||
|
||||
|
||||
return resultFilterText;
|
||||
}
|
||||
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AbstractAttributeWidget.h"
|
||||
#include "../../detail_data.h"
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
class QComboBox;
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class ComboBox : public AbstractAttributeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ComboBox(DetailData *detailData, const QString &attributeType,
|
||||
int eventType, const QString &initialValue, QWidget *parent = nullptr);
|
||||
QString filterText(bool typeSafe = false) const override;
|
||||
void updateData(DetailData *detailData) override;
|
||||
|
||||
private:
|
||||
QComboBox *m_cbValues;
|
||||
int m_eventType;
|
||||
QString m_concreteAttributeType;
|
||||
AttributeValueMap m_avm;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "DefaultRangeWidget.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QSpinBox>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
DefaultRangeWidget::DefaultRangeWidget(unsigned int min, unsigned int max, const QString &prefix, const QString &suffix, const QString &initialValue, QWidget *parent)
|
||||
: AbstractAttributeWidget(parent)
|
||||
, box1(new QSpinBox())
|
||||
, box2(new QSpinBox())
|
||||
, m_logger(getLogger("EventFilter.Widgets.DefaultRangeWidget"))
|
||||
{
|
||||
connect(box1, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &DefaultRangeWidget::signalChanges);
|
||||
connect(box2, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &DefaultRangeWidget::signalChanges);
|
||||
|
||||
box1->setRange(min, max);
|
||||
box2->setRange(min, max);
|
||||
|
||||
box1->setPrefix(prefix);
|
||||
box2->setPrefix(prefix);
|
||||
|
||||
box1->setSuffix(suffix);
|
||||
box2->setSuffix(suffix);
|
||||
|
||||
box1->setValue(min);
|
||||
box2->setValue(max);
|
||||
|
||||
|
||||
QHBoxLayout* mainLayout = new QHBoxLayout();
|
||||
|
||||
mainLayout->addWidget(new QLabel(tr("between")));
|
||||
mainLayout->addWidget(box1);
|
||||
mainLayout->addWidget(new QLabel(tr("and")));
|
||||
mainLayout->addWidget(box2);
|
||||
|
||||
QWidget* mainLayoutWidget = new QWidget();
|
||||
mainLayoutWidget->setLayout(mainLayout);
|
||||
|
||||
this->addCustomWidget(mainLayoutWidget);
|
||||
|
||||
box1->setFocus();
|
||||
|
||||
|
||||
|
||||
if (initialValue.length())
|
||||
{
|
||||
QStringList valueList = initialValue.split(QLatin1Char('-'), QString::SkipEmptyParts);
|
||||
|
||||
if (valueList.count() != 2)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "DefaultRangeWidget: invalid initial value '" << initialValue << "'";
|
||||
return;
|
||||
}
|
||||
|
||||
bool k1 = false;
|
||||
bool k2 = false;
|
||||
|
||||
unsigned int val1 = valueList.at(0).toUInt(&k1);
|
||||
unsigned int val2 = valueList.at(1).toUInt(&k2);
|
||||
|
||||
if (!k1 || !k2)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "DefaultRangeWidget: initial value is not numeric '" << initialValue << "'";
|
||||
return;
|
||||
}
|
||||
|
||||
box1->setValue(val1);
|
||||
box2->setValue(val2);
|
||||
}
|
||||
}
|
||||
|
||||
QString DefaultRangeWidget::filterText(bool typeSafe) const
|
||||
{
|
||||
Q_UNUSED(typeSafe);
|
||||
return QStringLiteral("%1 - %2").arg(box1->value(), box2->value());
|
||||
}
|
||||
|
||||
void DefaultRangeWidget::updateData(DetailData *detailData)
|
||||
{
|
||||
|
||||
Q_UNUSED(detailData);
|
||||
}
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AbstractAttributeWidget.h"
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
|
||||
class QHBoxLayout;
|
||||
class QSpinBox;
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class DefaultRangeWidget : public AbstractAttributeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DefaultRangeWidget(unsigned int min,
|
||||
unsigned int max,
|
||||
const QString &prefix,
|
||||
const QString &suffix,
|
||||
const QString &initialValue = QString(),
|
||||
QWidget *parent = nullptr);
|
||||
QString filterText(bool typeSafe = false) const override;
|
||||
void updateData(DetailData *detailData) override;
|
||||
|
||||
private:
|
||||
QSpinBox* box1;
|
||||
QSpinBox* box2;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "RadiusWidget.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QSpinBox>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
RadiusWidget::RadiusWidget(int n1, int n2, int o1, int o2, int radius, QWidget *parent)
|
||||
: AbstractAttributeWidget(parent)
|
||||
, sbN(new QSpinBox(this))
|
||||
, sbO(new QSpinBox(this))
|
||||
, sbR(new QSpinBox(this))
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
|
||||
QString sbNPrefix = tr("N ");
|
||||
QString sbOPrefix = tr("O ");
|
||||
QString sbRPrefix = tr("radius of ");
|
||||
|
||||
sbN->setPrefix(sbNPrefix);
|
||||
sbO->setPrefix(sbOPrefix);
|
||||
sbR->setPrefix(sbRPrefix);
|
||||
|
||||
sbN->setRange(n1, n2);
|
||||
sbO->setRange(o1, o2);
|
||||
sbR->setRange(0, 9999);
|
||||
|
||||
sbN->setValue(n1);
|
||||
sbO->setValue(o1);
|
||||
sbR->setValue(radius);
|
||||
|
||||
|
||||
|
||||
QGridLayout* mainLayout = new QGridLayout();
|
||||
|
||||
mainLayout->addWidget(sbN, 0, 0);
|
||||
mainLayout->addWidget(sbR, 0, 1);
|
||||
mainLayout->addWidget(sbO, 0, 2);
|
||||
|
||||
QWidget* mainLayoutWidget = new QWidget();
|
||||
mainLayoutWidget->setLayout(mainLayout);
|
||||
|
||||
addCustomWidget(mainLayoutWidget);
|
||||
}
|
||||
|
||||
QString RadiusWidget::filterText(bool typeSafe) const
|
||||
{
|
||||
Q_UNUSED(typeSafe);
|
||||
return QStringLiteral("%1x%2x%3").arg(sbN->cleanText(), sbO->cleanText(), sbR->cleanText());
|
||||
}
|
||||
|
||||
void RadiusWidget::updateData(DetailData *)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AbstractAttributeWidget.h"
|
||||
|
||||
class QSpinBox;
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class RadiusWidget : public AbstractAttributeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RadiusWidget(int n1, int n2, int o1, int o2, int radius, QWidget *parent = nullptr);
|
||||
QString filterText(bool typeSafe = false) const override;
|
||||
void updateData(DetailData *detailData) override;
|
||||
|
||||
private:
|
||||
QSpinBox* sbN;
|
||||
QSpinBox* sbO;
|
||||
QSpinBox* sbR;
|
||||
};
|
||||
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
#include "TimeRangeWidget.h"
|
||||
#include "../../detail_data.h"
|
||||
|
||||
#include <LtsWidgets/lts_date_time_edit.h>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QDateTime>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
TimeRangeWidget::TimeRangeWidget(DetailData *detailData, const QString &initialValue, QWidget *parent)
|
||||
: AbstractAttributeWidget(parent)
|
||||
, m_logger(getLogger("EventFilter.Widgets.TimeRangeWidget"))
|
||||
, m_edit1(new LtsWidgets::LtsDateTimeEdit(this))
|
||||
, m_edit2(new LtsWidgets::LtsDateTimeEdit(this))
|
||||
{
|
||||
connect(m_edit1, &LtsWidgets::LtsDateTimeEdit::dateTimeChanged, this, &TimeRangeWidget::signalChanges);
|
||||
connect(m_edit2, &LtsWidgets::LtsDateTimeEdit::dateTimeChanged, this, &TimeRangeWidget::signalChanges);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QHBoxLayout* mainLayout = new QHBoxLayout();
|
||||
|
||||
mainLayout->addWidget(new QLabel(tr("between")));
|
||||
mainLayout->addWidget(m_edit1);
|
||||
mainLayout->addWidget(new QLabel(tr("and")));
|
||||
mainLayout->addWidget(m_edit2);
|
||||
|
||||
QWidget* mainLayoutWidget = new QWidget();
|
||||
mainLayoutWidget->setLayout(mainLayout);
|
||||
|
||||
addCustomWidget(mainLayoutWidget);
|
||||
|
||||
m_edit1->setFocus();
|
||||
|
||||
|
||||
updateData(detailData);
|
||||
|
||||
|
||||
if (initialValue.isEmpty())
|
||||
return;
|
||||
|
||||
const auto initialTimeRange(initialValue.splitRef(QLatin1Char('-'), QString::SkipEmptyParts));
|
||||
|
||||
if (initialTimeRange.count() != 2)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "invalid initial time range value: " << initialValue;
|
||||
return;
|
||||
}
|
||||
|
||||
bool k = false;
|
||||
qint64 time = initialTimeRange.at(0).toInt(&k);
|
||||
time *= 1000;
|
||||
|
||||
if (!k)
|
||||
WARNING_LOG(m_logger) << "invalid initial time range start value: " << initialTimeRange.at(0).toString();
|
||||
else
|
||||
m_edit1->setMsecsSinceEpoch(time);
|
||||
|
||||
|
||||
time = initialTimeRange.at(1).toInt(&k);
|
||||
time *= 1000;
|
||||
|
||||
if (!k)
|
||||
WARNING_LOG(m_logger) << "invalid initial time range start value: " << initialTimeRange.at(1).toString();
|
||||
else
|
||||
m_edit2->setMsecsSinceEpoch(time);
|
||||
}
|
||||
|
||||
|
||||
QString TimeRangeWidget::filterText(bool typeSafe) const
|
||||
{
|
||||
(void)typeSafe;
|
||||
QString filterText;
|
||||
|
||||
filterText += QString::number(m_edit1->msecsSinceEpoch() / 1000 );
|
||||
filterText += QLatin1Char('-');
|
||||
filterText += QString::number(m_edit2->msecsSinceEpoch() / 1000 );
|
||||
|
||||
return filterText;
|
||||
}
|
||||
|
||||
|
||||
void TimeRangeWidget::updateData(DetailData *detailData)
|
||||
{
|
||||
LtsSession::LtsSession *session = detailData->session();
|
||||
m_edit1->setMsecsSinceEpoch(session->partitionTime() - 60 * 1000 );
|
||||
m_edit2->setMsecsSinceEpoch(session->partitionTime());
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AbstractAttributeWidget.h"
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
class LtsDateTimeEdit;
|
||||
}
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class TimeRangeWidget : public AbstractAttributeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TimeRangeWidget(DetailData *detailData, const QString &initialValue, QWidget *parent = nullptr);
|
||||
QString filterText(bool typeSafe = false) const override;
|
||||
void updateData(DetailData *detailData) override;
|
||||
|
||||
private:
|
||||
NGL::INGLLogger &m_logger;
|
||||
public:
|
||||
LtsWidgets::LtsDateTimeEdit *m_edit1;
|
||||
LtsWidgets::LtsDateTimeEdit *m_edit2;
|
||||
};
|
||||
|
||||
}
|
||||
+296
@@ -0,0 +1,296 @@
|
||||
|
||||
|
||||
|
||||
#include "attribute_value_lookup.h"
|
||||
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <AudioVideoManagement/stream_name_mapping.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <ProjectDataManagement/pdm_dtc.h>
|
||||
|
||||
#include <OperatorManagement/opm_translation.h>
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
|
||||
#include <QVector>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
AttributeValueMap AvmChargeType::getAttributeValueMap(int eventType) const
|
||||
{
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
|
||||
using namespace ProjectDataManagement;
|
||||
QVector<ChargeType> charges;
|
||||
switch (eventType)
|
||||
{
|
||||
case EventType::Hit:
|
||||
case EventType::WeaponAssignment:
|
||||
case EventType::FireEvent:
|
||||
charges = m_dtc->chargesForGearClass(GearClass::DuelSim);
|
||||
break;
|
||||
case EventType::HitBuilding:
|
||||
charges = m_dtc->chargesForGearClass(GearClass::DuelSim);
|
||||
Q_FALLTHROUGH();
|
||||
case EventType::HitEffectSimulation:
|
||||
charges += m_dtc->chargesForGearClass(GearClass::Artillery);
|
||||
charges += m_dtc->chargesForGearClass(GearClass::Mortar);
|
||||
charges += m_dtc->chargesForGearClass(GearClass::Geopairing);
|
||||
charges += m_dtc->chargesForGearClass(GearClass::AirSupport);
|
||||
charges += m_dtc->chargesForGearClass(GearClass::MineArea);
|
||||
charges += m_dtc->chargesForGearClass(GearClass::Biological);
|
||||
charges += m_dtc->chargesForGearClass(GearClass::Chemical);
|
||||
break;
|
||||
case EventType::HitB:
|
||||
charges = m_dtc->chargesForGearClass(GearClass::Biological);
|
||||
break;
|
||||
case EventType::HitC:
|
||||
charges = m_dtc->chargesForGearClass(GearClass::Chemical);
|
||||
break;
|
||||
case EventType::BCContamination:
|
||||
charges = m_dtc->chargesForGearClass(GearClass::Biological);
|
||||
charges += m_dtc->chargesForGearClass(GearClass::Chemical);
|
||||
break;
|
||||
case EventType::HitMine:
|
||||
case EventType::EnterMineArea:
|
||||
case EventType::LeaveMineArea:
|
||||
case EventType::MineArea:
|
||||
charges = m_dtc->chargesForGearClass(GearClass::MineArea);
|
||||
|
||||
break;
|
||||
}
|
||||
Q_ASSERT(!charges.isEmpty());
|
||||
|
||||
AttributeValueMap ret;
|
||||
for (const ChargeType &data : qAsConst(charges))
|
||||
ret.insert(data.id(), m_dtc->trChargeTypeShortName(data.id()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString AvmChargeType::getValueStringFromValueId(int attributeValueId) const
|
||||
{
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
return m_dtc->trChargeTypeShortName(attributeValueId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
AttributeValueMap AvmGearType::getAttributeValueMap(int eventType) const
|
||||
{
|
||||
using namespace ProjectDataManagement;
|
||||
if (eventType != EventType_def::WeaponAssignment &&
|
||||
eventType != EventType_def::FireEvent)
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
|
||||
const auto gearTypes = m_dtc->gearTypes();
|
||||
AttributeValueMap ret;
|
||||
for (const auto &data : gearTypes)
|
||||
{
|
||||
if (data.gearClassId() == GearClass::DuelSim &&
|
||||
data.tasCode() != 0)
|
||||
ret.insert(data.id(), m_dtc->trGearTypeName(data.id()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString AvmGearType::getValueStringFromValueId(int attributeValueId) const
|
||||
{
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
return m_dtc->trGearTypeName(attributeValueId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
AttributeValueMap AvmParty::getAttributeValueMap(int eventType) const
|
||||
{
|
||||
Q_UNUSED(eventType);
|
||||
|
||||
using namespace ParticipantManagement;
|
||||
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
|
||||
const auto parties = m_dtc->partys();
|
||||
AttributeValueMap ret;
|
||||
for (const auto &data : parties)
|
||||
ret.insert(data.id(), trPartyName(data.name()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString AvmParty::getValueStringFromValueId(int attributeValueId) const
|
||||
{
|
||||
using namespace ParticipantManagement;
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
return trPartyName(m_dtc->party(attributeValueId).name());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
AttributeValueMap AvmEquipmentNumber::getAttributeValueMap(int eventType) const
|
||||
{
|
||||
Q_UNUSED(eventType);
|
||||
|
||||
using namespace ParticipantManagement;
|
||||
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
|
||||
AttributeValueMap ret;
|
||||
auto cb = [&ret](const ParticipantManagement::Participant & p) -> void
|
||||
{
|
||||
if (!p.equipmentNumber().is_set())
|
||||
return;
|
||||
const auto equipNo = p.equipmentNumber().get();
|
||||
ret.insert(equipNo, QString::number(equipNo));
|
||||
};
|
||||
m_dtc->participants(cb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString AvmEquipmentNumber::getValueStringFromValueId(int attributeValueId) const
|
||||
{
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
auto ret = m_dtc->participant(attributeValueId).equipmentNumber();
|
||||
return ret.is_set() ? QString::number(ret.get()) : QString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
AttributeValueMap AvmOperator::getAttributeValueMap(int eventType) const
|
||||
{
|
||||
Q_UNUSED(eventType);
|
||||
|
||||
using namespace OperatorManagement;
|
||||
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
|
||||
const auto users = m_dtc->users();
|
||||
AttributeValueMap ret;
|
||||
for (const auto &data : users)
|
||||
ret.insert(data.id(), QString::fromStdString(data.name()));
|
||||
ret.insert(0, QObject::tr("EXCON"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString AvmOperator::getValueStringFromValueId(int attributeValueId) const
|
||||
{
|
||||
if (attributeValueId == 0)
|
||||
return QObject::tr("EXCON");
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
return QString::fromStdString(m_dtc->user(attributeValueId).name());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
AttributeValueMap AvmBuilding::getAttributeValueMap(int eventType) const
|
||||
{
|
||||
Q_UNUSED(eventType);
|
||||
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
|
||||
AttributeValueMap ret;
|
||||
auto cb = [this, &ret](const InfrastructureManagement::MainStructureElement &mse) -> void
|
||||
{
|
||||
if (mse.structureElementTypeId() != InfrastructureManagement::StructureElementType::Building)
|
||||
return;
|
||||
ret.insert(mse.id(), m_dtc->getBuildingDisplayName(mse));
|
||||
};
|
||||
m_dtc->mainStructureElements(cb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString AvmBuilding::getValueStringFromValueId(int attributeValueId) const
|
||||
{
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
return m_dtc->getBuildingDisplayName(attributeValueId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
AvmStreamName::AvmStreamName(const std::shared_ptr<AudioVideoManagement::Interface::Dtc> &dtc)
|
||||
: m_dtc(dtc)
|
||||
, m_snm(AudioVideoManagement::StreamNameMapping::create(m_dtc.get()))
|
||||
{}
|
||||
|
||||
AvmStreamName::~AvmStreamName() = default;
|
||||
|
||||
AttributeValueMap AvmStreamName::getAttributeValueMap(int eventType) const
|
||||
{
|
||||
AttributeValueMap ret;
|
||||
|
||||
if (!m_dtc)
|
||||
return ret;
|
||||
|
||||
switch (eventType)
|
||||
{
|
||||
case ProjectDataManagement::EventType::RadioCnr:
|
||||
{
|
||||
auto cb = [&ret](const AudioVideoManagement::CnrConfig &cnrConfig) -> void
|
||||
{
|
||||
ret.insert(cnrConfig.id(), QString::fromStdString(cnrConfig.radioCircuit()));
|
||||
};
|
||||
m_dtc->cnrConfigs(cb);
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::EventType::RadioTvc:
|
||||
{
|
||||
auto cb = [&ret](const AudioVideoManagement::TvcConfig &tvcConfig) -> void
|
||||
{
|
||||
ret.insert(tvcConfig.id(), QString::fromStdString(tvcConfig.radioCircuit()));
|
||||
};
|
||||
m_dtc->tvcConfigs(cb);
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::EventType::CameraVideo:
|
||||
{
|
||||
auto cb = [this, &ret](const AudioVideoManagement::Stream &stream) -> void
|
||||
{
|
||||
if (stream.mountingPointId() == 0 ||
|
||||
stream.type() != AudioVideoManagement::StreamType::Video)
|
||||
return;
|
||||
ret.insert(stream.id(), m_snm->displayName(stream.mountingPointId()));
|
||||
};
|
||||
m_dtc->streams(cb);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString AvmStreamName::getValueStringFromValueId(int attributeValueId) const
|
||||
{
|
||||
if (!m_dtc)
|
||||
return {};
|
||||
return QString::fromStdString(m_dtc->stream(attributeValueId).name());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class StreamNameMapping;
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
namespace OperatorManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
namespace ProjectDataManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
using AttributeValueMap = QMap<int, QString>;
|
||||
using AtributeValueLookupMap = QMap<QString, AttributeValueMap>;
|
||||
|
||||
class AttributeValueLookupProvider
|
||||
{
|
||||
public:
|
||||
virtual ~AttributeValueLookupProvider() = default;
|
||||
virtual AttributeValueMap getAttributeValueMap(int eventType) const = 0;
|
||||
virtual QString getValueStringFromValueId(int attributeValueId) const = 0;
|
||||
};
|
||||
|
||||
class AvmChargeType final : public AttributeValueLookupProvider
|
||||
{
|
||||
public:
|
||||
explicit AvmChargeType(const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &dtc) : m_dtc(dtc) {}
|
||||
AttributeValueMap getAttributeValueMap(int eventType) const override;
|
||||
QString getValueStringFromValueId(int attributeValueId) const override;
|
||||
private:
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_dtc;
|
||||
};
|
||||
|
||||
class AvmGearType final : public AttributeValueLookupProvider
|
||||
{
|
||||
public:
|
||||
explicit AvmGearType(const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &dtc) : m_dtc(dtc) {}
|
||||
AttributeValueMap getAttributeValueMap(int eventType) const override;
|
||||
QString getValueStringFromValueId(int attributeValueId) const override;
|
||||
private:
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_dtc;
|
||||
};
|
||||
|
||||
class AvmParty final : public AttributeValueLookupProvider
|
||||
{
|
||||
public:
|
||||
explicit AvmParty(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &dtc) : m_dtc(dtc) {}
|
||||
AttributeValueMap getAttributeValueMap(int eventType) const override;
|
||||
QString getValueStringFromValueId(int attributeValueId) const override;
|
||||
private:
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_dtc;
|
||||
};
|
||||
|
||||
class AvmEquipmentNumber final : public AttributeValueLookupProvider
|
||||
{
|
||||
public:
|
||||
explicit AvmEquipmentNumber(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &dtc) : m_dtc(dtc) {}
|
||||
AttributeValueMap getAttributeValueMap(int eventType) const override;
|
||||
QString getValueStringFromValueId(int attributeValueId) const override;
|
||||
private:
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_dtc;
|
||||
};
|
||||
|
||||
class AvmOperator final : public AttributeValueLookupProvider
|
||||
{
|
||||
public:
|
||||
explicit AvmOperator(const std::shared_ptr<OperatorManagement::Interface::Dtc> &dtc) : m_dtc(dtc) {}
|
||||
AttributeValueMap getAttributeValueMap(int eventType) const override;
|
||||
QString getValueStringFromValueId(int attributeValueId) const override;
|
||||
private:
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_dtc;
|
||||
};
|
||||
|
||||
class AvmBuilding final : public AttributeValueLookupProvider
|
||||
{
|
||||
public:
|
||||
explicit AvmBuilding(const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &dtc) : m_dtc(dtc) {}
|
||||
AttributeValueMap getAttributeValueMap(int eventType) const override;
|
||||
QString getValueStringFromValueId(int attributeValueId) const override;
|
||||
private:
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_dtc;
|
||||
};
|
||||
|
||||
class AvmStreamName final : public AttributeValueLookupProvider
|
||||
{
|
||||
public:
|
||||
explicit AvmStreamName(const std::shared_ptr<AudioVideoManagement::Interface::Dtc> &dtc);
|
||||
~AvmStreamName();
|
||||
AttributeValueMap getAttributeValueMap(int eventType) const override;
|
||||
QString getValueStringFromValueId(int attributeValueId) const override;
|
||||
private:
|
||||
std::shared_ptr<AudioVideoManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<AudioVideoManagement::StreamNameMapping> m_snm;
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+857
@@ -0,0 +1,857 @@
|
||||
|
||||
|
||||
|
||||
#include "detail_data.h"
|
||||
#include "logger.h"
|
||||
#include "tln_legend.h"
|
||||
#include "attribute_value_lookup.h"
|
||||
|
||||
#include <LtsTimelineClassic/Event.h>
|
||||
#include <LtsWidgets/lts_date_time_edit.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
|
||||
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/MarkerManagement/mrk_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
|
||||
#include <Plugins/AudioVideoManagement/avm_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
|
||||
|
||||
|
||||
#include <Services/ExerciseEventManagement/eem_enums.hpp>
|
||||
#include <Services/ExerciseEventManagement/eem_translation.h>
|
||||
#include <Services/ProjectDataManagement/pdm_translation.h>
|
||||
#include <Services/AreaEffectSimulation/aes_translation.h>
|
||||
#include <Services/MarkerManagement/mrk_translation.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
static inline QString removeSpaces(const QString &str)
|
||||
{
|
||||
|
||||
QString ret;
|
||||
ret.reserve(str.size());
|
||||
for (const QChar c : str)
|
||||
{
|
||||
if (!c.isSpace())
|
||||
ret += c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DetailData::DetailData(LtsSession::LtsSession *session, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_session(session)
|
||||
, __already_populated__(false)
|
||||
, m_logger(getLogger("DetailData"))
|
||||
{
|
||||
populate();
|
||||
}
|
||||
|
||||
void DetailData::addRedirectedAttributeType(const QString &newAttributeTypeId, const QString &attributeText, const QString &redirectToAttributeTypeId)
|
||||
{
|
||||
attributeTypeLookup.addAttributeText(newAttributeTypeId, attributeText);
|
||||
attributeRedirectionLookup.addRedirection(newAttributeTypeId, redirectToAttributeTypeId);
|
||||
}
|
||||
|
||||
|
||||
void DetailData::addAttributeType(const QString &attributeTypeId, const QString &attributeText, const int uiTypeId, const int interpreterTypeId)
|
||||
{
|
||||
attributeTypeLookup.addAttributeText(attributeTypeId, attributeText);
|
||||
attributeUITypeLookup.addUITypeToAttribute(attributeTypeId, uiTypeId);
|
||||
attributeInterpreterLookup.addInterpreterTypeToAttribute(attributeTypeId, interpreterTypeId);
|
||||
}
|
||||
|
||||
|
||||
void DetailData::addEventType(int eventTypeId, const QString &eventTypeString)
|
||||
{
|
||||
eventTypeLookup.addEventType(eventTypeId, eventTypeString);
|
||||
attributeEventLookup.addAttributesToEvent(eventTypeId, {QStringLiteral("TimeRange")});
|
||||
}
|
||||
|
||||
|
||||
void DetailData::addEventType(const ProjectDataManagement::EventType &eventType)
|
||||
{
|
||||
addEventType(eventType.underlying(), ProjectDataManagement::toString(eventType));
|
||||
}
|
||||
|
||||
|
||||
void DetailData::populate()
|
||||
{
|
||||
if (__already_populated__)
|
||||
return;
|
||||
__already_populated__ = true;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
addEventType(0, tr("General"));
|
||||
|
||||
addEventType(markerTypeId, tr("Marker"));
|
||||
attributeEventLookup.addAttributesToEvent(markerTypeId, {QStringLiteral("MarkerName"),
|
||||
QStringLiteral("MarkerNote"),
|
||||
QStringLiteral("Operator"),
|
||||
QStringLiteral("MarkerOffset"),
|
||||
QStringLiteral("IsSituationType"),
|
||||
QStringLiteral("IsVideoType"),
|
||||
QStringLiteral("IsAudioType")});
|
||||
|
||||
|
||||
using namespace ProjectDataManagement;
|
||||
const auto possibleEventTypes = TimelineLegendDialog::possibleEvents();
|
||||
for (const auto eventType : possibleEventTypes)
|
||||
{
|
||||
switch (eventType.underlying())
|
||||
{
|
||||
case EventType::Hit:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("VulnerabilityState"),
|
||||
QStringLiteral("OriginatorChargeTypeId"),
|
||||
QStringLiteral("FriendlyFire"),
|
||||
|
||||
|
||||
QStringLiteral("OriginatorEquipmentNumber")});
|
||||
break;
|
||||
case EventType::BiteMessage:
|
||||
break;
|
||||
case EventType::WeaponAssignment:
|
||||
case EventType::FireEvent:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {
|
||||
QStringLiteral("GearTypeId"),
|
||||
QStringLiteral("ChargeTypeId")});
|
||||
break;
|
||||
case EventType::HitBuilding:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("AesType"),
|
||||
QStringLiteral("ChargeTypeId"),
|
||||
QStringLiteral("OriginatorEquipmentNumber"),
|
||||
QStringLiteral("MainStructureElementId"),
|
||||
QStringLiteral("VulnerabilityState"),
|
||||
QStringLiteral("damagePercent"),
|
||||
|
||||
});
|
||||
break;
|
||||
case EventType::Manipulation:
|
||||
break;
|
||||
case EventType::Sanitation:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("Vitality"),
|
||||
QStringLiteral("SanitationProceduresNeeded"),
|
||||
QStringLiteral("SanitationProceduresTaken")});
|
||||
break;
|
||||
case EventType::CameraVideo:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("PartyId"),
|
||||
QStringLiteral("MainStructureElementId"),
|
||||
QStringLiteral("duration"),
|
||||
QStringLiteral("streamName")});
|
||||
break;
|
||||
case EventType::RadioCnr:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("PartyId"),
|
||||
QStringLiteral("duration"),
|
||||
QStringLiteral("streamName")});
|
||||
break;
|
||||
case EventType::RadioTvc:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("duration"),
|
||||
QStringLiteral("streamName")});
|
||||
|
||||
break;
|
||||
case EventType::HitEffectSimulation:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("AesType"),
|
||||
QStringLiteral("AesName"),
|
||||
QStringLiteral("OriginatorChargeTypeId")});
|
||||
break;
|
||||
case EventType::HitC:
|
||||
case EventType::HitB:
|
||||
case EventType::HitMine:
|
||||
case EventType::EnterMineArea:
|
||||
case EventType::LeaveMineArea:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("AesName"),
|
||||
QStringLiteral("OriginatorChargeTypeId")});
|
||||
break;
|
||||
case EventType::HitN:
|
||||
case EventType::HitGasPipe:
|
||||
case EventType::EnterDangerArea:
|
||||
case EventType::LeaveDangerArea:
|
||||
case EventType::CrossLocalBorderline:
|
||||
case EventType::CrossGlobalBorderline:
|
||||
case EventType::EnterFunctionalArea:
|
||||
case EventType::LeaveFunctionalArea:
|
||||
case EventType::EnterNuclear:
|
||||
case EventType::LeaveNuclear:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("AesName")});
|
||||
break;
|
||||
case EventType::Borderline:
|
||||
case EventType::NContamination:
|
||||
case EventType::DangerArea:
|
||||
case EventType::FunctionalArea:
|
||||
case EventType::MineCorridor:
|
||||
case ProjectDataManagement::EventType::GasPipe:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("AesName"),
|
||||
QStringLiteral("duration")});
|
||||
break;
|
||||
case EventType::MineArea:
|
||||
case EventType::BCContamination:
|
||||
attributeEventLookup.addAttributesToEvent(eventType, {QStringLiteral("AesName"),
|
||||
QStringLiteral("duration"),
|
||||
QStringLiteral("ChargeTypeId")});
|
||||
break;
|
||||
case EventType::Unknown:
|
||||
case EventType::FriendlyFire:
|
||||
case EventType::TechnicalArea:
|
||||
case EventType::EquipmentErrorReport:
|
||||
case EventType::EmergencyCall:
|
||||
Q_ASSERT(false);
|
||||
continue;
|
||||
}
|
||||
addEventType(eventType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("TimeRange"), tr("Time range:"), ATTRIBUTE_UI_TYPE_TIME_RANGE_WIDGET , INTERPRETER_TYPE_TIME);
|
||||
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("VulnerabilityState"), tr("Vulnerability State:"));
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::CombatReady);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::LightDamage);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::MediumDamage);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::HeavyDamage);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::MobilityKill);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::VisibleMobilityKill);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::WeaponSystemDamage);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::VisibleWeaponSystemDamage);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::CatastrophicKill);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::TemporarySeverance);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::NearMiss);
|
||||
addAttributeValue(QStringLiteral("VulnerabilityState"), ProjectDataManagement::VulnerabilityState::HitWithNoEffect);
|
||||
|
||||
|
||||
|
||||
|
||||
addAttributeTypeWithYesAndNo(QStringLiteral("IsSituationType"), tr("Is situation type:"));
|
||||
addAttributeTypeWithYesAndNo(QStringLiteral("IsVideoType"), tr("Is video type:"));
|
||||
addAttributeTypeWithYesAndNo(QStringLiteral("IsAudioType"), tr("Is audio type:"));
|
||||
|
||||
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("AesType"), tr("Aes Type:"));
|
||||
|
||||
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtNContamination);
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtBCContamination);
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtExplosionSingle);
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtMineArea);
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtDangerArea);
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtFunctionalArea);
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtMineCorridor);
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtBorderline);
|
||||
|
||||
|
||||
addAttributeValue(QStringLiteral("AesType"), AreaEffectSimulation::AesType::AtMineAreaSingleMines);
|
||||
|
||||
|
||||
|
||||
addAttributeTypeWithYesAndNo(QStringLiteral("FriendlyFire"), tr("Friendly Fire:"));
|
||||
|
||||
|
||||
addAttributeTypeWithYesAndNo(QStringLiteral("DryFire"), tr("Dry Fire:"));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("MarkerName"), tr("Name:"), ATTRIBUTE_UI_TYPE_CHECKBOX , INTERPRETER_TYPE_NONE);
|
||||
addAttributeType(QStringLiteral("MarkerNote"), tr("Note:"), ATTRIBUTE_UI_TYPE_CHECKBOX , INTERPRETER_TYPE_NONE);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("MarkerOffset"), tr("Offset [msecs]:"), ATTRIBUTE_UI_TYPE_DEFAULT_RANGE_WIDGET , INTERPRETER_TYPE_RANGE);
|
||||
{
|
||||
DetailData::AttributeParameterLookup::ParameterMap pm;
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_MIN, QVariant::fromValue<unsigned int>(0));
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_MAX, QVariant::fromValue<unsigned int>(9999999));
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_SUFFIX, QVariant::fromValue<QString>(QString()));
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_PREFIX, QVariant::fromValue<QString>(QString()));
|
||||
attributeParameterLookup.addParameter(QStringLiteral("MarkerOffset"), pm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("duration"), tr("Duration [msecs]:"), ATTRIBUTE_UI_TYPE_DEFAULT_RANGE_WIDGET , INTERPRETER_TYPE_RANGE);
|
||||
{
|
||||
DetailData::AttributeParameterLookup::ParameterMap pm;
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_MIN, QVariant::fromValue<unsigned int>(0));
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_MAX, QVariant::fromValue<unsigned int>(99999999));
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_SUFFIX, QVariant::fromValue<QString>(QString()));
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_PREFIX, QVariant::fromValue<QString>(QString()));
|
||||
attributeParameterLookup.addParameter(QStringLiteral("duration"), pm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("damagePercent"), tr("Damage [%]:"), ATTRIBUTE_UI_TYPE_DEFAULT_RANGE_WIDGET , INTERPRETER_TYPE_RANGE);
|
||||
addRedirectedAttributeType(QStringLiteral("damagePercentOld"), tr("Damage before [%]:"), QStringLiteral("damagePercent"));
|
||||
|
||||
{
|
||||
DetailData::AttributeParameterLookup::ParameterMap pm;
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_MIN, QVariant::fromValue<unsigned int>(0));
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_MAX, QVariant::fromValue<unsigned int>(100));
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_SUFFIX, QVariant::fromValue<QString>(tr(" %")));
|
||||
pm.insert(DetailData::UI_PARAM_TYPE_PREFIX, QVariant::fromValue<QString>(QString()));
|
||||
attributeParameterLookup.addParameter(QStringLiteral("damagePercent"), pm);
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> dtcPpm;
|
||||
m_session->getDtc<ParticipantManagement::DataInterface>(dtcPpm);
|
||||
addAttributeType(QStringLiteral("EquipmentNumber"), tr("Equip. No.:"));
|
||||
m_attributeValueLookupDtc.addHandlerForDtc(QStringLiteral("EquipmentNumber"), new AvmEquipmentNumber(dtcPpm));
|
||||
addRedirectedAttributeType(QStringLiteral("OriginatorEquipmentNumber"), tr("Equip. No. of Originator:"), QStringLiteral("EquipmentNumber"));
|
||||
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> dtcPdm;
|
||||
m_session->getDtc<ProjectDataManagement::DataInterface>(dtcPdm);
|
||||
|
||||
addAttributeType(QStringLiteral("ChargeTypeId"), tr("Charge Type:"));
|
||||
addRedirectedAttributeType(QStringLiteral("OriginatorChargeTypeId"), tr("Originator Charge Type:"), QStringLiteral("ChargeTypeId"));
|
||||
m_attributeValueLookupDtc.addHandlerForDtc(QStringLiteral("ChargeTypeId"), new AvmChargeType(dtcPdm));
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("GearTypeId"), tr("Gear Type:"));
|
||||
m_attributeValueLookupDtc.addHandlerForDtc(QStringLiteral("GearTypeId"), new AvmGearType(dtcPdm));
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("OriginatorType"), tr("Originator Type:"));
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::Unknown);
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::Participant);
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::AreaEffectSimulation);
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::ObserverController);
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::ExerciseControl);
|
||||
|
||||
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::FunctionalArea);
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::Initialization);
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::ImprovisedExplosiveDevice);
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::DusMine);
|
||||
const bool showPvSan = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"),
|
||||
QStringLiteral("HasPvSan"));
|
||||
if (showPvSan)
|
||||
addAttributeValue(QStringLiteral("OriginatorType"), ProjectDataManagement::StateChangeOriginator::Sanitation);
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> dtcIsm;
|
||||
m_session->getDtc<InfrastructureManagement::DataInterface>(dtcIsm);
|
||||
addAttributeType(QStringLiteral("MainStructureElementId"), tr("Building:"));
|
||||
m_attributeValueLookupDtc.addHandlerForDtc(QStringLiteral("MainStructureElementId"), new AvmBuilding(dtcIsm));
|
||||
|
||||
|
||||
addAttributeType(QStringLiteral("PartyId"), tr("Party:"));
|
||||
m_attributeValueLookupDtc.addHandlerForDtc(QStringLiteral("PartyId"), new AvmParty(dtcPpm));
|
||||
|
||||
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> dtcOpm;
|
||||
m_session->getDtc<OperatorManagement::DataInterface>(dtcOpm);
|
||||
addAttributeType(QStringLiteral("Operator"), tr("Operator:"));
|
||||
m_attributeValueLookupDtc.addHandlerForDtc(QStringLiteral("Operator"), new AvmOperator(dtcOpm));
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<AudioVideoManagement::Interface::Dtc> dtcAvm;
|
||||
m_session->getDtc<AudioVideoManagement::DataInterface>(dtcAvm);
|
||||
addAttributeType(QStringLiteral("streamName"), tr("Stream Name:"));
|
||||
m_attributeValueLookupDtc.addHandlerForDtc(QStringLiteral("streamName"), new AvmStreamName(dtcAvm));
|
||||
}
|
||||
|
||||
DetailData::GetDetailDataResultList DetailData::getDetailData(const LtsTimelineClassic::Event *event)
|
||||
{
|
||||
GetDetailDataResultList result;
|
||||
|
||||
if (event->detailData().isEmpty())
|
||||
return result;
|
||||
|
||||
const QJsonObject &root = event->detailData();
|
||||
for (auto i = root.constBegin(); i != root.constEnd(); ++i)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Adding Detail Data for: " << i.key();
|
||||
result.append(getDetailDataForAttribute(i.key(), *i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DetailData::GetDetailDataForAttributeResult DetailData::getDetailDataForAttribute(const LtsTimelineClassic::Event *event, const QString &attributeType)
|
||||
{
|
||||
GetDetailDataForAttributeResult result;
|
||||
|
||||
const QJsonObject &root = event->detailData();
|
||||
root[QStringLiteral("TimeRange")] = event->startTime() / 1000 ;
|
||||
root[QStringLiteral("PartyId")] = event->partyId();
|
||||
|
||||
const QJsonValue attribute = root[attributeType];
|
||||
|
||||
if (attribute.isNull() || attribute.isUndefined())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "DetailData::getDetailDataForAttribute: no attribute type " << attributeType
|
||||
<< " in " << QJsonDocument(root).toJson();
|
||||
|
||||
result.requestResult = DetailData::RequestResult::InvalidAttributeType;
|
||||
return result;
|
||||
}
|
||||
|
||||
return getDetailDataForAttribute(attributeType, attribute);
|
||||
}
|
||||
|
||||
|
||||
DetailData::GetDetailDataForAttributeResult DetailData::getDetailDataForAttribute(const QString &attributeType, const QJsonValue &attributeValueJson)
|
||||
{
|
||||
GetDetailDataForAttributeResult result;
|
||||
result.attributeTypeId = attributeType;
|
||||
result.attributeValueId = -1;
|
||||
result.requestResult = DetailData::RequestResult::Error;
|
||||
QString attributeTypeTranslated = attributeTypeLookup.getAttributeText(attributeType);
|
||||
|
||||
if (attributeTypeTranslated.isEmpty())
|
||||
{
|
||||
result.requestResult = DetailData::RequestResult::InvalidAttributeType;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
result.attributeType = attributeTypeTranslated;
|
||||
|
||||
int attributeValueId = -1;
|
||||
|
||||
|
||||
|
||||
|
||||
switch (attributeValueJson.type())
|
||||
{
|
||||
|
||||
case QJsonValue::Double:
|
||||
{
|
||||
attributeValueId = attributeValueJson.toInt(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
case QJsonValue::Null:
|
||||
case QJsonValue::Undefined:
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Timeline: DetailData::getDetailDataForAttribute: attribute value is null or undefined! " << attributeValueJson.toString();
|
||||
result.requestResult = DetailData::RequestResult::InvalidAttributeTypeJson;
|
||||
return result;
|
||||
}
|
||||
|
||||
case QJsonValue::Bool:
|
||||
{
|
||||
attributeValueId = attributeValueJson.toBool() ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case QJsonValue::String:
|
||||
{
|
||||
bool k = false;
|
||||
QString attributeValueString = attributeValueJson.toString();
|
||||
|
||||
if (attributeValueString.isEmpty())
|
||||
{
|
||||
attributeValueId = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
attributeValueId = attributeValueString.toInt(&k);
|
||||
|
||||
if (!k)
|
||||
{
|
||||
result.attributeValue = attributeValueString;
|
||||
result.requestResult = DetailData::RequestResult::Okay;
|
||||
return result;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Timeline: DetailData::getDetailDataForAttribute: attribute value cannot be handled. Type " << attributeValueJson.type() << attributeValueJson.toString();
|
||||
result.requestResult = DetailData::RequestResult::InvalidAttributeType;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (attributeValueId == -1)
|
||||
{
|
||||
result.requestResult = DetailData::RequestResult::InvalidAttributeType;
|
||||
return result;
|
||||
}
|
||||
|
||||
result.attributeValueId = attributeValueId;
|
||||
|
||||
|
||||
|
||||
int attributeUiType = attributeUITypeLookup.getUIType(attributeType);
|
||||
switch (attributeUiType)
|
||||
{
|
||||
|
||||
case ATTRIBUTE_UI_TYPE_TIME_RANGE_WIDGET:
|
||||
case ATTRIBUTE_UI_TYPE_DEFAULT_RANGE_WIDGET:
|
||||
case ATTRIBUTE_UI_TYPE_RAD_RANGE_WIDGET:
|
||||
case ATTRIBUTE_UI_TYPE_AREA_RANGE_WIDGET:
|
||||
{
|
||||
result.attributeValue = QString::number(attributeValueId);
|
||||
result.requestResult = DetailData::RequestResult::Okay;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case ATTRIBUTE_UI_TYPE_COMBO_BOX:
|
||||
case ATTRIBUTE_UI_TYPE_CHECKBOX:
|
||||
{
|
||||
result.attributeValue = attributeValueLookup.getValueStringFromValueId(attributeType, attributeValueId);
|
||||
if (result.attributeValue.isEmpty())
|
||||
result.attributeValue = m_attributeValueLookupDtc.getValueStringFromValueId(attributeType, attributeValueId);
|
||||
result.requestResult = DetailData::RequestResult::Okay;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
QString concreteAttributeType = attributeRedirectionLookup.getRedirection(attributeType);
|
||||
|
||||
if (concreteAttributeType == attributeType)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "getDetailDataForAttribute: attribute type " << attributeType << " does not have an UiType !!!";
|
||||
result.requestResult = DetailData::RequestResult::NoUiTypeForAttribute;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
|
||||
QString attributeType = result.attributeType;
|
||||
QString attributeTypeId = result.attributeTypeId;
|
||||
|
||||
result = getDetailDataForAttribute(concreteAttributeType, attributeValueJson);
|
||||
|
||||
result.attributeType = attributeType;
|
||||
result.attributeTypeId = attributeTypeId;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DetailData::createRetrieveCurrentTimeCallback(LtsWidgets::LtsDateTimeEdit *dateTimeEdit)
|
||||
{
|
||||
dateTimeEdit->setRetrieveCurrentTimeCallback([this]() { return m_session->partitionTime(); });
|
||||
}
|
||||
|
||||
|
||||
|
||||
DetailData::LookupBase::LookupBase(const QString &lookupClassName)
|
||||
: m_lookupClassName(lookupClassName)
|
||||
, m_logger(getLogger(QStringLiteral("DetailData.") + lookupClassName))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
DetailData::EventTypeLookup::EventTypeLookup()
|
||||
: LookupBase(QStringLiteral("EventTypeLookup"))
|
||||
{
|
||||
}
|
||||
|
||||
void DetailData::EventTypeLookup::addEventType(const int key, const QString &value)
|
||||
{
|
||||
m_eventTypeMap.insert(key, value);
|
||||
}
|
||||
|
||||
int DetailData::EventTypeLookup::getEventType(const QString &eventText) const
|
||||
{
|
||||
|
||||
|
||||
const QString paramText = removeSpaces(eventText);
|
||||
for (auto i = m_eventTypeMap.constBegin(); i != m_eventTypeMap.constEnd(); ++i)
|
||||
{
|
||||
const QString mapText = removeSpaces(i.value());
|
||||
if (mapText == paramText)
|
||||
return i.key();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString DetailData::EventTypeLookup::getEventText(const int eventType) const
|
||||
{
|
||||
return m_eventTypeMap.value(eventType);
|
||||
}
|
||||
|
||||
bool DetailData::EventTypeLookup::isEventExists(const int eventType) const
|
||||
{
|
||||
return m_eventTypeMap.contains(eventType);
|
||||
}
|
||||
|
||||
QStringList DetailData::EventTypeLookup::getEventTexts() const
|
||||
{
|
||||
return m_eventTypeMap.values();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DetailData::AttributeEventLookup::AttributeEventLookup()
|
||||
: LookupBase(QStringLiteral("AttributeEventLookup"))
|
||||
{
|
||||
}
|
||||
|
||||
void DetailData::AttributeEventLookup::addAttributesToEvent(const int eventType, const AttributeList &attributeTypeList)
|
||||
{
|
||||
AttributeList &al = m_attributeEventLookupMap[eventType];
|
||||
al += attributeTypeList;
|
||||
}
|
||||
|
||||
void DetailData::AttributeEventLookup::addAttributesToEvent(const ProjectDataManagement::EventType &eventType, const AttributeList &attributeTypeList)
|
||||
{
|
||||
addAttributesToEvent(eventType.underlying(), attributeTypeList);
|
||||
}
|
||||
|
||||
bool DetailData::AttributeEventLookup::isAttributeInEvent(const int eventType, const QString &attributeType)
|
||||
{
|
||||
auto eventTypeIt = m_attributeEventLookupMap.constFind(eventType);
|
||||
|
||||
if (eventTypeIt == m_attributeEventLookupMap.constEnd())
|
||||
return false;
|
||||
|
||||
const AttributeList &attributeList = *eventTypeIt;
|
||||
|
||||
if (attributeList.contains(attributeType))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DetailData::AttributeEventLookup::AttributeList DetailData::AttributeEventLookup::getEventsAttributeList(const int eventType) const
|
||||
{
|
||||
return m_attributeEventLookupMap.value(eventType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DetailData::AttributeTypeLookup::AttributeTypeLookup()
|
||||
: LookupBase(QStringLiteral("AttributeTypeLookup"))
|
||||
{
|
||||
}
|
||||
|
||||
void DetailData::AttributeTypeLookup::addAttributeText(const QString &attributeType, const QString &attributeText)
|
||||
{
|
||||
m_attributeTypeLookupMap.insert(attributeType, attributeText);
|
||||
}
|
||||
|
||||
QString DetailData::AttributeTypeLookup::getAttributeType(const QString &attributeText) const
|
||||
{
|
||||
const QString paramText = removeSpaces(attributeText);
|
||||
|
||||
for (auto i = m_attributeTypeLookupMap.constBegin(); i != m_attributeTypeLookupMap.constEnd(); ++i)
|
||||
{
|
||||
const QString mapText = removeSpaces(i.value());
|
||||
if (mapText == paramText)
|
||||
return i.key();
|
||||
}
|
||||
|
||||
WARNING_LOG(m_logger) << "getAttributeType: attribute type not found by text '" << attributeText << "'";
|
||||
return QString();
|
||||
}
|
||||
|
||||
DetailData::AttributeTypeLookup::AttributeTypeList DetailData::AttributeTypeLookup::getAttributeTypes() const
|
||||
{
|
||||
return m_attributeTypeLookupMap.keys();
|
||||
}
|
||||
|
||||
QString DetailData::AttributeTypeLookup::getAttributeText(const QString &attributeType, const QString &defaultReturnValue) const
|
||||
{
|
||||
return m_attributeTypeLookupMap.value(attributeType, defaultReturnValue);
|
||||
}
|
||||
|
||||
DetailData::AttributeTypeLookup::AttributeTextList DetailData::AttributeTypeLookup::getAttributeTexts() const
|
||||
{
|
||||
return m_attributeTypeLookupMap.values();
|
||||
}
|
||||
|
||||
|
||||
|
||||
DetailData::AttributeParameterLookup::AttributeParameterLookup()
|
||||
: LookupBase(QStringLiteral("AttributeParameterLookup"))
|
||||
{
|
||||
}
|
||||
|
||||
void DetailData::AttributeParameterLookup::addParameter(const QString &attributeType, const ParameterMap ¶meterMap)
|
||||
{
|
||||
if (!parameterMap.count())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "addParameter: parameter map is empty!";
|
||||
return;
|
||||
}
|
||||
|
||||
m_attributeParameterMap.insert(attributeType, parameterMap);
|
||||
}
|
||||
|
||||
DetailData::AttributeParameterLookup::ParameterMap DetailData::AttributeParameterLookup::getParameterMap(const QString &attributeType) const
|
||||
{
|
||||
return m_attributeParameterMap.value(attributeType);
|
||||
}
|
||||
|
||||
QVariant DetailData::AttributeParameterLookup::getParameterValue(const QString &attributeType, const int parameterType) const
|
||||
{
|
||||
const ParameterMap &pm = getParameterMap(attributeType);
|
||||
|
||||
auto pmci = pm.constFind(parameterType);
|
||||
|
||||
if (pmci == pm.constEnd())
|
||||
return QVariant();
|
||||
|
||||
return *pmci;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DetailData::AttributeUITypeLookup::AttributeUITypeLookup()
|
||||
: LookupBase(QStringLiteral("AttributeUITypeLookup"))
|
||||
{
|
||||
}
|
||||
|
||||
void DetailData::AttributeUITypeLookup::addUITypeToAttribute(const QString &attributeType, const int uiType)
|
||||
{
|
||||
m_attributeUITypeLookupMap.insert(attributeType, uiType);
|
||||
}
|
||||
|
||||
int DetailData::AttributeUITypeLookup::getUIType(const QString &attributeType) const
|
||||
{
|
||||
return m_attributeUITypeLookupMap.value(attributeType, -1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DetailData::AttributeInterpreterLookup::AttributeInterpreterLookup()
|
||||
: LookupBase(QStringLiteral("AttributeInterpreterLookup"))
|
||||
{
|
||||
}
|
||||
|
||||
void DetailData::AttributeInterpreterLookup::addInterpreterTypeToAttribute(const QString &attributeType, const int interpreterType)
|
||||
{
|
||||
m_attributeInterpreterLookupMap.insert(attributeType, interpreterType);
|
||||
}
|
||||
|
||||
int DetailData::AttributeInterpreterLookup::getInterpreterType(const QString &attributeType) const
|
||||
{
|
||||
return m_attributeInterpreterLookupMap.value(attributeType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DetailData::AttributeValueLookup::AttributeValueLookup()
|
||||
: LookupBase(QStringLiteral("AttributeValueLookup"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DetailData::AttributeValueLookup::removeValueFromAttributeValueMap(const QString &attributeType, const int valueKey)
|
||||
{
|
||||
auto attributeTypeValueMapIt = m_attributeTypeValueMap.find(attributeType);
|
||||
|
||||
if (attributeTypeValueMapIt == m_attributeTypeValueMap.end())
|
||||
return;
|
||||
|
||||
AttributeValueMap ¤tAttributeValueMap = *attributeTypeValueMapIt;
|
||||
currentAttributeValueMap.remove(valueKey);
|
||||
}
|
||||
|
||||
|
||||
void DetailData::AttributeValueLookup::addValueToAttributeValueMap(const QString &attributeType, const int valueKey, const QString &valueValue)
|
||||
{
|
||||
AttributeValueMap &avm = m_attributeTypeValueMap[attributeType];
|
||||
avm.insert(valueKey, valueValue);
|
||||
}
|
||||
|
||||
|
||||
void DetailData::AttributeValueLookup::addValuesToAttributeValueMap(const QString &attributeType, const AttributeValueMap &avm)
|
||||
{
|
||||
AttributeValueMap &thisAvm = m_attributeTypeValueMap[attributeType];
|
||||
for (auto i = avm.constBegin(); i != avm.constEnd(); ++i)
|
||||
{
|
||||
thisAvm.insert(i.key(), i.value());
|
||||
}
|
||||
}
|
||||
|
||||
AttributeValueMap DetailData::AttributeValueLookup::getAttributeValueMap(const QString &attributeType) const
|
||||
{
|
||||
return m_attributeTypeValueMap.value(attributeType);
|
||||
}
|
||||
|
||||
QString DetailData::AttributeValueLookup::getValueStringFromValueId(const QString &attributeType, const int attributeValueId, const QString& defaultValue) const
|
||||
{
|
||||
return getAttributeValueMap(attributeType).value(attributeValueId, defaultValue);
|
||||
}
|
||||
|
||||
void DetailData::AttributeValueLookup::clear()
|
||||
{
|
||||
m_attributeTypeValueMap.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
DetailData::AttributeRedirectionLookup::AttributeRedirectionLookup()
|
||||
: LookupBase(QStringLiteral("AttributeRedirectionLookup"))
|
||||
{
|
||||
}
|
||||
|
||||
void DetailData::AttributeRedirectionLookup::addRedirection(const QString &attributeType, const QString &redirectTo)
|
||||
{
|
||||
m_attributeRedirectionMap.insert(attributeType, redirectTo);
|
||||
}
|
||||
|
||||
QString DetailData::AttributeRedirectionLookup::getRedirection(const QString &attributeType) const
|
||||
{
|
||||
auto it = m_attributeRedirectionMap.find(attributeType);
|
||||
if (it == m_attributeRedirectionMap.end())
|
||||
return attributeType;
|
||||
return it.value();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Executable
+332
@@ -0,0 +1,332 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <LtsUtilsCore/data_modification_enum.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
#include <Services/ProjectDataManagement/pdm_enums.hpp>
|
||||
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
|
||||
#include "attribute_value_lookup.h"
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
namespace LtsTimelineClassic
|
||||
{
|
||||
class Event;
|
||||
}
|
||||
namespace LtsWidgets
|
||||
{
|
||||
class LtsDateTimeEdit;
|
||||
}
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
constexpr int markerTypeId = 999999;
|
||||
|
||||
class DetailData : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class RequestResult
|
||||
{
|
||||
Error = 0,
|
||||
Okay = 1,
|
||||
InvalidAttributeType,
|
||||
NoValueTranslationForAttribute,
|
||||
NoUiTypeForAttribute,
|
||||
InvalidAttributeTypeJson,
|
||||
JsonCorrupted
|
||||
};
|
||||
|
||||
struct GetDetailDataForAttributeResult
|
||||
{
|
||||
QString attributeType;
|
||||
QString attributeValue;
|
||||
|
||||
QString attributeTypeId;
|
||||
int attributeValueId = 0;
|
||||
RequestResult requestResult = RequestResult::Error;
|
||||
};
|
||||
|
||||
using GetDetailDataResultList = QVector<GetDetailDataForAttributeResult>;
|
||||
|
||||
enum AttributeUITypes
|
||||
{
|
||||
ATTRIBUTE_UI_TYPE_TIME_RANGE_WIDGET = 0,
|
||||
ATTRIBUTE_UI_TYPE_DEFAULT_RANGE_WIDGET,
|
||||
ATTRIBUTE_UI_TYPE_AREA_RANGE_WIDGET,
|
||||
ATTRIBUTE_UI_TYPE_COMBO_BOX,
|
||||
ATTRIBUTE_UI_TYPE_CHECKBOX,
|
||||
ATTRIBUTE_UI_TYPE_RAD_RANGE_WIDGET
|
||||
};
|
||||
|
||||
enum UIParameterType
|
||||
{
|
||||
UI_PARAM_TYPE_N1,
|
||||
UI_PARAM_TYPE_N2,
|
||||
UI_PARAM_TYPE_O1,
|
||||
UI_PARAM_TYPE_O2,
|
||||
UI_PARAM_TYPE_RAD,
|
||||
|
||||
UI_PARAM_TYPE_MIN,
|
||||
UI_PARAM_TYPE_MAX,
|
||||
UI_PARAM_TYPE_PREFIX,
|
||||
UI_PARAM_TYPE_SUFFIX
|
||||
};
|
||||
|
||||
enum InterpreterTypes
|
||||
{
|
||||
INTERPRETER_TYPE_NONE = 0,
|
||||
|
||||
INTERPRETER_TYPE_RANGE,
|
||||
INTERPRETER_TYPE_AREA,
|
||||
INTERPRETER_TYPE_ID_COMPARE,
|
||||
INTERPRETER_TYPE_STR_COMPARE,
|
||||
INTERPRETER_TYPE_POSITION,
|
||||
INTERPRETER_TYPE_TIME,
|
||||
INTERPRETER_TYPE_DURATION,
|
||||
INTERPRETER_TYPE_RAD
|
||||
};
|
||||
|
||||
|
||||
explicit DetailData(LtsSession::LtsSession *session, QObject *parent = nullptr);
|
||||
|
||||
void populate();
|
||||
GetDetailDataResultList getDetailData(const LtsTimelineClassic::Event *event);
|
||||
GetDetailDataForAttributeResult getDetailDataForAttribute(const LtsTimelineClassic::Event *event, const QString &attributeType);
|
||||
void createRetrieveCurrentTimeCallback(LtsWidgets::LtsDateTimeEdit *dateTimeEdit);
|
||||
LtsSession::LtsSession *session() { return m_session; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void addRedirectedAttributeType(const QString &newAttributeTypeId, const QString &attributeText, const QString &redirectToAttributeTypeId);
|
||||
void addAttributeType(const QString &attributeTypeId, const QString &attributeText, const int uiTypeId = ATTRIBUTE_UI_TYPE_COMBO_BOX, const int interpreterTypeId = INTERPRETER_TYPE_ID_COMPARE);
|
||||
|
||||
void addAttributeTypeWithYesAndNo(const QString &attributeTypeId, const QString &attributeText)
|
||||
{
|
||||
addAttributeType(attributeTypeId, attributeText, ATTRIBUTE_UI_TYPE_CHECKBOX);
|
||||
attributeValueLookup.addValueToAttributeValueMap(attributeTypeId, 0, tr("No"));
|
||||
attributeValueLookup.addValueToAttributeValueMap(attributeTypeId, 1, tr("Yes"));
|
||||
}
|
||||
|
||||
template <typename AttributeEnumType>
|
||||
void addAttributeValue(const QString &attributeTypeId, const AttributeEnumType &attributeEnum)
|
||||
{
|
||||
|
||||
attributeValueLookup.addValueToAttributeValueMap(attributeTypeId, (int)attributeEnum, toString(attributeEnum));
|
||||
}
|
||||
|
||||
void addEventType(int eventTypeId, const QString &eventTypeString);
|
||||
void addEventType(const ProjectDataManagement::EventType &eventType);
|
||||
|
||||
GetDetailDataForAttributeResult getDetailDataForAttribute(const QString &attributeType, const QJsonValue &attributeValueJson);
|
||||
|
||||
LtsSession::LtsSession *m_session;
|
||||
bool __already_populated__;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
public:
|
||||
|
||||
class LookupBase
|
||||
{
|
||||
public:
|
||||
explicit LookupBase(const QString &lookupClassName);
|
||||
|
||||
protected:
|
||||
QString m_lookupClassName;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
|
||||
class EventTypeLookup : public LookupBase
|
||||
{
|
||||
public:
|
||||
using EventTypeMap = QMap<int , QString >;
|
||||
|
||||
EventTypeLookup();
|
||||
|
||||
void addEventType(const int key, const QString &value);
|
||||
int getEventType(const QString &eventText) const;
|
||||
QString getEventText(const int eventType) const;
|
||||
QStringList getEventTexts() const;
|
||||
bool isEventExists(const int eventType) const;
|
||||
|
||||
private:
|
||||
EventTypeMap m_eventTypeMap;
|
||||
};
|
||||
EventTypeLookup eventTypeLookup;
|
||||
|
||||
|
||||
class AttributeTypeLookup : public LookupBase
|
||||
{
|
||||
public:
|
||||
using AttributeTypeLookupMap = QMap<QString , QString >;
|
||||
using AttributeTypeList = QList<QString>;
|
||||
using AttributeTextList = QStringList;
|
||||
|
||||
AttributeTypeLookup();
|
||||
|
||||
void addAttributeText(const QString &attributeType, const QString &attributeText);
|
||||
QString getAttributeType(const QString &attributeText) const;
|
||||
AttributeTypeList getAttributeTypes() const;
|
||||
QString getAttributeText(const QString &attributeType, const QString &defaultReturnValue = QString()) const;
|
||||
AttributeTextList getAttributeTexts() const;
|
||||
|
||||
private:
|
||||
AttributeTypeLookupMap m_attributeTypeLookupMap;
|
||||
};
|
||||
AttributeTypeLookup attributeTypeLookup;
|
||||
|
||||
|
||||
class AttributeEventLookup : public LookupBase
|
||||
{
|
||||
public:
|
||||
using AttributeEventLookupMap = QMap<int , QList<QString> >;
|
||||
using AttributeList = QList<QString>;
|
||||
|
||||
AttributeEventLookup();
|
||||
|
||||
void addAttributesToEvent(const int eventType, const AttributeList &attributeTypeList);
|
||||
void addAttributesToEvent(const ProjectDataManagement::EventType &eventType, const AttributeList &attributeTypeList);
|
||||
bool isAttributeInEvent(const int eventType, const QString &attributeType);
|
||||
AttributeList getEventsAttributeList(const int eventType) const;
|
||||
|
||||
private:
|
||||
AttributeEventLookupMap m_attributeEventLookupMap;
|
||||
};
|
||||
AttributeEventLookup attributeEventLookup;
|
||||
|
||||
|
||||
class AttributeParameterLookup : public LookupBase
|
||||
{
|
||||
public:
|
||||
using ParameterMap = QMap<int, QVariant>;
|
||||
using AttributeParameterMap = QHash<QString, ParameterMap>;
|
||||
|
||||
AttributeParameterLookup();
|
||||
|
||||
void addParameter(const QString &attributeType, const ParameterMap ¶meterMap);
|
||||
ParameterMap getParameterMap(const QString &attributeType) const;
|
||||
QVariant getParameterValue(const QString &attributeType, const int parameterType) const;
|
||||
|
||||
private:
|
||||
AttributeParameterMap m_attributeParameterMap;
|
||||
};
|
||||
AttributeParameterLookup attributeParameterLookup;
|
||||
|
||||
|
||||
class AttributeUITypeLookup : public LookupBase
|
||||
{
|
||||
public:
|
||||
using AttributeUITypeLookupMap = QHash<QString, int>;
|
||||
|
||||
AttributeUITypeLookup();
|
||||
|
||||
void addUITypeToAttribute(const QString &attributeType, const int uiType);
|
||||
int getUIType(const QString &attributeType) const;
|
||||
|
||||
private:
|
||||
AttributeUITypeLookupMap m_attributeUITypeLookupMap;
|
||||
};
|
||||
AttributeUITypeLookup attributeUITypeLookup;
|
||||
|
||||
|
||||
class AttributeInterpreterLookup : public LookupBase
|
||||
{
|
||||
public:
|
||||
using AttributeInterpreterLookupMap = QHash<QString, int>;
|
||||
|
||||
AttributeInterpreterLookup();
|
||||
|
||||
void addInterpreterTypeToAttribute(const QString &attributeType, const int interpreterType);
|
||||
int getInterpreterType(const QString &attributeType) const;
|
||||
|
||||
private:
|
||||
AttributeInterpreterLookupMap m_attributeInterpreterLookupMap;
|
||||
};
|
||||
AttributeInterpreterLookup attributeInterpreterLookup;
|
||||
|
||||
|
||||
class AttributeValueLookup : public LookupBase
|
||||
{
|
||||
public:
|
||||
AttributeValueLookup();
|
||||
|
||||
void addValueToAttributeValueMap(const QString &attributeType, const int valueKey, const QString &valueValue );
|
||||
void removeValueFromAttributeValueMap(const QString &attributeType, const int valueKey);
|
||||
void addValuesToAttributeValueMap(const QString &attributeType, const AttributeValueMap &avm);
|
||||
void clear();
|
||||
|
||||
AttributeValueMap getAttributeValueMap(const QString &attributeType) const;
|
||||
QString getValueStringFromValueId(const QString &attributeType, const int attributeValueId, const QString &defaultValue = QString()) const;
|
||||
|
||||
private:
|
||||
AtributeValueLookupMap m_attributeTypeValueMap;
|
||||
};
|
||||
AttributeValueLookup attributeValueLookup;
|
||||
|
||||
class AttributeValueLookupDtc : public LookupBase
|
||||
{
|
||||
public:
|
||||
AttributeValueLookupDtc() : LookupBase(QStringLiteral("AttributeValueLookupDtc")) {}
|
||||
~AttributeValueLookupDtc() { qDeleteAll(m_provider); }
|
||||
|
||||
|
||||
void addHandlerForDtc(const QString &attributeType, AttributeValueLookupProvider *provider)
|
||||
{
|
||||
auto &p = m_provider[attributeType];
|
||||
delete p;
|
||||
p = provider;
|
||||
}
|
||||
AttributeValueMap getAttributeValueMap(int eventType, const QString &attributeType) const
|
||||
{
|
||||
const auto provider = m_provider.value(attributeType);
|
||||
if (!provider)
|
||||
return {};
|
||||
return provider->getAttributeValueMap(eventType);
|
||||
}
|
||||
QString getValueStringFromValueId(const QString &attributeType, int attributeValueId) const
|
||||
{
|
||||
const auto provider = m_provider.value(attributeType);
|
||||
if (!provider)
|
||||
return {};
|
||||
return provider->getValueStringFromValueId(attributeValueId);
|
||||
}
|
||||
private:
|
||||
QHash<QString, AttributeValueLookupProvider*> m_provider;
|
||||
};
|
||||
AttributeValueLookupDtc m_attributeValueLookupDtc;
|
||||
AttributeValueMap operatorsForEventType(int eventType) const;
|
||||
QString operatorNameFromId(int id) const;
|
||||
|
||||
class AttributeRedirectionLookup : public LookupBase
|
||||
{
|
||||
public:
|
||||
using AttributeRedirectionMap = QHash<QString, QString>;
|
||||
|
||||
explicit AttributeRedirectionLookup();
|
||||
|
||||
void addRedirection(const QString &attributeType, const QString &redirectTo);
|
||||
QString getRedirection(const QString &attributeType) const;
|
||||
|
||||
private:
|
||||
AttributeRedirectionMap m_attributeRedirectionMap;
|
||||
};
|
||||
AttributeRedirectionLookup attributeRedirectionLookup;
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+200
@@ -0,0 +1,200 @@
|
||||
#include "excon_filter.h"
|
||||
#include "detail_data.h"
|
||||
#include "EventFilter/interpreter/FilterWorker.h"
|
||||
#include "EventFilter/interpreter/FilterEquationFunctions.h"
|
||||
|
||||
#include <LtsTimelineClassic/EventList.h>
|
||||
#include <LtsTimelineClassic/Event.h>
|
||||
#include <ProjectDataManagement/pdm_enums.hpp>
|
||||
#include "logger.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
|
||||
static LtsTimelineClassic::EventList applyFilter(DetailData *detailData,
|
||||
const LtsTimelineClassic::EventList &eventList,
|
||||
const ModelFilterList &modelFilterList,
|
||||
bool simulation)
|
||||
{
|
||||
NGL::INGLLogger &logger(getLogger("ExconFilter"));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LtsTimelineClassic::EventList visibleEvents;
|
||||
|
||||
bool resetFilterOnly = false;
|
||||
|
||||
if (!modelFilterList.count())
|
||||
{
|
||||
DEBUG_LOG(logger) << "applyFilter: Model Filter List is EMPTY";
|
||||
|
||||
if (simulation)
|
||||
return visibleEvents;
|
||||
|
||||
resetFilterOnly = true;
|
||||
}
|
||||
|
||||
visibleEvents = eventList;
|
||||
|
||||
|
||||
QSet<int> mentionedEventTypes;
|
||||
mentionedEventTypes.insert(markerTypeId);
|
||||
|
||||
for (const FilterWorker::ModelFilter &mf : modelFilterList)
|
||||
{
|
||||
if (mf.active)
|
||||
mentionedEventTypes.insert(mf.eventType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool showAllEvents = false;
|
||||
|
||||
if (mentionedEventTypes.count() == 1 && mentionedEventTypes.contains(0 ))
|
||||
showAllEvents = true;
|
||||
|
||||
|
||||
|
||||
for (LtsTimelineClassic::Event *event : eventList)
|
||||
{
|
||||
if (!event)
|
||||
{
|
||||
WARNING_LOG(logger) << "applyFilter: Erroneous event!";
|
||||
continue;
|
||||
}
|
||||
|
||||
int eventType = event->typeId();
|
||||
|
||||
|
||||
if (resetFilterOnly )
|
||||
{
|
||||
if (!simulation)
|
||||
event->show();
|
||||
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
bool eventVisible = true;
|
||||
|
||||
|
||||
if (!showAllEvents && !mentionedEventTypes.contains(eventType))
|
||||
eventVisible = false;
|
||||
|
||||
if (!eventVisible )
|
||||
{
|
||||
if (!simulation)
|
||||
event->hide();
|
||||
|
||||
visibleEvents.removeAll(event);
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto eventsAttributeList = detailData->attributeEventLookup.getEventsAttributeList(eventType);
|
||||
|
||||
|
||||
for (const QString &attributeType : eventsAttributeList)
|
||||
{
|
||||
QString concreteAttributeType = detailData->attributeRedirectionLookup.getRedirection(attributeType);
|
||||
bool visibleByAttribute = false;
|
||||
bool attributeTypeMentioned = false;
|
||||
|
||||
|
||||
|
||||
for (const FilterWorker::ModelFilter &mf : modelFilterList)
|
||||
{
|
||||
if (mf.eventType == eventType || mf.eventType == 0 )
|
||||
{
|
||||
if (mf.attributeType == concreteAttributeType && mf.active)
|
||||
{
|
||||
attributeTypeMentioned = true;
|
||||
|
||||
DetailData::GetDetailDataForAttributeResult result = detailData->getDetailDataForAttribute(event, attributeType);
|
||||
if (result.requestResult != DetailData::RequestResult::Okay)
|
||||
result = detailData->getDetailDataForAttribute(event, concreteAttributeType);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (result.requestResult != DetailData::RequestResult::Okay)
|
||||
{
|
||||
WARNING_LOG(logger) << "applyFilter: result.requestResult != DetailData::OKAY -" << (int)result.requestResult;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
visibleByAttribute = FilterEquationFunctions::checkValue(detailData, concreteAttributeType, result.attributeValueId, mf.attributeValue);
|
||||
|
||||
if (visibleByAttribute)
|
||||
break;
|
||||
|
||||
#ifdef DEBUG
|
||||
DEBUG_LOG(logger)
|
||||
<< "\r\napplyFilter:\r\n"
|
||||
<< "Evnt Type (" << eventType << ")\r\n"
|
||||
<< "Attr Type (" << attributeType << ")\r\n"
|
||||
<< "Evnt Val (" << result.resultValue << ")\r\n"
|
||||
<< "Fltr Val (" << mf.attributeValue << ")\r\n"
|
||||
<< "Evnt SHOW (" << eventVisible << ")\r\n"
|
||||
<< "Attr SHOW (" << visibleByAttribute << ")\r\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (attributeTypeMentioned && !visibleByAttribute)
|
||||
{
|
||||
eventVisible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!simulation)
|
||||
event->setVisible(eventVisible);
|
||||
|
||||
if (!eventVisible)
|
||||
visibleEvents.removeAll(event);
|
||||
}
|
||||
|
||||
DEBUG_LOG(logger) << "applyFilter: Visible Events after applying filter:" << visibleEvents.count();
|
||||
|
||||
return visibleEvents;
|
||||
}
|
||||
|
||||
|
||||
LtsTimelineClassic::EventList setFilter(DetailData *detailData,
|
||||
const LtsTimelineClassic::EventList &eventListToFilter,
|
||||
const QJsonArray &filter,
|
||||
QWidget *parentWidget,
|
||||
bool simulation,
|
||||
bool handleResult)
|
||||
{
|
||||
|
||||
|
||||
|
||||
LtsTimelineClassic::EventList visibleEvents;
|
||||
|
||||
FilterWorker::GetModelFilterListResult result = FilterWorker::getModelFilterList(detailData, filter, true );
|
||||
ModelFilterList modelFilterList = result.result;
|
||||
if (handleResult)
|
||||
FilterWorker::getInstance()->handleResultValues(result.resultValueList, parentWidget);
|
||||
|
||||
visibleEvents = applyFilter(detailData, eventListToFilter, modelFilterList, simulation);
|
||||
|
||||
|
||||
return visibleEvents;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <LtsTimelineClassic/EventList.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
|
||||
class QWidget;
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
|
||||
LtsTimelineClassic::EventList setFilter(DetailData *detailData,
|
||||
const LtsTimelineClassic::EventList &eventListToFilter,
|
||||
const QJsonArray &filter,
|
||||
QWidget *parentWidget,
|
||||
bool simulation = false,
|
||||
bool handleResult = true);
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "Plugins.Timeline.Gui.";
|
||||
std::string loggerName;
|
||||
const size_t len = strlen(name);
|
||||
loggerName.reserve(sizeof(ns) + len);
|
||||
loggerName.append(ns, sizeof(ns) - 1);
|
||||
loggerName.append(name, len);
|
||||
|
||||
try
|
||||
{
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
|
||||
getNGLLogger(loggerName);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
using LOGGER_T = NGL::INGLLogger &;
|
||||
|
||||
LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
|
||||
|
||||
|
||||
#include "tln_cache_dialog.h"
|
||||
#include "ui_tln_cache_dialog.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
TimelineCacheDialog::TimelineCacheDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::TimelineCacheDialog)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->pbUncache, &QPushButton::clicked,
|
||||
this, [this]()
|
||||
{
|
||||
bool k = false;
|
||||
int index = m_ui->twCaches->item(m_ui->twCaches->selectionModel()->currentIndex().row(), 0)->text().toInt(&k);
|
||||
|
||||
if (!k)
|
||||
return;
|
||||
|
||||
emit signalUncache(index);
|
||||
close();
|
||||
});
|
||||
|
||||
|
||||
connect(m_ui->pbDelete, &QPushButton::clicked,
|
||||
this, [this]()
|
||||
{
|
||||
bool k = false;
|
||||
int index = m_ui->twCaches->item(m_ui->twCaches->selectionModel()->currentIndex().row(), 0)->text().toInt(&k);
|
||||
|
||||
if (!k)
|
||||
return;
|
||||
|
||||
emit signalDelete(index);
|
||||
close();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
TimelineCacheDialog::~TimelineCacheDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void TimelineCacheDialog::addCache(const CacheRange &cr, const QString &indexString)
|
||||
{
|
||||
int rowCount = m_ui->twCaches->rowCount();
|
||||
m_ui->twCaches->insertRow(rowCount);
|
||||
int row = m_ui->twCaches->rowCount() - 1;
|
||||
int c = 0;
|
||||
|
||||
m_ui->twCaches->setItem(row, c++ , new QTableWidgetItem(indexString));
|
||||
|
||||
QString hash(QStringLiteral("<%1:%2:%3>").arg(cr.start).arg(cr.end).arg(cr.events.count()));
|
||||
m_ui->twCaches->setItem(row, c++, new QTableWidgetItem(QString::number(qHash(hash), 16)));
|
||||
|
||||
m_ui->twCaches->setItem(row, c++, new QTableWidgetItem(QStringLiteral("%1 (%2)").arg(QDateTime::fromMSecsSinceEpoch(cr.start).toString()).arg(cr.start)));
|
||||
m_ui->twCaches->setItem(row, c++, new QTableWidgetItem(QStringLiteral("%1 (%2)").arg(QDateTime::fromMSecsSinceEpoch(cr.end).toString()).arg(cr.end)));
|
||||
m_ui->twCaches->setItem(row, c++, new QTableWidgetItem(QString::number(cr.events.count())));
|
||||
}
|
||||
|
||||
|
||||
bool TimelineCacheDialog::init(const QVector<QPair<qint64, CacheRange>> &cachedRanges, const CacheRange &liveCache)
|
||||
{
|
||||
m_ui->twCaches->setRowCount(0);
|
||||
|
||||
int eventCount = 0;
|
||||
{
|
||||
int i = 0;
|
||||
for (auto it = cachedRanges.constBegin(); it != cachedRanges.constEnd(); ++it)
|
||||
{
|
||||
const CacheRange &cr = it->second;
|
||||
|
||||
eventCount += cr.events.count();
|
||||
addCache(cr, QString::number(i));
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
addCache(liveCache, QStringLiteral("live"));
|
||||
m_ui->lblEventCount->setText(QString::number(eventCount));
|
||||
|
||||
|
||||
for (int i = 0; i < m_ui->twCaches->columnCount(); i++)
|
||||
{
|
||||
m_ui->twCaches->resizeColumnToContents(i);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tln_dialog_model.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class TimelineCacheDialog;
|
||||
}
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class TimelineCacheDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TimelineCacheDialog(QWidget *parent = nullptr);
|
||||
~TimelineCacheDialog();
|
||||
|
||||
bool init(const QVector<QPair<qint64, CacheRange> > &cachedRanges, const CacheRange &liveCache);
|
||||
|
||||
private:
|
||||
void addCache(const CacheRange &cache, const QString &indexString);
|
||||
|
||||
Ui::TimelineCacheDialog *m_ui;
|
||||
|
||||
signals:
|
||||
void signalUncache(int index);
|
||||
void signalDelete(int index);
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+134
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TimelineCacheDialog</class>
|
||||
<widget class="QWidget" name="TimelineCacheDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>846</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Cache View</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Event count:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblEventCount">
|
||||
<property name="text">
|
||||
<string notr="true">-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Never uncache events from a stale cache vector !</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="twCaches">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>100</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>idx</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>hash</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>start</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>end</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>event count</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbUncache">
|
||||
<property name="text">
|
||||
<string>uncache selected</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbDelete">
|
||||
<property name="text">
|
||||
<string>delete selected</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Executable
+1078
File diff suppressed because it is too large.
Load diff
Executable
+167
@@ -0,0 +1,167 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tln_view_gui_plugin.h"
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <LtsTimelineClassic/EventList.h>
|
||||
#include <Plugins/Timeline/tln_data_plugin_interface.h>
|
||||
#include <Plugins/MarkerManagement/mrk_gui_plugin_interface.h>
|
||||
#include <Plugins/SituationReplayManagement/srm_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
||||
|
||||
|
||||
#include <Plugins/SituationReplay/srp_gui_plugin_interface.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class StreamNameMapping;
|
||||
}
|
||||
|
||||
namespace LtsTimelineClassic
|
||||
{
|
||||
class EventGraphic;
|
||||
class Event;
|
||||
}
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class TimelineViewDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace LtsPluginManager
|
||||
{
|
||||
class LtsPluginManager;
|
||||
}
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class FilterWindow;
|
||||
class DetailData;
|
||||
class DDSTimelineModel;
|
||||
class EventListDialog;
|
||||
class TimelineLegendDialog;
|
||||
|
||||
|
||||
class TimelineViewDialog : public LtsWidgets::LtsDialog
|
||||
, protected SituationReplayManagement::Interface::Ftc::ReplayPartitionCreateReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TimelineViewDialog(const QString &menuGroup, const LtsWidgets::ButtonCombination &buttonCombo, bool isMain, QWidget *parent = nullptr);
|
||||
~TimelineViewDialog();
|
||||
|
||||
bool init(const std::shared_ptr<TimeLineManagement::ForeignDataInterface> &eemForeign,
|
||||
const std::shared_ptr<MarkerManagement::Interface::Dtc> &mrkDtc,
|
||||
const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc,
|
||||
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmIfc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> &ppmInfoIfc,
|
||||
const std::shared_ptr<AudioVideoManagement::ForeignMenuEditGuiInterface> &avmIfc,
|
||||
const std::shared_ptr<MarkerManagement::ForeignGuiInterface> &mrkIfc,
|
||||
const std::shared_ptr<SituationReplayManagement::ForeignDataInterface> &srmDataIfc,
|
||||
const std::shared_ptr<Core::Interface::Dtc> &coreDtc,
|
||||
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
const std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> &fltParticipantIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignAesGuiInterface> &fltAesIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> &fltBuildingComponentIfc,
|
||||
LtsSession::LtsSession *session,
|
||||
AudioVideoManagement::StreamNameMapping *streamNameMapping);
|
||||
|
||||
private slots:
|
||||
void showDetailsAction(LtsTimelineClassic::EventGraphic *eg, int action);
|
||||
void showDetails(const LtsTimelineClassic::EventList &eventList);
|
||||
void slotApplyFilter(const QJsonArray &filter);
|
||||
void slotShowEventDetails(const LtsTimelineClassic::Event *event);
|
||||
void slotShowEvents(const QJsonArray &filter);
|
||||
void slotWaitForReady();
|
||||
void slotShowFiltersDialog();
|
||||
void slotShowLegend();
|
||||
void slotStartReplaySituation();
|
||||
void updateRange(bool initial = false);
|
||||
void slotLoading();
|
||||
void slotLoadingDone();
|
||||
void slotSpanChanged();
|
||||
void slotEventTypesChanged(QSet<int> activeEventTypeIds);
|
||||
void loadAllEvents();
|
||||
void slotDebugCreateFakeEvent();
|
||||
|
||||
signals:
|
||||
void signalWaitForReady();
|
||||
void signalInitEventList();
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void onReplayPartitionCreateReply(const Core::FunctionReplyObject &reply) override { m_requestHelper->requestReply(reply); }
|
||||
qint64 currentSpanTime() const;
|
||||
|
||||
|
||||
std::shared_ptr<Core::Interface::Dtc> m_coreDtc;
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
std::shared_ptr<MarkerManagement::Interface::Dtc> m_mrkDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
|
||||
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmIfc;
|
||||
std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> m_ppmInfoIfc;
|
||||
std::shared_ptr<AudioVideoManagement::ForeignMenuEditGuiInterface> m_avmIfc;
|
||||
std::shared_ptr<MarkerManagement::ForeignGuiInterface> m_mrkIfc;
|
||||
std::shared_ptr<SituationReplayManagement::ForeignDataInterface> m_srmDataIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> m_fltAesIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> m_fltBuildingComponentIfc;
|
||||
|
||||
Ui::TimelineViewDialog *m_ui;
|
||||
QString m_menuGroup;
|
||||
DDSTimelineModel *m_model;
|
||||
DetailData *m_detailData;
|
||||
FilterWindow *m_filterWindow;
|
||||
QPointer<EventListDialog> m_eventListDialog;
|
||||
QPointer<EventListDialog> m_allEventsListDialog;
|
||||
LtsSession::LtsSession *m_session;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
QPointer<LtsPluginManager::LtsPluginManager> m_replayApp;
|
||||
QPointer<LtsSession::LtsSession> m_replayAppSession;
|
||||
AudioVideoManagement::StreamNameMapping *m_streamNameMapping;
|
||||
bool m_rangeChanged;
|
||||
QJsonArray m_filter;
|
||||
int m_loadingCount;
|
||||
bool m_armed;
|
||||
qint64 m_exerciseStart;
|
||||
TimelineLegendDialog *m_legendDialog;
|
||||
QTimer *m_armTimer;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
void setCustomSpan();
|
||||
void calculateAndSetRange();
|
||||
void setRange(qint64 min, qint64 max);
|
||||
void updateActiveEventTypesByFilters();
|
||||
void updateFiltersByActiveEventTypes();
|
||||
void applyFilter(const QJsonArray &filter, bool doUpdateActiveEventTypes = true, bool reloadFilterWindow = false);
|
||||
void rangeChanged();
|
||||
void setTimelineUsable(bool usable = true);
|
||||
void aboutToClose() override;
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+215
@@ -0,0 +1,215 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TimelineViewDialog</class>
|
||||
<widget class="QWidget" name="TimelineViewDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1401</width>
|
||||
<height>519</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Timeline View</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Time span:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbLive">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Live</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblStartTime">
|
||||
<property name="text">
|
||||
<string>Start:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbStartTime">
|
||||
<property name="text">
|
||||
<string notr="true">-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollBar" name="sbSpan">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>3600</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>3600</number>
|
||||
</property>
|
||||
<property name="tracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblEndTime">
|
||||
<property name="text">
|
||||
<string>End:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbEndTime">
|
||||
<property name="text">
|
||||
<string notr="true">-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblNoEventsSelected">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" color:#ff5656;">Please create at least one filter of any event type to see events.</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsTimelineClassic::TimelineWidget" name="widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="debugWidget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Cursor at </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblCursorTime">
|
||||
<property name="text">
|
||||
<string notr="true">-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbFake">
|
||||
<property name="text">
|
||||
<string notr="true">[fake]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbUpdate">
|
||||
<property name="text">
|
||||
<string notr="true">[update]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbShowCache">
|
||||
<property name="text">
|
||||
<string notr="true">[show cache]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbDebugCreateFakeEvent">
|
||||
<property name="text">
|
||||
<string notr="true">[create fake event]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsTimelineClassic::TimelineWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">LtsTimelineClassic/TimelineWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Executable
+1714
File diff suppressed because it is too large.
Load diff
Executable
+203
@@ -0,0 +1,203 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail_data.h"
|
||||
|
||||
#include <LtsTimelineClassic/AbstractTimelineModel.h>
|
||||
#include <Plugins/Timeline/tln_data_plugin_interface.h>
|
||||
#include <Plugins/MarkerManagement/mrk_data_plugin_interface.h>
|
||||
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QAbstractSocket>
|
||||
|
||||
|
||||
namespace LtsUtils
|
||||
{
|
||||
class RequestHelper;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class StreamNameMapping;
|
||||
}
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
struct CacheRange : public LtsTimelineClassic::Range
|
||||
{
|
||||
QVector<LtsTimelineClassic::Event *> events;
|
||||
bool incomplete = true;
|
||||
bool visible = false;
|
||||
};
|
||||
|
||||
|
||||
class DDSTimelineModel : public LtsTimelineClassic::AbstractTimelineModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DDSTimelineModel(QObject *parent);
|
||||
~DDSTimelineModel();
|
||||
|
||||
bool init(const std::shared_ptr<TimeLineManagement::ForeignDataInterface> &eemForeign,
|
||||
const std::shared_ptr<MarkerManagement::Interface::Dtc> &mrkDtc,
|
||||
const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
LtsSession::LtsSession *session,
|
||||
Timeline::DetailData *detailData,
|
||||
AudioVideoManagement::StreamNameMapping *streamNameMapping);
|
||||
|
||||
void applyFilter(const QJsonArray &filter);
|
||||
void setDetailData(DetailData *detailData) { m_detailData = detailData; }
|
||||
void setColorPaintFun(LtsTimelineClassic::Event::EventPaintFunc &paintFunc, QColor &color, ProjectDataManagement::EventType eventType) const;
|
||||
void setTimeRange(qint64 min, qint64 max);
|
||||
void getEvents(qint64 rangeMin, qint64 rangeMax);
|
||||
QVector<LtsTimelineClassic::Range> getKnownRanges() const;
|
||||
const QVector<QPair<qint64, CacheRange>> &cachedEvents() const { return m_cachedEvents; }
|
||||
const CacheRange &liveCache() const { return m_liveCache; }
|
||||
void forceUncache();
|
||||
void setLive(bool isLive = true);
|
||||
void setCreateFakeEvents(bool createFakeEvents = true);
|
||||
void setActiveEventTypeIds(const QSet<int> &activeEventTypeIds);
|
||||
const QSet<int> &activeEventTypeIds() const { return m_activeEventTypeIds; }
|
||||
bool hasActiveEventTypes() const { return !m_activeEventTypeIds.isEmpty(); }
|
||||
void getAllEventsOfType(const QSet<int> &eventTypeIds);
|
||||
|
||||
|
||||
private:
|
||||
qint64 currentTime() const override;
|
||||
|
||||
QStringList getPathForAvsEvents(const QString &type, const QJsonObject &obj) const;
|
||||
QStringList getPathForBuildingEvents(const QString &type, const QJsonObject &obj) const;
|
||||
QStringList getPathForAesEvents(const QString &type, const QJsonObject &obj) const;
|
||||
void addMarkerManagementMarker(const MarkerManagement::Marker &data);
|
||||
void addEventsAndFilter(const QVector<LtsTimelineClassic::Event *> &eventList);
|
||||
void addEventAndFilter(LtsTimelineClassic::Event *event);
|
||||
void deleteMarker(int uniqueId);
|
||||
void modifyMarker(const MarkerManagement::Marker &data);
|
||||
QJsonObject createMarkerDetailData(const MarkerManagement::Marker &data) const;
|
||||
LtsTimelineClassic::Event *getMarker(int uniqueId);
|
||||
void checkCache();
|
||||
void removeEvent(int eventId);
|
||||
void addCacheRange(const LtsTimelineClassic::Range &range, const QVector<LtsTimelineClassic::Event *> &cachedEvents, qint64 incompleteEnd, bool addToTimeline = true);
|
||||
bool isLive() const { return m_isLive; }
|
||||
LtsTimelineClassic::Event *createEvent(const ExerciseEventManagement::Event &data) const;
|
||||
|
||||
bool checkDetailData(const LtsTimelineClassic::Event *event) const;
|
||||
void processEventList(qint64 &highest, bool &incomplete, QVector<LtsTimelineClassic::Event *> &cachedEvents, QVector<LtsTimelineClassic::Event *> &eventList, const int initialCount = 0);
|
||||
void receivedEvents(const LtsTimelineClassic::Range &range, QVector<LtsTimelineClassic::Event *> &receivedEventsList);
|
||||
void requestEvents(const LtsTimelineClassic::Range &range);
|
||||
QVector<LtsTimelineClassic::Event *> createTestEvents(qint64 time, int count, qint64 distance, qint64 duration = 0);
|
||||
static bool isInsideCachedRange(const CacheRange &cacheRange, qint64 start, qint64 end);
|
||||
bool isCached(int eventId) const;
|
||||
void showCached(CacheRange &cacheRange);
|
||||
bool isCacheFull() const;
|
||||
|
||||
void uncache(CacheRange &cr);
|
||||
const CacheRange *getCache(int eventId) const;
|
||||
void addCacheRangeToTimeline(const CacheRange &cr);
|
||||
bool splitLowest(qint64 &rangeMin, qint64 rangeMax, qint64 &requestMin, qint64 &requestMax, const CacheRange &lowestCache) const;
|
||||
void rebuildTimelineKnownRanges();
|
||||
void _uncache(const CacheRange &cr);
|
||||
void saveAndClearLiveCache();
|
||||
const QJsonObject getDetailData(const ExerciseEventManagement::Event &event) const;
|
||||
const QJsonObject getDetailData(const QByteArray &data, int id, const ProjectDataManagement::EventType& type, qint64 startTime) const;
|
||||
|
||||
std::shared_ptr<TimeLineManagement::ForeignDataInterface> m_eemForeign;
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_dtcExm;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
|
||||
std::shared_ptr<MarkerManagement::Interface::Dtc> m_mrkDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
|
||||
QJsonArray m_filter;
|
||||
LtsSession::LtsSession *m_session;
|
||||
int64_t m_startTime;
|
||||
int64_t m_endTime;
|
||||
DetailData *m_detailData;
|
||||
AudioVideoManagement::StreamNameMapping *m_streamNameMapping;
|
||||
bool m_isLive;
|
||||
int m_cacheSize;
|
||||
int m_maxCacheRanges;
|
||||
int m_eventCount;
|
||||
|
||||
qint64 m_lastCachedEventsId;
|
||||
QVector<QPair<qint64, CacheRange>> m_cachedEvents;
|
||||
|
||||
CacheRange m_liveCache;
|
||||
bool m_createFakeEvents;
|
||||
QSet<int> m_activeEventTypeIds;
|
||||
|
||||
QVector<int> m_knownMarkerIds;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
|
||||
public slots:
|
||||
void slotAddLiveEvent(const ExerciseEventManagement::Event &event);
|
||||
|
||||
|
||||
private slots:
|
||||
|
||||
void slotMarkerChanged(const MarkerManagement::Marker &data, DataModification modType);
|
||||
void slotAddLiveEventsFake();
|
||||
void slotRequestMessageReceived(const QString &message);
|
||||
|
||||
|
||||
signals:
|
||||
void signalTooMuchEvents();
|
||||
void signalRebuildTimelineKnownRanges();
|
||||
void signalLoading();
|
||||
void signalLoadingDone();
|
||||
|
||||
};
|
||||
|
||||
|
||||
class EventRequest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EventRequest(const QUrl &url, qint64 start, qint64 end, const QSet<int> &eventTypes, int limit);
|
||||
~EventRequest() = default;
|
||||
|
||||
void append(LtsTimelineClassic::Event *newEvent) { m_eventList.push_back(newEvent); }
|
||||
const QVector<LtsTimelineClassic::Event *> &eventList() const { return m_eventList; }
|
||||
qint64 start() const { return m_start; }
|
||||
qint64 end() const { return m_end; }
|
||||
|
||||
private:
|
||||
void requestFailed(const QString &errorString);
|
||||
|
||||
qint64 m_start;
|
||||
qint64 m_end;
|
||||
QVector<LtsTimelineClassic::Event *> m_eventList;
|
||||
QTimer *m_timeoutTimer;
|
||||
|
||||
|
||||
private slots:
|
||||
void slotRequestFailed();
|
||||
void slotMessageReceived(const QString &message);
|
||||
|
||||
|
||||
signals:
|
||||
void signalRequestFailed(const QString &errorString);
|
||||
void signalMessageReceived(const QString &message);
|
||||
void signalDone();
|
||||
void signalTimeout();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+274
@@ -0,0 +1,274 @@
|
||||
#include "tln_event_list.h"
|
||||
#include "tln_event_list_columns.h"
|
||||
|
||||
#include "ui_tln_event_list.h"
|
||||
#include "ui_tln_event_list_columns.h"
|
||||
|
||||
#include "tln_event_list_model.h"
|
||||
#include "tln_show_details.h"
|
||||
|
||||
#include <Viewer/LtsDataView/lts_data_view.h>
|
||||
#include <LtsTimelineClassic/EventGraphic.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QTreeView>
|
||||
|
||||
const int MAX_EVENTS = 30;
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
EventListDialog::EventListDialog(const QString &menuGroup,
|
||||
LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmIfc,
|
||||
bool showMarkers,
|
||||
QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_ui(new Ui::EventListDialog)
|
||||
, m_columns(nullptr)
|
||||
, m_model(new EventListDialogModel(ppmDtc, pdmDtc, ismDtc, this))
|
||||
, m_detailData(nullptr)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_listEvents(false)
|
||||
, m_flmIfc(flmIfc)
|
||||
, m_session(session)
|
||||
, m_logger(getLogger("EventList"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
if (showMarkers)
|
||||
{
|
||||
m_ui->ltsDataView->setModel(m_model);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_proxyModel = new EventListDialogProxyModel(this);
|
||||
m_proxyModel->setSourceModel(m_model);
|
||||
m_ui->ltsDataView->setModel(m_proxyModel);
|
||||
}
|
||||
|
||||
connect(m_ui->ltsDataView, &LtsDataView::LtsDataView::signalDoubleClicked,
|
||||
this, &EventListDialog::slotShowSelected);
|
||||
|
||||
connect(m_ui->ltsDataView, &LtsDataView::LtsDataView::signalSelectionChanged,
|
||||
this, &EventListDialog::slotEnaDisa);
|
||||
|
||||
connect(this, &EventListDialog::signalAddNewEvents,
|
||||
m_model, &EventListDialogModel::appendEventList);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Show, this, &EventListDialog::slotShowSelected);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &EventListDialog::onPrint);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load, this, &EventListDialog::onConfigureColumns);
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
addConcealedColumns({ EventListDialogModel::Id, EventListDialogModel::AesId, EventListDialogModel::ParticipantId,
|
||||
EventListDialogModel::DamagePercentOld });
|
||||
#endif
|
||||
|
||||
setUnchangeable();
|
||||
}
|
||||
|
||||
|
||||
EventListDialog::~EventListDialog()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "~EventListDialog";
|
||||
if (m_proxyModel != nullptr)
|
||||
m_proxyModel->setInvalid();
|
||||
m_model->setInvalid();
|
||||
delete m_ui;
|
||||
delete m_columns;
|
||||
}
|
||||
|
||||
|
||||
void EventListDialog::retranslate()
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Configuration"));
|
||||
if (m_listEvents)
|
||||
translate(m_ui, QString(), false, tr("All Events"));
|
||||
else
|
||||
translate(m_ui, QString(), false, tr("%1 Events").arg(m_model->rowCount()));
|
||||
}
|
||||
|
||||
|
||||
bool EventListDialog::init(DetailData *detailData, const LtsTimelineClassic::EventList &eventList, bool listEvents)
|
||||
{
|
||||
m_detailData = detailData;
|
||||
m_listEvents = listEvents;
|
||||
|
||||
if (m_listEvents)
|
||||
m_ui->label->setVisible(false);
|
||||
|
||||
if (eventList.isEmpty())
|
||||
return false;
|
||||
|
||||
m_model->setData(eventList);
|
||||
|
||||
m_headerState = m_ui->ltsDataView->saveState();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
||||
m_ui->ltsDataView->treeView()->header()->setFirstSectionMovable(true);
|
||||
m_ui->ltsDataView->searchView()->header()->setFirstSectionMovable(true);
|
||||
#endif
|
||||
|
||||
initColumns();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void EventListDialog::addConcealedColumns(const QVector<int> &concealedColumns)
|
||||
{
|
||||
for (const int id : concealedColumns)
|
||||
{
|
||||
m_ui->ltsDataView->hideColumn(id);
|
||||
if (!m_concealedColumns.contains(id))
|
||||
m_concealedColumns += id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EventListDialog::initColumns()
|
||||
{
|
||||
const int colCount = m_model->columnCount();
|
||||
if (colCount > 0)
|
||||
{
|
||||
m_headerColumns.clear();
|
||||
QVector<ColumnInfo> columnInfos;
|
||||
columnInfos.reserve(colCount);
|
||||
const auto header = m_ui->ltsDataView->searchView()->header();
|
||||
|
||||
DEBUG_LOG(m_logger) << "concealed count: " << m_concealedColumns.length();
|
||||
for (int visualIndex = 0; visualIndex < colCount; ++visualIndex)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << visualIndex << " concealed? " << m_concealedColumns.contains(visualIndex);
|
||||
if (m_concealedColumns.contains(visualIndex))
|
||||
continue;
|
||||
|
||||
ColumnInfo ci;
|
||||
ci.logicalIndex = header->logicalIndex(visualIndex);
|
||||
ci.visualIndex = visualIndex;
|
||||
ci.size = header->sectionSize(ci.logicalIndex);
|
||||
ci.visible = !header->isSectionHidden(ci.logicalIndex);
|
||||
ci.name = m_model->headerData(ci.logicalIndex, Qt::Orientation::Horizontal, Qt::DisplayRole).toString();
|
||||
|
||||
DEBUG_LOG(m_logger) << "InitColumns: Adding column " << ci.name <<
|
||||
" with visual index = " << ci.visualIndex <<
|
||||
", logical index = " << ci.logicalIndex;
|
||||
|
||||
m_headerColumns.insert(ci.name, ci.logicalIndex);
|
||||
|
||||
columnInfos += ci;
|
||||
}
|
||||
|
||||
m_columns->deleteLater();
|
||||
m_columns = new Timeline::EventListColumns(columnInfos, m_flmIfc, this);
|
||||
|
||||
connect(m_columns, &EventListColumns::accepted,
|
||||
this, &EventListDialog::showColumns);
|
||||
|
||||
showColumns();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EventListDialog::clearModel()
|
||||
{
|
||||
m_model->clear();
|
||||
}
|
||||
|
||||
|
||||
bool EventListDialog::appendEventList(const LtsTimelineClassic::EventList &eventList)
|
||||
{
|
||||
m_model->appendEventList(eventList);
|
||||
retranslate();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void EventListDialog::slotEnaDisa()
|
||||
{
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Show, (m_ui->ltsDataView->selectedRows().size() > 0));
|
||||
}
|
||||
|
||||
|
||||
void EventListDialog::slotShowSelected()
|
||||
{
|
||||
const QModelIndexList indexList = m_ui->ltsDataView->selectedRows();
|
||||
|
||||
if (!m_listEvents && indexList.count() > MAX_EVENTS)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("You selected too many events to show (> %1). Please deselect some.").arg(MAX_EVENTS));
|
||||
return;
|
||||
}
|
||||
|
||||
for (const QModelIndex &idx : indexList)
|
||||
{
|
||||
const LtsTimelineClassic::Event *event = m_model->eventList().at(idx.row());
|
||||
if (event->uniqueId() > 0)
|
||||
emit signalShowEventDetails(event);
|
||||
}
|
||||
}
|
||||
|
||||
void EventListDialog::onPrint()
|
||||
{
|
||||
LtsPrinting::printView(m_session, this, m_ui->ltsDataView->treeView());
|
||||
}
|
||||
|
||||
void EventListDialog::onConfigureColumns()
|
||||
{
|
||||
initColumns();
|
||||
m_columns->show();
|
||||
}
|
||||
|
||||
void EventListDialog::showColumns()
|
||||
{
|
||||
if (!m_columns)
|
||||
return;
|
||||
|
||||
|
||||
const auto columnInfo = m_columns->currentColumnsState();
|
||||
|
||||
m_ui->ltsDataView->restoreState(m_headerState);
|
||||
|
||||
auto header = m_ui->ltsDataView->searchView()->header();
|
||||
for (const auto &ci : columnInfo)
|
||||
{
|
||||
int oldVisualIndex = header->visualIndex(ci.logicalIndex);
|
||||
|
||||
DEBUG_LOG(m_logger) << "ShowColumns: Column " << ci.name
|
||||
<< ", colVisible: " << ci.visible
|
||||
<< ", logical index: " << ci.logicalIndex
|
||||
<< ", old index: " << oldVisualIndex
|
||||
<< ", new index: " << ci.visualIndex;
|
||||
|
||||
if (oldVisualIndex != ci.visualIndex)
|
||||
header->moveSection(oldVisualIndex, ci.visualIndex);
|
||||
|
||||
header->setSectionHidden(ci.logicalIndex, !ci.visible);
|
||||
if (ci.visible && ci.size > 0)
|
||||
header->resizeSection(ci.logicalIndex, ci.size);
|
||||
}
|
||||
}
|
||||
|
||||
void EventListDialog::reInitEventList(const LtsTimelineClassic::EventList &eventList, qint64 startTime, qint64 endTime)
|
||||
{
|
||||
LtsTimelineClassic::EventList newEventList;
|
||||
|
||||
for (auto i = eventList.constBegin(); i != eventList.constEnd(); ++i)
|
||||
{
|
||||
LtsTimelineClassic::Event *e = (*i);
|
||||
|
||||
if (e->startTime() >= startTime && (e->startTime() + e->duration()) <= endTime)
|
||||
newEventList += e;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "reInitEventList size = " << eventList.size();
|
||||
DEBUG_LOG(m_logger) << "reInitEventList new size = " << newEventList.size();
|
||||
m_model->clear();
|
||||
m_model->setData(newEventList);
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <LtsTimelineClassic/EventList.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <ParticipantManagement/Data/ppm_data_plugin.h>
|
||||
#include <ProjectDataManagement/Data/pdm_data_plugin.h>
|
||||
#include <InfrastructureManagement/Data/ism_data_plugin.h>
|
||||
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EventListDialog;
|
||||
}
|
||||
|
||||
namespace LtsTimelineClassic
|
||||
{
|
||||
class EventGraphic;
|
||||
class Event;
|
||||
}
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class EventListDialogProxyModel;
|
||||
class EventListDialogModel;
|
||||
class DetailData;
|
||||
class EventListColumns;
|
||||
|
||||
class EventListDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EventListDialog(const QString &menuGroup, LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmIfc,
|
||||
bool showMarkers = false,
|
||||
QWidget *parent = nullptr);
|
||||
~EventListDialog();
|
||||
|
||||
bool init(DetailData *detailData, const LtsTimelineClassic::EventList &eventList, bool listEvents);
|
||||
bool appendEventList(const LtsTimelineClassic::EventList &eventList);
|
||||
void clearModel();
|
||||
void reInitEventList(const LtsTimelineClassic::EventList &eventList, qint64 startTime, qint64 endTime);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void initColumns();
|
||||
void addConcealedColumns(const QVector<int> &concealedColumns);
|
||||
|
||||
Ui::EventListDialog *m_ui;
|
||||
EventListColumns *m_columns;
|
||||
EventListDialogModel *m_model;
|
||||
DetailData *m_detailData;
|
||||
QHash<QString, int> m_headerColumns;
|
||||
QByteArray m_headerState;
|
||||
|
||||
QString m_menuGroup;
|
||||
bool m_listEvents;
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmIfc;
|
||||
LtsSession::LtsSession *m_session;
|
||||
EventListDialogProxyModel *m_proxyModel { nullptr };
|
||||
NGL::INGLLogger &m_logger;
|
||||
QVector<int> m_concealedColumns;
|
||||
|
||||
signals:
|
||||
void signalShowEventDetails(const LtsTimelineClassic::Event *event);
|
||||
void signalAddNewEvents(const QVector<LtsTimelineClassic::Event *> &eventList);
|
||||
|
||||
private slots:
|
||||
void showColumns();
|
||||
void slotShowSelected();
|
||||
void slotEnaDisa();
|
||||
void onPrint();
|
||||
void onConfigureColumns();
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EventListDialog</class>
|
||||
<widget class="QWidget" name="EventListDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>824</width>
|
||||
<height>445</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Exercise Management</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Selected event contained more than one event:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="ltsDataView">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
|
||||
|
||||
|
||||
#include "tln_event_list_columns.h"
|
||||
#include "ui_tln_event_list_columns.h"
|
||||
#include "tln_event_list_model.h"
|
||||
|
||||
#include <FileManagement/flm_translation.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QColor>
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonParseError>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
static inline QString colObjectName(int idx)
|
||||
{
|
||||
return QStringLiteral("Column_") + QString::number(idx);
|
||||
}
|
||||
|
||||
EventListColumns::EventListColumns(const QVector<ColumnInfo> &columns,
|
||||
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmIfc,
|
||||
QWidget *parent)
|
||||
: LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal )
|
||||
, m_ui(new Ui::EventListColumns)
|
||||
, m_flmIfc(flmIfc)
|
||||
, m_columns(columns)
|
||||
, m_logger(getLogger("EventListColumns"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->pbOk, &QPushButton::clicked,
|
||||
this, &EventListColumns::accept);
|
||||
connect(m_ui->pbClose, &QPushButton::clicked,
|
||||
this, &EventListColumns::reject);
|
||||
connect(m_ui->pbLoad, &QPushButton::clicked,
|
||||
this, &EventListColumns::load);
|
||||
connect(m_ui->pbSave, &QPushButton::clicked,
|
||||
this, &EventListColumns::save);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
EventListColumns::~EventListColumns()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
QVector<ColumnInfo> EventListColumns::currentColumnsState() const
|
||||
{
|
||||
const auto children = m_ui->itemLayoutWidget->findChildren<EventListColumn*>();
|
||||
QVector<ColumnInfo> result;
|
||||
result.reserve(children.size());
|
||||
for (const EventListColumn *elc : children)
|
||||
result.push_back(elc->columnInfo());
|
||||
std::sort(result.begin(), result.end(),
|
||||
[](const ColumnInfo &a, const ColumnInfo &b)
|
||||
{
|
||||
return a.visualIndex < b.visualIndex;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void EventListColumns::init()
|
||||
{
|
||||
qDeleteAll(m_ui->itemLayoutWidget->findChildren<EventListColumn*>());
|
||||
|
||||
|
||||
for (const auto &ci : qAsConst(m_columns))
|
||||
{
|
||||
EventListColumn *rtcItem = new EventListColumn(ci);
|
||||
rtcItem->setObjectName(colObjectName(ci.logicalIndex));
|
||||
m_ui->itemLayoutWidget->layout()->addWidget(rtcItem);
|
||||
}
|
||||
|
||||
m_ui->lblConfiguration->setText(tr("No configuration file loaded"));
|
||||
}
|
||||
|
||||
bool EventListColumns::load()
|
||||
{
|
||||
bool ret = false;
|
||||
QByteArray content;
|
||||
int fileId = m_flmIfc->loadFileContent(this, content, {FileManagement::FileType::Xml}, 0, FileManagement::toString(FileManagement::XmlType::TLNEventListConfiguration));
|
||||
if (fileId > 0)
|
||||
{
|
||||
if (!m_flmIfc->isXmlType(content, FileManagement::toString(FileManagement::XmlType::TLNEventListConfiguration)))
|
||||
{
|
||||
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Invalid xml file content"),
|
||||
windowTitle(),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes,
|
||||
texts);
|
||||
}
|
||||
else
|
||||
{
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(content));
|
||||
const QJsonObject obj(doc.object());
|
||||
const QJsonArray elcCols(obj.value(QStringLiteral("Columns")).toArray());
|
||||
|
||||
loadColumns(elcCols);
|
||||
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
QString fileName = m_flmIfc->getFileName(fileId);
|
||||
m_ui->lblConfiguration->setText(tr("Configuration file: %1").arg(fileName));
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Successfully loaded configuration file"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->lblConfiguration->setText(tr("No configuration file loaded"));
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Could not load configuration file"));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EventListColumns::loadColumns(const QJsonArray &cols)
|
||||
{
|
||||
qDeleteAll(m_ui->itemLayoutWidget->findChildren<EventListColumn*>());
|
||||
|
||||
Timeline::ColumnInfo ci;
|
||||
for (const auto &val : cols)
|
||||
{
|
||||
const QJsonObject obj = val.toObject();
|
||||
ci.logicalIndex = obj.value(QStringLiteral("logicalIndex")).toInt();
|
||||
ci.visualIndex = obj.value(QStringLiteral("visualIndex")).toInt();
|
||||
ci.name = obj.value(QStringLiteral("name")).toString();
|
||||
ci.size = obj.value(QStringLiteral("size")).toInt();
|
||||
ci.visible = obj.value(QStringLiteral("visible")).toBool();
|
||||
const QString objName = colObjectName(ci.logicalIndex);
|
||||
|
||||
EventListColumn *elc = m_ui->itemLayoutWidget->findChild<EventListColumn*>(objName);
|
||||
if (elc)
|
||||
{
|
||||
|
||||
ERROR_LOG(m_logger) << "Modifed Column: " << ci.visualIndex
|
||||
<< ", " << ci.logicalIndex << ", " << ci.name
|
||||
<< ", " << ci.visible << ", " << objName;
|
||||
elc->setChecked(ci.visible);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger) << "New Column: " << ci.visualIndex
|
||||
<< ", " << ci.logicalIndex << ", " << ci.name
|
||||
<< ", " << ci.visible << ", " << objName;
|
||||
elc = new EventListColumn(ci);
|
||||
elc->setObjectName(objName);
|
||||
m_ui->itemLayoutWidget->layout()->addWidget(elc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EventListColumns::save()
|
||||
{
|
||||
int fileId = m_flmIfc->saveFileContent(this, FileManagement::FileType::Xml, 0, columnsToDoc(exportColumns()));
|
||||
if (fileId > 0)
|
||||
DEBUG_LOG(m_logger) << "Saved file with id = " << fileId;
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Could not save file in library ";
|
||||
return (fileId > 0);
|
||||
}
|
||||
|
||||
const QByteArray EventListColumns::columnsToDoc(const QJsonArray &cols)
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj[QStringLiteral("XmlType")] = FileManagement::toString(FileManagement::XmlType::TLNEventListConfiguration);
|
||||
obj[QStringLiteral("Columns")] = cols;
|
||||
|
||||
QJsonDocument doc(obj);
|
||||
return doc.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
const QJsonArray EventListColumns::exportColumns() const
|
||||
{
|
||||
QJsonArray result = QJsonArray();
|
||||
const auto children = m_ui->itemLayoutWidget->findChildren<EventListColumn*>();
|
||||
for (const EventListColumn *elc : children)
|
||||
{
|
||||
const auto &ci = elc->columnInfo();
|
||||
DEBUG_LOG(m_logger) << "Saving column: " << ci.visualIndex << ", " << elc->text() << ", " << elc->isChecked();
|
||||
QJsonObject elcObj;
|
||||
elcObj[QStringLiteral("visualIndex")] = ci.visualIndex;
|
||||
elcObj[QStringLiteral("logicalIndex")] = ci.logicalIndex;
|
||||
elcObj[QStringLiteral("name")] = ci.name;
|
||||
elcObj[QStringLiteral("size")] = ci.size;
|
||||
elcObj[QStringLiteral("visible")] = ci.visible;
|
||||
result.append(elcObj);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EventListColumns;
|
||||
}
|
||||
|
||||
class QAbstractItemModel;
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
struct ColumnInfo
|
||||
{
|
||||
QString name;
|
||||
int logicalIndex = 0;
|
||||
int visualIndex = 0;
|
||||
int size = 0;
|
||||
bool visible = false;
|
||||
};
|
||||
|
||||
class EventListColumn : public QCheckBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EventListColumn(const ColumnInfo &ci)
|
||||
: QCheckBox(ci.name)
|
||||
, m_ci(ci)
|
||||
{
|
||||
setChecked(ci.visible);
|
||||
connect(this, &EventListColumn::clicked,
|
||||
this, [this]() { m_ci.visible = isChecked(); });
|
||||
}
|
||||
const ColumnInfo &columnInfo() const { return m_ci; }
|
||||
|
||||
private:
|
||||
ColumnInfo m_ci;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class EventListColumns : public LtsWidgets::LtsFramelessDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
|
||||
EventListColumns(const QVector<ColumnInfo> &columns,
|
||||
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmIfc,
|
||||
QWidget *parent = nullptr);
|
||||
~EventListColumns();
|
||||
|
||||
QVector<ColumnInfo> currentColumnsState() const;
|
||||
public slots:
|
||||
bool save();
|
||||
bool load();
|
||||
|
||||
private:
|
||||
const QJsonArray exportColumns() const;
|
||||
void init();
|
||||
|
||||
const QByteArray columnsToDoc(const QJsonArray &cols);
|
||||
void loadColumns(const QJsonArray &cols);
|
||||
|
||||
private:
|
||||
QString m_fileLoaded;
|
||||
Ui::EventListColumns *m_ui;
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmIfc;
|
||||
QVector<ColumnInfo> m_columns;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
}
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EventListColumns</class>
|
||||
<widget class="QDialog" name="EventListColumns">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>368</width>
|
||||
<height>234</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblShowColumns">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Columns:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblConfiguration">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<widget class="QWidget" name="itemLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>356</width>
|
||||
<height>96</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>800</width>
|
||||
<height>800</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbSave">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbLoad">
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbOk">
|
||||
<property name="text">
|
||||
<string>Ok</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbClose">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>pbSave</tabstop>
|
||||
<tabstop>pbClose</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
#include "tln_event_list_model.h"
|
||||
#include "detail_data.h"
|
||||
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <Services/ProjectDataManagement/pdm_translation.h>
|
||||
#include <Services/ParticipantManagement/ppm_translation.h>
|
||||
#include <Services/AreaEffectSimulation/aes_translation.h>
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QDateTime>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
EventListDialogModel::EventListDialogModel(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<LtsTimelineClassic::Event *>({tr("Id"),
|
||||
tr("Type"),
|
||||
tr("Time"),
|
||||
tr("Duration [s]", "Dauer in Sekunden"),
|
||||
tr("Party"),
|
||||
tr("Equipment Number"),
|
||||
tr("Hierarchy"),
|
||||
tr("Participant Id"),
|
||||
tr("Aes Name"),
|
||||
tr("Aes Type"),
|
||||
|
||||
|
||||
tr("Building"),
|
||||
tr("Charge Type"),
|
||||
tr("Charge Remain"),
|
||||
|
||||
tr("Damage Percent"),
|
||||
tr("Damage Percent Old"),
|
||||
|
||||
tr("Friendly Fire"),
|
||||
tr("Gear Type"),
|
||||
tr("Stream Name"),
|
||||
tr("Vulnerability State")},
|
||||
parent)
|
||||
, m_ppmDtc(ppmDtc)
|
||||
, m_pdmDtc(pdmDtc)
|
||||
, m_ismDtc(ismDtc)
|
||||
, m_logger(getLogger("EventListModel"))
|
||||
{}
|
||||
|
||||
|
||||
QVariant EventListDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole || !indexIsValid(index) || m_invalid)
|
||||
return QVariant();
|
||||
|
||||
LtsTimelineClassic::Event *event = m_vecData.at(index.row());
|
||||
|
||||
const QJsonObject &obj = event->detailData();
|
||||
|
||||
|
||||
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case EventListDialogModel::Columns::Id:
|
||||
return event->uniqueId();
|
||||
case EventListDialogModel::Columns::Type:
|
||||
{
|
||||
if (event->typeId() == markerTypeId )
|
||||
return tr("Marker");
|
||||
|
||||
return ProjectDataManagement::toString(static_cast<ProjectDataManagement::EventType::type>(event->typeId()));
|
||||
}
|
||||
case EventListDialogModel::Columns::Time:
|
||||
return QDateTime::fromMSecsSinceEpoch(event->startTime());
|
||||
case EventListDialogModel::Columns::Duration:
|
||||
return (event->duration() / 1000);
|
||||
case EventListDialogModel::Columns::Party:
|
||||
{
|
||||
if (event->typeId() == ProjectDataManagement::EventType::HitBuilding)
|
||||
break;
|
||||
return ParticipantManagement::trPartyName(m_ppmDtc->party(event->partyId()).name());
|
||||
}
|
||||
case EventListDialogModel::Columns::EquipNo:
|
||||
{
|
||||
if (event->typeId() == ProjectDataManagement::EventType::HitBuilding)
|
||||
break;
|
||||
return event->equipmentId();
|
||||
}
|
||||
case EventListDialogModel::Columns::Hierarchy:
|
||||
return m_ppmDtc->hierarchyFromParticipant(event->playerId());
|
||||
case EventListDialogModel::Columns::ParticipantId:
|
||||
return event->playerId();
|
||||
|
||||
|
||||
case EventListDialogModel::AesType:
|
||||
{
|
||||
const auto ele = obj.value(QLatin1String("AesType"));
|
||||
if (!ele.isDouble())
|
||||
return QVariant();
|
||||
const int aesTypeId = ele.toInt();
|
||||
return AreaEffectSimulation::toString(static_cast<AreaEffectSimulation::AesType_def::type>(aesTypeId));
|
||||
}
|
||||
case EventListDialogModel::AesId:
|
||||
{
|
||||
const auto ele = obj.value(QLatin1String("AesName"));
|
||||
if (ele.isString())
|
||||
return ele.toString();
|
||||
const auto ele2 = obj.value(QLatin1String("AesId"));
|
||||
return ele2.isDouble() ? QVariant(ele.toInt()) : QVariant();
|
||||
}
|
||||
|
||||
|
||||
case EventListDialogModel::Building:
|
||||
{
|
||||
const auto ele = obj.value(QLatin1String("MainStructureElementId"));
|
||||
if (!ele.isDouble())
|
||||
return QVariant();
|
||||
int buildingId = ele.toInt();
|
||||
if (buildingId > 0)
|
||||
return m_ismDtc->getBuildingDisplayName(buildingId);
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
case EventListDialogModel::ChargeType:
|
||||
{
|
||||
int chargeTypeId = obj.value(QLatin1String("OriginatorChargeTypeId")).toInt();
|
||||
if (chargeTypeId <= 0)
|
||||
chargeTypeId = obj.value(QLatin1String("ChargeTypeId")).toInt();
|
||||
if (chargeTypeId <= 0)
|
||||
return QVariant();
|
||||
return m_pdmDtc->trChargeTypeShortName(chargeTypeId);
|
||||
}
|
||||
case EventListDialogModel::ChargeRemain:
|
||||
{
|
||||
const auto ele = obj.value(QLatin1String("Remain"));
|
||||
if (!ele.isDouble())
|
||||
return QVariant();
|
||||
return ele.toInt();
|
||||
}
|
||||
case EventListDialogModel::DamagePercent:
|
||||
{
|
||||
const auto ele = obj.value(QLatin1String("damagePercent"));
|
||||
if (!ele.isDouble())
|
||||
return QVariant();
|
||||
return ele.toInt();
|
||||
}
|
||||
case EventListDialogModel::DamagePercentOld:
|
||||
{
|
||||
const auto ele = obj.value(QLatin1String("damagePercentOld"));
|
||||
if (!ele.isDouble())
|
||||
return QVariant();
|
||||
return ele.toInt();
|
||||
}
|
||||
case EventListDialogModel::FriendlyFire:
|
||||
{
|
||||
const auto ele = obj.value(QLatin1String("FriendlyFire"));
|
||||
if (!ele.isBool())
|
||||
return QVariant();
|
||||
return ele.toBool();
|
||||
}
|
||||
case EventListDialogModel::GearType:
|
||||
{
|
||||
int gearTypeId = obj.value(QLatin1String("GearTypeId")).toInt();
|
||||
if (gearTypeId <= 0)
|
||||
return QVariant();
|
||||
return m_pdmDtc->trGearTypeName(gearTypeId);
|
||||
}
|
||||
case EventListDialogModel::StreamName:
|
||||
{
|
||||
const auto ele = obj.value(QLatin1String("streamName"));
|
||||
if (!ele.isString())
|
||||
return QVariant();
|
||||
return ele.toString();
|
||||
}
|
||||
case EventListDialogModel::VulnerabilityState:
|
||||
{
|
||||
const auto ele = obj.value(QLatin1String("VulnerabilityState"));
|
||||
if (!ele.isDouble())
|
||||
return QVariant();
|
||||
const int vId = ele.toInt();
|
||||
return ProjectDataManagement::toString(static_cast<ProjectDataManagement::VulnerabilityState_def::type>(vId));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void EventListDialogModel::appendEventList(const QVector<LtsTimelineClassic::Event *> &eventList)
|
||||
{
|
||||
for (const auto &event : eventList)
|
||||
{
|
||||
if (!m_vecData.contains(event))
|
||||
insertRow(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EventListDialogProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
{
|
||||
m_sourceModel = qobject_cast<EventListDialogModel*>(sourceModel);
|
||||
LtsWidgets::LtsColumnFilterProxyModel::setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
bool EventListDialogProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||
{
|
||||
if (!m_sourceModel ||
|
||||
source_left.column() != source_right.column() ||
|
||||
!source_left.isValid() ||
|
||||
!source_right.isValid() ||
|
||||
m_invalid)
|
||||
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
|
||||
const auto &dataLeft = m_sourceModel->m_vecData.at(source_left.row());
|
||||
const auto dataRight = m_sourceModel->m_vecData.at(source_right.row());
|
||||
switch (source_left.column())
|
||||
{
|
||||
case EventListDialogModel::Time:
|
||||
return dataLeft->startTime() < dataRight->startTime();
|
||||
case EventListDialogModel::EquipNo:
|
||||
return dataLeft->equipmentId() < dataRight->equipmentId();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
|
||||
}
|
||||
|
||||
|
||||
bool EventListDialogProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if (!m_sourceModel || source_parent.isValid() || source_row < 0 || source_row >= m_sourceModel->rowCount() || m_invalid)
|
||||
return LtsWidgets::LtsColumnFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
|
||||
LtsTimelineClassic::Event *event = m_sourceModel->m_vecData.at(source_row);
|
||||
if (event->typeId() == markerTypeId)
|
||||
return false;
|
||||
return LtsWidgets::LtsColumnFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Executable
+86
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <LtsTimelineClassic/Event.h>
|
||||
#include <ParticipantManagement/Data/ppm_data_plugin.h>
|
||||
#include <ProjectDataManagement/Data/pdm_data_plugin.h>
|
||||
#include <InfrastructureManagement/Data/ism_data_plugin.h>
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class EventListDialogModel final : public LtsWidgets::LtsAbstractTableModel<LtsTimelineClassic::Event *>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
Id,
|
||||
Type,
|
||||
Time,
|
||||
Duration,
|
||||
Party,
|
||||
EquipNo,
|
||||
Hierarchy,
|
||||
ParticipantId,
|
||||
AesId,
|
||||
AesType,
|
||||
|
||||
|
||||
Building,
|
||||
ChargeType,
|
||||
ChargeRemain,
|
||||
|
||||
DamagePercent,
|
||||
DamagePercentOld,
|
||||
|
||||
FriendlyFire,
|
||||
GearType,
|
||||
|
||||
StreamName,
|
||||
VulnerabilityState,
|
||||
Count
|
||||
};
|
||||
|
||||
explicit EventListDialogModel(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &pdmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
const QVector<LtsTimelineClassic::Event *> &eventList() const { return m_vecData; }
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
void setInvalid() { m_invalid = true; }
|
||||
|
||||
public slots:
|
||||
void appendEventList(const QVector<LtsTimelineClassic::Event *> &eventList);
|
||||
|
||||
private:
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
bool m_invalid = false;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
friend class EventListDialogProxyModel;
|
||||
};
|
||||
|
||||
class EventListDialogProxyModel final : public LtsWidgets::LtsColumnFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
void setInvalid() { m_invalid = true; }
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
private:
|
||||
EventListDialogModel *m_sourceModel = nullptr;
|
||||
bool m_invalid = false;
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+320
@@ -0,0 +1,320 @@
|
||||
|
||||
|
||||
|
||||
#include "tln_legend.h"
|
||||
#include "ui_tln_legend.h"
|
||||
#include "detail_data.h"
|
||||
#include "tln_dialog_model.h"
|
||||
|
||||
#include <LtsTimelineClassic/Event.h>
|
||||
#include <LtsTimelineClassic/EventGraphic.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <ProjectDataManagement/pdm_enums.hpp>
|
||||
#include <ProjectDataManagement/pdm_translation.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
#include <QPainter>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
TimelineLegendDialog::TimelineLegendDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_ui(new Ui::TimelineLegendDialog)
|
||||
, m_logger(getLogger("TimelineLegendDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->hide();
|
||||
|
||||
connect(m_ui->cbCheckAll, &QCheckBox::toggled,
|
||||
this, [this](bool toggled)
|
||||
{
|
||||
const auto cbList = findChildren<QCheckBox *>();
|
||||
for (QCheckBox *cb : cbList)
|
||||
{
|
||||
if (cb == m_ui->cbCheckAll)
|
||||
continue;
|
||||
|
||||
cb->setChecked(toggled);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
TimelineLegendDialog::~TimelineLegendDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void TimelineLegendDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Timeline Legend"));
|
||||
}
|
||||
|
||||
|
||||
void TimelineLegendDialog::setActiveEventTypeIds(const QSet<int> &activeEventTypeIds)
|
||||
{
|
||||
setUnchangeable();
|
||||
|
||||
|
||||
const QList<QCheckBox *> cbs(findChildren<QCheckBox *>());
|
||||
|
||||
for (QCheckBox *cb : cbs)
|
||||
cb->setChecked(false);
|
||||
|
||||
for (int activeEventType : activeEventTypeIds)
|
||||
{
|
||||
QCheckBox *cb = checkBox(activeEventType);
|
||||
|
||||
if (cb != nullptr)
|
||||
cb->setChecked(true);
|
||||
else
|
||||
WARNING_LOG(m_logger) << "cb for event type " << activeEventType << " not found!";
|
||||
}
|
||||
|
||||
setUnchangeable(false);
|
||||
}
|
||||
|
||||
QVector<ProjectDataManagement::EventType> TimelineLegendDialog::possibleEvents()
|
||||
{
|
||||
QVector<ProjectDataManagement::EventType> ret
|
||||
({
|
||||
|
||||
ProjectDataManagement::EventType::Hit,
|
||||
ProjectDataManagement::EventType::WeaponAssignment,
|
||||
ProjectDataManagement::EventType::BiteMessage,
|
||||
ProjectDataManagement::EventType::FireEvent,
|
||||
ProjectDataManagement::EventType::HitBuilding,
|
||||
ProjectDataManagement::EventType::Manipulation,
|
||||
ProjectDataManagement::EventType::CameraVideo,
|
||||
ProjectDataManagement::EventType::RadioCnr,
|
||||
ProjectDataManagement::EventType::RadioTvc,
|
||||
ProjectDataManagement::EventType::HitEffectSimulation,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ProjectDataManagement::EventType::CrossLocalBorderline,
|
||||
|
||||
|
||||
|
||||
|
||||
ProjectDataManagement::EventType::CrossGlobalBorderline,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
|
||||
if (ps->value(QStringLiteral("tln"),
|
||||
QStringLiteral("showEffectSimulationEvents")).toBool())
|
||||
{
|
||||
ret += ProjectDataManagement::EventType::MineArea;
|
||||
ret += ProjectDataManagement::EventType::DangerArea;
|
||||
ret += ProjectDataManagement::EventType::FunctionalArea;
|
||||
ret += ProjectDataManagement::EventType::MineCorridor;
|
||||
ret += ProjectDataManagement::EventType::Borderline;
|
||||
if (ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableNuclearContaminations")).toBool())
|
||||
ret += ProjectDataManagement::EventType::NContamination;
|
||||
if (ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableNuclearContaminations")).toBool() ||
|
||||
ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableNuclearContaminations")).toBool())
|
||||
ret += ProjectDataManagement::EventType::BCContamination;
|
||||
}
|
||||
|
||||
|
||||
if (ps->value(QStringLiteral("tln"),
|
||||
QStringLiteral("showEnterLeaveEvents")).toBool())
|
||||
{
|
||||
ret += ProjectDataManagement::EventType::EnterDangerArea;
|
||||
ret += ProjectDataManagement::EventType::LeaveDangerArea;
|
||||
ret += ProjectDataManagement::EventType::EnterMineArea;
|
||||
ret += ProjectDataManagement::EventType::LeaveMineArea;
|
||||
ret += ProjectDataManagement::EventType::EnterFunctionalArea;
|
||||
ret += ProjectDataManagement::EventType::LeaveFunctionalArea;
|
||||
|
||||
if (ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableNuclearContaminations")).toBool())
|
||||
{
|
||||
ret += ProjectDataManagement::EventType::EnterNuclear;
|
||||
ret += ProjectDataManagement::EventType::LeaveNuclear;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableGasPipes")).toBool())
|
||||
{
|
||||
ret += ProjectDataManagement::EventType::GasPipe;
|
||||
|
||||
}
|
||||
|
||||
const bool showPvSan = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"),
|
||||
QStringLiteral("HasPvSan"));
|
||||
if (showPvSan)
|
||||
ret += ProjectDataManagement::EventType::Sanitation;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int categoryFromEventType(ProjectDataManagement::EventType et)
|
||||
{
|
||||
switch (et.underlying())
|
||||
{
|
||||
case ProjectDataManagement::EventType::Unknown:
|
||||
return 0;
|
||||
case ProjectDataManagement::EventType::Hit:
|
||||
case ProjectDataManagement::EventType::WeaponAssignment:
|
||||
case ProjectDataManagement::EventType::BiteMessage:
|
||||
case ProjectDataManagement::EventType::FireEvent:
|
||||
case ProjectDataManagement::EventType::FriendlyFire:
|
||||
case ProjectDataManagement::EventType::Manipulation:
|
||||
return 1;
|
||||
case ProjectDataManagement::EventType::CameraVideo:
|
||||
case ProjectDataManagement::EventType::RadioCnr:
|
||||
case ProjectDataManagement::EventType::RadioTvc:
|
||||
return 5;
|
||||
case ProjectDataManagement::EventType::HitBuilding:
|
||||
case ProjectDataManagement::EventType::HitEffectSimulation:
|
||||
case ProjectDataManagement::EventType::HitMine:
|
||||
case ProjectDataManagement::EventType::HitN:
|
||||
case ProjectDataManagement::EventType::HitB:
|
||||
case ProjectDataManagement::EventType::HitC:
|
||||
case ProjectDataManagement::EventType::HitGasPipe:
|
||||
return 2;
|
||||
case ProjectDataManagement::EventType::EnterDangerArea:
|
||||
case ProjectDataManagement::EventType::LeaveDangerArea:
|
||||
case ProjectDataManagement::EventType::EnterMineArea:
|
||||
case ProjectDataManagement::EventType::LeaveMineArea:
|
||||
case ProjectDataManagement::EventType::CrossLocalBorderline:
|
||||
case ProjectDataManagement::EventType::EnterFunctionalArea:
|
||||
case ProjectDataManagement::EventType::LeaveFunctionalArea:
|
||||
case ProjectDataManagement::EventType::EnterNuclear:
|
||||
case ProjectDataManagement::EventType::LeaveNuclear:
|
||||
case ProjectDataManagement::EventType::CrossGlobalBorderline:
|
||||
case ProjectDataManagement::EventType::Sanitation:
|
||||
return 3;
|
||||
case ProjectDataManagement::EventType::MineArea:
|
||||
case ProjectDataManagement::EventType::NContamination:
|
||||
case ProjectDataManagement::EventType::BCContamination:
|
||||
case ProjectDataManagement::EventType::DangerArea:
|
||||
case ProjectDataManagement::EventType::FunctionalArea:
|
||||
case ProjectDataManagement::EventType::MineCorridor:
|
||||
case ProjectDataManagement::EventType::Borderline:
|
||||
case ProjectDataManagement::EventType::GasPipe:
|
||||
return 6;
|
||||
case ProjectDataManagement::EventType::TechnicalArea:
|
||||
case ProjectDataManagement::EventType::EquipmentErrorReport:
|
||||
case ProjectDataManagement::EventType::EmergencyCall:
|
||||
return 0;
|
||||
}
|
||||
Q_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool TimelineLegendDialog::init(DDSTimelineModel *model, const QSet<int> &activeEventTypeIds)
|
||||
{
|
||||
struct WidgetSortHelper
|
||||
{
|
||||
QLabel *lbl = nullptr;
|
||||
QCheckBox *cbx = nullptr;
|
||||
ProjectDataManagement::EventType et = ProjectDataManagement::EventType::Unknown;
|
||||
};
|
||||
QImage p(16, 24, QImage::Format_ARGB32);
|
||||
QColor c;
|
||||
LtsTimelineClassic::Event::EventPaintFunc paintFunc;
|
||||
WidgetSortHelper wsh;
|
||||
|
||||
const auto events = possibleEvents();
|
||||
std::vector<WidgetSortHelper> helperCont;
|
||||
helperCont.reserve(events.size());
|
||||
for (const ProjectDataManagement::EventType eventType : events)
|
||||
{
|
||||
model->setColorPaintFun(paintFunc, c, eventType.underlying());
|
||||
|
||||
if (paintFunc == nullptr)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "No draw function for event " << eventType;
|
||||
Q_ASSERT(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
p.fill(Qt::transparent);
|
||||
QPainter pp(&p);
|
||||
pp.setRenderHint(QPainter::Antialiasing);
|
||||
pp.setBrush(QBrush(c));
|
||||
paintFunc(&pp, p.rect().adjusted(0, 0, -1, -1));
|
||||
|
||||
wsh.lbl = new QLabel(this);
|
||||
wsh.lbl->setPixmap(QPixmap::fromImage(p));
|
||||
|
||||
wsh.et = eventType;
|
||||
wsh.cbx = new QCheckBox(ProjectDataManagement::toString(eventType), this);
|
||||
wsh.cbx->setObjectName(checkBoxName(eventType));
|
||||
wsh.cbx->setChecked(activeEventTypeIds.contains(eventType.underlying()));
|
||||
wsh.cbx->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
||||
helperCont.push_back(wsh);
|
||||
}
|
||||
|
||||
std::sort(helperCont.begin(), helperCont.end(), [](const WidgetSortHelper &a, const WidgetSortHelper &b)
|
||||
{
|
||||
const auto et1 = categoryFromEventType(a.et);
|
||||
const auto et2 = categoryFromEventType(b.et);
|
||||
if (et1 != et2)
|
||||
return et1 < et2;
|
||||
return a.cbx->text() < b.cbx->text();
|
||||
});
|
||||
|
||||
int curGridRow = 1;
|
||||
for (const auto &ele : helperCont)
|
||||
{
|
||||
m_ui->gridLayout->addWidget(ele.lbl, curGridRow, 0);
|
||||
m_ui->gridLayout->addWidget(ele.cbx, curGridRow, 1);
|
||||
m_ui->gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding), curGridRow, 2);
|
||||
++curGridRow;
|
||||
}
|
||||
m_ui->gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), curGridRow, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TimelineLegendDialog::apply()
|
||||
{
|
||||
QSet<int> activeEventTypeIds;
|
||||
const auto events = possibleEvents();
|
||||
for (const ProjectDataManagement::EventType eventType : events)
|
||||
{
|
||||
if (checkBox(eventType)->isChecked())
|
||||
activeEventTypeIds.insert(eventType.underlying());
|
||||
}
|
||||
emit signalEventTypesChanged(activeEventTypeIds);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <ProjectDataManagement/pdm_enums.hpp>
|
||||
#include "logger.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class TimelineLegendDialog;
|
||||
}
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DDSTimelineModel;
|
||||
|
||||
|
||||
class TimelineLegendDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TimelineLegendDialog(QWidget *parent = nullptr);
|
||||
~TimelineLegendDialog();
|
||||
|
||||
bool apply() override;
|
||||
bool init(DDSTimelineModel *model, const QSet<int> &activeEventTypeIds);
|
||||
void setActiveEventTypeIds(const QSet<int> &activeEventTypeIds);
|
||||
|
||||
static QVector<ProjectDataManagement::EventType> possibleEvents();
|
||||
signals:
|
||||
void signalEventTypesChanged(const QSet<int> &activeEventTypeIds);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
|
||||
static QString checkBoxName(int eventTypeId) { return QStringLiteral("CheckBoxEvent%1").arg(eventTypeId); }
|
||||
static QString checkBoxName(ProjectDataManagement::EventType eventType) { return checkBoxName(eventType.underlying()); }
|
||||
QCheckBox *checkBox(int eventTypeId) { return findChild<QCheckBox *>(checkBoxName(eventTypeId)); }
|
||||
QCheckBox *checkBox(ProjectDataManagement::EventType eventType) { return checkBox(eventType.underlying()); }
|
||||
|
||||
private:
|
||||
Ui::TimelineLegendDialog *m_ui;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TimelineLegendDialog</class>
|
||||
<widget class="QWidget" name="TimelineLegendDialog">
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Timeline View</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="cbCheckAll">
|
||||
<property name="text">
|
||||
<string>Check all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Executable
+505
@@ -0,0 +1,505 @@
|
||||
|
||||
|
||||
|
||||
#include "tln_show_details.h"
|
||||
#include "ui_tln_show_details.h"
|
||||
#include "tln_view_gui_plugin.h"
|
||||
#include "detail_data.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <LtsWidgets/lts_base.h>
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <LtsTimelineClassic/Event.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <Services/ProjectDataManagement/pdm_translation.h>
|
||||
#include <AudioVideoManagement/stream_name_mapping.h>
|
||||
#include <Plugins/MarkerManagement/Gui/Common/mrk_apply_filter.h>
|
||||
#include <Plugins/SituationReplay/srp_gui_plugin_interface.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonValue>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
ShowDetailsDialog::ShowDetailsDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_ui(new Ui::ShowDetailsDialog)
|
||||
, m_logger(getLogger("ShowDetailsDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
setUnchangeable();
|
||||
|
||||
m_ui->debugWidget->hide();
|
||||
|
||||
connect(m_ui->pbStartReplay, &QPushButton::clicked,
|
||||
this, &ShowDetailsDialog::slotStartReplay);
|
||||
|
||||
connect(m_ui->pbShowMarker, &QPushButton::clicked,
|
||||
this, &ShowDetailsDialog::slotShowMarker);
|
||||
|
||||
connect(m_ui->pbPlayback, &QPushButton::clicked,
|
||||
this, &ShowDetailsDialog::slotStartPlayback);
|
||||
|
||||
connect(m_ui->pbFocus, &QPushButton::clicked,
|
||||
this, &ShowDetailsDialog::slotFocusOnMap);
|
||||
|
||||
m_ui->tbFocus->hide();
|
||||
m_ui->tbMarker->hide();
|
||||
m_ui->tbPlayback->hide();
|
||||
m_ui->tbReplay->hide();
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
if (LtsSessionData::LtsSessionData::getInstance()->debugFlagValue(QStringLiteral("Timeline.Debug")) == QVariant(true))
|
||||
#endif
|
||||
{
|
||||
m_ui->debugWidget->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ShowDetailsDialog::~ShowDetailsDialog()
|
||||
{
|
||||
m_session = nullptr;
|
||||
m_mrkDtc = nullptr;
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void ShowDetailsDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, m_eventType, false, tr("Event"));
|
||||
}
|
||||
|
||||
|
||||
void ShowDetailsDialog::slotFocusOnMap()
|
||||
{
|
||||
if (m_replayAppSession == nullptr)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::init: no replay app, no focus";
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> sitMapIfc;
|
||||
|
||||
if (!m_replayAppSession->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(sitMapIfc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "no sitMapIfc, no focusing on replay in Show Details Dialog 1";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sitMapIfc)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "no sitMapIfc, no focusing on replay in Show Details Dialog 2";
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_event->typeId() != markerTypeId)
|
||||
{
|
||||
if (!m_event->positionValid())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "event has no valid position, skip focusOnMap";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
sitMapIfc->setCenterPoint(m_event->pos2d());
|
||||
}
|
||||
|
||||
const QJsonObject root(m_event->detailData());
|
||||
const QJsonValue mapSettings(root[QStringLiteral("MapSettings")]);
|
||||
|
||||
if (!mapSettings.isUndefined())
|
||||
sitMapIfc->setOperatorMapSettings(mapSettings);
|
||||
|
||||
const QJsonValue filterSettings(root[QStringLiteral("Filter")]);
|
||||
if (!filterSettings.isUndefined())
|
||||
{
|
||||
MarkerManagement::MarkerManagementApplyFilter applyFilter(m_replayAppSession, m_fltParticipantIfc, m_fltAesIfc, m_fltBuildingComponentIfc);
|
||||
if (!applyFilter.applyFilter(filterSettings.toObject()))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "filters from event #"<<m_event->uniqueId()<<" could not be applied";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ShowDetailsDialog::slotShowMarker()
|
||||
{
|
||||
m_mrkIfc->showMarker(m_event->uniqueId());
|
||||
}
|
||||
|
||||
|
||||
bool ShowDetailsDialog::hasNameAndEndTime() const
|
||||
{
|
||||
QString dummy1;
|
||||
qint64 dummy2;
|
||||
return getStreamNameAndEndTime(dummy1, dummy2, true);
|
||||
}
|
||||
|
||||
|
||||
bool ShowDetailsDialog::getStreamNameAndEndTime(QString &streamName, qint64 &endTime, bool silent) const
|
||||
{
|
||||
const QJsonObject root(m_event->detailData());
|
||||
const QString _streamName = root[QStringLiteral("streamName")].toString();
|
||||
|
||||
if (_streamName.isEmpty())
|
||||
{
|
||||
if (!silent)
|
||||
ERROR_LOG(m_logger) << "ShowDetailsDialog::slotStartVideo(): stream name is empty " << QJsonDocument(m_event->detailData()).toJson();
|
||||
return false;
|
||||
}
|
||||
|
||||
qint64 _endTime = root[QStringLiteral("endTime")].toDouble(0);
|
||||
|
||||
if (_endTime == 0 && !silent)
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::slotStartPlayback: event " << m_event->uniqueId() << " has no end time!";
|
||||
|
||||
streamName = _streamName;
|
||||
endTime = _endTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ShowDetailsDialog::slotStartPlayback()
|
||||
{
|
||||
QString streamName;
|
||||
qint64 endTime;
|
||||
|
||||
if (!getStreamNameAndEndTime(streamName, endTime))
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Cannot start playback as this event's informations are missing."));
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isAudio = isAudioEventType(m_event->typeId());
|
||||
if (!m_avmIfc->startAudioVideoPlayback(streamName, m_event->startTime(), isAudio))
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Playback cannot be started because of an error. Please try again later."));
|
||||
}
|
||||
|
||||
|
||||
void ShowDetailsDialog::slotStartReplay()
|
||||
{
|
||||
if (m_replayAppSession == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "ShowDetailsDialog::slotStartReplay: no replay app, no replay";
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<SituationReplay::ForeignGuiInterface> srpIfc;
|
||||
|
||||
if (!m_replayAppSession->getForeignGuiInterface<SituationReplay::ForeignGuiInterface>(srpIfc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "ShowDetailsDialog::slotStartReplay: no srp, no replay in Show Details Dialog";
|
||||
return;
|
||||
}
|
||||
|
||||
srpIfc->startReplay(m_event->startTime() - (10 * 1000) );
|
||||
slotFocusOnMap();
|
||||
}
|
||||
|
||||
|
||||
void ShowDetailsDialog::setButtonDisabled(QPushButton *button, QToolButton *warningButton, const QString &reasonMessage, bool hide)
|
||||
{
|
||||
if (hide)
|
||||
button->setVisible(false);
|
||||
button->setEnabled(false);
|
||||
button->setToolTip(reasonMessage);
|
||||
warningButton->setToolTip(reasonMessage);
|
||||
warningButton->show();
|
||||
|
||||
connect(warningButton, &QToolButton::clicked,
|
||||
warningButton, [this, warningButton]()
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, warningButton->toolTip());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ShowDetailsDialog::isMarkerAudioVideo() const
|
||||
{
|
||||
const QJsonObject root(m_event->detailData());
|
||||
|
||||
return (root[QStringLiteral("IsAudioType")].toBool(false) || root[QStringLiteral("IsVideoType")].toBool(false));
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ShowDetailsDialog::isAvsCapable(const LtsTimelineClassic::Event *event)
|
||||
{
|
||||
const int eventType = event->typeId();
|
||||
return isAvEventType(eventType) || eventType == Timeline::markerTypeId;
|
||||
}
|
||||
|
||||
|
||||
bool ShowDetailsDialog::isHitEventType(int eventTypeId)
|
||||
{
|
||||
return (eventTypeId == ProjectDataManagement::EventType_def::Hit ||
|
||||
eventTypeId == ProjectDataManagement::EventType_def::HitB ||
|
||||
eventTypeId == ProjectDataManagement::EventType_def::HitBuilding ||
|
||||
eventTypeId == ProjectDataManagement::EventType_def::HitC ||
|
||||
eventTypeId == ProjectDataManagement::EventType_def::HitGasPipe ||
|
||||
eventTypeId == ProjectDataManagement::EventType_def::HitEffectSimulation ||
|
||||
eventTypeId == ProjectDataManagement::EventType_def::HitMine ||
|
||||
eventTypeId == ProjectDataManagement::EventType_def::HitN);
|
||||
}
|
||||
|
||||
|
||||
bool ShowDetailsDialog::isAvEventType(int eventTypeId)
|
||||
{
|
||||
return (isAudioEventType(eventTypeId) ||
|
||||
eventTypeId == ProjectDataManagement::EventType_def::CameraVideo);
|
||||
}
|
||||
|
||||
|
||||
bool ShowDetailsDialog::isAudioEventType(int eventTypeId)
|
||||
{
|
||||
return (eventTypeId == ProjectDataManagement::EventType_def::RadioCnr ||
|
||||
eventTypeId == ProjectDataManagement::EventType_def::RadioTvc);
|
||||
}
|
||||
|
||||
|
||||
bool ShowDetailsDialog::init(DetailData *detailData, const LtsTimelineClassic::Event *event,
|
||||
const QPointer<LtsSession::LtsSession> &session,
|
||||
const QPointer<LtsSession::LtsSession> &replayAppSession,
|
||||
const std::shared_ptr<AudioVideoManagement::ForeignMenuEditGuiInterface> &avmIfc,
|
||||
const std::shared_ptr<MarkerManagement::ForeignGuiInterface> &mrkIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> &fltParticipantIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignAesGuiInterface> &fltAesIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> &fltBuildingComponentIfc,
|
||||
bool isTimelineApp,
|
||||
QWidget *pseudoParent,
|
||||
AudioVideoManagement::StreamNameMapping *streamNameMapping)
|
||||
{
|
||||
m_session = session;
|
||||
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<SituationReplay::ForeignGuiInterface> srpIfc;
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> sitMapIfc;
|
||||
if (!m_session->getDtc<MarkerManagement::DataInterface>(m_mrkDtc))
|
||||
WARNING_LOG(m_logger) << "!m_session->getDtc<MarkerManagement::DataInterface>(m_mrkDtc)";
|
||||
|
||||
m_mrkDtc->enableMarker();
|
||||
|
||||
connect(m_mrkDtc.get(), &MarkerManagement::Interface::Dtc::markerChanged,
|
||||
this, &ShowDetailsDialog::updateMarker);
|
||||
|
||||
|
||||
if (replayAppSession != nullptr)
|
||||
{
|
||||
m_replayAppSession = replayAppSession;
|
||||
|
||||
connect(replayAppSession.data(), &LtsSession::LtsSession::destroyed,
|
||||
this, [this]()
|
||||
{
|
||||
setButtonDisabled(m_ui->pbFocus, m_ui->tbFocus, tr("No map available."));
|
||||
setButtonDisabled(m_ui->pbStartReplay, m_ui->tbReplay, tr("Situation Replay App not started."));
|
||||
});
|
||||
|
||||
if (!replayAppSession->getForeignGuiInterface<SituationReplay::ForeignGuiInterface>(srpIfc))
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::init: no srp, no replay in Show Details Dialog";
|
||||
|
||||
if (!replayAppSession->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(sitMapIfc))
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::init: no sitMapIfc, no focusing on replay in Show Details Dialog";
|
||||
}
|
||||
|
||||
m_avmIfc = avmIfc;
|
||||
m_mrkIfc = mrkIfc;
|
||||
m_fltParticipantIfc = fltParticipantIfc;
|
||||
m_fltAesIfc = fltAesIfc;
|
||||
m_fltBuildingComponentIfc = fltBuildingComponentIfc;
|
||||
m_streamNameMapping = streamNameMapping;
|
||||
|
||||
if (m_avmIfc == nullptr)
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::init: no avm ifc given";
|
||||
|
||||
if (m_mrkIfc == nullptr)
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::init: no mrk ifc given";
|
||||
|
||||
if (m_fltParticipantIfc == nullptr)
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::init: no flt Part ifc given";
|
||||
|
||||
if (m_fltAesIfc == nullptr)
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::init: no flt Aes ifc given";
|
||||
|
||||
if (m_fltBuildingComponentIfc == nullptr)
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::init: no flt buildingComponent ifc given";
|
||||
|
||||
if (m_streamNameMapping == nullptr)
|
||||
WARNING_LOG(m_logger) << "ShowDetailsDialog::init: no stream name mapping given";
|
||||
|
||||
m_event = event;
|
||||
int eventTypeId = event->typeId();
|
||||
|
||||
|
||||
if (event->equipmentId() <= 0)
|
||||
{
|
||||
m_ui->lblEquipNo->hide();
|
||||
m_ui->lblValueEquipNo->hide();
|
||||
}
|
||||
else
|
||||
m_ui->lblValueEquipNo->setText(QString::number(event->equipmentId()));
|
||||
|
||||
connect(pseudoParent, &QWidget::destroyed, this, &ShowDetailsDialog::deleteLater);
|
||||
|
||||
QString eventTime;
|
||||
|
||||
if (m_logger.isDebugEnabled())
|
||||
eventTime = QStringLiteral("%1 <font color='#aebac6'>(%2)</font>").arg(DTG::toStringMSec(event->startTime())).arg(event->startTime());
|
||||
else
|
||||
eventTime = DTG::toStringMSec(event->startTime());
|
||||
|
||||
m_ui->lblValueEventTime->setText(eventTime);
|
||||
m_eventType = detailData->eventTypeLookup.getEventText(eventTypeId);
|
||||
|
||||
if (m_eventType.isEmpty())
|
||||
m_eventType = tr("<unknown> (%1)").arg(eventTypeId);
|
||||
|
||||
if (sitMapIfc == nullptr || isTimelineApp)
|
||||
setButtonDisabled(m_ui->pbFocus, m_ui->tbFocus, tr("No map available"), true);
|
||||
else if (eventTypeId != markerTypeId && !m_event->positionValid())
|
||||
setButtonDisabled(m_ui->pbFocus, m_ui->tbFocus, tr("Event has an invalid position and cannot be focused"));
|
||||
|
||||
if (srpIfc == nullptr)
|
||||
setButtonDisabled(m_ui->pbStartReplay, m_ui->tbReplay, tr("Situation Replay App not started."));
|
||||
else if (sitMapIfc == nullptr)
|
||||
setButtonDisabled(m_ui->pbStartReplay, m_ui->tbReplay, tr("This app has no map to focus this event on."));
|
||||
else if (eventTypeId != markerTypeId && !m_event->positionValid())
|
||||
setButtonDisabled(m_ui->pbStartReplay, m_ui->tbReplay, tr("Event has an invalid position, cannot be focused and therefore has no replay capability."));
|
||||
|
||||
if (eventTypeId != markerTypeId)
|
||||
setButtonDisabled(m_ui->pbShowMarker, m_ui->tbMarker, tr("This event is not a marker."), true);
|
||||
else if (m_mrkIfc == nullptr)
|
||||
setButtonDisabled(m_ui->pbShowMarker, m_ui->tbMarker, tr("This app has no marker interface available."), true);
|
||||
|
||||
if (!isAvsCapable(event))
|
||||
setButtonDisabled(m_ui->pbPlayback, m_ui->tbPlayback, tr("This event is not an audio/video type."), true);
|
||||
else if (m_avmIfc == nullptr)
|
||||
setButtonDisabled(m_ui->pbPlayback, m_ui->tbPlayback, tr("This app has no audio/video interface available."), true);
|
||||
else if (eventTypeId == Timeline::markerTypeId && !isMarkerAudioVideo())
|
||||
setButtonDisabled(m_ui->pbPlayback, m_ui->tbPlayback, tr("This marker event is not an audio / video type."), true);
|
||||
else if (!hasNameAndEndTime())
|
||||
setButtonDisabled(m_ui->pbPlayback, m_ui->tbPlayback, tr("This event has missing informations about the playback."));
|
||||
|
||||
|
||||
|
||||
if (isAvsCapable(event))
|
||||
{
|
||||
m_ui->pbFocus->hide();
|
||||
m_ui->tbFocus->hide();
|
||||
m_ui->pbStartReplay->hide();
|
||||
m_ui->tbReplay->hide();
|
||||
}
|
||||
|
||||
const DetailData::GetDetailDataResultList result = detailData->getDetailData(event);
|
||||
QLocale locale;
|
||||
|
||||
for (const DetailData::GetDetailDataForAttributeResult &attributeDetail : result)
|
||||
{
|
||||
|
||||
if (detailData->attributeInterpreterLookup.getInterpreterType(attributeDetail.attributeTypeId) == DetailData::INTERPRETER_TYPE_TIME)
|
||||
continue;
|
||||
|
||||
QString attributeTypeText;
|
||||
QString attributeValueText;
|
||||
|
||||
if (attributeDetail.requestResult != DetailData::RequestResult::Okay)
|
||||
{
|
||||
if (attributeDetail.requestResult == DetailData::RequestResult::NoValueTranslationForAttribute)
|
||||
{
|
||||
attributeTypeText = attributeDetail.attributeType;
|
||||
attributeValueText = QStringLiteral("%1 (%2)").arg(tr("<unknown>")).arg(attributeDetail.attributeValueId);
|
||||
}
|
||||
else if (attributeDetail.requestResult == DetailData::RequestResult::InvalidAttributeType)
|
||||
{
|
||||
|
||||
DEBUG_LOG(m_logger) << "Unhandled attribute " << attributeDetail.attributeTypeId << " - skipping";
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
attributeTypeText = QStringLiteral("%1 (%2)").arg(tr("<unknown>"), attributeDetail.attributeTypeId);
|
||||
attributeValueText = tr("<type unknown>");
|
||||
|
||||
WARNING_LOG(m_logger) << "getDetailData failed with message id " << (int)attributeDetail.requestResult << " for attribute " << attributeDetail.attributeTypeId;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attributeTypeText = attributeDetail.attributeType;
|
||||
|
||||
|
||||
bool isNumber = false;
|
||||
qint64 attributeValueAsNumber = attributeValueText.toLongLong(&isNumber);
|
||||
if (isNumber)
|
||||
attributeValueText = locale.toString(attributeValueAsNumber);
|
||||
|
||||
if (m_logger.isDebugEnabled())
|
||||
attributeValueText = QStringLiteral("%1 <font color='#aebac6'>(%2)</font>").arg(attributeDetail.attributeValue).arg(attributeDetail.attributeValueId);
|
||||
else
|
||||
attributeValueText = attributeDetail.attributeValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString attributeType(attributeDetail.attributeTypeId);
|
||||
|
||||
|
||||
int eventType = event->typeId();
|
||||
if (isAudioEventType(eventType))
|
||||
{
|
||||
if (attributeType == QStringLiteral("MainStructureElementId"))
|
||||
continue;
|
||||
}
|
||||
else if (isHitEventType(eventType))
|
||||
{
|
||||
if (attributeType == QStringLiteral("OriginatorType"))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attributeType == QStringLiteral("GearId"))
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
|
||||
QLabel *attributeValueTextLabel = new QLabel(attributeValueText);
|
||||
DEBUG_LOG(m_logger) << "attributeValueText=" << attributeValueText;
|
||||
attributeValueTextLabel->setTextInteractionFlags(attributeValueTextLabel->textInteractionFlags() | Qt::TextInteractionFlag::TextSelectableByMouse);
|
||||
DEBUG_LOG(m_logger) << "attributeTypeText=" << attributeTypeText
|
||||
<< " attributeValueTextLabel=" << attributeValueTextLabel;
|
||||
m_ui->formLayout->addRow(new QLabel(attributeTypeText), attributeValueTextLabel);
|
||||
}
|
||||
|
||||
if (m_eventType.isEmpty())
|
||||
m_eventType = QStringLiteral("%1 (%2)").arg(tr("<unknown>"), ProjectDataManagement::toString(static_cast<ProjectDataManagement::EventType::type>(event->typeId())));
|
||||
m_ui->lblEventType->setText(QStringLiteral("<b>%1</b>").arg(m_eventType));
|
||||
|
||||
m_ui->pteDetailDataTest->setPlainText(QString::fromUtf8(QJsonDocument(event->detailData()).toJson()));
|
||||
|
||||
QString pos(QStringLiteral("x: %1 - y: %2 - z: %3").arg(m_event->position().x()).arg(m_event->position().y()).arg(m_event->position().z()));
|
||||
m_ui->lblPos->setText(pos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShowDetailsDialog::updateMarker()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ShowDetailsDialog::updateMarker";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tln_view_gui_plugin.h"
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsTimelineClassic/Event.h>
|
||||
#include <Plugins/AudioVideoManagement/avm_menu_edit_gui_plugin_interface.h>
|
||||
#include <Plugins/MarkerManagement/mrk_gui_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_aes_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
||||
#include <MarkerManagement/mrk_dtc.h>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ShowDetailsDialog;
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class StreamNameMapping;
|
||||
}
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
class DetailData;
|
||||
|
||||
class ShowDetailsDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ShowDetailsDialog(QWidget *parent = nullptr);
|
||||
~ShowDetailsDialog();
|
||||
|
||||
bool init(DetailData *detailData, const LtsTimelineClassic::Event *event,
|
||||
const QPointer<LtsSession::LtsSession> &session,
|
||||
const QPointer<LtsSession::LtsSession> &replayAppSession,
|
||||
const std::shared_ptr<AudioVideoManagement::ForeignMenuEditGuiInterface> &avmIfc,
|
||||
const std::shared_ptr<MarkerManagement::ForeignGuiInterface> &mrkIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> &fltParticipantIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignAesGuiInterface> &fltAesIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> &fltBuildingComponentIfc,
|
||||
bool isTimelineApp,
|
||||
QWidget *pseudoParent,
|
||||
AudioVideoManagement::StreamNameMapping *streamNameMapping);
|
||||
|
||||
void retranslate() override;
|
||||
|
||||
private slots:
|
||||
void slotStartReplay();
|
||||
void slotStartPlayback();
|
||||
void slotShowMarker();
|
||||
void slotFocusOnMap();
|
||||
void updateMarker();
|
||||
|
||||
private:
|
||||
bool hasNameAndEndTime() const;
|
||||
bool getStreamNameAndEndTime(QString &streamName, qint64 &endTime, bool silent = false) const;
|
||||
void setButtonDisabled(QPushButton *button, QToolButton *warningButton, const QString &reasonMessage, bool hide = false);
|
||||
bool isMarkerAudioVideo() const;
|
||||
static bool isAvsCapable(const LtsTimelineClassic::Event *event);
|
||||
static bool isHitEventType(int eventTypeId);
|
||||
static bool isAvEventType(int eventTypeId);
|
||||
static bool isAudioEventType(int eventTypeId);
|
||||
|
||||
QString m_eventType;
|
||||
Ui::ShowDetailsDialog *m_ui{nullptr};
|
||||
const LtsTimelineClassic::Event *m_event{nullptr};
|
||||
|
||||
|
||||
QPointer<LtsSession::LtsSession> m_replayAppSession;
|
||||
|
||||
|
||||
std::shared_ptr<AudioVideoManagement::ForeignMenuEditGuiInterface> m_avmIfc;
|
||||
std::shared_ptr<MarkerManagement::ForeignGuiInterface> m_mrkIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> m_fltAesIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> m_fltBuildingComponentIfc;
|
||||
AudioVideoManagement::StreamNameMapping *m_streamNameMapping{nullptr};
|
||||
std::shared_ptr<MarkerManagement::Interface::Dtc> m_mrkDtc;
|
||||
LtsSession::LtsSessionDataDds *m_session{nullptr};
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
Executable
+304
@@ -0,0 +1,304 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ShowDetailsDialog</class>
|
||||
<widget class="QWidget" name="ShowDetailsDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>366</width>
|
||||
<height>451</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Exercise Management</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblEventType">
|
||||
<property name="text">
|
||||
<string notr="true"><Event Type></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblEquipNo">
|
||||
<property name="toolTip">
|
||||
<string>Folder Name</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Equip. No.:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblTime">
|
||||
<property name="text">
|
||||
<string>Event Time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblValueEquipNo">
|
||||
<property name="text">
|
||||
<string notr="true">...</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblValueEventTime">
|
||||
<property name="text">
|
||||
<string notr="true">...</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbPlayback">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
|
||||
<normaloff>:/style/warning.svg</normaloff>:/style/warning.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbPlayback">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Plays the audio and/or video clip assoociated to the event in the replay application, in a audio/video dialog.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start Playback</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbFocus">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
|
||||
<normaloff>:/style/warning.svg</normaloff>:/style/warning.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbFocus">
|
||||
<property name="text">
|
||||
<string>Focus on map</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbReplay">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
|
||||
<normaloff>:/style/warning.svg</normaloff>:/style/warning.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbStartReplay">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Sets the replay application back to the time the event occured and focuses the event on the map. </p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start Replay</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbMarker">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
|
||||
<normaloff>:/style/warning.svg</normaloff>:/style/warning.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbShowMarker">
|
||||
<property name="text">
|
||||
<string>Show Marker</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="debugWidget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblDebug">
|
||||
<property name="text">
|
||||
<string notr="true"><font color='#aebac6'>Debug:</font></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string notr="true">Position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblPos">
|
||||
<property name="text">
|
||||
<string notr="true">-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="pteDetailDataTest">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../Styles/Dark/resources/rme_dark_style.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
qt6-after/qt6-migrated-legatus/Lts/Plugins/Timeline/Gui/EventTimelineClassic/tln_view_gui_plugin.cpp
Executable
+160
@@ -0,0 +1,160 @@
|
||||
|
||||
|
||||
|
||||
#include "EventFilter/FilterWindow.h"
|
||||
#include "tln_view_gui_plugin.h"
|
||||
#include "tln_dialog.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_manager.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("View"))
|
||||
{}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getForeignDataInterface<TimeLineManagement::DataInterface>(m_eemForeign))
|
||||
return false;
|
||||
if (!m_session->getDtc<MarkerManagement::DataInterface>(m_mrkDtc))
|
||||
return false;
|
||||
if (!m_session->getDtc<ExerciseManagement::DataInterface>(m_exmDtc))
|
||||
return false;
|
||||
if (!m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
|
||||
return false;
|
||||
if (!m_session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_flmIfc))
|
||||
return false;
|
||||
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignParticipantInfoGuiInterface>(m_ppmInfoIfc))
|
||||
return false;
|
||||
if (!m_session->getDtc<ProjectDataManagement::DataInterface>(m_pdmDtc))
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
if (!m_session->getForeignDataInterface_NEW(m_avmDataIfc))
|
||||
WARNING_LOG(m_logger) << "no avm data ifc, no stream name mapping";
|
||||
if (!m_session->getForeignDataInterface<SituationReplayManagement::DataInterface>(m_srmDataIfc))
|
||||
WARNING_LOG(m_logger) << "no srm data ifc, no situation replay app";
|
||||
if (!m_session->getDtc<SituationReplayManagement::DataInterface>(m_coreDtc))
|
||||
WARNING_LOG(m_logger) << "no core dtc, no situation replay app";
|
||||
if (!m_session->getForeignGuiInterface<AudioVideoManagement::ForeignMenuEditGuiInterface>(m_avmIfc))
|
||||
WARNING_LOG(m_logger) << "Timeline Gui Plugin: no avm ifc";
|
||||
if (!m_session->getForeignGuiInterface<MarkerManagement::ForeignGuiInterface>(m_mrkIfc))
|
||||
WARNING_LOG(m_logger) << "Timeline Gui Plugin: no mrk ifc";
|
||||
if (!m_session->getForeignGuiInterface<FilterManagement::ForeignFltParticipantGuiInterface>(m_fltParticipantIfc))
|
||||
WARNING_LOG(m_logger) << "Timeline Gui Plugin: no flt Part ifc";
|
||||
if (!m_session->getForeignGuiInterface<FilterManagement::ForeignAesGuiInterface>(m_fltAesIfc))
|
||||
WARNING_LOG(m_logger) << "Timeline Gui Plugin: no flt Aes ifc";
|
||||
if (!m_session->getForeignGuiInterface<FilterManagement::ForeignFltBuildingComponentGuiInterface>(m_fltBuildingComponentIfc))
|
||||
WARNING_LOG(m_logger) << "Timeline Gui Plugin: no flt BuildingComponent ifc";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::clearInterfaces()
|
||||
{
|
||||
m_eemForeign = nullptr;
|
||||
m_mrkDtc = nullptr;
|
||||
m_exmDtc = nullptr;
|
||||
m_ppmDtc = nullptr;
|
||||
m_flmIfc = nullptr;
|
||||
m_ppmInfoIfc = nullptr;
|
||||
m_srmDataIfc = nullptr;
|
||||
m_coreDtc = nullptr;
|
||||
m_avmIfc = nullptr;
|
||||
m_mrkIfc = nullptr;
|
||||
m_avmDataIfc = nullptr;
|
||||
m_pdmDtc = nullptr;
|
||||
|
||||
m_fltParticipantIfc = nullptr;
|
||||
m_fltAesIfc = nullptr;
|
||||
m_fltBuildingComponentIfc = nullptr;
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
|
||||
{
|
||||
LtsWidgets::PluginData plData;
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Timeline");
|
||||
plData.identifier = QLatin1String("tlnView");
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eExecution;
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:timeline.svg"));
|
||||
|
||||
if (getFlags().testFlag(LtsAppDescriptor::PluginInfo::Flag::MAIN))
|
||||
{
|
||||
plData.layoutArea = LtsWidgets::LayoutArea::eMainTab;
|
||||
plData.createInstant = LtsWidgets::CreateInstantType::CreateInstantAndDiscardAction;
|
||||
|
||||
plData.createWidgetFunc = [this](QWidget *)
|
||||
{
|
||||
return onShowTimelineViewDialog(true);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
plData.layoutArea = LtsWidgets::LayoutArea::eDialogTab;
|
||||
|
||||
plData.createWidgetFunc = [this](QWidget *)
|
||||
{
|
||||
return onShowTimelineViewDialog(false);
|
||||
};
|
||||
}
|
||||
|
||||
ret.append(plData);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QString InterfaceImpl::menuGroup() const
|
||||
{
|
||||
return tr("Timeline");
|
||||
}
|
||||
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowTimelineViewDialog(bool isMain)
|
||||
{
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc;
|
||||
if (!m_session->getDtc<InfrastructureManagement::DataInterface>(ismDtc))
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(m_session->baseLayoutWidget(), tr("The Infrastructure Management is not available!"), tr("Cannot open Timeline"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
LtsWidgets::ButtonCombination buttonCombo = LtsWidgets::ButtonCombination::CloseOnly;
|
||||
|
||||
AudioVideoManagement::StreamNameMapping *streamNameMapping = nullptr;
|
||||
|
||||
if (m_avmDataIfc)
|
||||
streamNameMapping = m_avmDataIfc->streamNameMapping();
|
||||
|
||||
return LtsWidgets::initDialog(new TimelineViewDialog(menuGroup(), buttonCombo, isMain, nullptr),
|
||||
m_eemForeign, m_mrkDtc, m_exmDtc, m_flmIfc, m_ppmDtc,
|
||||
m_ppmInfoIfc, m_avmIfc, m_mrkIfc,m_srmDataIfc, m_coreDtc,
|
||||
m_pdmDtc, ismDtc, m_fltParticipantIfc, m_fltAesIfc, m_fltBuildingComponentIfc, m_session,
|
||||
streamNameMapping);
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+87
@@ -0,0 +1,87 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/Timeline/tln_view_gui_plugin_interface.h>
|
||||
#include <Plugins/Timeline/tln_data_plugin_interface.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Common/ProjectConfig/project_defines.h>
|
||||
#include <Plugins/MarkerManagement/mrk_data_plugin_interface.h>
|
||||
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
|
||||
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_participant_info_gui_plugin_interface.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <Plugins/AudioVideoManagement/avm_menu_edit_gui_plugin_interface.h>
|
||||
#include <Plugins/MarkerManagement/mrk_gui_plugin_interface.h>
|
||||
#include <Plugins/SituationReplayManagement/srm_data_plugin_interface.h>
|
||||
#include <Plugins/AudioVideoManagement/avm_data_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_aes_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
|
||||
|
||||
namespace Timeline
|
||||
{
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:tln.view")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QLatin1String("TimelineGuiPlugin"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return partition == IDL::PartitionType::Exercise || partition == IDL::PartitionType::Replay;
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final : public QObject, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
QString menuGroup() const override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override { return partition == IDL::PartitionType::Exercise || partition == IDL::PartitionType::Replay; }
|
||||
bool fetchInterfaces() override;
|
||||
void clearInterfaces() override;
|
||||
|
||||
private:
|
||||
LtsWidgets::LtsDialog *onShowTimelineViewDialog(bool isMain);
|
||||
|
||||
|
||||
std::shared_ptr<Core::Interface::Dtc> m_coreDtc;
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
|
||||
std::shared_ptr<MarkerManagement::Interface::Dtc> m_mrkDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
|
||||
|
||||
std::shared_ptr<AudioVideoManagement::DataInterface> m_avmDataIfc;
|
||||
|
||||
|
||||
std::shared_ptr<TimeLineManagement::ForeignDataInterface> m_eemForeign;
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmIfc;
|
||||
std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> m_ppmInfoIfc;
|
||||
std::shared_ptr<AudioVideoManagement::ForeignMenuEditGuiInterface> m_avmIfc;
|
||||
std::shared_ptr<MarkerManagement::ForeignGuiInterface> m_mrkIfc;
|
||||
std::shared_ptr<SituationReplayManagement::ForeignDataInterface> m_srmDataIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> m_fltAesIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> m_fltBuildingComponentIfc;
|
||||
};
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user