Files
qt5-legatus-legacy/Lts/Plugins/AreaEffectSimulation/Gui/Base/aes_base_model.h
T
2026-08-13 18:33:10 +02:00

376 lines
12 KiB
C++
Executable File

/**
* @RDE_HEADER@
* AreaEffectManangement - Overview Dialog Model Base
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2016-09-26
*/
#pragma once
#include "aes_base_exports.h"
#include <AreaEffectSimulation/aes.hpp>
#include <AreaEffectSimulation/aes_translation.h>
#include <AreaEffectSimulation/aes_dtc.h>
#include <AreaEffectSimulation/logger.h>
#include <ProjectDataManagement/pdm_translation.h>
#include <QSet>
#include <QVector>
#include <LtsWidgets/lts_abstract_table_model.h>
#include <LtsWidgets/lts_column_filter_proxy_model.h>
#include <ngltools/ngltools_dtg.h>
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
#include <ProjectDataManagement/pdm_enums.hpp>
const static int DEFAULT_EFFECT_DURATION = 777777;
namespace LtsSession
{
class LtsSession;
}
namespace ParticipantManagement
{
namespace Interface
{
class Dtc;
}
class ForeignGuiComboboxInterface;
}
namespace ProjectDataManagement
{
namespace Interface
{
class Dtc;
}
}
namespace AreaEffectSimulation
{
class AESBASEGUI_EXPORT AesGuiBasHelpers
{
public:
enum BaseColumns
{
BcId,
BcName,
BcChargeType,
BcEffectDuration,
BcEffectStart,
BcEffectState,
BcParty,
BcParticipant,
BcIsCentral,
BcEffectSource,
BcCount
};
protected:
AesGuiBasHelpers();
virtual ~AesGuiBasHelpers() = default;
virtual bool initModel(LtsSession::LtsSession *session);
QVariant stringFromPartyId(const dds::core::optional<int> &id) const;
QIcon iconFromPartyId(const dds::core::optional<int> &id) const;
QVariant hierarchyFromParticipantId(const dds::core::optional<int> &id) const;
QVariant chargeTypeName(int chargeTypeId, bool shortName = true) const;
static QString simulationTypeText(bool isCentral);
void updateEffectStateComboboxFilterData(bool bWithPause);
void updateComboboxFilterData(const QSet<int> &availablePartyIds,
const QSet<int> &availabelChargeIds);
void updateSimulationTypeComboboxFilterData();
void fillAvailableChargeIds(ProjectDataManagement::GearClass gc);
void fillAvailableChargeIds(const QVector<ProjectDataManagement::GearClass> &gcs);
protected:
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmGuiCbxIfc;
QVariant m_cbxFilterChargeType;
QVariant m_cbxFilterEffectState;
QVariant m_cbxFilterParty;
QVariant m_cbxFilterSimulationType;
QSet<int> m_availableChargeIds;
LOGGER_T m_logger;
private:
mutable QHash<int, QVariant> m_partyNames;
mutable QHash<int, QIcon> m_partyIcons;
mutable QHash<int, QVariant> m_participantHierarchy;
mutable QHash<int, QVariant> m_chargeTypeNames;
mutable QHash<int, QVariant> m_chargeTypeShortNames;
};
template<class T>
class AesGuiBaseModel : public LtsWidgets::LtsAbstractTableModel<T>, public AesGuiBasHelpers
{
protected:
explicit AesGuiBaseModel(QObject *parent = nullptr, const QVector<QString> &vecAdditionalColumns = QVector<QString>())
: LtsWidgets::LtsAbstractTableModel<T>({QObject::tr("Id"),
QObject::tr("Name"),
QObject::tr("Charge Type"),
QObject::tr("Effect Duration"),
QObject::tr("Effect Start"),
QObject::tr("Effect State"),
QObject::tr("Party"),
QObject::tr("Participant"),
QObject::tr("SimulationType"),
QObject::tr("EffectSource")},
parent)
{
LtsWidgets::LtsAbstractTableModel<T>::m_vecColumns.append(vecAdditionalColumns);
QObject::connect(this, &AesGuiBaseModel::rowsInserted,
this, &AesGuiBaseModel::onUpdateComboboxFilterData);
QObject::connect(this, &AesGuiBaseModel::rowsRemoved,
this, &AesGuiBaseModel::onUpdateComboboxFilterData);
QObject::connect(this, &AesGuiBaseModel::modelReset,
this, &AesGuiBaseModel::onUpdateComboboxFilterData);
updateEffectStateComboboxFilterData(false);
updateSimulationTypeComboboxFilterData();
onUpdateComboboxFilterData();
}
void onUpdateComboboxFilterData()
{
QSet<int> availabelChargeIds;
QSet<int> availablePartyIds;
for (const T &data : qAsConst(AesGuiBaseModel::m_vecData))
{
availabelChargeIds.insert(data.chargeStruct().chargeTypeId());
if (data.partyId().is_set())
availablePartyIds.insert(data.partyId().get());
}
updateComboboxFilterData(availablePartyIds, availabelChargeIds);
}
int cntBaseColumns() const
{
return BcCount;
}
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
{
if (orientation == Qt::Horizontal && role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
{
switch (section)
{
case BcParty:
return m_cbxFilterParty;
case BcChargeType:
return m_cbxFilterChargeType;
case BcEffectState:
return m_cbxFilterEffectState;
case BcIsCentral:
return m_cbxFilterSimulationType;
default:
return QVariant();
}
}
return LtsWidgets::LtsAbstractTableModel<T>::headerData(section, orientation, role);
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
{
if (!LtsWidgets::LtsAbstractTableModel<T>::indexIsValid(index))
return QVariant();
const T &item = LtsWidgets::LtsAbstractTableModel<T>::m_vecData.at(index.row());
return data(item, index.column(), role);
}
QVariant data(const T &item, int column, int role = Qt::DisplayRole) const
{
if (role == Qt::ToolTipRole)
{
switch (column)
{
case BcId:
case BcName:
case BcEffectStart:
case BcIsCentral:
return QVariant();
case BcChargeType:
return QObject::tr("Id: %1").arg(item.chargeStruct().chargeTypeId());
case BcEffectDuration:
{
if (item.effectDuration() == DEFAULT_EFFECT_DURATION)
return QStringLiteral("---");
else
return QObject::tr("%1 secs").arg(QString::number(item.effectDuration() / 1000.0, 'f', 3));
}
case BcEffectState:
return QObject::tr("Id: %1").arg(item.effectStateId().underlying());
case BcEffectSource:
return QObject::tr("Id: %1").arg(item.effectSourceId().underlying());
case BcParty:
return QObject::tr("Id: %1").arg(item.partyId().is_set() ? item.partyId().get() : -1);
case BcParticipant:
return QObject::tr("Id: %1").arg(item.participantId().is_set() ? item.participantId().get() : -1);
}
}
if (role == Qt::DisplayRole)
{
switch (column)
{
case BcId:
return item.id();
case BcName:
return QString::fromUtf8(item.name().c_str());
case BcChargeType:
return chargeTypeName(item.chargeStruct().chargeTypeId());
case BcEffectDuration:
if (item.effectDuration() == DEFAULT_EFFECT_DURATION)
return QStringLiteral("---");
else
return LtsWidgets::readableDuration(item.effectDuration());
case BcEffectStart:
return item.effectStart().is_set() ? DTG::toStringMSec(item.effectStart().get()) : QObject::tr("---");
case BcEffectState:
return AreaEffectSimulation::toString(item.effectStateId());
case BcEffectSource:
return ProjectDataManagement::toString(item.effectSourceId());
case BcParty:
return stringFromPartyId(item.partyId());
case BcParticipant:
return hierarchyFromParticipantId(item.participantId());
case BcIsCentral:
return simulationTypeText(item.isCentral());
}
return QVariant();
}
if (role == Qt::DecorationRole)
{
switch (column)
{
case BcParty:
return iconFromPartyId(item.partyId());
default:
break;
}
return QVariant();
}
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
{
switch (column)
{
case BcChargeType:
return item.chargeStruct().chargeTypeId();
case BcEffectState:
return item.effectStateId().underlying();
case BcParty:
return item.partyId().is_set() ? item.partyId().get() : -1;
case BcIsCentral:
return simulationTypeText(item.isCentral());
default:
break;
}
return QVariant();
}
return QVariant();
}
public:
T aesItem(int row) const { return LtsWidgets::LtsAbstractTableModel<T>::getRowData(row); }
protected:
bool isFiltered(const T &data, DataModification modType) const override
{
if (!m_availableChargeIds.isEmpty() && !m_availableChargeIds.contains(data.chargeStruct().chargeTypeId()))
return true;
return LtsWidgets::LtsAbstractTableModel<T>::isFiltered(data, modType);
}
};
class AESBASEGUI_EXPORT AesItemSortFilterProxyModel : public LtsWidgets::LtsColumnFilterProxyModel
{
Q_OBJECT
public:
explicit AesItemSortFilterProxyModel(LtsSession::LtsSession *session, QObject *parent = nullptr);
~AesItemSortFilterProxyModel() = default;
bool showExpired() const { return m_showExpired; }
int offset() const { return m_offset; }
virtual int aesId(int row) const = 0;
virtual bool isExpired(int row) const = 0;
virtual bool isExternal(int row) const = 0;
virtual AesEffectState aesEffectStateId(int row) const = 0;
virtual ProjectDataManagement::EffectSource aesEffectSourceId(int row) const = 0;
virtual dds::core::optional<rti::core::int64> aesEffectStart(int row) const = 0;
virtual int32_t aesEffectDuration(int row) const = 0;
virtual int32_t partyId(int row) const = 0;
QColor partyColor(int row) const { return m_partyColors.value(partyId(row), Qt::black); }
public slots:
void setOffset(int offsetMsecs);
void setShowExpired(bool showExpired);
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override final;
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override final;
private:
bool checkFilter(int source_row) const;
private:
LtsSession::LtsSession *m_session;
bool m_showExpired;
int m_offset;
QMap<int, QColor> m_partyColors;
};
template<typename T>
class AesItemSortFilterProxyModelTmpl : public AesItemSortFilterProxyModel
{
public:
using AesItemSortFilterProxyModel::AesItemSortFilterProxyModel;
void setSourceModel(QAbstractItemModel *sm) override
{
m_sourceModel = dynamic_cast<AesGuiBaseModel<T>*>(sm);
Q_ASSERT(m_sourceModel);
AesItemSortFilterProxyModel::setSourceModel(sm);
}
T aesItem(int row) const { return m_sourceModel->aesItem(row); }
int aesId(int row) const override { return aesItem(row).id(); }
bool isExpired(int row) const override
{
const auto es = aesItem(row).effectStateId();
// alles andere wird als expired angesehen -> also nicht löschbar
return es != AreaEffectSimulation::AesEffectState_def::EsCreated &&
es != AreaEffectSimulation::AesEffectState_def::EsPrepared &&
es != AreaEffectSimulation::AesEffectState_def::EsActivated &&
es != AreaEffectSimulation::AesEffectState_def::EsPaused &&
es != AreaEffectSimulation::AesEffectState_def::EsReceived;
}
bool isExternal(int row) const override
{
return aesItem(row).externalId() > 0;
}
protected:
AesEffectState aesEffectStateId(int row) const override { return aesItem(row).effectStateId(); }
ProjectDataManagement::EffectSource aesEffectSourceId(int row) const override { return aesItem(row).effectSourceId(); }
dds::core::optional<rti::core::int64> aesEffectStart(int row) const override { return aesItem(row).effectStart(); }
int32_t aesEffectDuration(int row) const override { return aesItem(row).effectDuration(); }
virtual int32_t partyId(int row) const override { return aesItem(row).partyId().is_set()?aesItem(row).partyId().get():-1; }
AesGuiBaseModel<T> *m_sourceModel = nullptr;
};
} //namespace AreaEffectSimulation