621 lines
21 KiB
C++
Executable File
621 lines
21 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Exportieren von SAAB-Dateien
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#include "saab_export.h"
|
|
#include "ui_saab_export.h"
|
|
#include "saab_xml_strings.h"
|
|
#include "saab_map_type.h"
|
|
#include "saab_map_party.h"
|
|
|
|
#include <QFileDialog>
|
|
#include <QXmlStreamWriter>
|
|
#include <QXmlStreamReader>
|
|
#include <QDateTime>
|
|
#include <QUuid>
|
|
|
|
#include <LtsSession/lts_session.h>
|
|
#include <LtsUtils/LtsUtilsSettings/settings.h>
|
|
#include <LtsWidgets/lts_message_dialog.h>
|
|
#include <ParticipantManagement/ppm_translation.h>
|
|
|
|
/*
|
|
* QUuid::QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8)
|
|
* Creates a UUID with the value specified by the parameters, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8.
|
|
* General QUuid format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
* The vaues will be visualized in HEX-Code.
|
|
|
|
* Used QUuid Format: aaaaaaaa-bbbb-xxxx-ccxx-xxxxxxxxxxdd
|
|
* a = Participant ID, Parameter: l
|
|
* b = Exercise ID, Parameter: w1
|
|
* c = Party ID, Parameter: b1
|
|
* d = GUID Context, Parameter: b8
|
|
* 1 = Exercise
|
|
* 2 = Party
|
|
* 3 = Participant
|
|
* x = Unused, curretly filled with '0'
|
|
*
|
|
* Exercise format: xxxxxxxx-bbbb-xxxx-xxxx-xxxxxxxxxx01
|
|
* Party format: xxxxxxxx-bbbb-xxxx-ccxx-xxxxxxxxxx02
|
|
* Participant format: aaaaaaaa-bbbb.xxxx.ccxx-xxxxxxxxxx03
|
|
*/
|
|
|
|
namespace saab
|
|
{
|
|
|
|
static const QString xmlnsValue(QStringLiteral("http://www.saab.se/training/schemas/ExerciseOrbat/1.1.1"));
|
|
static const uint l = 0;
|
|
static const ushort w1 = 0;
|
|
static const ushort w2 = 0x88;
|
|
static const uchar b1 = 0;
|
|
static const uchar b2 = 0xde;
|
|
static const uchar b3 = 0xad;
|
|
static const uchar b4 = 0xbe;
|
|
static const uchar b5 = 0xef;
|
|
static const uchar b6 = 0x33;
|
|
static const uchar b7 = 0x44;
|
|
static const uchar b8 = 0;
|
|
|
|
ExportSaab::ExportSaab(LtsSession::LtsSession *session, const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc, const ExerciseManagement::Exercise &exercise, QWidget *parent)
|
|
: LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
|
|
, m_currentExercise(exercise)
|
|
, m_ppmDtc(ppmDtc)
|
|
, m_session(session)
|
|
, m_configFile(nullptr)
|
|
, m_ui(new Ui_SAABExport)
|
|
, m_logger(getLogger("ExportSaab"))
|
|
{
|
|
m_ui->setupUi(this);
|
|
|
|
connect(m_ui->m_pushbutton_SelectConfig, &QToolButton::clicked,
|
|
this, &ExportSaab::onSelectConfigFile);
|
|
connect(m_ui->m_pushbutton_SelectFile, &QToolButton::clicked,
|
|
this, &ExportSaab::onSelectExportFile);
|
|
connect(m_ui->m_pushButton_StartImport, &QPushButton::clicked,
|
|
this, &ExportSaab::onStartExport);
|
|
|
|
QString strExportFile = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedExportFile"), QString()).toString();
|
|
QString strConfigFile = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedConfigFile"), QString()).toString();
|
|
|
|
m_ui->m_lineedit_ExportFile->setText(strExportFile);
|
|
m_ui->m_lineedit_ConfigFile->setText(strConfigFile);
|
|
|
|
m_ui->m_pushButton_StartImport->setEnabled(strExportFile.size() && strConfigFile.size());
|
|
|
|
m_parties = m_ppmDtc->partys();
|
|
m_types = m_ppmDtc->types();
|
|
}
|
|
|
|
ExportSaab::~ExportSaab()
|
|
{
|
|
delete m_ui;
|
|
}
|
|
|
|
void ExportSaab::onStartExport()
|
|
{
|
|
QString strExportFile = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedExportFile"), QString()).toString();
|
|
QString strConfigFile = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedConfigFile"), QString()).toString();
|
|
|
|
QFile file(strExportFile);
|
|
|
|
if (m_configFile)
|
|
{
|
|
m_configFile->close();
|
|
delete m_configFile;
|
|
m_configFile = nullptr;
|
|
}
|
|
|
|
m_configFile = new QFile(strConfigFile, this);
|
|
|
|
if (!file.open(QIODevice::WriteOnly))
|
|
{
|
|
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Not possible to start export. You do not have the permission to write the selected file."));
|
|
ERROR_LOG(m_logger) << "Could not export exercise: \"" << strExportFile << "\" could not be opened for writing";
|
|
return;
|
|
}
|
|
|
|
if (!isValidConfigFile())
|
|
{
|
|
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Not possible to start export. Config file invalid."));
|
|
ERROR_LOG(m_logger) << "Could not export exercise: \"" << strConfigFile << "\" invalid";
|
|
return;
|
|
}
|
|
|
|
importConfig();
|
|
|
|
QXmlStreamWriter writer(&file);
|
|
|
|
writer.setAutoFormatting(true);
|
|
writer.writeStartDocument();
|
|
writer.writeStartElement(XmlStrings::SAAB_EXERCISE_ORBAT());
|
|
writer.writeAttribute(XmlStrings::SAAB_XMLNS_XSI(), QStringLiteral("http://www.w3.org/2001/XMLSchema-instance"));
|
|
writer.writeAttribute(XmlStrings::SAAB_XMLNS_XSD(), QStringLiteral("http://www.w3.org/2001/XMLSchema"));
|
|
writer.writeAttribute(XmlStrings::SAAB_XMLNS(), xmlnsValue);
|
|
|
|
writeExercise(&writer);
|
|
writeOrbat(&writer);
|
|
writeFooter(&writer);
|
|
|
|
writer.writeEndElement();
|
|
writer.writeEndDocument();
|
|
|
|
file.close();
|
|
|
|
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Export finished"));
|
|
close();
|
|
}
|
|
|
|
void ExportSaab::onSelectConfigFile()
|
|
{
|
|
QString strPathSelectedConfigFolder = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedConfigFolder"), QStringLiteral("/shd/CTC/TOOLS/TDS/")).toString();
|
|
QString strPathSelectedConfigFile = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedConfigFile"), QStringLiteral("/shd/CTC/TOOLS/TDS/")).toString();
|
|
|
|
QList<QUrl> urls;
|
|
urls << QUrl::fromLocalFile(strPathSelectedConfigFile);
|
|
|
|
QFileDialog fileDialog(this, tr("Select File"), strPathSelectedConfigFolder, tr("XML files (*.xml)"));
|
|
fileDialog.setSidebarUrls(urls);
|
|
fileDialog.setOptions(QFileDialog::ReadOnly);
|
|
fileDialog.setFileMode(QFileDialog::ExistingFile);
|
|
|
|
if (fileDialog.exec()) // TODO: use show(), use signals & slots !
|
|
{
|
|
strPathSelectedConfigFile = fileDialog.selectedFiles().constFirst();
|
|
|
|
LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("SAAB"), QStringLiteral("pathSelectedConfigFolder"), strPathSelectedConfigFolder);
|
|
|
|
if (!strPathSelectedConfigFile.size())
|
|
return;
|
|
|
|
LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("SAAB"), QStringLiteral("pathSelectedConfigFile"), strPathSelectedConfigFile);
|
|
m_ui->m_lineedit_ConfigFile->setText(strPathSelectedConfigFile);
|
|
m_ui->m_pushButton_StartImport->setEnabled(LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedExportFile"), QString()).toString().size());
|
|
}
|
|
}
|
|
|
|
void ExportSaab::onSelectExportFile()
|
|
{
|
|
QString strPathSelectedExportFolder = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedExportFolder"), QStringLiteral("/tmp")).toString();
|
|
QString strPathSelectedExportFile = QFileDialog::getSaveFileName(this, tr("Export file"),
|
|
strPathSelectedExportFolder,
|
|
tr("XML files (*.xml)"));
|
|
if (strPathSelectedExportFile.isEmpty())
|
|
return;
|
|
|
|
strPathSelectedExportFolder = strPathSelectedExportFile.mid(0, strPathSelectedExportFile.lastIndexOf(QLatin1Char('/')));
|
|
|
|
QString suffix = QStringLiteral(".xml");
|
|
|
|
if (!strPathSelectedExportFile.endsWith(suffix))
|
|
strPathSelectedExportFile += suffix;
|
|
|
|
LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("SAAB"), QStringLiteral("pathSelectedExportFolder"), strPathSelectedExportFolder);
|
|
LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("SAAB"), QStringLiteral("pathSelectedExportFile"), strPathSelectedExportFile);
|
|
|
|
m_ui->m_lineedit_ExportFile->setText(strPathSelectedExportFile);
|
|
m_ui->m_pushButton_StartImport->setEnabled(LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedConfigFile"), QString()).toString().size());
|
|
}
|
|
|
|
bool ExportSaab::isValidConfigFile()
|
|
{
|
|
if (!m_configFile)
|
|
{
|
|
ERROR_LOG(m_logger) << "Not possible to read config: No file selected";
|
|
return false;
|
|
}
|
|
|
|
if (!m_configFile->open(QIODevice::ReadOnly))
|
|
{
|
|
ERROR_LOG(m_logger) << "Not possible to read config: Could not open file \""
|
|
<< m_configFile->fileName()
|
|
<< "\" for reading.";
|
|
return false;
|
|
}
|
|
|
|
using namespace XmlStrings;
|
|
|
|
QXmlStreamReader reader(m_configFile);
|
|
|
|
bool hasSymbols = false;
|
|
bool hasEchelons = false;
|
|
bool hasForces = false;
|
|
|
|
while (!reader.atEnd() && !(hasSymbols && hasEchelons && hasForces))
|
|
{
|
|
if (reader.readNextStartElement())
|
|
{
|
|
if (reader.name() == SAAB_SYMBOLS())
|
|
hasSymbols = true;
|
|
else if (reader.name() == SAAB_ECHELONS())
|
|
hasEchelons = true;
|
|
else if (reader.name() == SAAB_FORCES())
|
|
hasForces = true;
|
|
}
|
|
}
|
|
|
|
m_configFile->close();
|
|
|
|
if (!hasEchelons)
|
|
ERROR_LOG(m_logger) << "Could not find " << SAAB_ECHELONS() << " in file \"" << m_configFile->fileName() << '\"';
|
|
if (!hasSymbols)
|
|
ERROR_LOG(m_logger) << "Could not find " << SAAB_SYMBOLS() << " in file \"" << m_configFile->fileName() << '\"';
|
|
if (!hasForces)
|
|
ERROR_LOG(m_logger) << "Could not find " << SAAB_FORCES() << " in file \"" << m_configFile->fileName() << '\"';
|
|
|
|
return hasEchelons && hasSymbols && hasForces;
|
|
}
|
|
|
|
void ExportSaab::importConfig()
|
|
{
|
|
if (!m_mapSymbols.isEmpty() || !m_mapEchelons.isEmpty())
|
|
{
|
|
using namespace LtsWidgets;
|
|
|
|
Button b = LtsMessageDialog::showMessage(this,
|
|
tr("A config is already imported. Overwrite?"),
|
|
tr("Overwrite config?"),
|
|
Behaviour::Modal,
|
|
Button::Yes | Button::No);
|
|
if (b != Button::Yes)
|
|
return;
|
|
}
|
|
|
|
if (!m_configFile)
|
|
{
|
|
ERROR_LOG(m_logger) << "Not possible to read config: No file selected";
|
|
return;
|
|
}
|
|
|
|
if (!m_configFile->open(QIODevice::ReadOnly))
|
|
{
|
|
ERROR_LOG(m_logger) << "Not possible to read config: Could not open file \""
|
|
<< m_configFile->fileName()
|
|
<< "\" for reading.";
|
|
return;
|
|
}
|
|
|
|
m_mapSymbols.clear();
|
|
m_mapEchelons.clear();
|
|
m_mapTypeToSaabSymbol.clear();
|
|
m_mapPartyToForce.clear();
|
|
m_mapForces.clear();
|
|
|
|
QXmlStreamReader reader(m_configFile);
|
|
|
|
using namespace XmlStrings;
|
|
|
|
while (!reader.atEnd())
|
|
{
|
|
if (reader.readNextStartElement())
|
|
{
|
|
if (reader.name() == SAAB_SYMBOL())
|
|
{
|
|
SaabSymbol newSymbol = readSymbol(&reader);
|
|
m_mapSymbols.insert(newSymbol.code, newSymbol);
|
|
}
|
|
else if (reader.name() == SAAB_ECHELON())
|
|
{
|
|
SaabEchelon newEchelon = readEchelon(&reader);
|
|
m_mapEchelons.insert(newEchelon.code, newEchelon);
|
|
}
|
|
else if (reader.name() == SAAB_FORCE())
|
|
{
|
|
SaabForce newForce = readForce(&reader);
|
|
m_mapForces.insert(newForce.text, newForce.code);
|
|
}
|
|
}
|
|
}
|
|
|
|
m_configFile->close();
|
|
|
|
for (auto it = m_parties.constBegin(); it != m_parties.constEnd(); ++it)
|
|
{
|
|
if (m_mapForces.isEmpty())
|
|
{
|
|
LtsWidgets::LtsMessageDialog::showMessage(this, tr("All Forces are mapped."));
|
|
break;
|
|
}
|
|
|
|
mapPartyToForce(it.value());
|
|
}
|
|
}
|
|
|
|
SaabSymbol ExportSaab::readSymbol(QXmlStreamReader *reader) const
|
|
{
|
|
SaabSymbol result;
|
|
|
|
using namespace XmlStrings;
|
|
|
|
while (reader->readNext() != QXmlStreamReader::EndElement && reader->name() != SAAB_SYMBOL())
|
|
{
|
|
if (reader->name() == SAAB_CODE())
|
|
result.code = reader->readElementText();
|
|
else if (reader->name() == SAAB_TEXT())
|
|
result.text = reader->readElementText();
|
|
else if (reader->name() == SAAB_SYMBOL_ID())
|
|
result.symbolId = reader->readElementText();
|
|
else if (reader->name() == SAAB_MODEL_ID())
|
|
result.modelId = reader->readElementText();
|
|
else if (reader->name() == SAAB_ECHELON_ID())
|
|
result.echelonId = reader->readElementText();
|
|
else if (reader->name() == SAAB_PLAYER_TYPE_ID())
|
|
result.playerTypeId = reader->readElementText();
|
|
else if (reader->name() == SAAB_COLOR())
|
|
result.color = reader->readElementText();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SaabEchelon ExportSaab::readEchelon(QXmlStreamReader *reader) const
|
|
{
|
|
SaabEchelon result;
|
|
|
|
using namespace XmlStrings;
|
|
|
|
while (reader->readNext() != QXmlStreamReader::EndElement && reader->name() != SAAB_ECHELON())
|
|
{
|
|
if (reader->name() == SAAB_CODE())
|
|
result.code = reader->readElementText();
|
|
else if (reader->name() == SAAB_TEXT())
|
|
result.text = reader->readElementText();
|
|
else if (reader->name() == SAAB_ID())
|
|
result.id = reader->readElementText();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SaabForce ExportSaab::readForce(QXmlStreamReader *reader) const
|
|
{
|
|
SaabForce result;
|
|
|
|
using namespace XmlStrings;
|
|
|
|
while (reader->readNext() != QXmlStreamReader::EndElement && reader->name() != SAAB_FORCE())
|
|
{
|
|
if (reader->name() == SAAB_CODE())
|
|
result.code = reader->readElementText();
|
|
else if (reader->name() == SAAB_TEXT())
|
|
result.text = reader->readElementText();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void ExportSaab::writeExercise(QXmlStreamWriter *writer) const
|
|
{
|
|
using namespace XmlStrings;
|
|
|
|
writer->writeStartElement(SAAB_EXERCISE());
|
|
writer->writeAttribute(SAAB_ID(), QUuid(l, m_currentExercise.id(), w2, b1, b2, b3, b4, b5, b6, b7, GuidContext::GuidExercise).toString(QUuid::WithoutBraces));
|
|
|
|
writer->writeTextElement(SAAB_EXPORT_TIME(), toSaabTime(m_session->partitionTime()));
|
|
writer->writeTextElement(SAAB_PLANNED_START_TIME(), toSaabTime(m_currentExercise.beginTime()));
|
|
writer->writeTextElement(SAAB_PLANNED_STOP_TIME(), toSaabTime(m_currentExercise.endTime()));
|
|
writer->writeTextElement(SAAB_DESIGNATION(), QString::fromStdString(m_currentExercise.name()));
|
|
writer->writeTextElement(SAAB_DESCRIPTION(), QString::fromStdString(m_currentExercise.description()));
|
|
writer->writeTextElement(SAAB_WIND_SPEED(), QStringLiteral("0"));
|
|
writer->writeTextElement(SAAB_WIND_DIRECTION(), QStringLiteral("0"));
|
|
writer->writeEmptyElement(SAAB_EVALUATION_PACKAGE_FILE_NAME());
|
|
writer->writeTextElement(SAAB_EXERCISE_STATE(), QStringLiteral("0"));
|
|
|
|
writer->writeEndElement();
|
|
}
|
|
|
|
void ExportSaab::writeOrbat(QXmlStreamWriter *writer)
|
|
{
|
|
using namespace XmlStrings;
|
|
|
|
writer->writeStartElement(SAAB_ORBAT());
|
|
|
|
QMap<int, ParticipantManagement::Participant> participants = m_ppmDtc->participants();
|
|
|
|
for (auto it = m_mapPartyToForce.constBegin(); it != m_mapPartyToForce.constEnd(); ++it)
|
|
{
|
|
SaabPlayer *player = toSaabPlayer(m_parties.value(it.key()), participants);
|
|
|
|
player->writeToXml(writer);
|
|
|
|
delete player;
|
|
player = nullptr;
|
|
}
|
|
|
|
writer->writeEndElement();
|
|
}
|
|
|
|
void ExportSaab::writeFooter(QXmlStreamWriter *writer) const
|
|
{
|
|
using namespace XmlStrings;
|
|
|
|
writer->writeEmptyElement(SAAB_PERSONS());
|
|
writer->writeEmptyElement(SAAB_VEHICLES());
|
|
writer->writeEmptyElement(SAAB_HELICOPTERS());
|
|
}
|
|
|
|
SaabPlayer *ExportSaab::toSaabPlayer(const ParticipantManagement::Party &party, QMap<int, ParticipantManagement::Participant> &remainingParticipants)
|
|
{
|
|
SaabPlayer *result;
|
|
|
|
result = new SaabUnit;
|
|
|
|
result->symbol = m_mapPartyToForce.value(party.id()).symbolCode;
|
|
static_cast<SaabUnit *>(result)->unitSize = m_mapPartyToForce.value(party.id()).echelonCode;
|
|
result->designation = QString::fromStdString(party.name());
|
|
result->trashcan = false;
|
|
result->isExternalPlayer = true;
|
|
result->force = m_mapPartyToForce.value(party.id()).forceCode;
|
|
result->guid = QUuid(l, m_currentExercise.id(), w2, static_cast<uchar>(party.id()), b2, b3, b4, b5, b6, b7, GuidContext::GuidParty).toString(QUuid::WithoutBraces);
|
|
|
|
QList<int> keys = remainingParticipants.keys();
|
|
|
|
// add the root units/participants
|
|
for (int key : qAsConst(keys))
|
|
{
|
|
if (!remainingParticipants.contains(key))
|
|
continue;
|
|
|
|
ParticipantManagement::Participant participant = remainingParticipants.value(key);
|
|
|
|
if (!(participant.partyId() == party.id() && participant.superiorId() == 0))
|
|
continue;
|
|
|
|
SaabPlayer *player = toSaabPlayer(participant, remainingParticipants);
|
|
|
|
if (!player)
|
|
continue;
|
|
|
|
static_cast<SaabUnit *>(result)->inferiors.append(player);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SaabPlayer *ExportSaab::toSaabPlayer(const ParticipantManagement::Participant &participant, QMap<int, ParticipantManagement::Participant> &remainingParticipants)
|
|
{
|
|
if (participant.isDeleted())
|
|
{
|
|
DEBUG_LOG(m_logger) << "Participant with id " << participant.id() << " id deleted --> skipping";
|
|
return nullptr;
|
|
}
|
|
|
|
if (participant.externalId())
|
|
{
|
|
DEBUG_LOG(m_logger) << "Particpant with id " << participant.id() << " has external ID set to " << participant.externalId() << " --> not being exported.";
|
|
return nullptr;
|
|
}
|
|
|
|
SaabPlayer *result;
|
|
|
|
ParticipantManagement::Type type = m_types.value(participant.typeId());
|
|
|
|
if (!m_mapTypeToSaabSymbol.contains(type.id()))
|
|
mapType(type);
|
|
|
|
switch (type.typeClass().underlying())
|
|
{
|
|
case ParticipantManagement::TypeClass::SupportEntity: // OC Player
|
|
result = new SaabOcPlayer;
|
|
break;
|
|
case ParticipantManagement::TypeClass::Human: // Person Player
|
|
result = new SaabPersonPlayer;
|
|
break;
|
|
case ParticipantManagement::TypeClass::GroundVehicle: // Vehicle Player
|
|
case ParticipantManagement::TypeClass::VehicleWithGear:
|
|
case ParticipantManagement::TypeClass::WeaponSystem:
|
|
result = new SaabVehiclePlayer;
|
|
break;
|
|
case ParticipantManagement::TypeClass::Unit: // Unit
|
|
case ParticipantManagement::TypeClass::SupportUnit:
|
|
{
|
|
result = new SaabUnit;
|
|
|
|
DEBUG_LOG(m_logger) << "Reading unit with " << participant.inferiorIds().size() << " inferiors";
|
|
|
|
for (int32_t id : participant.inferiorIds())
|
|
{
|
|
SaabPlayer *player = toSaabPlayer(remainingParticipants.value(id), remainingParticipants);
|
|
|
|
if (player == nullptr)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Skipping inferior with id " << id;
|
|
continue;
|
|
}
|
|
|
|
static_cast<SaabUnit *>(result)->inferiors.append(player);
|
|
}
|
|
|
|
// do not export empty units
|
|
if (!static_cast<SaabUnit *>(result)->inferiors.size())
|
|
{
|
|
DEBUG_LOG(m_logger) << "Unit " << participant.id() << " has no inferiors.";
|
|
return nullptr;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case ParticipantManagement::TypeClass::Vessel: // we do not support that for export atm
|
|
case ParticipantManagement::TypeClass::Aircraft:
|
|
case ParticipantManagement::TypeClass::Unknown:
|
|
default:
|
|
DEBUG_LOG(m_logger) << "Type " << participant.typeId() << " is not supported.";
|
|
return nullptr;
|
|
}
|
|
|
|
QString symbol = m_mapTypeToSaabSymbol.value(type.id());
|
|
|
|
if (typeid(*result) == typeid(SaabUnit))
|
|
{
|
|
QStringList symbolUnitSize = symbol.split(QLatin1Char(';'));
|
|
|
|
result->symbol = symbolUnitSize.at(0);
|
|
static_cast<SaabUnit *>(result)->unitSize = symbolUnitSize.at(1);
|
|
}
|
|
else
|
|
result->symbol = symbol;
|
|
|
|
result->designation = QString::fromStdString(participant.designator());
|
|
result->trashcan = participant.isDeleted();
|
|
result->rank = QStringLiteral("OF1");
|
|
result->isExternalPlayer = true;
|
|
if (participant.equipmentNumber().is_set())
|
|
result->simulatorId = participant.equipmentNumber().get();
|
|
result->force = m_mapPartyToForce.value(participant.partyId()).forceCode;
|
|
result->guid = QUuid(participant.id(), m_currentExercise.id(), w2, static_cast<uchar>(participant.partyId()), b2, b3, b4, b5, b6, b7, GuidContext::GuidParticipant).toString(QUuid::WithoutBraces);
|
|
|
|
return result;
|
|
}
|
|
|
|
ParticipantManagement::Participant ExportSaab::rootParticipant(const ParticipantManagement::Participant &participant, const QMap<int, ParticipantManagement::Participant> &participants) const
|
|
{
|
|
if (participant.superiorId())
|
|
return rootParticipant(participants.value(participant.superiorId()), participants);
|
|
return participant;
|
|
}
|
|
|
|
QString ExportSaab::toSaabTime(qint64 msecs) const
|
|
{
|
|
return QDateTime::fromMSecsSinceEpoch(msecs).toString(QStringLiteral("yyyy-MM-ddThh:mm:ssZ"));
|
|
}
|
|
|
|
void ExportSaab::mapType(const ParticipantManagement::Type &type)
|
|
{
|
|
using namespace ParticipantManagement;
|
|
|
|
MapType dialog(ParticipantManagement::trTypeName(type.name()),
|
|
m_mapEchelons,
|
|
m_mapSymbols,
|
|
type.typeClass() == TypeClass::Unit || type.typeClass() == TypeClass::SupportUnit,
|
|
this);
|
|
|
|
dialog.exec();
|
|
|
|
QString saabTypeStr = dialog.symbolCode();
|
|
|
|
if (!dialog.echelonCode().isEmpty())
|
|
{
|
|
saabTypeStr.append(QLatin1Char(';'));
|
|
saabTypeStr.append(dialog.echelonCode());
|
|
}
|
|
|
|
m_mapTypeToSaabSymbol.insert(type.id(), saabTypeStr);
|
|
}
|
|
|
|
void ExportSaab::mapPartyToForce(const ParticipantManagement::Party &party)
|
|
{
|
|
MapParty dialog(QString::fromStdString(party.name()), m_mapForces, m_mapEchelons, m_mapSymbols, this);
|
|
|
|
dialog.exec();
|
|
|
|
if (dialog.isSkipped())
|
|
return;
|
|
|
|
m_mapPartyToForce.insert(party.id(), { m_mapForces.take(dialog.force()), dialog.echelonCode(), dialog.symbolCode() });
|
|
}
|
|
|
|
}
|