/** * @RDE_HEADER@ * Importieren von SAAB-Dateien * $Id$ * $HeadURL$ * $Author$ */ #include "saab_import.h" #include "ui_saab_import.h" #include "saab_logging.h" #include "saab_import_show.h" #include #include #include #include #include #include #include #include "saab_mapping_dialog.h" namespace saab { ImportSaab::ImportSaab(ParticipantManagement::ParticipantEditModel *pModel, const QModelIndex &index, QWidget *parent, LtsSession::LtsSession *pSession) : NGLDialog(parent) , m_xmlFile(nullptr) , m_configFile(nullptr) , m_indexRoot(index) , m_pModel(pModel) , m_requestHelper(new LtsUtils::RequestHelper(this)) , m_pUi(new Ui_SAABImport) , m_logger(saab::getLogger("ImportSaab")) { m_pUi->setupUi(this); setWindowTitle(tr("Import SAAB Orbat")); if (!pSession->getDtc(m_ppmDtc) || !pSession->getFtc(m_ppmFtc)) { ERROR_LOG(m_logger) << "Fetching m_ppmDtc or m_ppmFtc failed!"; setEnabled(false); } else m_mapTypes = m_ppmDtc->types(); connect(m_pUi->m_pushbutton_SelectFile, &QToolButton::clicked, this, &ImportSaab::slotOpenImportDialog); connect(m_pUi->m_pushbutton_SelectConfig, &QToolButton::clicked, this, &ImportSaab::slotOpenConfigDialog); connect(m_pUi->m_pushButton_StartImport, &QPushButton::clicked, this, &ImportSaab::slotStartImport); QString strImportFile = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedImportFile"), QString()).toString(); QString strConfigFile = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedConfigFile"), QString()).toString(); m_pUi->m_lineedit_ImportFile->setText(strImportFile); m_pUi->m_lineedit_configFile->setText(strConfigFile); m_pUi->m_pushButton_StartImport->setEnabled(strImportFile.size() && strConfigFile.size()); } ImportSaab::~ImportSaab() { delete m_pUi; } void ImportSaab::slotOpenImportDialog() { QString strPathSelectedImportFolder = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedImportFolder"), QStringLiteral("/shd/CTC/TOOLS/TDS/")).toString(); QString strPathSelectedImportFile = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedImportFile"), QStringLiteral("/shd/CTC/TOOLS/TDS/")).toString(); QList urls; urls << QUrl::fromLocalFile(strPathSelectedImportFile); QFileDialog fileDialog(this, tr("Select File"), strPathSelectedImportFolder, tr("XML files (*.xml)")); fileDialog.setSidebarUrls(urls); fileDialog.setOptions(QFileDialog::ReadOnly); fileDialog.setFileMode(QFileDialog::ExistingFile); if (fileDialog.exec()) // TODO: use show(), use signals & slots ! { strPathSelectedImportFile = fileDialog.selectedFiles().constFirst(); LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("SAAB"), QStringLiteral("pathSelectedImportFolder"), strPathSelectedImportFolder); if (!strPathSelectedImportFile.size()) return; LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("SAAB"), QStringLiteral("pathSelectedImportFile"), strPathSelectedImportFile); m_pUi->m_lineedit_ImportFile->setText(strPathSelectedImportFile); m_pUi->m_pushButton_StartImport->setEnabled(LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedConfigFile"), QString()).toString().size()); } } void ImportSaab::slotOpenConfigDialog() { 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 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_pUi->m_lineedit_configFile->setText(strPathSelectedConfigFile); m_pUi->m_pushButton_StartImport->setEnabled(LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("SAAB"), QStringLiteral("pathSelectedImportFile"), QString()).toString().size()); } } void ImportSaab::slotStartImport() { if (m_xmlFile) { m_xmlFile->close(); delete m_xmlFile; m_xmlFile = nullptr; } if (m_configFile) { m_configFile->close(); delete m_configFile; m_configFile = nullptr; } m_pModel->resetModel(); QString fileName = m_pUi->m_lineedit_ImportFile->text(); QString configFileName = m_pUi->m_lineedit_configFile->text(); m_xmlFile = new QFile(fileName, this); m_configFile = new QFile(configFileName, this); if (!isValidSaabOrbatFile()) { LtsWidgets::LtsMessageDialog::showMessage(this, tr("Error while reading file \"%1\".").arg(fileName)); return; } if (!isValidConfigFile()) { LtsWidgets::LtsMessageDialog::showMessage(this, tr("Error while reading file \"%1\".").arg(configFileName)); return; } importExerciseScenario(); } ParticipantManagement::ParticipantData ImportSaab::createParticipant(SaabPlayer *player) { ParticipantManagement::ParticipantData p; // Note: According to Uli D., in GÜZ, TactId shall be static and // received from SAAB and designator shall be freely changeable. // Designator p.tacticalIdentifier(player->designation.toStdString()); // State and Equipment p.equipmentNumber(player->simulatorId != INT_MIN ? player->simulatorId : 0); p.assignState() = ParticipantManagement::ParticipantAssignState::HandoutExcon; if (player->simulatorId != INT_MIN) p.externalId(player->simulatorId); p.symbol(m_mapTypes[player->mappedTypeId].symbol()); p.typeId(player->mappedTypeId); // Class type is internally derived from typeid, no need (and possibility) to set it here return p; } void ImportSaab::insertParticipant(SaabPlayer *player, const QModelIndex &index) { ParticipantManagement::ParticipantData newParticipant = createParticipant(player); createNode(newParticipant, index, player); } // Parties are the root units (m_rootUnits) void ImportSaab::insertParty(SaabUnit *party) { // Create "Force"-Node -> No symbol, no tact. identifier, no classtype ParticipantManagement::ParticipantData newParty; newParty.designator(party->designation.toStdString()); createNode(newParty, m_indexRoot, party); } void ImportSaab::createNode(const ParticipantManagement::ParticipantData &participant, const QModelIndex &index, SaabPlayer *parent) { int newRow = m_pModel->onInsertRow(index, participant); QModelIndex newIdx = m_pModel->index(newRow, 0, index); m_parentIndexCache[parent] = newIdx; } SaabPerson ImportSaab::saabPersonByGUID(const QString &guid) const { for (const auto ¤t : qAsConst(m_saabPersons)) { if (current.guid == guid) return current; } return SaabPerson(); } SaabVehicle ImportSaab::saabVehicleByGUID(const QString &guid) const { for (const auto ¤t : qAsConst(m_saabVehicles)) { if (current.guid == guid) return current; } return SaabVehicle(); } void ImportSaab::importOrbat() { if (!m_xmlFile) { ERROR_LOG(m_logger) << "Not possible to import ORBAT: No file selected"; return; } if (!m_xmlFile->open(QIODevice::ReadOnly)) { ERROR_LOG(m_logger) << "Not possible to import ORBAT: Could not open file \"" << m_xmlFile->fileName() << "\" for reading."; return; } QXmlStreamReader reader(m_xmlFile); qDeleteAll(m_rootUnits); m_rootUnits.clear(); m_unknownTypes.clear(); while (!(reader.readNext() == QXmlStreamReader::EndElement && reader.name() == XmlStrings::SAAB_ORBAT())) { if (reader.atEnd()) break; if (reader.tokenType() == QXmlStreamReader::StartElement && reader.name() == XmlStrings::SAAB_UNIT()) { SaabUnit *unit = static_cast(readUnit(&reader)); if (unit->isDeletedByDefault) continue; m_rootUnits.append(unit); } } if (m_logger.isDebugEnabled()) { for (SaabUnit *u : qAsConst(m_rootUnits)) DEBUG_LOG(m_logger) << u->toString(); } m_xmlFile->close(); } void ImportSaab::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_mapSaabSymbolToType.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); } } } m_configFile->close(); } QVector ImportSaab::flattenedPlayersWithoutRootUnits() const { QVector result; for (SaabUnit *p : qAsConst(m_rootUnits)) { QVector inferiorInferiors = inferiors(p); for (SaabPlayer *infInf : qAsConst(inferiorInferiors)) result.append(infInf); } return result; } QVector ImportSaab::inferiors(SaabPlayer *player) const { QVector result; if (typeid(*player) != typeid(SaabUnit)) { result.append(player); return result; } SaabUnit *unit = static_cast(player); if (!m_rootUnits.contains(unit)) result.append(player); for (SaabPlayer *inf : qAsConst(unit->inferiors)) { QVector inferiorInferiors = inferiors(inf); for (SaabPlayer *infInf : qAsConst(inferiorInferiors)) result.append(infInf); } return result; } SaabPlayer *ImportSaab::readUnit(QXmlStreamReader *reader) const { DEBUG_LOG(m_logger) << "reading unit: tokentype: " << reader->tokenString() << " | name: " << reader->name().toString(); SaabUnit *result = new SaabUnit; using namespace XmlStrings; QMap funcMap; funcMap.insert(SAAB_PERSON_PLAYER(), &ImportSaab::readPersonPlayer); funcMap.insert(SAAB_OC_PLAYER(), &ImportSaab::readOcPlayer); funcMap.insert(SAAB_VEHICLE_PLAYER(), &ImportSaab::readVehiclePlayer); funcMap.insert(SAAB_UNIT(), &ImportSaab::readUnit); result->guid = reader->attributes().value(SAAB_ID()).toString(); while (!(reader->readNext() == QXmlStreamReader::EndElement && reader->name() == SAAB_UNIT())) { if (reader->tokenType() == QXmlStreamReader::StartElement) { if (reader->name() == SAAB_DESIGNATION()) result->designation = reader->readElementText(); else if (reader->name() == SAAB_FORCE()) result->force = reader->readElementText(); else if (reader->name() == SAAB_SYMBOL()) result->symbol = reader->readElementText(); else if (reader->name() == SAAB_TRASHCAN()) result->trashcan = reader->readElementText() == SAAB_TRUE(); else if (reader->name() == SAAB_POSITION_BY_PLAYER_ID()) result->positionByPlayerId = reader->readElementText(); else if (reader->name() == SAAB_UNIT_SIZE()) result->unitSize = reader->readElementText(); else if (reader->name() == SAAB_CHANGE_INFO()) result->isDeletedByDefault = reader->attributes().value(SAAB_CHANGE_TYPE()).toString() == SAAB_DELETE(); else if (reader->name() == SAAB_ORBAT_ENTITIES()) { while (!(reader->readNext() == QXmlStreamReader::EndElement && reader->name() == SAAB_ORBAT_ENTITIES())) { QString tagName = reader->name().toString(); if (reader->tokenType() == QXmlStreamReader::StartElement && funcMap.contains(tagName)) { SaabPlayer *newParticipant = (this->*funcMap.value(tagName))(reader); if (newParticipant->isDeletedByDefault || newParticipant->isExternalPlayer) continue; newParticipant->superior = result; result->inferiors.append(newParticipant); } } } } } // if the unit has to take the position of a specific participant, // take the participant to the top of the inferiors if (!result->positionByPlayerId.isEmpty()) { int index = playerIndexByGuid(result->guid, result->inferiors); if (index < 0) WARNING_LOG(m_logger) << SAAB_POSITION_BY_PLAYER_ID() << " set, but GUID " << result->positionByPlayerId << " could not be found."; else result->inferiors.prepend(result->inferiors.takeAt(index)); } return result; } SaabPlayer *ImportSaab::readOcPlayer(QXmlStreamReader *reader) const { DEBUG_LOG(m_logger) << "reading oc player: tokentype: " << reader->tokenString() << " | name: " << reader->name().toString(); return readPersonOcPlayer(reader, XmlStrings::SAAB_OC_PLAYER());; } SaabPlayer *ImportSaab::readPersonPlayer(QXmlStreamReader *reader) const { DEBUG_LOG(m_logger) << "reading person player: tokentype: " << reader->tokenString() << " | name: " << reader->name().toString(); return readPersonOcPlayer(reader, XmlStrings::SAAB_PERSON_PLAYER()); } SaabPlayer *ImportSaab::readVehiclePlayer(QXmlStreamReader *reader) const { DEBUG_LOG(m_logger) << "reading vehicle player: tokentype: " << reader->tokenString() << " | name: " << reader->name().toString(); using namespace XmlStrings; SaabVehiclePlayer *result = readPlayerBaseData(reader, SAAB_VEHICLE_PLAYER(), SAAB_VEHICLE_REF_ID()); if (!result->refId.isEmpty()) { SaabVehicle vehicle = saabVehicleByGUID(reader->readElementText()); if (vehicle.guid.isEmpty()) WARNING_LOG(m_logger) << SAAB_VEHICLE_REF_ID() << " set, but GUID " << result->refId << " could not be found."; else { result->registrationNumber = vehicle.registrationNumber; result->description = vehicle.description; } } return result; } SaabSymbol ImportSaab::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 ImportSaab::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; } int ImportSaab::playerIndexByGuid(const QString &guid, const QVector &vec) { for (int i = 0; i < vec.size(); ++i) { if (vec.at(i)->guid == guid) return i; } return -1; } void ImportSaab::importExerciseScenario() { using namespace XmlStrings; importConfig(); importRefData(m_saabPersons, SAAB_PERSONS(), SAAB_PERSON(), SAAB_PERSONAL_ID(), SAAB_NAME()); // import persons importRefData(m_saabVehicles, SAAB_VEHICLES(), SAAB_VEHICLE(), SAAB_REGISTRATION_NUMBER(), SAAB_DESCRIPTION()); // import vehicles importOrbat(); for (SaabUnit *party : qAsConst(m_rootUnits)) insertParty(party); QVector vecUnitsWithValidDISTypes = resolveImportMapping(flattenedPlayersWithoutRootUnits()); if (!vecUnitsWithValidDISTypes.size()) { LtsWidgets::LtsMessageDialog::showMessage(this, tr("There are no units or participants which can be imported."), tr("Import Warning")); return; } buildImportTreeView(vecUnitsWithValidDISTypes); close(); } void ImportSaab::buildImportTreeView(const QVector &vecUnitsWithValidDISTypes) { QVector tmp; QVector current = vecUnitsWithValidDISTypes; do { for (SaabPlayer *player : current) { auto it = m_parentIndexCache.find(player->superior); if (it == m_parentIndexCache.end()) { // check if the parent exists in vecUnitsWithValidDISTypes for the next approach if (vecUnitsWithValidDISTypes.contains(player->superior)) tmp.append(player); else WARNING_LOG(m_logger) << "Parent missing: Could not import player " << player->designation; continue; } QModelIndex &parentIdx = (*it); insertParticipant(player, parentIdx); } current = tmp; tmp.clear(); } while (!current.isEmpty()); } bool ImportSaab::isValidSaabOrbatFile() const { if (!m_xmlFile) { ERROR_LOG(m_logger) << "Not possible to import ORBAT: No file selected"; return false; } if (!m_xmlFile->open(QIODevice::ReadOnly)) { ERROR_LOG(m_logger) << "Not possible to import ORBAT: Could not open file \"" << m_xmlFile->fileName() << "\" for reading."; return false; } bool hasExerciseOrbatRoot = false; bool hasExercise = false; bool hasOrbat = false; QXmlStreamReader reader(m_xmlFile); using namespace XmlStrings; while (!(hasExerciseOrbatRoot && hasExercise && hasOrbat) && !reader.atEnd()) { if (reader.readNextStartElement()) { if (reader.name() == SAAB_EXERCISE_ORBAT()) hasExerciseOrbatRoot = true; else if (reader.name() == SAAB_EXERCISE()) hasExercise = true; else if (reader.name() == SAAB_ORBAT()) hasOrbat = true; } } m_xmlFile->close(); if (!hasExerciseOrbatRoot) ERROR_LOG(m_logger) << "Could not find " << SAAB_EXERCISE_ORBAT() << " in file \"" << m_xmlFile->fileName() << '\"'; if (!hasExercise) ERROR_LOG(m_logger) << "Could not find " << SAAB_EXERCISE() << " in file \"" << m_xmlFile->fileName() << '\"'; if (!hasOrbat) ERROR_LOG(m_logger) << "Could not find " << SAAB_ORBAT() << " in file \"" << m_xmlFile->fileName() << '\"'; return hasExerciseOrbatRoot && hasExercise && hasOrbat; } bool ImportSaab::isValidConfigFile() const { 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; while (!reader.atEnd() && !(hasSymbols && hasEchelons)) { if (reader.readNextStartElement()) { if (reader.name() == SAAB_SYMBOLS()) hasSymbols = true; else if (reader.name() == SAAB_ECHELONS()) hasEchelons = 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() << '\"'; return hasEchelons && hasSymbols; } bool ImportSaab::hasValidType(SaabPlayer *player) const { return m_mapSymbols.value(player->symbol).mappedTypeId > -1; } QVector ImportSaab::resolveImportMapping(const QVector &playerVec) { QVector vecObjectsWithValidTypes; QMap> mapParticipantsWithUnknownType, mapUnitsWithUnknownType; // first perform a mapping of saab type to rme type for (SaabPlayer *player : playerVec) { if (!hasValidType(player)) { if (typeid(*player) == typeid(SaabUnit)) { QString text = m_mapSymbols.contains(player->symbol) ? m_mapSymbols.value(player->symbol).text : player->symbol; QString unitSize = static_cast(player)->unitSize; text.append(tr(" - Size: %1").arg(m_mapEchelons.contains(unitSize) ? m_mapEchelons.value(unitSize).text : unitSize)); mapUnitsWithUnknownType[text].append(player); } else mapParticipantsWithUnknownType[m_mapSymbols.contains(player->symbol) ? m_mapSymbols.value(player->symbol).text : player->symbol].append(player); } else { // A match between the imported unit (its DIS id) and one of the database types exists: Perform mapping, everything is fine. vecObjectsWithValidTypes.append(player); } } if (mapUnitsWithUnknownType.size()) { LtsWidgets::LtsMessageDialog::showMessage(this, tr("Units exist whose external type is unknown.
You have to solve this by manually mapping
the external types to existing unit types."), tr("Import Error")); vecObjectsWithValidTypes.append(showMappingDialog(mapUnitsWithUnknownType, true)); } if (mapParticipantsWithUnknownType.size()) { LtsWidgets::LtsMessageDialog::showMessage(this, tr("Participants exist whose external type is unknown.
You have to solve this by manually mapping
the external types to existing participant types."), tr("Import Error")); vecObjectsWithValidTypes.append(showMappingDialog(mapParticipantsWithUnknownType, false)); } return vecObjectsWithValidTypes; } QVector ImportSaab::showMappingDialog(const QMap> &mapConflictMap, bool typeClassIsUnit) { QVector vecUnitsWithValidSymbols; int32_t mappedTypeId = 0; for (auto it = mapConflictMap.begin(); it != mapConflictMap.end(); ++it) { const QString &strSaabSymbol = it.key(); const QVector &vecData = it.value(); QString strReason; bool offerDatabaseEntriesWithoutDISType; if (!strSaabSymbol.size()) { strReason = QString(tr("No type specified.")); // Imported unit/participant has no DIS type. Mapping "no DIS type" to database elements without a DIS type does not make sense offerDatabaseEntriesWithoutDISType = false; } else { strReason = QString(tr("Specified type \"%1\" is unknown.")).arg(strSaabSymbol); offerDatabaseEntriesWithoutDISType = true; } QString strType = typeClassIsUnit ? tr("unit(s)") : tr("participant(s)"); strReason += tr("
This applies for %1 %2. Please choose an option:").arg(QString::number(vecData.size()), strType); saab::MappingDialog dialog(this, typeClassIsUnit, strReason, m_ppmDtc, offerDatabaseEntriesWithoutDISType); dialog.exec(); // TODO: use show(), use signals & slots ! if (dialog.skipAllUnmappedElements()) break; mappedTypeId = dialog.getMappedTypeId(); if (dialog.mappingApplied()) { m_mapSaabSymbolToType.insert(strSaabSymbol, mappedTypeId); for (SaabPlayer *participant : qAsConst(vecData)) { participant->mappedTypeId = mappedTypeId; vecUnitsWithValidSymbols.push_back(participant); } } } return vecUnitsWithValidSymbols; } }