Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,774 @@
/**
* @RDE_HEADER@
* Exportable widget with replay controls
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, NLE, 2019-10-02
*/
#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> // manipulation of OperatorMapSettings
#include <QTimer>
namespace SituationReplay
{
SituationReplayControlWidget::SituationReplayControlWidget(QWidget *parent)
: QWidget(parent)
, m_ui(new Ui::SituationReplayControlWidget)
, m_dtc(nullptr)
, m_ftc(nullptr)
, m_mrkDtc(nullptr) // can be 0 !
, m_markerModel(nullptr)
, m_sitMapGuiIfc(nullptr) // can be 0 !
, 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);
// to avoid enabeling of apply button of lts_dialog
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, // can be 0 !
const std::shared_ptr<SituationMap::ForeignGuiInterface> &sitMapGuiIfc, // can be 0 !
int partitionId, bool useExistingReplay)
{
m_session = session;
m_dtc = dtc;
m_ftc = ftc;
m_mrkDtc = mrkDtc; // can be 0 !
m_partitionId = partitionId;
m_sitMapGuiIfc = sitMapGuiIfc; // can be 0 !
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; // replay really exists
break;
}
}
}
m_ui->dteStartTime->setRetrieveCurrentTimeCallback([]() { return QDateTime::currentMSecsSinceEpoch(); });
enaDisa();
connect(m_dtc.get(), &Interface::Dtc::sitReplayChanged,
this, &SituationReplayControlWidget::onSitReplayChanged);
// this, [this](const SituationReplay::SitReplay & _t1, DataModification _t2)
// {
// QTimer::singleShot(3000, this, [this, _t1, _t2]()
// {
// onSitReplayChanged(_t1, _t2);
// });
// });
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);
// set end time every new second
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();
// set start time if start time not taken from existing replay
// TODO: unclog this getDtc & waitForX mess
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)
{
//WARNING_LOG(m_logger) << "exc start time " << startTime;
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()); // 5 days ... just a guess
}
}
}
else
{
WARNING_LOG(m_logger) << "no exc dtc for getting exercise start time";
m_ui->dteStartTime->setMsecsSinceEpoch(QDateTime::currentDateTime().addDays(-5).toMSecsSinceEpoch()); // 5 days ... just a guess
}
}
// PeriodSlider, print start & end time
qint64 startInSecs = getSecs(m_ui->dteStartTime->msecsSinceEpoch());
qint64 endInSecs = QDateTime::currentSecsSinceEpoch();
m_ui->slPeriodSlider->setMinimum(startInSecs);
m_ui->slPeriodSlider->setMaximum(endInSecs);
{ // shorten lifetime of blocker
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)));
// Marker
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); // newest marker first
// may be delayed because data must be intiially read from opm here
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(); // prevent the user from clicking again while waiting ...
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) // nothing 2 do
{
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(); // prevent the user from clicking again while waiting ...
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(); // ... and bail out if operation didn't work out
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) // nothing 2 do
{
WARNING_LOG(m_logger) << "replay stop requested, but no replay active in this context";
return;
}
disableAllReplayButtons(); // prevent the user from clicking again while waiting ...
ChangeReplayStateRequest req;
req.id(m_id);
req.replayPartitionId(m_partitionId);
req.state(SrpState::Stopped);
// since this may potentially take some time, disable user interaction which may delete this widget for now
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(); // ... and bail out if operation didn't work out
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(); // prevent the user from clicking again while waiting ...
ChangeReplayStateRequest req;
req.id(m_id);
req.replayPartitionId(m_partitionId);
req.state(SrpState::Resumed);
req.beginTime(m_ui->dteStartTime->msecsSinceEpoch());
req.endTime(0); // infinite
req.pace(m_ui->slSpeed->value() / 10.);
if (!m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->changeReplayStateRequest(req, this);
}))
{
enaDisa(); // ... and bail out if operation didn't work out
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));
}
/**
* @brief
* @details Executed if the user double clicked on the Event in list. Set the map settings and focus the event on the map if the marker is an situation marker ans has an valid position
* @param index
*/
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)
// && m_session->getForeignGuiInterface(fltBuildingComponentGuiIfc) // Nachtrag zu GUEZE-1769: since fltBuildingComponentIfc is optional:
)
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";
// set filter from marker
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
{
// this path will be taken if marker is created automatically (like CES)
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()));
}
}
// set map settings from marker
if (appFilter)
{
QByteArray mapSettings(QByteArray::fromRawData(marker.mapSettings().c_str(), marker.mapSettings().size()));
DEBUG_LOG(m_logger) << "set map settings from marker " << (mapSettings.toStdString());
// Layer EmergencyCall should not be modified.
// So remove from data to be restored:
SituationMap::OperatorMapSettings oms;
oms.fromJson(mapSettings);
DEBUG_LOG(m_logger) << ">>>> oms.orderedLayers.size() " << oms.orderedLayers.size();
static const QLatin1String LayerNameEmergencyCall("EmergencyCall");
// remove entry: (EmergencyCall ist most likely at the end)
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);
// write back:
mapSettings = oms.toJson();
// apply: oms.orderedLayers.end()
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); // otherwise 'valueChanged' would do another request
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);
/*DEBUG*/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;
/*DEBUG*/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(); // ... bail (startReplay does a disableAllButtons(..))
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 /* infinite */, speed);
}
void SituationReplayControlWidget::onStopReplay() // TODO: InterfaceImpl::startReplay needs this method to check if there is currently a replay running!!
{
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)) // nothing 2 do
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;
}
} // namespace SituationReplay