Files
qt5-legatus-legacy/Lts/Plugins/TargetManagement/Gui/ShootbackTargetConfiguration/tgt_target_part_model.cpp
T
2026-08-13 18:33:10 +02:00

389 lines
14 KiB
C++
Executable File

/**
* @RDE_HEADER@
* TargetParticipantModel
* $Id$
* $HeadURL$
* $Author$
* Created by Norbert Thoden, NLE, 2020-06-29
*/
#include "tgt_target_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
{
QString toString(const std::vector< int32_t > &ids)
{
QString ret;
for (auto id : ids)
ret.append(QString::number(id));
return ret;
}
//---------------------------------
// TargetParticipantModel
//---------------------------------
TargetParticipantModel::TargetParticipantModel(QObject *parent)
: BaseClass(
{
tr("Id"),
tr("Target Name"),
// associated participant:
tr("Participant Id"),
tr("Equipmentnumber"),
tr("Type"), // Equipmenttype
tr("Participant"),
// main/base config
tr("Position"),
tr("ActivateLaserDesignation"),
tr("ActivateLights"),
tr("ActivatePopupAutomatic"),
tr("HitsToKill"),
tr("PermanentInstalledTarget"),
tr("VisibleParticipants")
},
parent)
, m_logger(getLogger("TargetParticipantModel"))
{}
bool TargetParticipantModel::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);
connect(m_participantHandler, &ParticipantHandler::signalParticipantNamesChanged,
this, &TargetParticipantModel::signalParticipantNamesChanged);
connect(m_participantHandler, &ParticipantHandler::signalParticipantChanged,
this, &TargetParticipantModel::update);
// insert Model
const QMap<qint32, TargetManagement::ShootbackTarget> targetParticipants = m_tgt_dtc->shootbackTargets();
INFO_LOG(m_logger) << "initModel - #TargetParticipantModel: " << targetParticipants.size();
connect(m_tgt_dtc.get(), &Interface::Dtc::shootbackTargetChanged,
this, &TargetParticipantModel::onShootbackTargetChanged);
{
auto cb = [this](const TargetManagement::ShootbackTarget & d) { onShootbackTargetChanged(d, DataModification::eAdded); };
m_tgt_dtc->shootbackTargets(cb);
}
// updateColumnFilter
connect(this, &TargetParticipantModel::rowsInserted, this, &TargetParticipantModel::updateColumnFilter);
connect(this, &TargetParticipantModel::rowsRemoved, this, &TargetParticipantModel::updateColumnFilter);
connect(this, &TargetParticipantModel::modelReset, this, &TargetParticipantModel::updateColumnFilter);
// in case of changing value like hitsToKill:
connect(this, &TargetParticipantModel::dataChanged, this, &TargetParticipantModel::updateColumnFilter);
updateColumnFilter();
return true;
}
QVariant TargetParticipantModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole &&
orientation == Qt::Horizontal)
{
// 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 == ActivateLaserDesignation)
return processBoolean(m_usedActiveLaserDesignations);
else if (section == ActivateLights)
return processBoolean(m_usedActivateLights);
else if (section == ActivatePopupAutomatic)
return processBoolean(m_usedActivatePopupAutomatic);
else if (section == HitsToKill)
return processInt(m_usedHitsToKill);
else if (section == PermanentInstalledTarget)
return processBoolean(m_usedPermanetTargetInstalled);
}
return BaseClass::headerData(section, orientation, role);
}
QVariant TargetParticipantModel::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::DecorationRole &&
role != Qt::BackgroundRole &&
role != Qt::ToolTipRole &&
role != LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
return QVariant();
const TargetManagement::ShootbackTarget &shootbackTarget = m_vecData.at(index.row());
if (role == Qt::DecorationRole)
{
if (index.column() == Participant)
{
static const int pmSize = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
const QPixmap &pm = m_participantHandler->getParticipantDecoration(shootbackTarget.targetParticipantId());
if (!pm.isNull())
return pm.scaled(pmSize, pmSize);
}
else if ((index.column() == ActivateLaserDesignation))
return shootbackTarget.activateLaserDesignation() ? m_yes : m_no;
else if ((index.column() == ActivateLights))
return shootbackTarget.activateLights() ? m_yes : m_no;
else if ((index.column() == ActivatePopupAutomatic))
return shootbackTarget.activatePopupAutomatic() ? m_yes : m_no;
else if ((index.column() == PermanentInstalledTarget))
return shootbackTarget.permanentInstalledTarget() ? m_yes : m_no;
return QVariant();
}
else if (role == Qt::BackgroundRole)
{
if ((index.column() == TargetPartipantId) && (shootbackTarget.targetParticipantId() <= 0))
return getWarningBackgroundRole(); // orange
if (index.column() == TargetPartipantEquipmentNumber)
{
const int eqNo = m_participantHandler->getParticipantIdToEquipmentNumber(shootbackTarget.targetParticipantId());
if (eqNo <= 0)
return getWarningBackgroundRole(); // orange
}
}
else if (role == Qt::ToolTipRole)
{
if (index.column() == Participant)
{
QString tooltip(QStringLiteral("<html>"));
const QPixmap &img = m_participantHandler->getParticipantDecoration(shootbackTarget.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(ShootbackTargetName, Qt::Horizontal, Qt::DisplayRole).toString();
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, QString::fromStdString(shootbackTarget.name())));
hdr = this->headerData(Participant, Qt::Horizontal, Qt::DisplayRole).toString();
const QString &val = m_participantHandler->getParticipantHierarchie(shootbackTarget.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() == ActivateLaserDesignation)
return static_cast<int>(shootbackTarget.activateLaserDesignation());
if (index.column() == ActivateLights)
return static_cast<int>(shootbackTarget.activateLights());
if (index.column() == ActivatePopupAutomatic)
return static_cast<int>(shootbackTarget.activatePopupAutomatic());
if (index.column() == HitsToKill)
return shootbackTarget.hitsToKill();
}
switch (index.column())
{
case Id:
return shootbackTarget.id();
// associated participant:
case ShootbackTargetName:
return QString::fromStdString(shootbackTarget.name());
case TargetPartipantId:
return shootbackTarget.targetParticipantId();
case TargetPartipantEquipmentNumber:
{
const int eqNo = m_participantHandler->getParticipantIdToEquipmentNumber(shootbackTarget.targetParticipantId());
if (eqNo <= 0)
return QStringLiteral("-");
return eqNo;
}
case TargetPartipantEquipmentType:
{
const auto type = m_participantHandler->getParticipantIdToWmsTypeClass(shootbackTarget.targetParticipantId());
return ParticipantHandler::target_wmsTypeClassToString(type);
}
case Participant:
return m_participantHandler->getParticipantHierarchie(shootbackTarget.targetParticipantId());
// main/base config
case Position:
{
const Core::GeoPosition2D &pos = shootbackTarget.position();
return LtsCoordTrans::mgrsFromGeographic(pos.lon(), pos.lat());
}
case ActivateLaserDesignation:
return shootbackTarget.activateLaserDesignation() ? tr("Yes") : tr("No");
case ActivateLights:
return shootbackTarget.activateLights() ? tr("Yes") : tr("No");
case ActivatePopupAutomatic:
return shootbackTarget.activatePopupAutomatic() ? tr("Yes") : tr("No");
case HitsToKill:
return shootbackTarget.hitsToKill();
case PermanentInstalledTarget:
return shootbackTarget.permanentInstalledTarget() ? tr("Yes") : tr("No");
case VisibleParticipants:
return TargetManagement::toString(shootbackTarget.visibleParticipants());
} // switch
return QVariant();
}
QSet<int> TargetParticipantModel::getAssociatedParticipantIds() const
{
QSet<int> ret;
ret.reserve(m_vecData.size());
for (const TargetManagement::ShootbackTarget &data : m_vecData)
ret += data.targetParticipantId();
return ret;
}
void TargetParticipantModel::onShootbackTargetChanged(const TargetManagement::ShootbackTarget &data,
const DataModification modType)
{
BaseClass::onDataChanged(data, modType);
emit signalParticipantNamesChanged();
}
void TargetParticipantModel::updateColumnFilter()
{
m_usedActiveLaserDesignations.clear();
m_usedActivateLights.clear();
m_usedActivatePopupAutomatic.clear();
m_usedHitsToKill.clear();
m_usedPermanetTargetInstalled.clear();
for (const ShootbackTarget &item : qAsConst(m_vecData))
{
m_usedActiveLaserDesignations.insert(item.activateLaserDesignation());
m_usedActivateLights.insert(item.activateLights());
m_usedActivatePopupAutomatic.insert(item.activatePopupAutomatic());
m_usedHitsToKill.insert(item.hitsToKill());
m_usedPermanetTargetInstalled.insert(item.permanentInstalledTarget());
}
}
// --------------------------------------------------------
// TargetParticipantProxyModel
// --------------------------------------------------------
void TargetParticipantProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
m_sourceModel = qobject_cast<TargetParticipantModel *>(sourceModel);
BaseClass::setSourceModel(sourceModel);
}
bool TargetParticipantProxyModel::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::ShootbackTarget &left = m_sourceModel->m_vecData.at(source_left.row());
const TargetManagement::ShootbackTarget &right = m_sourceModel->m_vecData.at(source_right.row());
switch (source_left.column())
{
case TargetParticipantModel::Columns::Id:
return left.id() < right.id();
case TargetParticipantModel::Columns::ShootbackTargetName:
return left.name() < right.name();
case TargetParticipantModel::Columns::TargetPartipantId:
return left.targetParticipantId() < right.targetParticipantId();
case TargetParticipantModel::Columns::TargetPartipantEquipmentNumber:
{
const int eqNoLeft = m_sourceModel->m_participantHandler->getParticipantIdToEquipmentNumber(left.targetParticipantId());
const int eqNoRight = m_sourceModel->m_participantHandler->getParticipantIdToEquipmentNumber(left.targetParticipantId());
return eqNoLeft < eqNoRight;
}
// case TargetParticipantModel::Columns::Position:
case TargetParticipantModel::Columns::ActivateLaserDesignation:
return left.activateLaserDesignation() < right.activateLaserDesignation();
case TargetParticipantModel::Columns::ActivateLights:
return left.activateLights() < right.activateLights();
case TargetParticipantModel::Columns::ActivatePopupAutomatic:
return left.activatePopupAutomatic() < right.activatePopupAutomatic();
case TargetParticipantModel::Columns::HitsToKill:
return left.hitsToKill() < right.hitsToKill();
case TargetParticipantModel::Columns::PermanentInstalledTarget:
return left.permanentInstalledTarget() < right.permanentInstalledTarget();
case TargetParticipantModel::Columns::VisibleParticipants:
return toString(left.visibleParticipants()) < toString(right.visibleParticipants());
case TargetParticipantModel::Columns::Participant:
// QString compare
return LtsUtils::lessThan(source_left.data(), source_right.data());
}
return BaseClass::lessThan(source_left, source_right);
}
} // namespace TargetManagement