Files
qt5-legatus-legacy/Lts/Plugins/ParticipantManagement/Gui/MSDL/msdl/msdl_export.cpp
T
2026-08-13 18:33:10 +02:00

579 lines
24 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Exportieren einer Uebung in eine MSDL-Datei
* $Id$
* $HeadURL$
* $Author$
*/
// at first to avoid compiler errors on windows
#include <xsd/MilitaryScenario_1.0.0.hxx>
#include "msdl_export.h"
#include "ui_msdl_export.h"
#include "msdl_export_scenario_data.h"
#include <Common/participant_dis_helper.h>
#include <ngltools/ngltools_filesystem.h>
#include <QFileDialog>
#include <QFileInfo>
#include <QUrl>
#include <QDate>
#include <QUuid>
#include <fstream>
#include <LtsWidgets/lts_message_dialog.h>
#include <LtsUtilsSettings/settings.h>
#include <LtsSession/lts_session.h>
#include <ParticipantManagement/ppm_data_plugin_interface.h>
namespace msdl
{
using organizationsType = msdl_1::MilitaryScenarioType::Organizations_type;
using equipType = organizationsType::Equipment_type;
using equipItemType = equipType::EquipmentItem_type;
using coordChoiceType = equipItemType::Disposition_type::Location_type::CoordinateChoice_type;
using coordDataType = equipItemType::Disposition_type::Location_type::CoordinateData_type;
using descriptionType = schemas::modelID::modelIdentificationType::description_type;
using equipOptional = organizationsType::Equipment_optional;
using equipRelationsType = equipItemType::Relations_type;
using unitsType = organizationsType::Units_type;
using unitType = unitsType::Unit_type;
using relationsType = unitType::Relations_type;
using forceRelationChoiceType = relationsType::ForceRelation_type::ForceRelationChoice_type;
using forceRelationDataType = relationsType::ForceRelation_type::ForceRelationData_type;
using forceSidesType = msdl_1::MilitaryScenarioType::ForceSides_type;
using forceSideType = forceSidesType::ForceSide_type;
using ownerChoiceType = equipRelationsType::HoldingOrganization_type::OwnerChoice_type;
using ownerDataType = equipRelationsType::HoldingOrganization_type::OwnerData_type;
namespace Private
{
static msdl_1::MilitaryScenarioType::ScenarioID_type createTagScenarioID(const msdl::ScenarioDataDialog &dlgData);
static msdl_1::MilitaryScenarioType::ForceSides_type createTagForceSides(const QMap<qint32, ParticipantManagement::Party> &mapForces,
QMap<qint32, QString> &mapForceHandles);
static msdl_1::MilitaryScenarioType::Options_type createTagOptions();
static msdl_1::MilitaryScenarioType::Environment_type createTagEnvironment();
static msdl_1::MilitaryScenarioType::Organizations_type::Units_type createTagUnits(const QMap<qint32, ParticipantManagement::Participant> &mapParticipants,
const QMap<qint32, QString> &mapForceHandles,
QMap<qint32, std::string> &mapParticipantsUUIDs);
static msdl_1::MilitaryScenarioType::Organizations_type::Equipment_type createTagEquipment(const QMap<qint32, ParticipantManagement::Participant> &mapParticipants,
const QMap<qint32, std::string> &mapParticipantsUUIDs,
const QMap<int32_t, ParticipantManagement::ParticipantPosition> &mapParticipantPositions,
const QMap<qint32, ParticipantManagement::Type> &mapTypes,
const QMap<int32_t, ParticipantManagement::EquipmentType> &mapEquipment,
const QMap<qint32, QString> &mapForceHandles, NGL::INGLLogger &logger);
static void writeMilitaryScenario(const msdl_1::MilitaryScenarioType &miType,
const std::string &filename);
}
ExportMsdl::ExportMsdl(LtsSession::LtsSession *pSession, QWidget *parent)
: NGLDialog(parent)
, mLogger(msdl::getLogger("ExportMsdl"))
, mUi(new Ui_MSDLExport)
, m_pSession(pSession)
{
mUi->setupUi(this);
setWindowTitle(tr("Export Exercise Scenario"));
connect(mUi->tbExportFile, &QToolButton::clicked, this, &ExportMsdl::onTbExportFileClicked);
connect(mUi->m_pushButton_StartExport, &QPushButton::clicked, this, &ExportMsdl::onApply);
QString strExportFile = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("MSDL"), QStringLiteral("pathSelectedExportFile"), QString()).toString();
if (strExportFile.size())
{
mUi->leExportFile->setText(strExportFile);
mUi->m_pushButton_StartExport->setEnabled(true);
}
if (!m_pSession->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc) ||
!m_pSession->getDtc<ExerciseManagement::DataInterface>(m_exmDtc) ||
!m_pSession->getDtc<OperatorManagement::DataInterface>(m_opmDtc))
{
ERROR_LOG(mLogger) << "Fetching m_ppmDtc or m_exmDtc or m_opmDtc failed!";
setEnabled(false);
}
}
ExportMsdl::~ExportMsdl()
{
delete mUi;
}
void ExportMsdl::onTbExportFileClicked()
{
QString strExportPath = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("MSDL"), QStringLiteral("pathSelectedExportFile"), QStringLiteral("/tmp/msdl.xml")).toString();
QString caption(tr("Select File"));
QFileDialog fileDialog(this, caption, strExportPath, tr("XML files (*.xml)"));
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
QList<QUrl> urls;
urls << QUrl::fromLocalFile(strExportPath);
fileDialog.setSidebarUrls(urls);
if (fileDialog.exec()) // TODO: use show(), use signals & slots !
{
strExportPath = fileDialog.selectedFiles().constFirst();
mUi->leExportFile->setText(strExportPath);
LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("MSDL"), QStringLiteral("pathSelectedExportFile"), strExportPath);
}
mUi->m_pushButton_StartExport->setEnabled(!mUi->leExportFile->text().isEmpty());
}
msdl_1::MilitaryScenarioType::ScenarioID_type Private::createTagScenarioID(const msdl::ScenarioDataDialog &dlgData)
{
QDate cuDa = QDate::currentDate();
xml_schema::date da(cuDa.year(), cuDa.month(), cuDa.day());
// Block ScenarioID: General information
msdl_1::MilitaryScenarioType::ScenarioID_type::name_type nameType(dlgData.exerciseName().toStdString());
msdl_1::MilitaryScenarioType::ScenarioID_type::type_type typeType("BOM");
msdl_1::MilitaryScenarioType::ScenarioID_type::version_type versionType(dlgData.exerciseVersion().toStdString());
msdl_1::MilitaryScenarioType::ScenarioID_type::modificationDate_type modDateType(da);
msdl_1::MilitaryScenarioType::ScenarioID_type::securityClassification_type secClassType("Unclassified");
msdl_1::MilitaryScenarioType::ScenarioID_type::description_type desType(dlgData.exerciseDescription().toStdString());
msdl_1::MilitaryScenarioType::ScenarioID_type scIDType(nameType,
typeType,
versionType,
modDateType,
secClassType,
desType);
msdl_1::MilitaryScenarioType::ScenarioID_type::applicationDomain_type domainType(dlgData.exerciseDomain().toStdString());
scIDType.applicationDomain(domainType);
// ScenarioID: poc information as part of the general information (Mandatory!)
msdl_1::MilitaryScenarioType::ScenarioID_type::poc_type pocType(dlgData.pocType().toStdString());
pocType.pocName(dlgData.pocAuthor().toStdString());
msdl_1::MilitaryScenarioType::ScenarioID_type::poc_type::pocEmail_sequence pocSeqMail;
pocSeqMail.push_back(msdl_1::MilitaryScenarioType::ScenarioID_type::poc_type::pocEmail_type(dlgData.pocEmail().toStdString()));
pocType.pocEmail(pocSeqMail);
msdl_1::MilitaryScenarioType::ScenarioID_type::poc_type::pocTelephone_sequence pocSeqTelephone;
pocSeqTelephone.push_back(msdl_1::MilitaryScenarioType::ScenarioID_type::poc_type::pocTelephone_type(dlgData.pocTelephone().toStdString()));
// pocSeqTelephone.push_back(msdl_1::MilitaryScenarioType::ScenarioID_type::poc_type::pocTelephone_type("+421-1080-4288")); // Example for adding further telephone numbers
pocType.pocTelephone(pocSeqTelephone);
msdl_1::MilitaryScenarioType::ScenarioID_type::poc_type::pocOrg_type pocOrgType(dlgData.pocOrganization().toStdString());
pocType.pocOrg(pocOrgType);
msdl_1::MilitaryScenarioType::ScenarioID_type::poc_sequence pocSequence;
pocSequence.push_back(pocType);
scIDType.poc(pocSequence);
scIDType.purpose(dlgData.exercisePurpose().toStdString());
scIDType.modificationDate(da);
return scIDType;
}
msdl_1::MilitaryScenarioType::ForceSides_type Private::createTagForceSides(const QMap<qint32, ParticipantManagement::Party> &mapForces,
QMap<qint32, QString> &mapForceHandles)
{
msdl_1::MilitaryScenarioType::ForceSides_type foType;
msdl_1::MilitaryScenarioType::ForceSides_type::ForceSide_sequence &foSiSe(foType.ForceSide());
// We have to create all UUIDs first
QMap<QString, ParticipantManagement::Party> mapUUID2Force;
for (const ParticipantManagement::Party &party : mapForces)
{
// Skip Pool and O/C Service
if (party.id() == 0 || party.id() == 1)
continue;
QString obHaStr = QUuid::createUuid().toString();
obHaStr = obHaStr.mid(1, obHaStr.size() - 2);
mapUUID2Force[obHaStr] = party;
}
// Create ForceSide for each party
QMapIterator<QString, ParticipantManagement::Party> itForce(mapUUID2Force);
while (itForce.hasNext())
{
itForce.next();
const QString &strUUID = itForce.key();
const ParticipantManagement::Party &party = itForce.value();
msdl_1::ForceSideType::ObjectHandle_type obHaTy(strUUID.toStdString().c_str());
msdl_1::ForceSideType::ForceSideName_type foSiNaTy(party.name().c_str());
msdl_1::ForceSideType foSiTy(obHaTy, foSiNaTy);
// Connect all parties among each other by using their relationship status (Hostile, Friend, ...)
msdl_1::ForceSideType::Associations_type::Association_sequence asSequence;
QMapIterator<QString, ParticipantManagement::Party> itRelationship(mapUUID2Force);
while (itRelationship.hasNext())
{
itRelationship.next();
if (itRelationship.key() == strUUID)
continue;
/*
* Identify relationship. Only FR / HO / NEUTR / UNK are used
*/
ParticipantManagement::Role role = itRelationship.value().role();
msdl_1::ForceSideType::Associations_type::Association_type::Relationship_type relType = msdl_1::ForceSideType::Associations_type::Association_type::Relationship_type::UNK;
if (role == ParticipantManagement::Role_def::Enemy)
relType = msdl_1::ForceSideType::Associations_type::Association_type::Relationship_type::HO;
else if (role == ParticipantManagement::Role_def::Friend)
relType = msdl_1::ForceSideType::Associations_type::Association_type::Relationship_type::FR;
else if (role == ParticipantManagement::Role_def::Neutral)
relType = msdl_1::ForceSideType::Associations_type::Association_type::Relationship_type::NEUTRL;
msdl_1::ForceSideType::Associations_type::Association_type aType(itRelationship.key().toStdString().c_str(), relType);
asSequence.push_back(aType);
}
msdl_1::ForceSideType::Associations_type asType;
asType.Association(asSequence);
foSiTy.Associations(asType);
foSiSe.push_back(foSiTy);
mapForceHandles[party.id()] = strUUID;
}
return foType;
}
msdl_1::MilitaryScenarioType::Options_type Private::createTagOptions()
{
msdl_1::MilitaryScenarioType::Options_type opType("");
opType.MSDLVersion("1.0.0");
msdl_1::boolean aggrBased = false;
msdl_1::OrganizationDetailType orType(aggrBased);
msdl_1::OrganizationDetailType::AggregateEchelon_type aggrEchelon(msdl_1::OrganizationDetailType::AggregateEchelon_type::enumEchelon::BATTALION);
orType.AggregateEchelon(aggrEchelon);
opType.OrganizationDetail(orType);
return opType;
}
msdl_1::MilitaryScenarioType::Environment_type Private::createTagEnvironment()
{
msdl_1::MilitaryScenarioType::Environment_type enType;
// Time
msdl_1::MilitaryScenarioType::Environment_type::ScenarioTime_type timeType("2013-05-28T17:37:24Z");
enType.ScenarioTime(timeType);
// Upper Right
msdl_1::MilitaryScenarioType::Environment_type::AreaOfInterest_type::UpperRight_type::CoordinateChoice_type choiceType_ur(msdl_1::MilitaryScenarioType::Environment_type::AreaOfInterest_type::UpperRight_type::CoordinateChoice_type::GCC);
coordDataType::GCC_type::X_type x_ur(123);
coordDataType::GCC_type::X_type y_ur(456);
coordDataType::GCC_type::Z_type z_ur(789);
coordDataType::GCC_type utTy_ur(x_ur, y_ur, z_ur);
coordDataType coDaTy_ur;
coDaTy_ur.GCC(utTy_ur);
msdl_1::MilitaryScenarioType::Environment_type::AreaOfInterest_type::UpperRight_type urType(choiceType_ur, coDaTy_ur);
// Lower Left
msdl_1::MilitaryScenarioType::Environment_type::AreaOfInterest_type::LowerLeft_type::CoordinateChoice_type choiceType(msdl_1::MilitaryScenarioType::Environment_type::AreaOfInterest_type::UpperRight_type::CoordinateChoice_type::GCC);
coordDataType::GCC_type::X_type x_ll(987);
coordDataType::GCC_type::X_type y_ll(654);
coordDataType::GCC_type::Z_type z_ll(321);
coordDataType::GCC_type utTy_ll(x_ll, y_ll, z_ll);
coordDataType coDaTy_ll;
coDaTy_ll.GCC(utTy_ll);
msdl_1::MilitaryScenarioType::Environment_type::AreaOfInterest_type::LowerLeft_type llType(choiceType, coDaTy_ll);
// AreaOfInterest
msdl_1::MilitaryScenarioType::Environment_type::AreaOfInterest_type areaType(urType, llType);
enType.AreaOfInterest(areaType);
return enType;
}
msdl_1::MilitaryScenarioType::Organizations_type::Units_type Private::createTagUnits(const QMap<qint32, ParticipantManagement::Participant> &mapParticipants,
const QMap<qint32, QString> &mapForceHandles,
QMap<qint32, std::string> &mapParticipantsUUIDs)
{
mapParticipantsUUIDs.clear();
// Create unique identifier for all participants
for (const ParticipantManagement::Participant &participant : mapParticipants)
{
QString obHaStr = QUuid::createUuid().toString();
obHaStr = obHaStr.mid(1, obHaStr.size() - 2);
mapParticipantsUUIDs[participant.id()] = obHaStr.toStdString();
}
unitsType unitsTy;
unitsType::Unit_sequence &unSe(unitsTy.Unit());
for (auto it = mapForceHandles.begin(); it != mapForceHandles.end(); ++it)
{
for (const ParticipantManagement::Participant &participant : mapParticipants)
{
// Does participant belong to currently exported party?
if (participant.partyId() != it.key())
continue;
if (participant.isDeleted())
continue;
forceRelationDataType foReDaTy;
forceRelationChoiceType foReChTy = forceRelationChoiceType::FORCE_SIDE;
if (participant.superiorId() == 0) // Vorgesetzter ist die Truppe
{
foReChTy = forceRelationChoiceType::FORCE_SIDE;
const QString &obHaStr = it.value();
foReDaTy.ForceSideHandle(obHaStr.toStdString().c_str());
}
else
{
foReChTy = forceRelationChoiceType::UNIT;
msdl_1::CommandRelationType::CommandingSuperiorHandle_type handle(mapParticipantsUUIDs.value(participant.superiorId()));
forceRelationDataType::CommandRelation_type cmdRelation(handle, msdl_1::CommandRelationType::CommandRelationshipType_type::TACON); // No idea about the enumeration values (ADCON, None, etc.)
foReDaTy.CommandRelation(cmdRelation);
}
unitType::ObjectHandle_type unObHaTy(mapParticipantsUUIDs.value(participant.id()));
unitType::SymbolIdentifier_type syIdTy = "S--------------";
relationsType::ForceRelation_type foReTy(foReChTy, foReDaTy);
unitType::Relations_type reTy(foReTy);
unitType unitTy(unObHaTy, syIdTy, reTy);
unitTy.SymbolIdentifier(syIdTy);
unitType::Name_type naTy(participant.designator().c_str());
unitTy.Name(naTy);
unSe.push_back(unitTy);
}
}
return unitsTy;
}
msdl_1::MilitaryScenarioType::Organizations_type::Equipment_type Private::createTagEquipment(const QMap<qint32, ParticipantManagement::Participant> &mapParticipants,
const QMap<qint32, std::string> &mapParticipantsUUIDs,
const QMap<int32_t, ParticipantManagement::ParticipantPosition> &mapParticipantPositions,
const QMap<qint32, ParticipantManagement::Type> &mapTypes,
const QMap<int32_t, ParticipantManagement::EquipmentType> &mapEquipment,
const QMap<qint32, QString> &mapForceHandles,
NGL::INGLLogger &logger)
{
equipType eqTy;
equipType::EquipmentItem_sequence &eqItSeq(eqTy.EquipmentItem());
for (auto it = mapForceHandles.begin(); it != mapForceHandles.end(); ++it)
{
const int32_t partyId = it.key();
for (const ParticipantManagement::Participant &participant : mapParticipants)
{
// Does participant belong to current party?
if (participant.partyId() != partyId)
continue;
if (participant.isDeleted())
continue;
/*
* Identify equipment owner handle (UUID)
* According to ICD is 'ownerChoise' always unit
*/
ownerDataType::UnitOwnerHandle_type foOwHaTy;
foOwHaTy = mapParticipantsUUIDs.value(participant.id()).c_str();
ownerDataType owDaTy;
owDaTy.UnitOwnerHandle(foOwHaTy);
ownerChoiceType owChTy(ownerChoiceType::UNIT);
equipRelationsType::HoldingOrganization_type hoOrTy(owChTy, owDaTy);
equipItemType::Relations_type reTy(hoOrTy);
// Equipment modifiers
auto vecDISEntities = mapTypes.value(participant.typeId()).disEntities();
if (!vecDISEntities.size())
{
WARNING_LOG(logger) << "Participant id " << participant.id()
<< " belongs to a type id " << participant.typeId() << " which has no DIS id! Skipping export of participant!";
continue;
}
// DIS entity id: Does not matter if this type has more than 1 DIS id. Simply pick first one
equipItemType::EquipmentSymbolModifiers_type eqModifiers(ParticipantManagement::DIS::convertDISTypeInteger2MSDLString(vecDISEntities[0]).toStdString().c_str());
eqModifiers.Quantity(1);
eqModifiers.EquipmentType("S--------------");
// Coordinates and Elevation
// Unclear: Are participant coordinates correctly specified converted?
coordDataType::GCC_type::X_type x(mapParticipantPositions[participant.id()].pos().lon());
coordDataType::GCC_type::X_type y(mapParticipantPositions[participant.id()].pos().lat());
coordDataType::GCC_type::Z_type z(mapParticipantPositions[participant.id()].pos().z());
coordDataType::GCC_type utTy(x, y, z);
coordDataType coDaTy;
coDaTy.GCC(utTy);
coordChoiceType coChTy(coordChoiceType::enumCoordinateSystemType::GCC);
/*
// UTM Version
coordDataType::UTM_type::UTMGridZone_type utmGriZoTy("UTM");
coordDataType::UTM_type::UTMEasting_type utmEaTy(mapParticipantPositions[participant.id()].pos().lon());
coordDataType::UTM_type::UTMNorthing_type utmNoTy(mapParticipantPositions[participant.id()].pos().lat());
coordDataType::UTM_type utTy(utmGriZoTy, utmEaTy, utmNoTy);
coordDataType::UTM_type::ElevationAGL_type elType(mapParticipantPositions[participant.id()].pos().z());
utTy.ElevationAGL(elType);
coordDataType coDaTy;
coDaTy.UTM(utTy);
coordChoiceType coChTy(coordChoiceType::enumCoordinateSystemType::UTM);
*/
equipItemType::Disposition_type::Location_type loTy(coChTy, coDaTy);
equipItemType::Disposition_type diTy(loTy);
// Direction of Movement
equipItemType::Disposition_type::DirectionOfMovement_type loDir(0.0);
diTy.DirectionOfMovement(loDir);
// SIDC
equipItemType::SymbolIdentifier_type syIdTy("S--------------");
// Finally create equipment
equipItemType eqItTy(foOwHaTy, syIdTy, diTy, reTy);
eqItTy.EquipmentSymbolModifiers(eqModifiers);
// Create UUID for equipment
QString obHaStr = QUuid::createUuid().toString();
obHaStr = obHaStr.mid(1, obHaStr.size() - 2);
equipItemType::ObjectHandle_type eqObHaTy = obHaStr.toStdString().c_str();
eqItTy.ObjectHandle(eqObHaTy);
// Participant -> TypeId -> EquipmentId -> Equipment name (Easy workflow, right?)
equipItemType::Name_type naTy(mapEquipment.value(mapTypes.value(participant.typeId()).equipmentTypeId()).name());
eqItTy.Name(naTy);
eqItTy.SymbolIdentifier(syIdTy);
eqItSeq.push_back(eqItTy);
}
}
return eqTy;
}
void Private::writeMilitaryScenario(const msdl_1::MilitaryScenarioType &miType,
const std::string &filename)
{
xml_schema::namespace_infomap map;
map["msdl"].name = "urn:sisostds:scenario:military:data:draft:msdl:1";
map["msdl"].schema = NGL::findFile(NGL::FileType::ConfigFile, QStringLiteral("MilitaryScenario_1.0.0.xsd")).toStdString();
map["modelID"].name = "http://www.sisostds.org/schemas/modelID";
std::ofstream ofs(filename);
msdl_1::MilitaryScenario(ofs, miType, map);
}
void ExportMsdl::onApply()
{
ScenarioDataDialog dlg(this, m_pSession, m_opmDtc, m_exmDtc);
int retCode = dlg.exec();
if (retCode == QDialog::Rejected)
{
close();
return;
}
try
{
const auto participants = m_ppmDtc->participants();
QMap<qint32, QString> mapForceHandles;
QMap<qint32, std::string> mapParticipantsUUIDs;
msdl_1::MilitaryScenarioType::ScenarioID_type scIDType = Private::createTagScenarioID(dlg);
msdl_1::MilitaryScenarioType::ForceSides_type foType = Private::createTagForceSides(m_ppmDtc->partys(), mapForceHandles);
msdl_1::MilitaryScenarioType::Options_type opType = Private::createTagOptions();
msdl_1::MilitaryScenarioType miType(scIDType, opType, foType);
msdl_1::MilitaryScenarioType::Environment_type enType = Private::createTagEnvironment();
unitsType unitsTy = Private::createTagUnits(participants, mapForceHandles, mapParticipantsUUIDs);
equipType equipmentTy = Private::createTagEquipment(participants,
mapParticipantsUUIDs,
m_ppmDtc->participantPositions(),
m_ppmDtc->types(),
m_ppmDtc->equipmentTypes(),
mapForceHandles,
mLogger);
equipType::EquipmentItem_sequence &eqItSeq(equipmentTy.EquipmentItem());
organizationsType orTy(unitsTy);
miType.Environment(enType);
if ( eqItSeq.size() > 0)
{
INFO_LOG(mLogger) << "orTy.Equipment(equipmentTy)";
orTy.Equipment(equipmentTy);
}
miType.Organizations(orTy);
QString fileName = mUi->leExportFile->text();
QFileInfo fileInfo(fileName);
if ( !fileInfo.exists(fileName))
{
QFile file(fileName);
file.open(QIODevice::WriteOnly);
file.close();
}
if (!fileInfo.isWritable())
LtsWidgets::LtsMessageDialog::showMessage(this, tr("MSDL export file \"%1\" can not be written").arg(fileName));
else
{
Private::writeMilitaryScenario(miType, fileName.toStdString());
LtsWidgets::LtsMessageDialog::showMessage(this, tr("MSDL export file has successfully been created"));
}
}
catch (const std::exception &e)
{
// There is so much that could be wrong when importing or exporting MSDL files (missing tags, optional tags, ...)
LtsWidgets::LtsMessageDialog::showMessage(this, tr("MSDL export failed!"));
ERROR_LOG(mLogger) << "MSDL export failed with an exception, e.what(): " << e.what();
}
close();
}
}