389 lines
14 KiB
C++
Executable File
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
|