704 lines
23 KiB
C++
Executable File
704 lines
23 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* AssignmentParticipantModel
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Norbert Thoden, NLE, 2020-06-29
|
|
*/
|
|
|
|
#include "tgt_assignment_part_model.h"
|
|
#include "tgt_common.h"
|
|
|
|
#include <LtsUtilsCore/variant_operators.h>
|
|
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
#include <ParticipantManagement/ppm_translation.h>
|
|
|
|
#include <QApplication> // pixelMetric
|
|
#include <QBuffer>
|
|
|
|
namespace TargetManagement
|
|
{
|
|
// some helper
|
|
bool isEqual(const ShootbackConfiguration &c1, const ShootbackConfiguration &c2)
|
|
{
|
|
return (
|
|
(c1.interval1() == c2.interval1()) &&
|
|
(c1.flash1() == c2.flash1()) &&
|
|
(c1.effect1() == c2.effect1()) &&
|
|
(c1.interval2() == c2.interval2()) &&
|
|
(c1.flash2() == c2.flash2()) &&
|
|
(c1.effect2() == c2.effect2())
|
|
);
|
|
}
|
|
|
|
bool isDefault(const ShootbackConfiguration &c) { return isEqual(c, ShootbackConfiguration()); }
|
|
|
|
bool isEqual(const TargetAreaAssignment &a1, const TargetAreaAssignment &a2, bool ignoringAreaIdAndParticipantId)
|
|
{
|
|
return (
|
|
(a1.id() == a2.id()) &&
|
|
(a1.name() == a2.name()) &&
|
|
(ignoringAreaIdAndParticipantId || (a1.areaId() == a2.areaId())) &&
|
|
(ignoringAreaIdAndParticipantId || (a1.targetParticipantId() == a2.targetParticipantId())) &&
|
|
(a1.isActive() == a2.isActive()) &&
|
|
isEqual(a1.configuration(), a2.configuration())
|
|
);
|
|
}
|
|
|
|
|
|
//---------------------------------
|
|
// AssignmentParticipantModel
|
|
//---------------------------------
|
|
AssignmentParticipantModel::AssignmentParticipantModel(QObject *parent)
|
|
: BaseClass(
|
|
{
|
|
tr("Id"),
|
|
tr("Assignment Name"),
|
|
tr("Assigned"), // isActive
|
|
|
|
// associated target:
|
|
tr("TargetId"),
|
|
tr("TargetName"),
|
|
// associated participant:
|
|
tr("Participant Id"),
|
|
tr("Equipmentnumber"),
|
|
tr("Participant"),
|
|
|
|
// associated Area
|
|
tr("AreaId"),
|
|
tr("AreaName"),
|
|
|
|
// configuration
|
|
tr("Interval_1"),
|
|
tr("Flash_1"),
|
|
tr("Effect_1"),
|
|
tr("Interval_2"),
|
|
tr("Flash_2"),
|
|
tr("Effect_2")
|
|
},
|
|
parent)
|
|
, m_logger(getLogger("AssignmentParticipantModel"))
|
|
{}
|
|
|
|
|
|
bool AssignmentParticipantModel::initModel(const std::shared_ptr<TargetManagement::Interface::Dtc> &tgtDtc,
|
|
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
|
const std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> &ppmGuiCbxIfc,
|
|
LtsSession::LtsSession *session)
|
|
{
|
|
m_tgt_dtc = tgtDtc;
|
|
m_session = session;
|
|
|
|
delete m_participantHandler;
|
|
m_participantHandler = new ParticipantHandler(this);
|
|
|
|
m_participantHandler->init(m_tgt_dtc, ppmDtc, ppmGuiCbxIfc /*, exmDtc*/); // exercises are no relavant yet
|
|
|
|
connect(m_participantHandler, &ParticipantHandler::signalParticipantNamesChanged,
|
|
this, &AssignmentParticipantModel::signalParticipantNamesChanged);
|
|
connect(m_participantHandler, &ParticipantHandler::signalParticipantChanged,
|
|
this, &AssignmentParticipantModel::update);
|
|
|
|
// insert Model
|
|
const QMap<qint32, TargetManagement::TargetAreaAssignment> targetAreaAssignments = m_tgt_dtc->targetAreaAssignments();
|
|
INFO_LOG(m_logger) << "initModel - #targetAreaAssignments.size(): " << targetAreaAssignments.size();
|
|
|
|
connect(m_tgt_dtc.get(), &Interface::Dtc::targetAreaAssignmentChanged,
|
|
this, &AssignmentParticipantModel::onTargetAreaAssignmentChanged);
|
|
|
|
{
|
|
auto cb = [this](const TargetManagement::TargetAreaAssignment & d) { onTargetAreaAssignmentChanged(d, DataModification::eAdded); };
|
|
m_tgt_dtc->targetAreaAssignments(cb);
|
|
}
|
|
INFO_LOG(m_logger) << "initModel - #targetAreaAssignments.size(): " << targetAreaAssignments.size() << " DONE";
|
|
|
|
// updateColumnFilter
|
|
connect(this, &AssignmentParticipantModel::rowsInserted, this, &AssignmentParticipantModel::updateColumnFilter);
|
|
connect(this, &AssignmentParticipantModel::rowsRemoved, this, &AssignmentParticipantModel::updateColumnFilter);
|
|
connect(this, &AssignmentParticipantModel::modelReset, this, &AssignmentParticipantModel::updateColumnFilter);
|
|
// in case of changing value like hitsToKill:
|
|
connect(this, &AssignmentParticipantModel::dataChanged, this, &AssignmentParticipantModel::updateColumnFilter);
|
|
updateColumnFilter();
|
|
|
|
return true;
|
|
}
|
|
|
|
QVariant AssignmentParticipantModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole &&
|
|
orientation == Qt::Horizontal)
|
|
{
|
|
// a few QSet<QString> ==>
|
|
const auto processString = [](const QSet<QString> &usedXYCont) -> QVariant
|
|
{
|
|
LtsWidgets::ComboboxFilterContent cfc;
|
|
cfc.data.reserve(usedXYCont.size());
|
|
LtsWidgets::ComboboxFilterData cfd;
|
|
|
|
for (const QString &value : usedXYCont)
|
|
{
|
|
cfd.data = value;
|
|
cfd.text = value;
|
|
cfc.data.push_back(cfd);
|
|
}
|
|
cfc.sortItems = true;
|
|
return cfc.toVariant();
|
|
};
|
|
|
|
// a few Set<int> ==>
|
|
const auto processBoolean = [this](const QSet<int> &usedXYCont) -> QVariant
|
|
{
|
|
LtsWidgets::ComboboxFilterContent cfc;
|
|
cfc.data.reserve(usedXYCont.size());
|
|
LtsWidgets::ComboboxFilterData cfd;
|
|
|
|
for (int value : usedXYCont)
|
|
{
|
|
cfd.data = value;
|
|
cfd.text = value ? tr("Yes") : tr("No");
|
|
cfd.icon = value ? m_yes : m_no;
|
|
cfc.data.push_back(cfd);
|
|
}
|
|
cfc.sortItems = true;
|
|
return cfc.toVariant();
|
|
};
|
|
|
|
// a few Set<int> ==>
|
|
const auto processInt = [](const QSet<int> &usedXYCont) -> QVariant
|
|
{
|
|
LtsWidgets::ComboboxFilterContent cfc;
|
|
cfc.data.reserve(usedXYCont.size());
|
|
LtsWidgets::ComboboxFilterData cfd;
|
|
|
|
for (int value : usedXYCont)
|
|
{
|
|
cfd.data = value;
|
|
cfd.text = QString::number(value);
|
|
cfc.data.push_back(cfd);
|
|
}
|
|
cfc.sortItems = true;
|
|
return cfc.toVariant();
|
|
};
|
|
|
|
if (section == IsActive)
|
|
return processBoolean(m_usedIsActive);
|
|
|
|
else if (section == AreaId)
|
|
return processInt(m_usedAreaIds);
|
|
else if (section == AreaName)
|
|
return processString(m_usedAreas);
|
|
|
|
else if (section == TargetId)
|
|
return processInt(m_usedTargetIds);
|
|
else if (section == TargetName)
|
|
return processString(m_usedTargets);
|
|
|
|
else if (section == TargetPartipantId)
|
|
return processInt(m_usedTargetParticipantIds);
|
|
else if (section == TargetPartipantEquipmentNumber)
|
|
return processInt(m_usedParticipantEqNo);
|
|
else if (section == Participant)
|
|
return processString(m_usedParticipants);
|
|
}
|
|
return BaseClass::headerData(section, orientation, role);
|
|
}
|
|
|
|
|
|
template <typename T>
|
|
QVariant handleIsDefault(const TargetManagement::TargetAreaAssignment &assignment, const T &value)
|
|
{
|
|
if (isDefault(assignment.configuration()))
|
|
return QStringLiteral("-");
|
|
return value;
|
|
}
|
|
|
|
|
|
QVariant AssignmentParticipantModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " role=" << role
|
|
<< " index = " << index.column();
|
|
|
|
if (!indexIsValid(index))
|
|
return QVariant();
|
|
if (role != Qt::DisplayRole &&
|
|
role != Qt::EditRole &&
|
|
role != Qt::CheckStateRole &&
|
|
role != Qt::DecorationRole &&
|
|
role != Qt::ForegroundRole &&
|
|
role != Qt::BackgroundRole &&
|
|
role != Qt::ToolTipRole &&
|
|
role != LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
|
|
return QVariant();
|
|
|
|
const TargetManagement::TargetAreaAssignment &assignment = m_vecData.at(index.row());
|
|
|
|
if (role == Qt::CheckStateRole)
|
|
{
|
|
// CheckBoxes only for columns that are actually checkable
|
|
if (!flags(index).testFlag(Qt::ItemIsUserCheckable))
|
|
return QVariant();
|
|
return assignment.isActive() ? Qt::Checked : Qt::Unchecked;
|
|
}
|
|
else if (role == Qt::DecorationRole)
|
|
{
|
|
if (index.column() == Participant)
|
|
{
|
|
static const int pmSize = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
|
|
const QPixmap &pm = m_participantHandler->getParticipantDecoration(assignment.targetParticipantId());
|
|
if (!pm.isNull())
|
|
return pm.scaled(pmSize, pmSize);
|
|
}
|
|
else if ((index.column() == Flash_1))
|
|
return assignment.configuration().flash1() ? m_yes : m_no;
|
|
else if ((index.column() == Flash_2))
|
|
return assignment.configuration().flash2() ? m_yes : m_no;
|
|
return QVariant();
|
|
}
|
|
else if (role == Qt::BackgroundRole)
|
|
{
|
|
if ((index.column() == TargetId) || (index.column() == TargetName))
|
|
{
|
|
int targetId = m_participantHandler->getParticipantIdToTargetId(assignment.targetParticipantId());
|
|
if (targetId <= 0)
|
|
return getNoParticipantColor(); // orange
|
|
}
|
|
|
|
else if ((index.column() == AreaId) || (index.column() == AreaName))
|
|
{
|
|
if (m_tgt_dtc->shootbackArea(assignment.areaId()).id()<=0)
|
|
return getNoParticipantColor(); // orange
|
|
}
|
|
|
|
|
|
else if ((index.column() == TargetPartipantId) && (assignment.targetParticipantId() <= 0))
|
|
return getNoParticipantColor(); // orange
|
|
else if (index.column() == TargetPartipantEquipmentNumber)
|
|
{
|
|
const int eqNo = m_participantHandler->getParticipantIdToEquipmentNumber(assignment.targetParticipantId());
|
|
if (eqNo <= 0)
|
|
return getNoParticipantColor(); // orange
|
|
}
|
|
// no else here
|
|
if (assignment.isActive() && isDefault(assignment.configuration()))
|
|
return getAssignedButNoConfigurationColor(); // lightRed
|
|
}
|
|
else if (role == Qt::ForegroundRole)
|
|
{
|
|
if (!assignment.isActive() && (index.column() != Participant))
|
|
return QColor(Qt::gray);
|
|
}
|
|
else if (role == Qt::ToolTipRole)
|
|
{
|
|
if (index.column() == Participant)
|
|
{
|
|
QString tooltip(QStringLiteral("<html>"));
|
|
|
|
const QPixmap &img = m_participantHandler->getParticipantDecoration(assignment.targetParticipantId());
|
|
if (!img.isNull())
|
|
{
|
|
// without a temporary file:
|
|
QByteArray data;
|
|
QBuffer buffer(&data);
|
|
img.save(&buffer, "PNG", 100);
|
|
tooltip.append(QStringLiteral("<center><img src='data:image/png;base64,%1'></center>").arg(QString::fromLatin1(data.toBase64())));
|
|
|
|
QString hdr = this->headerData(AssignmentName, Qt::Horizontal, Qt::DisplayRole).toString();
|
|
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, QString::fromStdString(assignment.name())));
|
|
|
|
hdr = this->headerData(Participant, Qt::Horizontal, Qt::DisplayRole).toString();
|
|
const QString &val = m_participantHandler->getParticipantHierarchie(assignment.targetParticipantId());
|
|
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, val));
|
|
|
|
tooltip.append(QStringLiteral("</html>"));
|
|
return tooltip;
|
|
}
|
|
}
|
|
}
|
|
else if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
|
|
{
|
|
// following static_cast<int> are important!!!
|
|
if (index.column() == IsActive)
|
|
return static_cast<int>(assignment.isActive());
|
|
if (index.column() == AreaId)
|
|
return assignment.areaId();
|
|
if (index.column() == TargetPartipantId)
|
|
return assignment.targetParticipantId();
|
|
}
|
|
|
|
switch (index.column())
|
|
{
|
|
case Id:
|
|
return assignment.id();
|
|
|
|
case AssignmentName:
|
|
return QString::fromStdString(assignment.name());
|
|
case IsActive:
|
|
return assignment.isActive() ? tr("Yes") : tr("No");
|
|
|
|
case TargetId:
|
|
{
|
|
int targetId = m_participantHandler->getParticipantIdToTargetId(assignment.targetParticipantId());
|
|
return targetId;
|
|
}
|
|
|
|
case TargetName:
|
|
{
|
|
int targetId = m_participantHandler->getParticipantIdToTargetId(assignment.targetParticipantId());
|
|
if (targetId <= 0)
|
|
return QStringLiteral("-");
|
|
const ShootbackTarget &st = m_tgt_dtc->shootbackTarget(targetId);
|
|
if (st.id() != targetId)
|
|
return QStringLiteral("-");
|
|
return QString::fromStdString(st.name());
|
|
}
|
|
|
|
// associated participant:
|
|
case TargetPartipantId:
|
|
return assignment.targetParticipantId();
|
|
case TargetPartipantEquipmentNumber:
|
|
{
|
|
const int eqNo = m_participantHandler->getParticipantIdToEquipmentNumber(assignment.targetParticipantId());
|
|
if (eqNo <= 0)
|
|
return QStringLiteral("-");
|
|
return eqNo;
|
|
}
|
|
|
|
case Participant:
|
|
return m_participantHandler->getParticipantHierarchie(assignment.targetParticipantId());
|
|
|
|
// associated area:
|
|
case AreaId:
|
|
return assignment.areaId();
|
|
case AreaName:
|
|
return QString::fromStdString(m_tgt_dtc->shootbackArea(assignment.areaId()).name());
|
|
|
|
// configuration:
|
|
case Interval_1:
|
|
return handleIsDefault(assignment, assignment.configuration().interval1());
|
|
case Flash_1:
|
|
return handleIsDefault(assignment, assignment.configuration().flash1());
|
|
case Effect_1:
|
|
return handleIsDefault(assignment, effectToString(assignment.configuration().effect1()));
|
|
case Interval_2:
|
|
return handleIsDefault(assignment, assignment.configuration().interval2());
|
|
case Flash_2:
|
|
return handleIsDefault(assignment, assignment.configuration().flash2());
|
|
case Effect_2:
|
|
return handleIsDefault(assignment, effectToString(assignment.configuration().effect2()));
|
|
|
|
} // switch
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
bool AssignmentParticipantModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
{
|
|
if (!indexIsValid(index))
|
|
return false;
|
|
|
|
if (role != Qt::CheckStateRole)
|
|
return false;
|
|
|
|
if (!value.canConvert<bool>())
|
|
return false;
|
|
|
|
bool bVal = value.toBool();
|
|
|
|
TargetAreaAssignment &data = m_vecData[index.row()];
|
|
if (data.isActive() != bVal)
|
|
{
|
|
data.isActive(bVal);
|
|
emit dataChanged(index, index);
|
|
emit signalEditableItemChanged();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Qt::ItemFlags AssignmentParticipantModel::flags(const QModelIndex &index) const
|
|
{
|
|
auto f = QAbstractTableModel::flags(index);
|
|
if (!index.isValid() || index.row() >= m_vecData.size())
|
|
return f;
|
|
if (index.column() == Columns::IsActive)
|
|
{
|
|
f.setFlag(Qt::ItemIsUserCheckable);
|
|
return f;
|
|
}
|
|
return f;
|
|
}
|
|
|
|
|
|
QSet<int> AssignmentParticipantModel::getAssociatedParticipantIds() const
|
|
{
|
|
QSet<int> ret;
|
|
ret.reserve(m_vecData.size());
|
|
for (const TargetManagement::TargetAreaAssignment &data : m_vecData)
|
|
ret += data.targetParticipantId();
|
|
return ret;
|
|
}
|
|
|
|
QSet<int> AssignmentParticipantModel::getAssociatedParticipantIdsForArea(int areaId) const
|
|
{
|
|
QSet<int> ret;
|
|
ret.reserve(m_vecData.size());
|
|
for (const TargetManagement::TargetAreaAssignment &data : m_vecData)
|
|
if (data.areaId() == areaId)
|
|
ret += data.targetParticipantId();
|
|
return ret;
|
|
}
|
|
|
|
QSet<int> AssignmentParticipantModel::getAssociatedAreasIdsForParticipantId(int participantId) const
|
|
{
|
|
QSet<int> ret;
|
|
ret.reserve(m_vecData.size());
|
|
for (const TargetManagement::TargetAreaAssignment &data : m_vecData)
|
|
if (data.targetParticipantId() == participantId)
|
|
ret += data.areaId();
|
|
return ret;
|
|
}
|
|
|
|
int AssignmentParticipantModel::findRowForAreaTargetParticipantId(int areaId, int targetParticipantId)
|
|
{
|
|
for (int i = 0; i < m_vecData.size(); ++i) // clazy:exclude=range-loop
|
|
{
|
|
const TargetAreaAssignment &curAssignment = m_vecData.at(i);
|
|
if ((curAssignment.areaId() == areaId) && (curAssignment.targetParticipantId() == targetParticipantId))
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void AssignmentParticipantModel::addGapFillerForArea(int areaId)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, areaId=" << areaId;
|
|
|
|
const QSet<int> &associatedParticipantIds = getAssociatedParticipantIdsForArea(areaId);
|
|
|
|
QVector<TargetManagement::TargetAreaAssignment> gapFillers;
|
|
|
|
#define USE_PARTICIPANTS_OF_ORBAT
|
|
#ifdef USE_PARTICIPANTS_OF_ORBAT
|
|
// participantIds with EquipmentType (WmsTypeClass::TargetVehicle||WmsTypeClass::TargetHuman)
|
|
QList<int> pIds = getParticipantHierarchies().keys();
|
|
|
|
for (auto pId : qAsConst(pIds))
|
|
{
|
|
if (!associatedParticipantIds.contains(pId))
|
|
{
|
|
TargetManagement::TargetAreaAssignment gapFiller;
|
|
gapFiller.areaId(areaId);
|
|
gapFiller.targetParticipantId(pId);
|
|
gapFiller.isActive(false);
|
|
gapFillers.push_back(gapFiller);
|
|
}
|
|
} // for
|
|
|
|
#else // USE_PARTICIPANTS_OF_ORBAT
|
|
|
|
// use just the (base)configured targets:
|
|
auto cb = [associatedParticipantIds, areaId, &gapFillers](const TargetManagement::ShootbackTarget & targets)
|
|
{
|
|
if (targets.targetParticipantId() <= 0)
|
|
return;
|
|
|
|
if (!associatedParticipantIds.contains(targets.targetParticipantId()))
|
|
{
|
|
TargetManagement::TargetAreaAssignment gapFiller;
|
|
gapFiller.areaId(areaId);
|
|
gapFiller.targetParticipantId(targets.targetParticipantId());
|
|
gapFiller.isActive(false);
|
|
gapFillers.push_back(gapFiller);
|
|
}
|
|
};
|
|
m_tgt_dtc->shootbackTargets(cb);
|
|
#endif
|
|
|
|
this->insertRows(gapFillers);
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, areaId=" << areaId;
|
|
}
|
|
|
|
void AssignmentParticipantModel::addGapFillerForTargetParticipantId(int targetParticipantId)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, targetParticipantId=" << targetParticipantId;
|
|
|
|
const QSet<int> &associatedAreaIds = getAssociatedAreasIdsForParticipantId(targetParticipantId);
|
|
|
|
QVector<TargetManagement::TargetAreaAssignment> gapFillers;
|
|
// gapFillers.reserve(1000);
|
|
|
|
auto cb = [associatedAreaIds, targetParticipantId, &gapFillers](const TargetManagement::ShootbackArea & area)
|
|
{
|
|
if (!associatedAreaIds.contains(area.id()))
|
|
{
|
|
TargetManagement::TargetAreaAssignment gapFiller;
|
|
gapFiller.areaId(area.id());
|
|
gapFiller.targetParticipantId(targetParticipantId);
|
|
gapFiller.isActive(false);
|
|
gapFillers.push_back(gapFiller);
|
|
}
|
|
};
|
|
m_tgt_dtc->shootbackAreas(cb);
|
|
|
|
this->insertRows(gapFillers);
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, targetParticipantId=" << targetParticipantId;
|
|
}
|
|
|
|
void AssignmentParticipantModel::onTargetAreaAssignmentChanged(const TargetManagement::TargetAreaAssignment &data,
|
|
DataModification modType)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " modType=" << modType << " data=" << data;
|
|
|
|
// avoid adding an assignment which already exists:
|
|
if (modType == DataModification::eAdded)
|
|
{
|
|
int row = findRowForAreaTargetParticipantId(data.areaId(), data.targetParticipantId());
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " row=" << row;
|
|
if (row >= 0)
|
|
{
|
|
setRowData(row, data);
|
|
emit signalParticipantNamesChanged();
|
|
return;
|
|
}
|
|
}
|
|
|
|
BaseClass::onDataChanged(data, modType);
|
|
|
|
emit signalParticipantNamesChanged();
|
|
}
|
|
|
|
void AssignmentParticipantModel::updateColumnFilter()
|
|
{
|
|
m_usedIsActive.clear();
|
|
|
|
m_usedAreaIds.clear();
|
|
m_usedAreas.clear();
|
|
|
|
m_usedTargetIds.clear();
|
|
m_usedTargets.clear();
|
|
|
|
m_usedTargetParticipantIds.clear();
|
|
m_usedParticipantEqNo.clear();
|
|
m_usedParticipants.clear();
|
|
|
|
int row = -1;
|
|
for (const TargetAreaAssignment &assignment : qAsConst(m_vecData))
|
|
{
|
|
++row;
|
|
// This loops over ALL item, even if some of them are filtered by the AssignmentParticipantProxyModel (areaId, ..)
|
|
m_usedIsActive.insert(assignment.isActive());
|
|
|
|
m_usedAreaIds.insert(assignment.areaId());
|
|
m_usedAreas.insert( QString::fromStdString(m_tgt_dtc->shootbackArea(assignment.areaId()).name()) );
|
|
|
|
int targetId = m_participantHandler->getParticipantIdToTargetId(assignment.targetParticipantId());
|
|
m_usedTargetIds.insert(targetId);
|
|
m_usedTargets.insert(this->data(index(row, TargetName), Qt::DisplayRole).toString());
|
|
|
|
m_usedTargetParticipantIds.insert(assignment.targetParticipantId());
|
|
const int eqNo = m_participantHandler->getParticipantIdToEquipmentNumber(assignment.targetParticipantId());
|
|
m_usedParticipantEqNo.insert(eqNo);
|
|
m_usedParticipants.insert(m_participantHandler->getParticipantHierarchie(assignment.targetParticipantId()));
|
|
}
|
|
}
|
|
|
|
QString AssignmentParticipantModel::effectToString(const Effect &effect) const
|
|
{
|
|
switch (effect.underlying())
|
|
{
|
|
case TargetManagement::Effect_def::NearMiss:
|
|
return tr("NearMiss");
|
|
case TargetManagement::Effect_def::MobilityKill:
|
|
return tr("MobilityKill");
|
|
case TargetManagement::Effect_def::WeaponKill:
|
|
return tr("WeaponKill");
|
|
default:
|
|
{
|
|
// empty
|
|
}
|
|
}
|
|
return QStringLiteral("-");
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------
|
|
// AssignmentParticipantProxyModel
|
|
// --------------------------------------------------------
|
|
void AssignmentParticipantProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
|
|
{
|
|
m_sourceModel = qobject_cast<AssignmentParticipantModel *>(sourceModel);
|
|
BaseClass::setSourceModel(sourceModel);
|
|
}
|
|
|
|
void AssignmentParticipantProxyModel::filterToAreaId(int areaId)
|
|
{
|
|
m_areaId = areaId;
|
|
m_targetParticipantId = -1;
|
|
invalidateFilter();
|
|
}
|
|
|
|
void AssignmentParticipantProxyModel::filterToTargetParticpantId(int targetParticpantId)
|
|
{
|
|
m_targetParticipantId = targetParticpantId;
|
|
m_areaId = -1;
|
|
invalidateFilter();
|
|
}
|
|
|
|
bool AssignmentParticipantProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
|
{
|
|
if (!m_sourceModel)
|
|
return BaseClass::filterAcceptsRow(source_row, source_parent);
|
|
|
|
if (m_areaId > 0)
|
|
{
|
|
const TargetManagement::TargetAreaAssignment &item = m_sourceModel->m_vecData.at(source_row);
|
|
return (item.areaId() == m_areaId) && BaseClass::filterAcceptsRow(source_row, source_parent);
|
|
}
|
|
else if ((m_targetParticipantId > 0))
|
|
{
|
|
const TargetManagement::TargetAreaAssignment &item = m_sourceModel->m_vecData.at(source_row);
|
|
return (item.targetParticipantId() == m_targetParticipantId) && BaseClass::filterAcceptsRow(source_row, source_parent);;
|
|
}
|
|
return BaseClass::filterAcceptsRow(source_row, source_parent);
|
|
}
|
|
|
|
bool AssignmentParticipantProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
|
{
|
|
if (!m_sourceModel || !m_sourceModel->m_participantHandler ||
|
|
source_left.column() != source_right.column() ||
|
|
source_left.row() < 0 || source_left.row() >= m_sourceModel->m_vecData.size() ||
|
|
source_right.row() < 0 || source_right.row() >= m_sourceModel->m_vecData.size()
|
|
)
|
|
return BaseClass::lessThan(source_left, source_right);
|
|
|
|
|
|
const TargetManagement::TargetAreaAssignment &left = m_sourceModel->m_vecData.at(source_left.row());
|
|
const TargetManagement::TargetAreaAssignment &right = m_sourceModel->m_vecData.at(source_right.row());
|
|
switch (source_left.column())
|
|
{
|
|
case AssignmentParticipantModel::Columns::Id:
|
|
return left.id() < right.id();
|
|
case AssignmentParticipantModel::Columns::AssignmentName:
|
|
return left.name() < right.name();
|
|
case AssignmentParticipantModel::Columns::TargetPartipantId:
|
|
return left.targetParticipantId() < right.targetParticipantId();
|
|
case AssignmentParticipantModel::Columns::TargetPartipantEquipmentNumber:
|
|
{
|
|
const int eqNoLeft = m_sourceModel->m_participantHandler->getParticipantIdToEquipmentNumber(left.targetParticipantId());
|
|
const int eqNoRight = m_sourceModel->m_participantHandler->getParticipantIdToEquipmentNumber(right.targetParticipantId());
|
|
return eqNoLeft < eqNoRight;
|
|
}
|
|
case AssignmentParticipantModel::Columns::AreaId:
|
|
return left.areaId() < right.areaId();
|
|
|
|
case AssignmentParticipantModel::Columns::Participant:
|
|
case AssignmentParticipantModel::Columns::AreaName:
|
|
// QString compare
|
|
return LtsUtils::lessThan(source_left.data(), source_right.data());
|
|
}
|
|
return BaseClass::lessThan(source_left, source_right);
|
|
}
|
|
|
|
|
|
} // namespace TargetManagement
|