Adds initial intermediate qt6 porting state
This commit is contained in:
11247 files changed
+1891537
No files matched your search
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Patric Karwat, SLSE, 2016-07-27
|
||||
#
|
||||
|
||||
SET(replay_control_gui_SRCS
|
||||
replay_control_gui_plugin.h
|
||||
replay_control_gui_plugin.cpp
|
||||
replay_control_dialog.h
|
||||
replay_control_dialog.cpp
|
||||
replay_control_widget.h
|
||||
replay_control_widget.cpp
|
||||
|
||||
TopicEditor/topic_editor.h
|
||||
TopicEditor/topic_editor.cpp
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(replay_control_gui_SRCS
|
||||
replay_control_widget.ui
|
||||
|
||||
TopicEditor/topic_editor.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS SrpReplayControlGuiPlugin MODULE ${replay_control_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(SrpReplayControlGuiPlugin
|
||||
NGLLogger
|
||||
ngltools # dtg
|
||||
SrpGuiPluginInterface
|
||||
SrpDataPluginInterface
|
||||
MrkCommon
|
||||
Qt5::Widgets
|
||||
LtsWidgets
|
||||
LtsSession
|
||||
SituationMapScriptFilterGuiPluginInterface
|
||||
LtsDataView
|
||||
LtsUtilsGuiDds
|
||||
|
||||
# TopicEditor:
|
||||
TopicEditorBase
|
||||
LtsScriptTimeline
|
||||
MrkDataPluginInterface
|
||||
MrkGuiPluginInterface
|
||||
OpmDataPluginInterface
|
||||
|
||||
PreGuiScriptCommon
|
||||
situationMap
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(SrpReplayControlGuiPlugin)
|
||||
|
||||
|
||||
+594
@@ -0,0 +1,594 @@
|
||||
|
||||
|
||||
|
||||
#include "topic_editor.h"
|
||||
#include "ui_topic_editor.h"
|
||||
#include "../replay_control_widget.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <MarkerManagement/Gui/Common/mrk_dialog_model.h>
|
||||
#include <Plugins/SituationReplay/srp_gui_plugin_interface.h>
|
||||
#include <Services/MarkerManagement/mrk.hpp>
|
||||
#include <SituationReplay/logger.h>
|
||||
#include <TopicEditorBase/topic_previewer.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
|
||||
|
||||
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
#include <QtMath>
|
||||
|
||||
|
||||
class QAbstractTableModel;
|
||||
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
SituationReplayEditor::SituationReplayEditor(
|
||||
MarkerManagement::MarkerManagementDialogModel *markerModel,
|
||||
const QPointer<MarkerManagement::MarkerManagementApplyFilter> &applyFilter,
|
||||
LtsSession::LtsSession *session, QWidget *parent,
|
||||
ForeignGuiInterface **essentialsViewsSrpIfc,
|
||||
SituationMap::ForeignGuiInterface **essentialsViewsSitMapIfc
|
||||
)
|
||||
: TopicEditorBase::TopicEditor(parent)
|
||||
, m_session(session)
|
||||
, m_essentialsViewsSrpIfc(essentialsViewsSrpIfc)
|
||||
, m_essentialsViewsSitMapIfc(essentialsViewsSitMapIfc)
|
||||
, m_markerModel(markerModel)
|
||||
, m_applyFilter(applyFilter)
|
||||
, m_ui(new Ui::SituationReplayEditor)
|
||||
, m_logger(getLogger("SituationReplayEditor"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->lblDuration->setText(QStringLiteral(" - "));
|
||||
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setText(tr("Preview Replay"));
|
||||
if ((*m_essentialsViewsSrpIfc) == nullptr)
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setToolTip(tr("To enable replay preview, start the essentials view first."));
|
||||
else
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setToolTip(QString());
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Show,
|
||||
this, &SituationReplayEditor::onPreview);
|
||||
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Add)->setText(tr("Show Map Settings"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Add)->setToolTip(tr("Show this topic's map settings in Essentials View"));
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &SituationReplayEditor::onShowMapSettings);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Add)->hide();
|
||||
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Get Map Settings"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setToolTip(tr("Get map settings from Essentials View and set this topic's map settings"));
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load, this, &SituationReplayEditor::onGetSettings);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->hide();
|
||||
|
||||
|
||||
onEssentialsViewChanged((*m_essentialsViewsSrpIfc), (*essentialsViewsSitMapIfc));
|
||||
init(m_ui->widget);
|
||||
|
||||
m_ui->dteStartTime->setRetrieveCurrentTimeCallback([this]() { return m_session->partitionTime(); });
|
||||
m_ui->dteEndTime->setRetrieveCurrentTimeCallback([this]() { return m_session->partitionTime(); });
|
||||
|
||||
connect(m_ui->dteStartTime, &LtsWidgets::LtsDateTimeEdit::dateTimeChanged,
|
||||
this, &SituationReplayEditor::onChangesMade);
|
||||
|
||||
connect(m_ui->dteEndTime, &LtsWidgets::LtsDateTimeEdit::dateTimeChanged,
|
||||
this, &SituationReplayEditor::onChangesMade);
|
||||
|
||||
connect(m_ui->sbSpeed, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
|
||||
this, &SituationReplayEditor::onChangesMade);
|
||||
|
||||
|
||||
|
||||
if (m_markerModel != nullptr)
|
||||
{
|
||||
m_markerModel->setParent(this);
|
||||
m_ui->markersDataView->setModel(m_markerModel);
|
||||
|
||||
m_ui->markersDataView->hideColumn(MarkerManagement::MarkerManagementDialogModel::ColImage);
|
||||
m_ui->markersDataView->hideColumn(MarkerManagement::MarkerManagementDialogModel::ColFileId);
|
||||
m_ui->markersDataView->hideColumn(MarkerManagement::MarkerManagementDialogModel::ColOffset);
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->markersDataView->hideColumn(MarkerManagement::MarkerManagementDialogModel::ColStreams);
|
||||
#endif
|
||||
m_ui->markersDataView->setInitialSearchContent(
|
||||
MarkerManagement::MarkerManagementDialogModel::ColOperator, LtsSessionData::LtsSessionData::getInstance()->getOperatorId()
|
||||
);
|
||||
|
||||
connect(m_ui->markersDataView, &LtsDataView::LtsDataView::activated,
|
||||
this, &SituationReplayEditor::onMarkerSelected);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->markersDataView->hide();
|
||||
m_ui->lblMrk->hide();
|
||||
}
|
||||
|
||||
|
||||
if ((*m_essentialsViewsSrpIfc) != nullptr)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "essentials view available - using srp replay control widget as editor!";
|
||||
onAddReplayControlWidget();
|
||||
}
|
||||
else
|
||||
{
|
||||
WARNING_LOG(m_logger) << "essentials view not available - using traditional editor";
|
||||
}
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_Situation_Replay_Topic"));
|
||||
}
|
||||
|
||||
SituationReplayEditor::~SituationReplayEditor()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SituationReplayEditor::updateInternalData()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION;
|
||||
|
||||
if (m_firstUpdate)
|
||||
{
|
||||
m_firstUpdate = false;
|
||||
retranslate();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
m_filterSettings = m_topicData.properties.value(QStringLiteral("filters"));
|
||||
m_currentSettings = m_topicData.properties.value(QStringLiteral("settings"));
|
||||
|
||||
|
||||
|
||||
if (m_topicData.topicType == TopicEditorBase::TopicType::Situation)
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Add)->show();
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->show();
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasTopicDataProperties())
|
||||
return;
|
||||
|
||||
|
||||
qint64 start = getTopicDataValue(QStringLiteral("start")).toDouble();
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(start);
|
||||
double speed = getTopicDataValue(QStringLiteral("speed")).toDouble(1.0);
|
||||
m_ui->sbSpeed->setValue(speed);
|
||||
updateInternalLength();
|
||||
|
||||
if (m_replayControlWidget)
|
||||
{
|
||||
m_replayControlWidget->setStartTime(start);
|
||||
}
|
||||
}
|
||||
|
||||
void SituationReplayEditor::updateInternalLength()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION;
|
||||
qint64 end = calculateEnd(m_ui->dteStartTime->msecsSinceEpoch(), m_topicData.duration, m_ui->sbSpeed->value(), true);
|
||||
bool hasChanges = hasUnsavedChanges();
|
||||
m_ui->dteEndTime->setMsecsSinceEpoch(end);
|
||||
m_ui->lblDuration->setText(tr("%1 sec").arg(m_topicData.duration));
|
||||
if (!hasChanges)
|
||||
apply2();
|
||||
}
|
||||
|
||||
void SituationReplayEditor::retranslate()
|
||||
{
|
||||
if (m_topicData.id == -1)
|
||||
translate(m_ui, tr("Topic Editor"));
|
||||
else
|
||||
{
|
||||
if (m_topicData.topicType == TopicEditorBase::TopicType::Situation)
|
||||
{
|
||||
translate(m_ui, tr("Situation Topic Editor"));
|
||||
m_ui->cbFilterSettings->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
translate(m_ui, tr("Replay Topic Editor"));
|
||||
m_ui->cbFilterSettings->hide();
|
||||
}
|
||||
}
|
||||
|
||||
m_uiRequirements->clear();
|
||||
m_uiRequirements->addRequirement({ m_ui->lbxEndTime, [this]() {
|
||||
return (m_ui->dteEndTime->msecsSinceEpoch() > m_ui->dteStartTime->msecsSinceEpoch());
|
||||
}, tr("End time must be greater than the start time") });
|
||||
m_uiRequirements->addRequirement({ m_ui->lbxStartTime, [this]() {
|
||||
return (m_ui->dteStartTime->msecsSinceEpoch() < m_ui->dteEndTime->msecsSinceEpoch());
|
||||
}, tr("Start time must be smaller than the end time") });
|
||||
}
|
||||
|
||||
|
||||
qint64 SituationReplayEditor::calculateEnd(qint64 startTime, int lengthInSeconds, double speed, bool backwards)
|
||||
{
|
||||
double result = (lengthInSeconds * 1000);
|
||||
if (backwards)
|
||||
result *= speed;
|
||||
else
|
||||
result /= speed;
|
||||
result += startTime;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " result = " << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
qint64 SituationReplayEditor::calculateDuration(qint64 startTime, qint64 endTime, double speed)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " startTime=" << startTime << " endTime=" << endTime << " speed=" << speed;
|
||||
qint64 duration = endTime - startTime;
|
||||
double result = duration;
|
||||
result /= speed;
|
||||
qint64 result2 = result;
|
||||
result2 += 500;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " result = " << result2;
|
||||
return result2;
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayEditor::setFilterAndSettings(const QByteArray &mapFilter, const QByteArray &mapSettings)
|
||||
{
|
||||
setMapFilter(mapFilter);
|
||||
setMapSettings(mapSettings);
|
||||
}
|
||||
|
||||
void SituationReplayEditor::setMapSettings(const QByteArray &mapSettings)
|
||||
{
|
||||
QJsonParseError parseError;
|
||||
QJsonValue settings = QJsonDocument::fromJson(mapSettings, &parseError).object();
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "map settings not valid json at" << parseError.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentSettings = settings;
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
void SituationReplayEditor::setMapFilter(const QByteArray &mapFilter)
|
||||
{
|
||||
QJsonParseError parseError;
|
||||
QJsonValue filter = QJsonDocument::fromJson(mapFilter, &parseError).object();
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "filter settings not valid json at" << parseError.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
m_filterSettings = filter;
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SituationReplayEditor::onEssentialsViewChanged(SituationReplay::ForeignGuiInterface *essentialsViewsSrpIfc,
|
||||
SituationMap::ForeignGuiInterface *essentialsViewsSitMapIfc)
|
||||
{
|
||||
*m_essentialsViewsSrpIfc = essentialsViewsSrpIfc;
|
||||
*m_essentialsViewsSitMapIfc = essentialsViewsSitMapIfc;
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Show, !!(*m_essentialsViewsSrpIfc));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool SituationReplayEditor::apply2()
|
||||
{
|
||||
qint64 start = m_ui->dteStartTime->msecsSinceEpoch();
|
||||
qint64 end = m_ui->dteEndTime->msecsSinceEpoch();
|
||||
double speed = m_ui->sbSpeed->value();
|
||||
qint64 duration = calculateDuration(start, end, speed) / 1000;
|
||||
|
||||
setDescription(m_ui->widget->description());
|
||||
setTopicDataProperty(QStringLiteral("start"), start);
|
||||
setTopicDataProperty(QStringLiteral("speed"), speed);
|
||||
setTopicDataProperty(QStringLiteral("end"), end);
|
||||
|
||||
if (m_topicData.channel.isEmpty())
|
||||
{
|
||||
m_ui->widget->setEnabled(true);
|
||||
m_topicDuration = duration;
|
||||
m_topicData.duration = duration;
|
||||
if (duration < 0)
|
||||
m_ui->lblDuration->setText(QStringLiteral(" - "));
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " setText length = " << duration;
|
||||
m_ui->lblDuration->setText(tr("%1 sec").arg(m_topicDuration));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ui->cbFilterSettings->isChecked() && m_ui->cbFilterSettings->isVisible())
|
||||
{
|
||||
setTopicDataProperty(QStringLiteral("filters"), m_filterSettings);
|
||||
setTopicDataProperty(QStringLiteral("settings"), m_currentSettings);
|
||||
}
|
||||
|
||||
m_ui->widget->previewer()->setTopicData(m_topicData);
|
||||
|
||||
if (m_topicData.channel.isEmpty())
|
||||
return true;
|
||||
|
||||
LtsUtils::Promise *promise = new LtsUtils::Promise(nullptr, this);
|
||||
promise->resolved([this, duration](const QVariant &)
|
||||
{
|
||||
m_topicData.duration = duration;
|
||||
this->__unchange__();
|
||||
m_ui->widget->previewer()->setTopicData(m_topicData);
|
||||
applied();
|
||||
});
|
||||
promise->rejected([this](const QVariant &)
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(
|
||||
this,
|
||||
tr("The new settings conflict with other topics in this script. <br>"
|
||||
"Maybe the new topic size would collide with another topic or would be "
|
||||
"parallel to a topic of a type that cannot be parallelized with this topic's type. <br>"
|
||||
"You might have changed the size by setting a bigger end time or decreased the "
|
||||
"replay speed. <br>"
|
||||
"To fix this issue, check if your topic has enough room to expand if you "
|
||||
"make changed that would resize it."),
|
||||
tr("Unable to apply changes"));
|
||||
});
|
||||
emit durationCheckRequested(duration, promise);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayEditor::onAddReplayControlWidget()
|
||||
{
|
||||
if (m_replayControlWidget)
|
||||
m_replayControlWidget->deleteLater();
|
||||
|
||||
m_replayControlWidget = qobject_cast<SituationReplayControlWidget *>((*m_essentialsViewsSrpIfc)->createControlWidget(true));
|
||||
|
||||
if (m_replayControlWidget == nullptr)
|
||||
return;
|
||||
|
||||
m_replayControlWidget->setStartTime(m_ui->dteStartTime->msecsSinceEpoch());
|
||||
|
||||
connect(m_replayControlWidget, &QObject::destroyed,
|
||||
m_ui->traditionalControlWidget, &QWidget::show,
|
||||
Qt::QueuedConnection );
|
||||
|
||||
connect(m_replayControlWidget, &SituationReplayControlWidget::signalSetStart, this, [this](qint64 start)
|
||||
{
|
||||
if (m_ui->dteStartTime->msecsSinceEpoch() != start)
|
||||
{
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(start);
|
||||
onChangesMade();
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_replayControlWidget, &SituationReplayControlWidget::signalSetEnd, this, [this](qint64 end)
|
||||
{
|
||||
if (m_ui->dteEndTime->msecsSinceEpoch() != end)
|
||||
{
|
||||
m_ui->dteEndTime->setMsecsSinceEpoch(end);
|
||||
onChangesMade();
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_replayControlWidget, &SituationReplayControlWidget::signalSetSpeed, this, [this](double speed)
|
||||
{
|
||||
if (m_ui->sbSpeed->value() != speed)
|
||||
{
|
||||
m_ui->sbSpeed->setValue(speed);
|
||||
onChangesMade();
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_ui->sbSpeed, qOverload<double>(&QDoubleSpinBox::valueChanged), this, [this](double speed)
|
||||
{
|
||||
speed *= 10;
|
||||
if (m_replayControlWidget->speed() != speed)
|
||||
{
|
||||
m_replayControlWidget->setSpeed(speed);
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_replayControlWidget, &SituationReplayControlWidget::signalSetMapSettings,
|
||||
this, &SituationReplayEditor::setMapSettings);
|
||||
connect(m_replayControlWidget, &SituationReplayControlWidget::signalSetMapFilter,
|
||||
this, &SituationReplayEditor::setMapFilter);
|
||||
|
||||
connect(m_replayControlWidget, &SituationReplayControlWidget::replayStarted,
|
||||
this, &SituationReplayEditor::onReplayStarted);
|
||||
connect(m_replayControlWidget, &SituationReplayControlWidget::replayPaused,
|
||||
this, &SituationReplayEditor::onReplayPaused);
|
||||
connect(m_replayControlWidget, &SituationReplayControlWidget::replayStopped,
|
||||
this, &SituationReplayEditor::onReplayStopped);
|
||||
|
||||
m_replayControlWidget->showEditorWidget();
|
||||
m_ui->traditionalControlWidget->hide();
|
||||
m_ui->verticalLayout_2->addWidget(m_replayControlWidget);
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayEditor::onMarkerSelected(const QModelIndex &idx)
|
||||
{
|
||||
const MarkerManagement::Marker marker = m_markerModel->getRowData(idx.row());
|
||||
|
||||
if (marker.id() <= 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "marker has id 0";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
onChangesMade();
|
||||
setFilterAndSettings(QByteArray(marker.filter().c_str(), marker.filter().size()), QByteArray(marker.mapSettings().c_str(), marker.mapSettings().size()));
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
void SituationReplayEditor::onChangesMade()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION;
|
||||
|
||||
qint64 start = m_ui->dteStartTime->msecsSinceEpoch();
|
||||
qint64 end = m_ui->dteEndTime->msecsSinceEpoch();
|
||||
double speed = m_ui->sbSpeed->value();
|
||||
qint64 duration = calculateDuration(start, end, speed) / 1000;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " duration = " << duration;
|
||||
|
||||
if (duration < 0)
|
||||
m_ui->lblDuration->setText(QStringLiteral(" - "));
|
||||
else
|
||||
{
|
||||
m_topicDuration = duration;
|
||||
m_topicData.duration = duration;
|
||||
m_ui->widget->previewer()->setTopicData(m_topicData);
|
||||
m_ui->lblDuration->setText(tr("%1 sec").arg(m_topicDuration));
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " setText duration = " << duration;
|
||||
}
|
||||
}
|
||||
|
||||
void SituationReplayEditor::onPreview()
|
||||
{
|
||||
if (m_ui->dteStartTime->msecsSinceEpoch() >= m_ui->dteEndTime->msecsSinceEpoch())
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Start time must be greater than end time"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*m_essentialsViewsSrpIfc) == nullptr)
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Preview could not be started because essentials view is not started."));
|
||||
return;
|
||||
}
|
||||
|
||||
(*m_essentialsViewsSrpIfc)->startReplay(
|
||||
m_ui->dteStartTime->msecsSinceEpoch(), m_ui->dteEndTime->msecsSinceEpoch(), m_ui->sbSpeed->value()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayEditor::onReplayStarted()
|
||||
{
|
||||
if (m_topicData.id != -1)
|
||||
m_ui->widget->setTopicEnabled(false);
|
||||
}
|
||||
|
||||
void SituationReplayEditor::onReplayPaused()
|
||||
{
|
||||
if (m_topicData.id != -1)
|
||||
m_ui->widget->setTopicEnabled(true);
|
||||
}
|
||||
|
||||
void SituationReplayEditor::onReplayStopped()
|
||||
{
|
||||
if (m_topicData.id != -1)
|
||||
m_ui->widget->setTopicEnabled(true);
|
||||
}
|
||||
|
||||
void SituationReplayEditor::onShowMapSettings()
|
||||
{
|
||||
if (m_currentSettings.isNull() && m_filterSettings.isNull())
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("No saved map and filter settings available to show"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*m_essentialsViewsSitMapIfc) == nullptr)
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Settings could not be shown because essentials view was closed"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_currentSettings.isNull())
|
||||
{
|
||||
if (!(*m_essentialsViewsSitMapIfc)->setOperatorMapSettings(m_currentSettings))
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("This topic has invalid map settings"), tr("Could not set map settings from topic"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_filterSettings.isNull())
|
||||
{
|
||||
if (m_applyFilter != nullptr)
|
||||
m_applyFilter->applyFilter(m_filterSettings.toObject());
|
||||
else
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Filter settings could not be set because essentials view was closed"));
|
||||
}
|
||||
}
|
||||
|
||||
void SituationReplayEditor::onGetSettings()
|
||||
{
|
||||
if ((*m_essentialsViewsSitMapIfc) == nullptr)
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Map settings could not be received because essentials view was closed"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_applyFilter == nullptr)
|
||||
{
|
||||
NOTICE_LOG(m_logger) << "m_applyFilter == nullptr";
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Filter settings could not be received because essentials view was closed"));
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentSettings = (*m_essentialsViewsSitMapIfc)->operatorMapSettings();
|
||||
m_filterSettings = m_applyFilter->getFilterParamsJson();
|
||||
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <Plugins/MarkerManagement/Gui/Common/mrk_dialog_model.h>
|
||||
#include <Plugins/MarkerManagement/Gui/Common/mrk_apply_filter.h>
|
||||
#include <Services/MarkerManagement/mrk.hpp>
|
||||
#include <TopicEditorBase/topic_preview_widget.h>
|
||||
#include <TopicEditorBase/topic_previewer.h>
|
||||
|
||||
#include <TopicEditorBase/topic_editor_base.h>
|
||||
|
||||
|
||||
namespace LtsSession { class LtsSession; }
|
||||
namespace MarkerManagement { class MarkerManagementDialogModel; }
|
||||
namespace NGL { class INGLLogger; }
|
||||
namespace Ui { class SituationReplayEditor; }
|
||||
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
class ForeignGuiInterface;
|
||||
class SituationReplayControlWidget;
|
||||
|
||||
|
||||
class SituationReplayEditor : public TopicEditorBase::TopicEditor
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SituationReplayEditor(MarkerManagement::MarkerManagementDialogModel *markerModel,
|
||||
const QPointer<MarkerManagement::MarkerManagementApplyFilter> &applyFilter,
|
||||
LtsSession::LtsSession *session, QWidget *parent,
|
||||
SituationReplay::ForeignGuiInterface **essentialsViewsSrpIfc,
|
||||
SituationMap::ForeignGuiInterface **essentialsViewsSitMapIfc
|
||||
);
|
||||
~SituationReplayEditor();
|
||||
|
||||
private:
|
||||
void updateInternalData() override;
|
||||
void updateInternalLength() override;
|
||||
void retranslate() override;
|
||||
|
||||
qint64 calculateEnd(qint64 startTime, int lengthInSeconds, double speed, bool backwards = false);
|
||||
qint64 calculateDuration(qint64 startTime, qint64 endTime, double speed);
|
||||
|
||||
void setFilterAndSettings(const QByteArray &mapFilter, const QByteArray &mapSettings);
|
||||
void setMapSettings(const QByteArray &mapSettings);
|
||||
void setMapFilter(const QByteArray &mapFilter);
|
||||
|
||||
public slots:
|
||||
void onEssentialsViewChanged(SituationReplay::ForeignGuiInterface *essentialsViewsSrpIfc, SituationMap::ForeignGuiInterface *essentialsViewsSitMapIfc);
|
||||
|
||||
private slots:
|
||||
bool apply2() override final;
|
||||
|
||||
void onAddReplayControlWidget();
|
||||
void onMarkerSelected(const QModelIndex &idx);
|
||||
void onChangesMade();
|
||||
void onPreview();
|
||||
|
||||
void onReplayStarted();
|
||||
void onReplayPaused();
|
||||
void onReplayStopped();
|
||||
void onShowMapSettings();
|
||||
void onGetSettings();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
LtsSession::LtsSession *m_session{nullptr};
|
||||
SituationReplay::ForeignGuiInterface **m_essentialsViewsSrpIfc;
|
||||
SituationMap::ForeignGuiInterface **m_essentialsViewsSitMapIfc { nullptr };
|
||||
SituationReplayControlWidget *m_replayControlWidget{nullptr};
|
||||
|
||||
MarkerManagement::MarkerManagementDialogModel *m_markerModel{nullptr};
|
||||
QPointer<MarkerManagement::MarkerManagementApplyFilter> m_applyFilter;
|
||||
QJsonValue m_currentSettings;
|
||||
QJsonValue m_filterSettings;
|
||||
bool m_firstUpdate{true};
|
||||
|
||||
Ui::SituationReplayEditor *m_ui{nullptr};
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SituationReplayEditor</class>
|
||||
<widget class="QWidget" name="SituationReplayEditor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>785</width>
|
||||
<height>540</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Script Editor</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxStartTime">
|
||||
<property name="text">
|
||||
<string>Start:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="LtsWidgets::LtsDateTimeEdit" name="dteStartTime">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxEndTime">
|
||||
<property name="text">
|
||||
<string>End:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="LtsWidgets::LtsDateTimeEdit" name="dteEndTime">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbxSpeed">
|
||||
<property name="text">
|
||||
<string>Speed:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="sbSpeed">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string notr="true">x</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>16.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lbxDuration">
|
||||
<property name="text">
|
||||
<string>Duration:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="lblDuration">
|
||||
<property name="text">
|
||||
<string notr="true">%1 sec</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="cbFilterSettings">
|
||||
<property name="text">
|
||||
<string>Include Filter Settings</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="TopicEditorBase::TopicPreviewWidget" name="widget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="traditionalControlWidget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string extracomment="Um einen detailierteren Editor mit Direkt-Abspiel Möglichkeit zu erhalten, starten Sie zuerst die Hilfsansicht und öffnen dann diesen Dialog erneut.">(To obtain a more detailed editor with direct replay controls, open the essentials view, then reopen this dialog.)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblMrk">
|
||||
<property name="text">
|
||||
<string>Set Start & End by markers:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="markersDataView">
|
||||
<property name="showColumnCount" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonsVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDateTimeEdit</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_date_time_edit.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>TopicEditorBase::TopicPreviewWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>TopicEditorBase/topic_preview_widget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
|
||||
|
||||
|
||||
#include "replay_control_dialog.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
SituationReplayControlDialog::SituationReplayControlDialog(SituationReplayControlWidget *replayWidget, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_logger(getLogger("ReplayControlDialog"))
|
||||
{
|
||||
auto l = new QHBoxLayout;
|
||||
setLayout(l);
|
||||
|
||||
l->addWidget(replayWidget);
|
||||
replayWidget->show();
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Start_Situation_Playback"));
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlDialog::retranslate()
|
||||
{
|
||||
|
||||
const QString txt(tr("Replay Control"));
|
||||
translate(txt);
|
||||
}
|
||||
|
||||
}
|
||||
qt6-after/qt6-migrated-legatus/Lts/Plugins/SituationReplay/Gui/ReplayControl/replay_control_dialog.h
Executable
+25
@@ -0,0 +1,25 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "replay_control_widget.h"
|
||||
|
||||
#include <SituationReplay/logger.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
class SituationReplayControlDialog final : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SituationReplayControlDialog(SituationReplayControlWidget *replayWidget, QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
+448
@@ -0,0 +1,448 @@
|
||||
|
||||
|
||||
|
||||
#include "replay_control_gui_plugin.h"
|
||||
#include "replay_control_widget.h"
|
||||
#include "replay_control_dialog.h"
|
||||
#include "TopicEditor/topic_editor.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <SituationReplay/srp_operator_rights.h>
|
||||
#include <PresentationManagement/Gui/Script/Common/TakeHomePackageGenerator/export.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_script_filter_gui_plugin_interface.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
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("Plugins.Gui.Srp.ReplayControl"))
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_mrkDtc(nullptr)
|
||||
, m_playbackStartTime(-1)
|
||||
, m_playbackEndTime(-1)
|
||||
, m_playbackSpeed(-1)
|
||||
, m_replayWidget(nullptr)
|
||||
, m_sitMapIfc(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getDtc<DataInterface>(m_dtc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "No Srp Dtc in ReplayControl GUI Plugin with domainId " << m_session->domainId()
|
||||
<< " partition " << m_session->partitionId()
|
||||
<< " type " << m_session->partitionType();
|
||||
return false;
|
||||
}
|
||||
if (!m_session->getFtc<DataInterface>(m_ftc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "No Srp Ftc in ReplayControl GUI Plugin with domainId " << m_session->domainId()
|
||||
<< " partition " << m_session->partitionId()
|
||||
<< " type " << m_session->partitionType();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!m_session->getDtc<MarkerManagement::DataInterface>(m_mrkDtc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "(Optional) No Mrk Data Ifc in ReplayControl GUI Plugin with domainId " << m_session->domainId()
|
||||
<< " partition " << m_session->partitionId()
|
||||
<< " type " << m_session->partitionType();
|
||||
}
|
||||
|
||||
|
||||
LtsSession::Fetcher *fetcher = m_session->fetcher(QStringLiteral("Situation Replay Control"));
|
||||
|
||||
fetcher->getForeignGuiInterface(m_mrkIfc, QStringLiteral("marker selection in replay control"), true);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(m_sitMapGuiIfc))
|
||||
WARNING_LOG(m_logger) << "No Map Gui Ifc: " << m_session->toString();
|
||||
|
||||
return fetcher->status();
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::clearInterfaces()
|
||||
{
|
||||
if (m_replayWidget != nullptr)
|
||||
m_replayWidget->deleteLater();
|
||||
|
||||
m_mrkDtc = nullptr;
|
||||
m_ftc = nullptr;
|
||||
m_dtc = nullptr;
|
||||
m_sitMapGuiIfc = nullptr;
|
||||
m_mrkIfc = nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceImpl::startReplay(const qint64 start, const qint64 end, const double speed, const QJsonObject &attributes)
|
||||
{
|
||||
const QJsonValue mapConfig = attributes[QStringLiteral("settings")];
|
||||
if (mapConfig.isNull())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Note: Situation Map Script Filter settings is empty";
|
||||
}
|
||||
|
||||
createReplayDialogIfNeeded();
|
||||
|
||||
ERROR_LOG(m_logger) << "start = " << start << ", end = " << end << ", speed = " << speed << ", attributes: " << QString::fromUtf8(QJsonDocument(attributes).toJson());
|
||||
ERROR_LOG(m_logger) << "state = " << m_replayWidget->getReplayState() << ", replay id = " << m_replayWidget->getId();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return m_replayWidget->startReplay(start, end, speed);
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::pauseReplay()
|
||||
{
|
||||
createReplayDialogIfNeeded(false);
|
||||
m_replayWidget->pauseReplay();
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::stopReplay()
|
||||
{
|
||||
createReplayDialogIfNeeded(false);
|
||||
m_replayWidget->stopReplay();
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
if (m_session->partitionType() != IDL::PartitionType::Replay)
|
||||
return ret;
|
||||
|
||||
LtsWidgets::PluginData plData;
|
||||
|
||||
plData.menuGroup = menuGroup();
|
||||
|
||||
LtsSessionData::LtsSessionData *sd = LtsSessionData::LtsSessionData::getInstance();
|
||||
|
||||
if (sd->debugFlagValue(QStringLiteral("DoNotCreateInstant.ReplayControl")) == QVariant(true) &&
|
||||
(!sd->hasDebugFlag(QStringLiteral("DoNotCreateInstant.ReplayControl.Ignore")) || sd->debugFlagValue(QStringLiteral("DoNotCreateInstant.ReplayControl.Ignore")) == QVariant(false)))
|
||||
sd->setDebugFlagValue(QStringLiteral("DoNotCreateInstant.ReplayControl"), false);
|
||||
else
|
||||
plData.createInstant = LtsWidgets::CreateInstantType::CreateInstantAndAddAction;
|
||||
|
||||
plData.layoutArea = LtsWidgets::LayoutArea::eDialogTab;
|
||||
plData.menuText = tr("Playback Control");
|
||||
plData.identifier = QLatin1String("PlaybackControlDialog");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:load.svg"));
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eAfterAction;
|
||||
plData.createWidgetFunc = [this](QWidget *parent)
|
||||
{
|
||||
return onShowReplayControlDialog(parent);
|
||||
};
|
||||
ret.append(plData);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
QString InterfaceImpl::menuGroup() const
|
||||
{
|
||||
return tr("Playbacks");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InterfaceImpl::createReplayDialogIfNeeded(bool useExistingReplay)
|
||||
{
|
||||
if (m_replayWidget != nullptr)
|
||||
return;
|
||||
|
||||
m_replayWidget = qobject_cast<SituationReplayControlWidget *>(createControlWidget(useExistingReplay));
|
||||
}
|
||||
|
||||
|
||||
QWidget *InterfaceImpl::createControlWidget(bool useExistingReplay)
|
||||
{
|
||||
auto situationReplayControlWidget = new SituationReplayControlWidget;
|
||||
bool r = situationReplayControlWidget->init(m_session, m_dtc, m_ftc, m_mrkDtc, m_sitMapGuiIfc, m_session->partitionId(), useExistingReplay);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
situationReplayControlWidget->deleteLater();
|
||||
situationReplayControlWidget = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return situationReplayControlWidget;
|
||||
}
|
||||
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowReplayControlDialog(QWidget *)
|
||||
{
|
||||
|
||||
createReplayDialogIfNeeded();
|
||||
return new SituationReplayControlDialog(m_replayWidget);
|
||||
}
|
||||
|
||||
|
||||
TopicEditorBase::TopicEditor *InterfaceImpl::createTopicEditor(const TopicEditorBase::TopicData &data)
|
||||
{
|
||||
MarkerManagement::MarkerManagementDialogModel *markerModel = nullptr;
|
||||
|
||||
if (m_mrkIfc)
|
||||
markerModel = m_mrkIfc->createMarkerModel();
|
||||
else
|
||||
WARNING_LOG(m_logger) << "No Mrk Ifc for SitRep Topic Editor";
|
||||
|
||||
if (m_essentialsViewSrpIfc == nullptr)
|
||||
WARNING_LOG(m_logger) << "essentials view's srp ifc not available - no preview available";
|
||||
if (m_applyFilter == nullptr)
|
||||
WARNING_LOG(m_logger) << "m_applyFilter == nullptr";
|
||||
SituationReplayEditor *editor = new SituationReplayEditor(markerModel, m_applyFilter,
|
||||
m_session, nullptr, &m_essentialsViewSrpIfc, &m_essentialsViewSitMapIfc);
|
||||
QObject::connect(this, &InterfaceImpl::signalEssentialsViewChanged, editor, &SituationReplayEditor::onEssentialsViewChanged);
|
||||
editor->setTopicData(data);
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::setSitMapIfc(SituationMap::ForeignGuiInterface *sitMapIfc)
|
||||
{
|
||||
m_sitMapIfc = sitMapIfc;
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::setEssentialsViewInterfaces(ForeignGuiInterface *srpIfc, SituationMap::ForeignGuiInterface *sitMapIfc)
|
||||
{
|
||||
m_essentialsViewSrpIfc = srpIfc;
|
||||
m_essentialsViewSitMapIfc = sitMapIfc;
|
||||
emit signalEssentialsViewChanged(m_essentialsViewSrpIfc, m_essentialsViewSitMapIfc);
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::setApplyFilter(const QPointer<MarkerManagement::MarkerManagementApplyFilter> &applyFilter)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "setApplyFilter";
|
||||
m_applyFilter = applyFilter;
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceImpl::playbackInit(const QJsonObject& attributes)
|
||||
{
|
||||
QJsonDocument doc(attributes);
|
||||
DEBUG_LOG(m_logger) << "attributes=" << doc.toJson(QJsonDocument::Compact);
|
||||
|
||||
|
||||
const QJsonValue mapConfig = attributes[QStringLiteral("settings")];
|
||||
|
||||
if (!mapConfig.isNull())
|
||||
{
|
||||
|
||||
m_sitMapIfc->setOperatorMapSettings(mapConfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Note: map settings is empty";
|
||||
}
|
||||
|
||||
|
||||
const QJsonObject mapFilters = attributes[QStringLiteral("filters")].toObject();
|
||||
|
||||
if (m_applyFilter != nullptr && !mapFilters.isEmpty())
|
||||
{
|
||||
|
||||
m_applyFilter->applyFilter(mapFilters);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_applyFilter == nullptr)
|
||||
WARNING_LOG(m_logger) << "ApplyFilter missing for ReplayControl TopicReplayInterface";
|
||||
else if (mapFilters.isEmpty())
|
||||
WARNING_LOG(m_logger) << "Note: filter settings is empty";
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "Replay Control playbackInit";
|
||||
|
||||
m_playbackStartTime = attributes.value(QStringLiteral("start")).toDouble();
|
||||
m_playbackEndTime = attributes.value(QStringLiteral("end")).toDouble();
|
||||
m_playbackSpeed = attributes.value(QStringLiteral("speed")).toDouble();
|
||||
|
||||
bool result = (m_playbackStartTime != 0 && m_playbackEndTime != 0 && m_playbackSpeed != 0);
|
||||
if (!result)
|
||||
WARNING_LOG(m_logger) << "Invalid data for topic replay: start " << m_playbackStartTime
|
||||
<< " end " << m_playbackEndTime
|
||||
<< " speed " << m_playbackSpeed;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceImpl::playbackStart(int secondsOffset)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Playback start: m_playbackStartTime = " << m_playbackStartTime << ", offset = " << secondsOffset << ", speed = " << m_playbackSpeed;
|
||||
return startReplay(m_playbackStartTime + ((secondsOffset * m_playbackSpeed) * 1000), 0 , m_playbackSpeed);
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceImpl::playbackPause()
|
||||
{
|
||||
pauseReplay();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
InterfaceImpl::TopicReplayInterface::TopicReplayInterface(TopicEditorBase::TopicType type, InterfaceImpl *replayControl)
|
||||
: m_replayControl(replayControl)
|
||||
, m_type(type)
|
||||
{}
|
||||
|
||||
|
||||
InterfaceImpl::TopicReplayInterface::~TopicReplayInterface()
|
||||
{
|
||||
m_replayControl->stopReplay();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool InterfaceImpl::TopicReplayInterface::playbackInit(const QJsonObject &attributes)
|
||||
{
|
||||
return m_replayControl->playbackInit(attributes);
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceImpl::TopicReplayInterface::playbackStart(int secondsOffset)
|
||||
{
|
||||
return m_replayControl->playbackStart(secondsOffset);
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceImpl::TopicReplayInterface::playbackPause()
|
||||
{
|
||||
return m_replayControl->playbackPause();
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceImpl::TopicReplayInterface::exportTopic(const QJsonObject &attributes,
|
||||
const QString &folderPath,
|
||||
TopicEditorBase::ExportNotifier *pExportNotifier)
|
||||
{
|
||||
qint64 playbackStartTime_ms = attributes.value(QStringLiteral("start")).toDouble();
|
||||
qint64 playbackEndTime_ms = attributes.value(QStringLiteral("end")).toDouble();
|
||||
|
||||
|
||||
if (playbackStartTime_ms == 0 && playbackEndTime_ms == 0)
|
||||
{
|
||||
pExportNotifier->setExportFailed();
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString attributesFileName = QStringLiteral("sitreplay.json");
|
||||
QFile f(folderPath + attributesFileName);
|
||||
f.open(QIODevice::WriteOnly);
|
||||
f.write(QJsonDocument(attributes).toJson(QJsonDocument::Indented));
|
||||
f.close();
|
||||
|
||||
const QString strFileName = QStringLiteral("sitreplay.sqlite");
|
||||
bool success = TakeHomePackageGenerator::exportSituationMapData(
|
||||
m_replayControl->getSession()->exerciseId(), folderPath + strFileName, playbackStartTime_ms, playbackEndTime_ms
|
||||
);
|
||||
if (success)
|
||||
pExportNotifier->setExportSuccessful(strFileName);
|
||||
else
|
||||
pExportNotifier->setExportFailed();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
QVector<TopicEditorBase::TopicData> InterfaceImpl::TopicReplayInterface::additionalTrackEntries(const QJsonObject &attributes, bool &keepOriginalTopic) const
|
||||
{
|
||||
keepOriginalTopic = true;
|
||||
|
||||
if (m_type != TopicEditorBase::TopicType::Situation)
|
||||
return {};
|
||||
|
||||
keepOriginalTopic = false;
|
||||
|
||||
|
||||
|
||||
QVector<TopicEditorBase::TopicData> result;
|
||||
|
||||
|
||||
TopicEditorBase::TopicData data;
|
||||
data.topicType = TopicEditorBase::TopicType::SituationMap;
|
||||
result.append(data);
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<SituationMap::ScriptFilterForeignGuiInterface> filterIfc;
|
||||
if (!m_replayControl->m_session->getForeignGuiInterface<SituationMap::ScriptFilterForeignGuiInterface>(filterIfc))
|
||||
{
|
||||
ERROR_LOG(m_replayControl->m_logger) << "sitmap filter ifc missing - map filters for thp will be missing!";
|
||||
return result;
|
||||
}
|
||||
|
||||
QScopedPointer<TopicReplay::Interface> topicIfc(filterIfc->createInterface(TopicEditorBase::TopicType::SituationMapFilter));
|
||||
if (topicIfc == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_replayControl->m_logger) << "sitmap filter topic replay interface cannot be created - map filters will not be available in thp!";
|
||||
return result;
|
||||
}
|
||||
|
||||
result += topicIfc->additionalTrackEntries(attributes);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SituationReplay/logger.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <PluginInterfaces/topic_replay_interface.h>
|
||||
#include <Plugins/SituationReplay/srp_data_plugin_interface.h>
|
||||
#include <Plugins/SituationReplay/srp_gui_plugin_interface.h>
|
||||
#include <Plugins/MarkerManagement/mrk_data_plugin_interface.h>
|
||||
#include <Plugins/MarkerManagement/mrk_gui_plugin_interface.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <MarkerManagement/Gui/Common/mrk_apply_filter.h>
|
||||
#include <QPointer>
|
||||
|
||||
|
||||
namespace LtsScriptTimeline { class TopicEditor; }
|
||||
namespace TopicEditorBase { struct TopicData; }
|
||||
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
class SituationReplayControlWidget;
|
||||
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:srp")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QStringLiteral("SituationReplayControl"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return partition == IDL::PartitionType::Replay || partition == IDL::PartitionType::Exercise;
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class InterfaceImpl final : public QObject, public ForeignGuiInterface, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void signalEssentialsViewChanged(SituationReplay::ForeignGuiInterface *essentialsViewSrpIfc,
|
||||
SituationMap::ForeignGuiInterface *sitMapIfc);
|
||||
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
QString menuGroup() const override;
|
||||
bool fetchInterfaces() override;
|
||||
void clearInterfaces() override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override { return partition == IDL::PartitionType::Replay; }
|
||||
|
||||
bool startReplay(const qint64 start, const qint64 end = 0, const double speed = 1.0, const QJsonObject &attributes = QJsonObject()) override;
|
||||
void pauseReplay() override;
|
||||
void stopReplay() override;
|
||||
|
||||
|
||||
void setSitMapIfc(SituationMap::ForeignGuiInterface *sitMapIfc) override;
|
||||
void setEssentialsViewInterfaces(ForeignGuiInterface *srpIfc, SituationMap::ForeignGuiInterface *sitMapIfc) override;
|
||||
void setApplyFilter(const QPointer<MarkerManagement::MarkerManagementApplyFilter> &applyFilter) override;
|
||||
|
||||
|
||||
bool playbackInit(const QJsonObject &attributes);
|
||||
bool playbackStart(int secondsOffset);
|
||||
bool playbackPause();
|
||||
|
||||
|
||||
|
||||
TopicEditorBase::TopicEditor *createTopicEditor(const TopicEditorBase::TopicData &data) override;
|
||||
|
||||
LtsSession::LtsSession* getSession() { return m_session; }
|
||||
QWidget *createControlWidget(bool useExistingReplay) override;
|
||||
|
||||
private:
|
||||
void createReplayDialogIfNeeded(bool useExistingReplay = true);
|
||||
LtsWidgets::LtsDialog *onShowReplayControlDialog(QWidget *parent);
|
||||
|
||||
private:
|
||||
std::shared_ptr<SituationReplay::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<SituationReplay::Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<MarkerManagement::Interface::Dtc> m_mrkDtc;
|
||||
std::shared_ptr<MarkerManagement::ForeignGuiInterface> m_mrkIfc;
|
||||
SituationReplay::ForeignGuiInterface *m_essentialsViewSrpIfc { nullptr };
|
||||
SituationMap::ForeignGuiInterface *m_essentialsViewSitMapIfc { nullptr };
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
|
||||
|
||||
qint64 m_playbackStartTime;
|
||||
qint64 m_playbackEndTime;
|
||||
double m_playbackSpeed;
|
||||
QPointer<SituationReplayControlWidget> m_replayWidget;
|
||||
|
||||
QPointer<MarkerManagement::MarkerManagementApplyFilter> m_applyFilter;
|
||||
|
||||
|
||||
SituationMap::ForeignGuiInterface *m_sitMapIfc { nullptr };
|
||||
|
||||
|
||||
class TopicReplayInterface : public TopicReplay::Interface
|
||||
{
|
||||
public:
|
||||
explicit TopicReplayInterface(TopicEditorBase::TopicType type, InterfaceImpl *replayControl);
|
||||
~TopicReplayInterface();
|
||||
|
||||
|
||||
bool playbackInit(const QJsonObject &attributes) override;
|
||||
bool playbackStart(int secondsOffset) override;
|
||||
bool playbackPause() override;
|
||||
|
||||
bool exportTopic(const QJsonObject &attributes,
|
||||
const QString &folderPath,
|
||||
TopicEditorBase::ExportNotifier *pExportNotifier) override;
|
||||
QVector<TopicEditorBase::TopicData> additionalTrackEntries(const QJsonObject &attributes, bool &keepOriginalTopic) const override;
|
||||
|
||||
private:
|
||||
InterfaceImpl *m_replayControl;
|
||||
TopicEditorBase::TopicType m_type;
|
||||
};
|
||||
TopicReplay::Interface *createInterface(TopicEditorBase::TopicType type) override
|
||||
{
|
||||
return new TopicReplayInterface(type, this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+765
@@ -0,0 +1,765 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "replay_control_widget.h"
|
||||
#include "replay_control_dialog.h"
|
||||
#include "ui_replay_control_widget.h"
|
||||
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <OperatorManagement/opm_data_plugin_interface.h>
|
||||
#include <MarkerManagement/Gui/Common/mrk_dialog_model.h>
|
||||
#include <MarkerManagement/Gui/Common/mrk_apply_filter.h>
|
||||
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <SituationMap/Map/operator_map_settings.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
SituationReplayControlWidget::SituationReplayControlWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::SituationReplayControlWidget)
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_mrkDtc(nullptr)
|
||||
, m_markerModel(nullptr)
|
||||
, m_sitMapGuiIfc(nullptr)
|
||||
, m_exmDtc(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this, true))
|
||||
, m_id(0)
|
||||
, m_partitionId(0)
|
||||
, m_state(SrpState::Unknown)
|
||||
, m_toggleStartPauseButton(true)
|
||||
, m_speedValueChangedTimer(new QTimer(this))
|
||||
, m_logger(getLogger("SituationReplayControlWidget"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->pbStart->setHidden(m_toggleStartPauseButton);
|
||||
m_ui->pbPause->setHidden(m_toggleStartPauseButton);
|
||||
m_ui->pbStartPause->setHidden(!m_toggleStartPauseButton);
|
||||
|
||||
|
||||
m_ui->lblCurrentPartitionTime->setProperty("const", true);
|
||||
m_ui->slPeriodSlider->setProperty("const", true);
|
||||
m_ui->lblStart->setProperty("const", true);
|
||||
m_ui->lblEnd->setProperty("const", true);
|
||||
m_ui->lblSpeedVal->setProperty("const", true);
|
||||
m_ui->slSpeed->setProperty("const", true);
|
||||
m_ui->pbStartPause->setProperty("const", true);
|
||||
m_ui->dteStartTime->setProperty("const", true);
|
||||
m_ui->dteStartTime->setSubWidgetsProperties(QStringLiteral("const"), true);
|
||||
|
||||
connect(m_ui->pbStartPause, &QToolButton::toggled,
|
||||
this, &SituationReplayControlWidget::onStartPauseButtonToggled);
|
||||
|
||||
connect(m_ui->pbStart, &QToolButton::clicked,
|
||||
this, &SituationReplayControlWidget::onStartReplay);
|
||||
connect(m_ui->pbStop, &QToolButton::clicked,
|
||||
this, &SituationReplayControlWidget::onStopReplay);
|
||||
connect(m_ui->pbPause, &QToolButton::clicked,
|
||||
this, &SituationReplayControlWidget::onPauseResumeReplay);
|
||||
|
||||
m_speedValueChangedTimer->setSingleShot(true);
|
||||
connect(m_speedValueChangedTimer, &QTimer::timeout,
|
||||
this, &SituationReplayControlWidget::onSpeedValueChanged);
|
||||
|
||||
connect(m_ui->slSpeed, &QSlider::valueChanged, this, [this](int val)
|
||||
{
|
||||
m_ui->lblSpeedVal->setText(QStringLiteral("%1").arg(val * 10.0, 0));
|
||||
m_speedValueChangedTimer->start(500);
|
||||
});
|
||||
|
||||
connect(m_ui->pbSetStart, &QPushButton::clicked,
|
||||
this, [this]()
|
||||
{
|
||||
emit signalSetStart(m_ui->dteStartTime->msecsSinceEpoch());
|
||||
});
|
||||
|
||||
connect(m_ui->pbSetEnd, &QPushButton::clicked,
|
||||
this, [this]()
|
||||
{
|
||||
emit signalSetEnd(m_ui->dteStartTime->msecsSinceEpoch());
|
||||
});
|
||||
|
||||
const QFontMetricsF fm(m_ui->lblSpeedVal->font());
|
||||
const QRectF rectSpeedVal = fm.boundingRect(QStringLiteral("000.0"));
|
||||
m_ui->lblSpeedVal->setFixedWidth(qRound(rectSpeedVal.width()));
|
||||
m_ui->slSpeed->setValue(10.0);
|
||||
|
||||
showEditorWidget(false);
|
||||
}
|
||||
|
||||
|
||||
SituationReplayControlWidget::~SituationReplayControlWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
bool SituationReplayControlWidget::init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<MarkerManagement::Interface::Dtc> &mrkDtc,
|
||||
const std::shared_ptr<SituationMap::ForeignGuiInterface> &sitMapGuiIfc,
|
||||
int partitionId, bool useExistingReplay)
|
||||
{
|
||||
m_session = session;
|
||||
m_dtc = dtc;
|
||||
m_ftc = ftc;
|
||||
m_mrkDtc = mrkDtc;
|
||||
m_partitionId = partitionId;
|
||||
m_sitMapGuiIfc = sitMapGuiIfc;
|
||||
|
||||
if (!m_session->getDtc<ExerciseManagement::DataInterface>(m_exmDtc))
|
||||
{
|
||||
ERROR_LOG(m_logger)<<" couldn't init exmDtc!";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ui->pbStart->setText(tr("Start"));
|
||||
m_ui->pbStop->setText(tr("Stop"));
|
||||
m_ui->pbPause->setText(tr("Pause"));
|
||||
m_ui->pbStartPause->setToolTip(tr("Start"));
|
||||
|
||||
|
||||
m_dtc->waitForHistoricalDataSitReplay(20000);
|
||||
|
||||
|
||||
if (useExistingReplay)
|
||||
{
|
||||
useExistingReplay = false;
|
||||
|
||||
const QMap<qint32, SituationReplay::SitReplay> replays = m_dtc->sitReplays();
|
||||
for (const SituationReplay::SitReplay &replay : replays)
|
||||
{
|
||||
if (replay.replayPartitionId() == m_partitionId)
|
||||
{
|
||||
m_state = replay.state();
|
||||
m_id = replay.id();
|
||||
DEBUG_LOG(m_logger) << "recycling replay with id" << m_id;
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(replay.beginTime());
|
||||
useExistingReplay = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_ui->dteStartTime->setRetrieveCurrentTimeCallback([]() { return QDateTime::currentMSecsSinceEpoch(); });
|
||||
enaDisa();
|
||||
|
||||
|
||||
connect(m_dtc.get(), &Interface::Dtc::sitReplayChanged,
|
||||
this, &SituationReplayControlWidget::onSitReplayChanged);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
connect(m_session, &LtsSession::LtsSession::partitionTimeChanged,
|
||||
this, &SituationReplayControlWidget::onPartitionTimeChanged);
|
||||
|
||||
connect(m_ui->slPeriodSlider, &QSlider::valueChanged, this,
|
||||
&SituationReplayControlWidget::onPeriodSliderChanged);
|
||||
connect(m_ui->dteStartTime, &LtsWidgets::LtsDateTimeEdit::dateTimeChanged, this,
|
||||
&SituationReplayControlWidget::onDteStartChanged);
|
||||
|
||||
|
||||
|
||||
QTimer *t = new QTimer(this);
|
||||
t->setInterval(200);
|
||||
|
||||
connect(t, &QTimer::timeout,
|
||||
this, [this]()
|
||||
{
|
||||
m_endTime = QDateTime::currentMSecsSinceEpoch();
|
||||
m_ui->lblEnd->setText(DTG::toStringMSec(m_endTime));
|
||||
m_ui->slPeriodSlider->setMaximum(getSecs(m_endTime));
|
||||
});
|
||||
|
||||
|
||||
const ExerciseManagement::Exercise &exercise = m_exmDtc->exercise(m_session->exerciseId());
|
||||
const qint64 stopTime = exercise.stopTime();
|
||||
if (stopTime > 0)
|
||||
{
|
||||
m_ui->lblEnd->setText(DTG::toStringMSec(stopTime));
|
||||
m_ui->slPeriodSlider->setMaximum(getSecs(stopTime));
|
||||
m_endTime = stopTime;
|
||||
}
|
||||
else
|
||||
t->start();
|
||||
|
||||
|
||||
|
||||
if (!useExistingReplay)
|
||||
{
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> excDtc;
|
||||
if (session->getDtc<ExerciseManagement::DataInterface>(excDtc))
|
||||
{
|
||||
int excId = session->exerciseId();
|
||||
|
||||
excDtc->waitForHistoricalDataExercise(3000);
|
||||
ExerciseManagement::Exercise exc = excDtc->exercise(excId);
|
||||
qint64 startTime = exc.startTime();
|
||||
|
||||
if (startTime > 0)
|
||||
{
|
||||
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(startTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 beginTime = exc.beginTime();
|
||||
|
||||
if (beginTime > 0)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "no exc start time set, using exc begin time " << beginTime;
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(beginTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARNING_LOG(m_logger) << "no valid exc for getting exercise start time";
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(QDateTime::currentDateTime().addDays(-5).toMSecsSinceEpoch());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WARNING_LOG(m_logger) << "no exc dtc for getting exercise start time";
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(QDateTime::currentDateTime().addDays(-5).toMSecsSinceEpoch());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
qint64 startInSecs = getSecs(m_ui->dteStartTime->msecsSinceEpoch());
|
||||
qint64 endInSecs = QDateTime::currentSecsSinceEpoch();
|
||||
|
||||
m_ui->slPeriodSlider->setMinimum(startInSecs);
|
||||
m_ui->slPeriodSlider->setMaximum(endInSecs);
|
||||
|
||||
{
|
||||
QSignalBlocker blocker(m_ui->slPeriodSlider);
|
||||
m_ui->slPeriodSlider->setValue(startInSecs);
|
||||
}
|
||||
|
||||
m_ui->lblStart->setText(DTG::toStringMSec(getMSecs(startInSecs)));
|
||||
m_ui->lblEnd->setText(DTG::toStringMSec(getMSecs(endInSecs)));
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> opmDtc;
|
||||
m_session->getDtc<OperatorManagement::DataInterface>(opmDtc);
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> flmGui;
|
||||
m_session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(flmGui);
|
||||
m_markerModel = new MarkerManagement::MarkerManagementDialogModel(this);
|
||||
m_markerModel->initModel(m_mrkDtc, opmDtc, flmGui);
|
||||
m_ui->tvMarker->setModel(m_markerModel);
|
||||
m_ui->tvMarker->hideColumn(MarkerManagement::MarkerManagementDialogModel::ColImage);
|
||||
m_ui->tvMarker->hideColumn(MarkerManagement::MarkerManagementDialogModel::ColFileId);
|
||||
m_ui->tvMarker->hideColumn(MarkerManagement::MarkerManagementDialogModel::ColOffset);
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->tvMarker->hideColumn(MarkerManagement::MarkerManagementDialogModel::ColStreams);
|
||||
#endif
|
||||
m_ui->tvMarker->setSortIndicator(MarkerManagement::MarkerManagementDialogModel::ColTime, Qt::DescendingOrder);
|
||||
|
||||
|
||||
const int curOpId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
if (!m_ui->tvMarker->setInitialSearchContent(MarkerManagement::MarkerManagementDialogModel::ColOperator, curOpId))
|
||||
{
|
||||
QTimer::singleShot(200, this, [this, curOpId]
|
||||
{
|
||||
m_ui->tvMarker->setInitialSearchContent(MarkerManagement::MarkerManagementDialogModel::ColOperator, curOpId);
|
||||
});
|
||||
}
|
||||
|
||||
connect(m_ui->tvMarker, &LtsDataView::LtsDataView::activated, this, &SituationReplayControlWidget::onMarkerClicked);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
qint64 SituationReplayControlWidget::startTime() const
|
||||
{
|
||||
return m_ui->dteStartTime->msecsSinceEpoch();
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::setStartTime(qint64 startTime)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " " << startTime;
|
||||
if (startTime < 0)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " called with invalid start time: " << startTime;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ui->dteStartTime->msecsSinceEpoch() == startTime)
|
||||
return;
|
||||
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(startTime);
|
||||
emit signalSetStart(startTime);
|
||||
}
|
||||
|
||||
|
||||
int SituationReplayControlWidget::speed() const
|
||||
{
|
||||
return m_ui->slSpeed->value();
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::setSpeed(int speed)
|
||||
{
|
||||
m_ui->slSpeed->setValue(speed);
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::showEditorWidget(bool visibility)
|
||||
{
|
||||
m_ui->editorWidget->setVisible(visibility);
|
||||
}
|
||||
|
||||
|
||||
bool SituationReplayControlWidget::startReplay(qint64 start, qint64 end, double speed)
|
||||
{
|
||||
stopReplay();
|
||||
|
||||
disableAllReplayButtons();
|
||||
|
||||
QTimer::singleShot(1 * 647, this, [this, start, end, speed]()
|
||||
{
|
||||
startReplayDelayed(start, end, speed);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::disableAllReplayButtons()
|
||||
{
|
||||
m_ui->pbStart->setEnabled(false);
|
||||
m_ui->slPeriodSlider->setEnabled(false);
|
||||
m_ui->dteStartTime->setEnabled(false);
|
||||
m_ui->tvMarker->setEnabled(false);
|
||||
m_ui->pbStop->setEnabled(false);
|
||||
m_ui->pbPause->setEnabled(false);
|
||||
m_ui->pbStartPause->setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::pauseReplay()
|
||||
{
|
||||
if (m_sitMapGuiIfc != nullptr)
|
||||
m_sitMapGuiIfc->enableFireEventFlashing(false);
|
||||
|
||||
if (m_id == 0)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "replay pause requested, but no replay active in this context";
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_state == SrpState::Resumed || m_state == SrpState::Started)
|
||||
{
|
||||
disableAllReplayButtons();
|
||||
|
||||
ChangeReplayStateRequest req;
|
||||
req.id(m_id);
|
||||
req.replayPartitionId(m_partitionId);
|
||||
req.state(SrpState::Paused);
|
||||
req.pace(m_ui->slSpeed->value() / 10.);
|
||||
|
||||
if (!m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->changeReplayStateRequest(req, this);
|
||||
}))
|
||||
{
|
||||
enaDisa();
|
||||
ERROR_LOG(m_logger) << "pausing failed for replay " << m_id << ": " << m_requestHelper->getErrorString();
|
||||
}
|
||||
else
|
||||
emit replayPaused();
|
||||
}
|
||||
else
|
||||
ERROR_LOG(m_logger) << "pause requested, but replay state was not resumed or started, but " << m_state << " for " << m_id;
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::stopReplay()
|
||||
{
|
||||
if (m_sitMapGuiIfc != nullptr)
|
||||
m_sitMapGuiIfc->enableFireEventFlashing(true);
|
||||
|
||||
if (m_id == 0)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "replay stop requested, but no replay active in this context";
|
||||
return;
|
||||
}
|
||||
|
||||
disableAllReplayButtons();
|
||||
|
||||
ChangeReplayStateRequest req;
|
||||
req.id(m_id);
|
||||
req.replayPartitionId(m_partitionId);
|
||||
req.state(SrpState::Stopped);
|
||||
|
||||
|
||||
const bool wasQuiet = m_requestHelper->quiet();
|
||||
m_requestHelper->setQuiet(false);
|
||||
if (m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->changeReplayStateRequest(req, this);
|
||||
}))
|
||||
{
|
||||
m_ui->pbStartPause->setChecked(false);
|
||||
m_ui->pbStartPause->setToolTip(tr("Start"));
|
||||
m_id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
enaDisa();
|
||||
ERROR_LOG(m_logger) << "stopping failed for replay " << m_id << ": " << m_requestHelper->getErrorString();
|
||||
}
|
||||
|
||||
m_requestHelper->setQuiet(wasQuiet);
|
||||
emit replayStopped();
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::resumeReplay()
|
||||
{
|
||||
if (m_sitMapGuiIfc != nullptr)
|
||||
m_sitMapGuiIfc->enableFireEventFlashing(true);
|
||||
|
||||
disableAllReplayButtons();
|
||||
|
||||
ChangeReplayStateRequest req;
|
||||
req.id(m_id);
|
||||
req.replayPartitionId(m_partitionId);
|
||||
req.state(SrpState::Resumed);
|
||||
req.beginTime(m_ui->dteStartTime->msecsSinceEpoch());
|
||||
req.endTime(0);
|
||||
req.pace(m_ui->slSpeed->value() / 10.);
|
||||
|
||||
if (!m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->changeReplayStateRequest(req, this);
|
||||
}))
|
||||
{
|
||||
enaDisa();
|
||||
ERROR_LOG(m_logger) << "resuming failed for replay " << m_id << ": " << m_requestHelper->getErrorString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onSitReplayChanged(const SitReplay &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSitReplayChanged: id = " << data.id() << ", exId = " << data.exerciseId() << ", repPartitionId = " << data.replayPartitionId()
|
||||
<< ", state = " << (int)data.state().underlying() << ", m_partitionId = " << m_partitionId << ", modType = " << (int)modType;
|
||||
|
||||
if (m_partitionId != data.replayPartitionId())
|
||||
return;
|
||||
|
||||
if (modType == DataModification::eAdded ||
|
||||
modType == DataModification::eModified)
|
||||
m_state = data.state();
|
||||
else
|
||||
m_state = SrpState::Stopped;
|
||||
|
||||
enaDisa();
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onPartitionTimeChanged(qint64 newPartitionTime)
|
||||
{
|
||||
const qint64 &partTime = getSecs(newPartitionTime);
|
||||
|
||||
if (partTime < getSecs(m_endTime) )
|
||||
m_ui->lblCurrentPartitionTime->setText(DTG::toStringMSec(newPartitionTime));
|
||||
else
|
||||
stopReplay();
|
||||
|
||||
m_ui->slPeriodSlider->setValue(getSecs(newPartitionTime));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onMarkerClicked(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
MarkerManagement::Marker marker = m_markerModel->getRowData(index.row());
|
||||
const qint64 mSecsSinceEpoch = marker.timeStamp() - marker.timeStampOffset();
|
||||
m_ui->slPeriodSlider->setValue(getSecs(mSecsSinceEpoch));
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(mSecsSinceEpoch);
|
||||
|
||||
|
||||
MarkerManagement::MarkerManagementApplyFilter *appFilter = nullptr;
|
||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> fltParticipantIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> fltAesIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> fltBuildingComponentGuiIfc;
|
||||
if (m_session->getForeignGuiInterface(fltParticipantIfc) &&
|
||||
m_session->getForeignGuiInterface(fltAesIfc)
|
||||
|
||||
)
|
||||
appFilter = new MarkerManagement::MarkerManagementApplyFilter(m_session, fltParticipantIfc, fltAesIfc, fltBuildingComponentGuiIfc);
|
||||
else
|
||||
WARNING_LOG(m_logger) << "unable to set filters from marker as flt ifc`s are missing";
|
||||
|
||||
|
||||
|
||||
if (marker.filter().size() > 0 && appFilter != nullptr)
|
||||
{
|
||||
QByteArray mapFilter(QByteArray::fromRawData(marker.filter().c_str(), marker.filter().size()));
|
||||
if (appFilter->applyFilter(mapFilter))
|
||||
emit signalSetMapFilter(mapFilter);
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Error while setting filters";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (m_sitMapGuiIfc != nullptr)
|
||||
{
|
||||
const std::vector<MarkerManagement::MarkerDescription> &descriptionsRef = marker.descriptions();
|
||||
QList<MarkerManagement::MarkerType> markerTypes;
|
||||
markerTypes.reserve(descriptionsRef.size());
|
||||
for (const MarkerManagement::MarkerDescription &desc : qAsConst(descriptionsRef))
|
||||
markerTypes.append(desc.markerType());
|
||||
|
||||
if (markerTypes.contains(MarkerManagement::MarkerType_def::Situation))
|
||||
m_sitMapGuiIfc->setCenterPoint(QPointF(marker.position().lon(), marker.position().lat()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (appFilter)
|
||||
{
|
||||
QByteArray mapSettings(QByteArray::fromRawData(marker.mapSettings().c_str(), marker.mapSettings().size()));
|
||||
DEBUG_LOG(m_logger) << "set map settings from marker " << (mapSettings.toStdString());
|
||||
|
||||
|
||||
|
||||
SituationMap::OperatorMapSettings oms;
|
||||
oms.fromJson(mapSettings);
|
||||
DEBUG_LOG(m_logger) << ">>>> oms.orderedLayers.size() " << oms.orderedLayers.size();
|
||||
|
||||
static const QLatin1String LayerNameEmergencyCall("EmergencyCall");
|
||||
|
||||
auto pos = std::remove_if( oms.orderedLayers.begin(),
|
||||
oms.orderedLayers.end(),
|
||||
[](const QPair<QString, SituationMap::LayerParameter> &pair) { return pair.first == LayerNameEmergencyCall; } );
|
||||
DEBUG_LOG(m_logger) << ">>>> remove iterator: " << pos << " END: " << oms.orderedLayers.end();
|
||||
if(pos != oms.orderedLayers.end())
|
||||
oms.orderedLayers.erase(pos);
|
||||
|
||||
|
||||
mapSettings = oms.toJson();
|
||||
|
||||
|
||||
if (appFilter->applyMapSettings(mapSettings))
|
||||
emit signalSetMapSettings(mapSettings);
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Error while setting mapSettings";
|
||||
}
|
||||
delete appFilter;
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::enaDisa()
|
||||
{
|
||||
bool enaStart = false;
|
||||
bool enaStop = false;
|
||||
bool enaPause = false;
|
||||
|
||||
switch (m_state.underlying())
|
||||
{
|
||||
case SrpState::Paused:
|
||||
enaStart = false;
|
||||
enaStop = true;
|
||||
enaPause = false;
|
||||
break;
|
||||
case SrpState::Resumed:
|
||||
case SrpState::Started:
|
||||
enaStart = false;
|
||||
enaStop = true;
|
||||
enaPause = true;
|
||||
break;
|
||||
case SrpState::Unknown:
|
||||
case SrpState::Stopped:
|
||||
enaStart = true;
|
||||
enaStop = false;
|
||||
enaPause = false;
|
||||
break;
|
||||
}
|
||||
|
||||
m_ui->pbStart->setEnabled(enaStart);
|
||||
m_ui->slPeriodSlider->setEnabled(!enaPause);
|
||||
m_ui->dteStartTime->setEnabled(!enaPause);
|
||||
m_ui->tvMarker->setEnabled(enaStart);
|
||||
m_ui->pbStop->setEnabled(enaStop);
|
||||
m_ui->pbPause->setEnabled(enaPause);
|
||||
m_ui->pbStartPause->setEnabled(true);
|
||||
|
||||
QSignalBlocker sb(m_ui->pbStartPause);
|
||||
m_ui->pbStartPause->setChecked(enaPause);
|
||||
}
|
||||
|
||||
|
||||
bool SituationReplayControlWidget::startReplayDelayed(qint64 start, qint64 end, double speed)
|
||||
{
|
||||
SituationMap::SitMapUpdatesEnabledHelper sitMapHelper(m_sitMapGuiIfc);
|
||||
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(start);
|
||||
|
||||
{
|
||||
QSignalBlocker block(m_ui->slSpeed);
|
||||
m_ui->slSpeed->setValue(qRound(speed * 10));
|
||||
}
|
||||
|
||||
ChangeReplayStateRequest req;
|
||||
req.id(m_id);
|
||||
req.replayPartitionId(m_partitionId);
|
||||
req.state(SrpState::Started);
|
||||
req.beginTime(start);
|
||||
req.endTime(end);
|
||||
req.pace(speed);
|
||||
|
||||
ERROR_LOG(m_logger) << "Start Replay Partition: "
|
||||
<< "id: " << m_id
|
||||
<< ", partition id: " << m_partitionId
|
||||
<< ", partition type: " << m_session->partitionType()
|
||||
<< ", start: " << start
|
||||
<< ", end: " << end
|
||||
<< ", speed: " << speed;
|
||||
|
||||
if (m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->changeReplayStateRequest(req, this);
|
||||
}))
|
||||
{
|
||||
int repliedId = m_requestHelper->getRepliedId();
|
||||
|
||||
if (repliedId > 0)
|
||||
{
|
||||
m_id = repliedId;
|
||||
ERROR_LOG(m_logger) << "Replied replay id: " << repliedId;
|
||||
emit replayStarted();
|
||||
return true;
|
||||
}
|
||||
|
||||
ERROR_LOG(m_logger) << "replay start didn't return a replay id!";
|
||||
}
|
||||
|
||||
ERROR_LOG(m_logger) << "could not start replay: " << m_requestHelper->getErrorString() << " (" << m_requestHelper->getRepliedId() << ")";
|
||||
enaDisa();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onStartReplay()
|
||||
{
|
||||
double speed = m_ui->slSpeed->value();
|
||||
speed /= 10;
|
||||
qint64 startInSecs = getSecs(m_ui->dteStartTime->msecsSinceEpoch());
|
||||
DEBUG_LOG(m_logger) << "onStartReplay startInSecs=" << startInSecs;
|
||||
m_ui->slPeriodSlider->setValue(startInSecs);
|
||||
|
||||
startReplay(m_ui->dteStartTime->msecsSinceEpoch(), 0 , speed);
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onStopReplay()
|
||||
{
|
||||
stopReplay();
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onPauseResumeReplay()
|
||||
{
|
||||
if (m_state == SrpState::Resumed || m_state == SrpState::Started)
|
||||
pauseReplay();
|
||||
else if (m_state == SrpState::Paused)
|
||||
resumeReplay();
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onStartPauseButtonToggled(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
{
|
||||
if (m_state == SrpState::Paused)
|
||||
{
|
||||
onPauseResumeReplay();
|
||||
m_ui->pbStartPause->setToolTip(tr("Pause"));
|
||||
}
|
||||
else
|
||||
{
|
||||
onStartReplay();
|
||||
m_ui->pbStartPause->setToolTip(tr("Pause"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onPauseResumeReplay();
|
||||
m_ui->pbStartPause->setToolTip(tr("Continue"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onSpeedValueChanged()
|
||||
{
|
||||
double speed = m_ui->slSpeed->value() / 10.;
|
||||
emit signalSetSpeed(speed);
|
||||
|
||||
if (m_id == 0 || (m_state != SrpState::Resumed && m_state != SrpState::Started))
|
||||
return;
|
||||
|
||||
ChangeReplayStateRequest req;
|
||||
req.id(m_id);
|
||||
req.replayPartitionId(m_partitionId);
|
||||
req.pace(speed);
|
||||
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->changeReplayStateRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onPeriodSliderChanged(int seconds)
|
||||
{
|
||||
m_ui->dteStartTime->setMsecsSinceEpoch(getMSecs(seconds));
|
||||
}
|
||||
|
||||
|
||||
void SituationReplayControlWidget::onDteStartChanged()
|
||||
{
|
||||
qint64 startInSecs = getSecs(m_ui->dteStartTime->msecsSinceEpoch());
|
||||
|
||||
QSignalBlocker block(m_ui->slPeriodSlider);
|
||||
m_ui->slPeriodSlider->setValue(startInSecs);
|
||||
}
|
||||
|
||||
|
||||
qint64 SituationReplayControlWidget::getMSecs(qint64 sec)
|
||||
{
|
||||
return sec * 1000;
|
||||
}
|
||||
|
||||
|
||||
qint64 SituationReplayControlWidget::getSecs(qint64 msec)
|
||||
{
|
||||
return msec / 1000;
|
||||
}
|
||||
|
||||
}
|
||||
qt6-after/qt6-migrated-legatus/Lts/Plugins/SituationReplay/Gui/ReplayControl/replay_control_widget.h
Executable
+121
@@ -0,0 +1,121 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SituationReplay/srp_ftc.h>
|
||||
#include <SituationReplay/srp_dtc.h>
|
||||
#include <SituationReplay/logger.h>
|
||||
|
||||
#include <Plugins/MarkerManagement/mrk_data_plugin_interface.h>
|
||||
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
|
||||
|
||||
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
|
||||
namespace MarkerManagement
|
||||
{
|
||||
class MarkerManagementDialogModel;
|
||||
}
|
||||
namespace Ui
|
||||
{
|
||||
class SituationReplayControlWidget;
|
||||
}
|
||||
class QTimer;
|
||||
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
|
||||
|
||||
class SituationReplayControlWidget final : public QWidget
|
||||
, protected Interface::Ftc::ChangeReplayStateReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SituationReplayControlWidget(QWidget *parent = nullptr);
|
||||
~SituationReplayControlWidget();
|
||||
|
||||
bool init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<MarkerManagement::Interface::Dtc> &mrkDtc,
|
||||
const std::shared_ptr<SituationMap::ForeignGuiInterface> &sitMapGuiIfc,
|
||||
int partitionId, bool useExistingReplay = true);
|
||||
|
||||
void onChangeReplayStateReply(const Core::FunctionReplyObject &replyObject) override final
|
||||
{
|
||||
|
||||
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
|
||||
}
|
||||
|
||||
|
||||
qint64 startTime() const;
|
||||
void setStartTime(qint64 startTime);
|
||||
|
||||
int speed() const;
|
||||
void setSpeed(int speed);
|
||||
|
||||
void showEditorWidget(bool visibility = true);
|
||||
|
||||
bool startReplay(qint64 start, qint64 end = 0 , double speed = 1.0f);
|
||||
void pauseReplay();
|
||||
void stopReplay();
|
||||
void resumeReplay();
|
||||
SrpState getReplayState() { return m_state; }
|
||||
int getId() { return m_id; }
|
||||
|
||||
signals:
|
||||
void signalSetStart(qint64 start);
|
||||
void signalSetEnd(qint64 end);
|
||||
void signalSetSpeed(double speed);
|
||||
void signalSetMapFilter(const QByteArray &mapFilter);
|
||||
void signalSetMapSettings(const QByteArray &mapSettings);
|
||||
void replayStarted();
|
||||
void replayPaused();
|
||||
void replayStopped();
|
||||
|
||||
private slots:
|
||||
void onSitReplayChanged(const SitReplay &data, DataModification modType);
|
||||
void onPartitionTimeChanged(qint64 newPartitionTime);
|
||||
void onMarkerClicked(const QModelIndex &index);
|
||||
void enaDisa();
|
||||
bool startReplayDelayed(qint64 start, qint64 end = 0 , double speed = 1.0f);
|
||||
void onStartReplay();
|
||||
void onStopReplay();
|
||||
void onPauseResumeReplay();
|
||||
void onStartPauseButtonToggled(bool checked);
|
||||
void onSpeedValueChanged();
|
||||
void onPeriodSliderChanged(int seconds);
|
||||
void onDteStartChanged();
|
||||
|
||||
private:
|
||||
void disableAllReplayButtons();
|
||||
qint64 getMSecs(qint64 sec);
|
||||
qint64 getSecs(qint64 msec);
|
||||
|
||||
Ui::SituationReplayControlWidget *m_ui;
|
||||
LtsSession::LtsSession *m_session;
|
||||
std::shared_ptr<SituationReplay::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<SituationReplay::Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<MarkerManagement::Interface::Dtc> m_mrkDtc;
|
||||
MarkerManagement::MarkerManagementDialogModel *m_markerModel;
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
int m_id;
|
||||
int m_partitionId;
|
||||
SrpState m_state;
|
||||
qint64 m_endTime;
|
||||
bool m_toggleStartPauseButton;
|
||||
QTimer *m_speedValueChangedTimer;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
+361
@@ -0,0 +1,361 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SituationReplayControlWidget</class>
|
||||
<widget class="QWidget" name="SituationReplayControlWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>849</width>
|
||||
<height>520</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Replay Control</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Current Partition Time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblCurrentPartitionTime">
|
||||
<property name="text">
|
||||
<string notr="true">-</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>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="tvMarker" native="true">
|
||||
<property name="showColumnCount" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonsVisible" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblStart">
|
||||
<property name="text">
|
||||
<string notr="true">0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="slPeriodSlider">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblEnd">
|
||||
<property name="text">
|
||||
<string notr="true">0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QToolButton" name="pbStartPause">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>|> / ||</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/style/avm_start.svg</normaloff>
|
||||
<normalon>:/style/avm_pause.svg</normalon>:/style/avm_start.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="pbStart">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">|></string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/style/avm_start.svg</normaloff>:/style/avm_start.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="pbPause">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">||</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/style/avm_pause.svg</normaloff>:/style/avm_pause.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="pbStop">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">[]</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/style/avm_stop.svg</normaloff>:/style/avm_stop.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblStartTime">
|
||||
<property name="text">
|
||||
<string>Start Time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsDateTimeEdit" name="dteStartTime" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="withNowButton" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Speed [%]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblSpeedVal">
|
||||
<property name="text">
|
||||
<string notr="true"><VALUE></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="slSpeed">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>160</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="editorWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Set time as..:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbSetStart">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbSetEnd">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>End</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>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDateTimeEdit</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_date_time_edit.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>slPeriodSlider</tabstop>
|
||||
<tabstop>pbStartPause</tabstop>
|
||||
<tabstop>pbStart</tabstop>
|
||||
<tabstop>pbPause</tabstop>
|
||||
<tabstop>pbStop</tabstop>
|
||||
<tabstop>dteStartTime</tabstop>
|
||||
<tabstop>slSpeed</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Reference in new issue
Block a user