539 lines
19 KiB
C++
Executable File
539 lines
19 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Dialog for Simulated Movement
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Gerlinde Rudolphus, SLSE, 2018-01-02 */
|
|
|
|
#include "participant_move_dialog.h"
|
|
#include "ui_participant_move_dialog.h"
|
|
|
|
#include <PluginInterfaces/gui_plugin_interface.h>
|
|
#include <LtsSession/lts_session_data.h>
|
|
|
|
#include <LtsWidgets/lts_message_dialog.h>
|
|
#include <Common/LtsCoordTrans/lts_coord_widget.h>
|
|
#include <Plugins/ProjectDataManagement/pdm_gui_plugin_interface.h>
|
|
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
|
|
#include <Plugins/CentralEffectSimulation/ces_data_plugin_interface.h>
|
|
|
|
#include "logger.h"
|
|
#include <ParticipantManagement/ppm_translation.h>
|
|
#include <ParticipantManagement/ppm_dtc.h>
|
|
#include <FileManagement/flm_translation.h>
|
|
|
|
#include <QJsonArray>
|
|
#include <QJsonObject>
|
|
#include <QJsonDocument>
|
|
|
|
namespace CentralEffectSimulation
|
|
{
|
|
static constexpr double s_msConversion = 3.6; // = 3.6 Convert from [km/h] to [m/s]
|
|
static constexpr int s_timeMilliConversion = 1000; // 1000 Convert from [s] to [ms]
|
|
|
|
ParticipantMoveDialog::ParticipantMoveDialog(QWidget *parent)
|
|
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
|
, m_ftc(nullptr)
|
|
, m_sitMapGuiIfc(nullptr)
|
|
, m_ui(new Ui::WaypointsEdit)
|
|
, m_id(0)
|
|
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
|
, m_polyline(QPolygonF())
|
|
, m_logger(getLogger("ParticipantMoveDialog"))
|
|
{
|
|
m_ui->setupUi(this);
|
|
m_ui->cbJump->hide();
|
|
m_ui->label_5->hide();
|
|
m_ui->spSpeed->setValue(30); // 30km/h per default
|
|
m_ui->lePrefix->setText(tr("Waypoint"));
|
|
m_uiRequirements->addRequirement({m_ui->lblMoveStart, [this]() { return hasValidEffectStart(m_ui->dteStartTime); }, tr("Begin time is smaller than current time")});
|
|
connect (this, &ParticipantMoveDialog::signalFocused, this, &ParticipantMoveDialog::onFocus);
|
|
setOnlineHelpFilename(QStringLiteral("Situation-Move_Participant_0"));
|
|
} // end of ctor()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
ParticipantMoveDialog::~ParticipantMoveDialog()
|
|
{
|
|
m_sitMapGuiIfc = nullptr;
|
|
delete m_ui;
|
|
emit closeDialog(m_participantData.id());
|
|
} // end of dtor()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void ParticipantMoveDialog::enableUiElements(bool enable)
|
|
{
|
|
m_ui->pbPosition->setEnabled(enable);
|
|
m_ui->pbClear->setEnabled(enable);
|
|
} // end of enableUiElements()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool ParticipantMoveDialog::init(LtsSession::LtsSessionDataDds *session,
|
|
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
|
const std::shared_ptr<CentralEffectSimulation::Interface::Dtc> &cesDtc,
|
|
const ParticipantManagement::ParticipantData &data)
|
|
{
|
|
m_session = session;
|
|
m_participantData = data;
|
|
m_cesDtc = cesDtc;
|
|
|
|
//bool editable = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::BorderlinesEdit);
|
|
//bool readable = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::BorderlinesShow);
|
|
//if (!readable && !editable)
|
|
// return false;
|
|
|
|
if (!m_session->getFtc<CentralEffectSimulation::DataInterface>(m_ftc))
|
|
return false;
|
|
|
|
m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(m_sitMapGuiIfc);
|
|
|
|
if (m_sitMapGuiIfc)
|
|
{
|
|
connect(m_ui->pbPosition, &QPushButton::clicked, this, &ParticipantMoveDialog::onGetPolyline);
|
|
connect(m_ui->pbClear, &QPushButton::clicked, this, &ParticipantMoveDialog::clearCoordinates);
|
|
}
|
|
else
|
|
{
|
|
m_ui->pbPosition->setEnabled(false);
|
|
m_ui->pbClear->setEnabled(false);
|
|
}
|
|
|
|
m_ui->dteStartTime->setMinimumTimeMSec(m_session->partitionTime());
|
|
m_ui->dteStartTime->setRetrieveCurrentTimeCallback([this]() { return m_session->partitionTime(); });
|
|
m_ui->lbIdentifier->setText(QString::fromStdString(data.tacticalIdentifier()));
|
|
QString partyStr = ParticipantManagement::trPartyName(ppmDtc->party(m_participantData.partyId()).name());
|
|
m_ui->lbParty->setText(partyStr);
|
|
QString typeStr = ParticipantManagement::trTypeName(ppmDtc->type(m_participantData.typeId()).name());
|
|
m_ui->lbType->setText(typeStr);
|
|
|
|
// enableUiElements(editable && readable);
|
|
enableUiElements(true);
|
|
|
|
initTableHeader();
|
|
|
|
connect(cesDtc.get(), &CentralEffectSimulation::Interface::Dtc::simulatedMovementChanged,
|
|
this, &ParticipantMoveDialog::onSimulatedMovementChanged);
|
|
|
|
// Get data for all SimulatedMovements
|
|
{
|
|
auto sm = [this](const CentralEffectSimulation::SimulatedMovement & sme)
|
|
{
|
|
onSimulatedMovementChanged(sme, DataModification::eAdded);
|
|
};
|
|
if (!m_cesDtc->simulatedMovements(sm))
|
|
return false;
|
|
}
|
|
|
|
// Save/Load from Library Button
|
|
m_buttonBox->connectLibraryButton(this,
|
|
&ParticipantMoveDialog::onImportButtonClicked,
|
|
&ParticipantMoveDialog::onExportButtonClicked);
|
|
|
|
if (!m_session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_flmGui))
|
|
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Library, false);
|
|
|
|
return true;
|
|
|
|
} // end of init()
|
|
|
|
void ParticipantMoveDialog::onSimulatedMovementChanged(const CentralEffectSimulation::SimulatedMovement &data, DataModification modType)
|
|
{
|
|
if (modType == DataModification::eRemoved || m_participantData.id() != data.participantId())
|
|
return;
|
|
INFO_LOG(m_logger) << "onSimulatedMovementChanged";
|
|
|
|
// Clear data
|
|
clearContent();
|
|
// set new Content
|
|
m_id = data.id();
|
|
m_ui->lePrefix->setText(QString::fromStdString(data.name()));
|
|
m_ui->cbRepeat->setChecked(data.repeat());
|
|
m_ui->cbJump->setChecked(data.jumpToStart());
|
|
m_ui->dteStartTime->setMsecsSinceEpoch(data.startTime());
|
|
m_polyline.clear();
|
|
// Insert data to Vector
|
|
for (const SimulatedMovementSegment &segment : data.segments())
|
|
{
|
|
const Core::GeoPosition2D &pointDds = segment.position();
|
|
insertPos(pointDds.lon(), pointDds.lat(), QString::fromStdString(segment.name()), segment.delay(), segment.speed());
|
|
m_polyline.push_back(QPointF(pointDds.lon(), pointDds.lat()));
|
|
}
|
|
// Insert data to Map (Preview)
|
|
if (this->amIFocused())
|
|
m_sitMapGuiIfc->displayPreviewObject(this, m_polyline, false);
|
|
}
|
|
|
|
void ParticipantMoveDialog::showPreview(bool show)
|
|
{
|
|
if (m_sitMapGuiIfc)
|
|
{
|
|
if (show)
|
|
m_sitMapGuiIfc->displayPreviewObject(this, m_polyline, false);
|
|
else
|
|
m_sitMapGuiIfc->removePreviewObject();
|
|
}
|
|
}
|
|
|
|
|
|
void ParticipantMoveDialog::onSimulatedMovementRemoveReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
m_requestHelper->requestReply(replyObject);
|
|
if (!replyObject.error())
|
|
{
|
|
m_sitMapGuiIfc->cancelActiveRubberbands();
|
|
m_sitMapGuiIfc->removePreviewObject();
|
|
}
|
|
}
|
|
|
|
void ParticipantMoveDialog::onSimulatedMovementModifyReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
m_requestHelper->requestReply(replyObject);
|
|
if (!replyObject.error())
|
|
m_sitMapGuiIfc->removePreviewObject();
|
|
}
|
|
|
|
void ParticipantMoveDialog::retranslate()
|
|
{
|
|
translate(m_ui, QString::fromStdString(m_participantData.tacticalIdentifier()), false, tr("Waypoints")); // TODO: lock topic?
|
|
DEBUG_LOG(m_logger) << "retranslate";
|
|
}
|
|
|
|
void ParticipantMoveDialog::initTableHeader()
|
|
{
|
|
QStringList headers;
|
|
headers << tr("Identifier") << tr("Idle Time [s]") << tr("Speed [km/h]") << tr("Position");
|
|
m_ui->tableWidget->setHorizontalHeaderLabels(headers);
|
|
m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
|
}
|
|
|
|
// idleTime in [s] speed in [m/s]
|
|
void ParticipantMoveDialog::insertPos(const double lon, const double lat, const QString &identifier, const int idleTime, const double speed)
|
|
{
|
|
QLineEdit *le = new QLineEdit;
|
|
QSpinBox *sbDelay = new QSpinBox;
|
|
QSpinBox *sbSpeed = new QSpinBox;
|
|
sbDelay->setMinimum(m_ui->spIdleTime->minimum());
|
|
sbDelay->setMaximum(m_ui->spIdleTime->maximum());
|
|
sbSpeed->setMinimum(m_ui->spSpeed->minimum());
|
|
sbSpeed->setMaximum(m_ui->spSpeed->maximum());
|
|
int rowCount = m_ui->tableWidget->rowCount();
|
|
|
|
LtsCoordWidget::LtsCoordWidget *wdg = new LtsCoordWidget::LtsCoordWidget();
|
|
//wdg->setCoordinate( 8.794556, 53.080827);
|
|
wdg->setCoordinate(lon, lat);
|
|
wdg->setObjectName(QStringLiteral("positionEdit_") + QString::number(rowCount));
|
|
m_ui->tableWidget->insertRow(rowCount);
|
|
le->setText(identifier);
|
|
m_ui->tableWidget->setCellWidget(rowCount, Name, le);
|
|
sbDelay->setValue(idleTime / s_timeMilliConversion);
|
|
m_ui->tableWidget->setCellWidget(rowCount, IdleTime, sbDelay);
|
|
sbSpeed->setValue(speed * s_msConversion);
|
|
m_ui->tableWidget->setCellWidget(rowCount, Speed, sbSpeed);
|
|
m_ui->tableWidget->setCellWidget(rowCount, Position, wdg);
|
|
wdg->setDisplayType(LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS);
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/*
|
|
void WaypointsEdit::setData(const Borderline &borderline, bool copy)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << "borderlineId: " << borderline.id()
|
|
<< " operatorId: " << borderline.operatorId();
|
|
|
|
} // end of setData()
|
|
*/
|
|
//-----------------------------------------------------------------------------
|
|
void ParticipantMoveDialog::clearContent()
|
|
{
|
|
m_ui->lePrefix->clear();
|
|
m_ui->cbRepeat->setChecked(false);
|
|
m_ui->cbJump->setChecked(false);
|
|
|
|
clearCoordinates();
|
|
}
|
|
|
|
void ParticipantMoveDialog::clearCoordinates()
|
|
{
|
|
if (m_ui)
|
|
{
|
|
m_ui->tableWidget->clearContents();
|
|
m_ui->tableWidget->setRowCount(0);
|
|
}
|
|
// remove PreviewObject:
|
|
if ( m_sitMapGuiIfc && this->amIFocused())
|
|
m_sitMapGuiIfc->removePreviewObject();
|
|
}
|
|
|
|
void ParticipantMoveDialog::onFocus()
|
|
{
|
|
showPreview(true);
|
|
m_sitMapGuiIfc->displayPreviewObject(this, m_polyline, false);
|
|
}
|
|
|
|
void ParticipantMoveDialog::onGetPolyline()
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION;
|
|
|
|
if (!m_sitMapGuiIfc)
|
|
return;
|
|
|
|
if (m_sitMapGuiIfc->mapMode() != SituationMap::MapMode::MapMode_2D)
|
|
{
|
|
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Only available in 2D mode"));
|
|
return;
|
|
}
|
|
|
|
QPolygonF coordinates;
|
|
int i = 0;
|
|
while (true)
|
|
{
|
|
LtsCoordWidget::LtsCoordWidget *w = findChild<LtsCoordWidget::LtsCoordWidget *>(QStringLiteral("positionEdit_%1").arg(i));
|
|
if (!w)
|
|
break;
|
|
if (!w->coordinate().isNull())
|
|
coordinates << w->coordinate();
|
|
++i;
|
|
}
|
|
|
|
m_sitMapGuiIfc->getPolyline(this,
|
|
SLOT(onPolylineData(QPolygonF)),
|
|
nullptr,
|
|
2,
|
|
11,
|
|
-1,
|
|
-1,
|
|
coordinates);
|
|
|
|
} // end of onGetPolyline()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void ParticipantMoveDialog::onPolylineData(const QPolygonF &polyline)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " numberOfPoints: " << polyline.size();
|
|
|
|
if (polyline.size() < 2)
|
|
return;
|
|
|
|
m_polyline = polyline;
|
|
|
|
clearCoordinates();
|
|
for (int i = 0; i < polyline.size(); i++)
|
|
insertPos(polyline.at(i).x(), polyline.at(i).y(),
|
|
m_ui->lePrefix->text() + QLatin1Char('_') + QString::number(i + 1),
|
|
m_ui->spIdleTime->value() * s_timeMilliConversion,
|
|
m_ui->spSpeed->value() / s_msConversion);
|
|
|
|
// create PreviewObject:
|
|
m_sitMapGuiIfc->displayPreviewObject(this, polyline, false);
|
|
|
|
} // end of onPolylineData()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool ParticipantMoveDialog::hasValidEffectStart(LtsWidgets::LtsDateTimeEdit *dte) const
|
|
{
|
|
// if there is visible a enabled/disable checkbox -> also allow 0 as effect start
|
|
const bool bEmptyAllowed = dte->isCheckable();
|
|
const auto ms = dte->msecsSinceEpoch();
|
|
// no effect start -> ok
|
|
if (bEmptyAllowed && ms == 0)
|
|
return true;
|
|
return ms > m_session->partitionTime();
|
|
}
|
|
|
|
SimulatedMovement ParticipantMoveDialog::requestContent() const
|
|
{
|
|
std::string name = m_ui->lePrefix->text().toStdString();
|
|
int32_t repeat = m_ui->cbRepeat->isChecked();
|
|
//int32_t jumpToStart = m_ui->cbJump->isChecked();
|
|
int32_t jumpToStart = true;
|
|
rti::core::int64 startTime = m_ui->dteStartTime->msecsSinceEpoch();
|
|
int32_t participantId = m_participantData.id();
|
|
int32_t nextPoint = 0;
|
|
|
|
int cntSegments = m_ui->tableWidget->rowCount();
|
|
std::vector<CentralEffectSimulation::SimulatedMovementSegment> segments;
|
|
segments.resize(cntSegments);
|
|
for (int i = 0; i < cntSegments; i++)
|
|
{
|
|
QWidget *widget = m_ui->tableWidget->cellWidget(i, Name);
|
|
const QString nameSeg = static_cast<QLineEdit *>(widget)->text();
|
|
segments[i].name(nameSeg.toStdString());
|
|
|
|
widget = m_ui->tableWidget->cellWidget(i, IdleTime);
|
|
const int idleTime = static_cast<QSpinBox *>(widget)->value() * s_timeMilliConversion;
|
|
segments[i].delay(idleTime);
|
|
|
|
widget = m_ui->tableWidget->cellWidget(i, Speed);
|
|
const double speed = static_cast<QSpinBox *>(widget)->value() / s_msConversion;
|
|
|
|
segments[i].speed(speed);
|
|
|
|
widget = m_ui->tableWidget->cellWidget(i, Position);
|
|
const QPointF point = static_cast<LtsCoordWidget::LtsCoordWidget *>(widget)->coordinate();
|
|
const Core::GeoPosition2D pos(Core::GeoPosition2D(point.x(), point.y()));
|
|
segments[i].position(pos);
|
|
}
|
|
|
|
return SimulatedMovement(m_id,
|
|
name,
|
|
startTime,
|
|
participantId,
|
|
segments,
|
|
repeat,
|
|
jumpToStart,
|
|
nextPoint
|
|
);
|
|
}
|
|
|
|
bool ParticipantMoveDialog::apply()
|
|
{
|
|
int cntSegments = m_ui->tableWidget->rowCount();
|
|
if (cntSegments > 0)
|
|
{
|
|
const SimulatedMovement req = requestContent();
|
|
|
|
INFO_LOG(m_logger) << "--- onApplyMessage() ";
|
|
|
|
m_requestHelper->addRequest([this, req]()
|
|
{
|
|
return m_ftc->simulatedMovementModifyRequest(req, this);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
if (m_id > 0)
|
|
{
|
|
Core::RemoveElementRequest req(m_id);
|
|
m_id = 0; // Next time new Route
|
|
|
|
INFO_LOG(m_logger) << "--- onApplyMessage() ";
|
|
|
|
m_requestHelper->addRequest([req, this]()
|
|
{
|
|
return m_ftc->simulatedMovementRemoveRequest(req, this);
|
|
});
|
|
}
|
|
}
|
|
|
|
return m_requestHelper->startRequests();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Save / Load Simulation in DB
|
|
//-----------------------------------------------------------------------------
|
|
|
|
QByteArray ParticipantMoveDialog::simulatedMovementToJson() const
|
|
{
|
|
const SimulatedMovement req = requestContent();
|
|
QJsonObject obj;
|
|
obj[QStringLiteral("XmlType")] = FileManagement::toString(FileManagement::XmlType::CESParticipantMove);
|
|
|
|
obj[QStringLiteral("id")] = req.id();
|
|
obj[QStringLiteral("jumpToStart")] = req.jumpToStart();
|
|
obj[QStringLiteral("name")] = QString::fromStdString(req.name());
|
|
obj[QStringLiteral("nextPoint")] = req.nextPoint();
|
|
obj[QStringLiteral("participantId")] = req.participantId();
|
|
obj[QStringLiteral("repeat")] = req.repeat();
|
|
obj[QStringLiteral("startTime")] = req.startTime();
|
|
|
|
QJsonArray arr;
|
|
for (auto it = req.segments().begin(); it != req.segments().end(); ++it)
|
|
{
|
|
QJsonObject inner;
|
|
inner[QStringLiteral("delay")] = it->delay();
|
|
inner[QStringLiteral("name")] = QString::fromStdString(it->name());
|
|
inner[QStringLiteral("speed")] = it->speed();
|
|
inner[QStringLiteral("lat")] = it->position().lat();
|
|
inner[QStringLiteral("lon")] = it->position().lon();
|
|
arr += inner;
|
|
}
|
|
obj[QStringLiteral("segments")] = arr;
|
|
|
|
QJsonDocument doc(obj);
|
|
return doc.toJson(QJsonDocument::Compact);
|
|
}
|
|
|
|
SimulatedMovement ParticipantMoveDialog::jsonToSimulatedMovement(const QByteArray &content) const
|
|
{
|
|
// already checked that content is not empty, parseable and contains proper XmlType (CESParticipantMove)
|
|
CentralEffectSimulation::SimulatedMovement result;
|
|
const QJsonDocument doc(QJsonDocument::fromJson(content));
|
|
const QJsonObject obj(doc.object());
|
|
|
|
result.id(obj[QStringLiteral("id")].toInt()); //TODO Library: check id = 0?
|
|
result.jumpToStart(obj[QStringLiteral("jumpToStart")].toInt());
|
|
result.name(obj[QStringLiteral("name")].toString().toStdString());
|
|
result.nextPoint(obj[QStringLiteral("nextPoint")].toInt());
|
|
result.participantId(m_participantData.id());
|
|
result.repeat(obj[QStringLiteral("repeat")].toInt());
|
|
result.startTime(obj[QStringLiteral("startTime")].toDouble());
|
|
|
|
const QJsonArray arr(obj.value(QStringLiteral("segments")).toArray());
|
|
auto &segments = result.segments();
|
|
segments.resize(arr.size());
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
{
|
|
CentralEffectSimulation::SimulatedMovementSegment &segment = segments[i];
|
|
const QJsonObject objArr(arr.at(i).toObject());
|
|
segment.delay(objArr[QStringLiteral("delay")].toDouble());
|
|
segment.name(objArr[QStringLiteral("name")].toString().toStdString());
|
|
|
|
|
|
segment.position().lat(objArr[QStringLiteral("lat")].toDouble());
|
|
segment.position().lon(objArr[QStringLiteral("lon")].toDouble());
|
|
segment.speed(objArr[QStringLiteral("speed")].toDouble());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void ParticipantMoveDialog::onExportButtonClicked()
|
|
{
|
|
QJsonObject saveObject;
|
|
saveObject[QStringLiteral("content")] = QString();
|
|
|
|
const QByteArray byteArray = simulatedMovementToJson();
|
|
|
|
int fileId = m_flmGui->saveFileContent(this, FileManagement::FileType::Xml, m_session->exerciseId(), byteArray);
|
|
if (fileId > 0)
|
|
DEBUG_LOG(m_logger) << "Saved file with id = " << fileId;
|
|
else
|
|
ERROR_LOG(m_logger) << "Could not save file in library ";
|
|
}
|
|
|
|
void ParticipantMoveDialog::onImportButtonClicked()
|
|
{
|
|
DEBUG_LOG(m_logger) << " onImportButtonClicked() ";
|
|
|
|
QByteArray content;
|
|
int fileId = m_flmGui->loadFileContent(this, content, {FileManagement::FileType::Xml}, m_session->exerciseId(), FileManagement::toString(FileManagement::XmlType::CESParticipantMove));
|
|
if (fileId > 0)
|
|
{
|
|
if (!m_flmGui->isXmlType(content, FileManagement::toString(FileManagement::XmlType::CESParticipantMove)))
|
|
{
|
|
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
|
|
LtsWidgets::LtsMessageDialog::showMessage(this,
|
|
tr("Invalid xml file content"),
|
|
windowTitle(),
|
|
LtsWidgets::Behaviour::Modal,
|
|
LtsWidgets::Button::Yes,
|
|
texts);
|
|
}
|
|
else
|
|
{
|
|
SimulatedMovement req = jsonToSimulatedMovement(content);
|
|
|
|
INFO_LOG(m_logger) << "--- onImportButtonClicked() ";
|
|
|
|
m_requestHelper->addRequest([this, req]()
|
|
{
|
|
return m_ftc->simulatedMovementModifyRequest(req, this);
|
|
});
|
|
m_requestHelper->startRequests();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
} // namespace CentralEffectSimulation
|