/** * @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 #include #include #include #include #include #include #include #include #include #include #include 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 &id) const; QIcon iconFromPartyId(const dds::core::optional &id) const; QVariant hierarchyFromParticipantId(const dds::core::optional &id) const; QVariant chargeTypeName(int chargeTypeId, bool shortName = true) const; static QString simulationTypeText(bool isCentral); void updateEffectStateComboboxFilterData(bool bWithPause); void updateComboboxFilterData(const QSet &availablePartyIds, const QSet &availabelChargeIds); void updateSimulationTypeComboboxFilterData(); void fillAvailableChargeIds(ProjectDataManagement::GearClass gc); void fillAvailableChargeIds(const QVector &gcs); protected: std::shared_ptr m_aesDtc; std::shared_ptr m_pdmDtc; std::shared_ptr m_ppmDtc; std::shared_ptr m_ppmGuiCbxIfc; QVariant m_cbxFilterChargeType; QVariant m_cbxFilterEffectState; QVariant m_cbxFilterParty; QVariant m_cbxFilterSimulationType; QSet m_availableChargeIds; LOGGER_T m_logger; private: mutable QHash m_partyNames; mutable QHash m_partyIcons; mutable QHash m_participantHierarchy; mutable QHash m_chargeTypeNames; mutable QHash m_chargeTypeShortNames; }; template class AesGuiBaseModel : public LtsWidgets::LtsAbstractTableModel, public AesGuiBasHelpers { protected: explicit AesGuiBaseModel(QObject *parent = nullptr, const QVector &vecAdditionalColumns = QVector()) : LtsWidgets::LtsAbstractTableModel({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::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 availabelChargeIds; QSet 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::headerData(section, orientation, role); } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { if (!LtsWidgets::LtsAbstractTableModel::indexIsValid(index)) return QVariant(); const T &item = LtsWidgets::LtsAbstractTableModel::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::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::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 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 m_partyColors; }; template class AesItemSortFilterProxyModelTmpl : public AesItemSortFilterProxyModel { public: using AesItemSortFilterProxyModel::AesItemSortFilterProxyModel; void setSourceModel(QAbstractItemModel *sm) override { m_sourceModel = dynamic_cast*>(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 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 *m_sourceModel = nullptr; }; } //namespace AreaEffectSimulation