315 lines
13 KiB
C++
Executable File
315 lines
13 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* HMI Plugin for ParticipantManagement - Participant Edit Model
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Patric Karwat, SLSE, 2016-10-05
|
|
*/
|
|
#pragma once
|
|
|
|
#include "participant_icon_model_base.h"
|
|
|
|
#include <ParticipantManagement/logger.h>
|
|
#include <Plugins/ParticipantManagement/Gui/Common/ppmcommon_export.h>
|
|
#include <nglwidgets/ngltreeitem.h>
|
|
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
|
|
|
#include <QSet>
|
|
|
|
class QTreeView;
|
|
|
|
namespace ParticipantManagement
|
|
{
|
|
|
|
class CheckedTreeItem;
|
|
class FiringUnitValidator;
|
|
|
|
//=============================================================================================================================
|
|
// PARTICIPANTEDITMODEL
|
|
//=============================================================================================================================
|
|
class PPMCOMMON_EXPORT ParticipantEditModel : public ParticipantIconModelBase
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
enum Columns
|
|
{
|
|
ColDesignator,
|
|
ColIdentifier,
|
|
ColTypeClass,
|
|
ColType,
|
|
ColEquipmentNumber,
|
|
ColParticipantId,
|
|
ColInfo,
|
|
ColSign
|
|
};
|
|
|
|
class CheckedTreeItem final : public NGLTreeItem
|
|
{
|
|
public:
|
|
using NGLTreeItem::NGLTreeItem;
|
|
|
|
ParticipantData participant;
|
|
bool bIsChecked = false;
|
|
};
|
|
|
|
ParticipantEditModel(QObject *parent,
|
|
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
|
const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asbIfc);
|
|
|
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
|
QVariant data(const QModelIndex &index, int role) const override;
|
|
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
|
|
|
bool canDropMimeData(const QMimeData *data, Qt::DropAction action,
|
|
int row, int column, const QModelIndex &parent) const override;
|
|
bool dropMimeData(const QMimeData *data, Qt::DropAction action,
|
|
int row, int column, const QModelIndex &parent) override;
|
|
|
|
Qt::DropActions supportedDropActions() const override { return Qt::MoveAction; }
|
|
Qt::DropActions supportedDragActions() const override { return Qt::MoveAction; }
|
|
|
|
virtual bool onReinitModel(int partyId, const QSet<int> &checkedParticipants = QSet<int>(), Qt::CheckState cs = Qt::Checked);
|
|
|
|
bool insertRow(int row, const QModelIndex &parent, NGLTreeItem *item);
|
|
bool removeRow(int row, const QModelIndex &parent = QModelIndex());
|
|
bool isRowRemovable(const CheckedTreeItem *parentItem) const;
|
|
|
|
bool rowsCheckable() const { return m_bRowsAreCheckable; }
|
|
bool unitsSelectable() const { return m_bUnitsSelectable; }
|
|
int partyId() const { return m_partyId; }
|
|
|
|
void dataCommitted();
|
|
void processMissingSuperiorId();
|
|
void selectItemByParticipantId(int participantId,
|
|
const std::function<void(const QModelIndex &)> &selectItem,
|
|
const QModelIndex &parent = QModelIndex());
|
|
|
|
QModelIndexList getIndexesByParticipantIds(const std::vector<int32_t> &participantIds,
|
|
const QModelIndex &parent = QModelIndex()) const;
|
|
|
|
void setRowsCheckable(bool bCheckable);
|
|
void setUnitsSelectable(bool bSelectable) { m_bUnitsSelectable = bSelectable; }
|
|
bool setCheckStateForParticipants(const QSet<int> &checkedParticipants, Qt::CheckState cs);
|
|
|
|
ParticipantManagement::ParticipantData getParticipantData(const QModelIndex &idx) const;
|
|
std::vector<ParticipantData> participantData(bool bOnlyModified = true) const;
|
|
QSet<int> participantIds() const;
|
|
QSet<int> checkStateForParticipants(Qt::CheckState cs) const;
|
|
QVector<int> usedEquipmentNumbers() const;
|
|
|
|
CheckedTreeItem *privateData(const QModelIndex &index);
|
|
const CheckedTreeItem *privateData(const QModelIndex &index) const;
|
|
|
|
QModelIndex indexFromParticipantId(int participantId) const;
|
|
|
|
QString getHierarchyFromIndex(const QModelIndex &index) const;
|
|
|
|
protected:
|
|
void gatherParticipants(QHash<int, ParticipantData> &tmap,
|
|
QHash<int, QSet<int>> &parentId2id) const;
|
|
|
|
std::vector<ParticipantData> getChildrenOf(NGLTreeItem *item,
|
|
int parentId,
|
|
int hierarchyNumber,
|
|
bool bOnlyModifed,
|
|
int &highestModId) const;
|
|
bool updateChildrenOf(int parentId,
|
|
NGLTreeItem *parent,
|
|
const QHash<int, QSet<int>> &parentId2id,
|
|
const QHash<int, ParticipantData> &tmap);
|
|
void insertChildrenOf(int parentId,
|
|
NGLTreeItem *parent,
|
|
const QModelIndex &parentIdx,
|
|
const QHash<int, QSet<int>> &parentId2id,
|
|
const QHash<int, ParticipantData> &tmap,
|
|
const QSet<int> &checkedParticipants,
|
|
Qt::CheckState cs);
|
|
|
|
bool isParentOf(const NGLTreeItem *item, int participantId) const;
|
|
|
|
QSet<int> participantIds(NGLTreeItem *parentItem) const;
|
|
QSet<int> checkState(CheckedTreeItem *parentItem, Qt::CheckState cs) const;
|
|
QVector<int> usedEquipmentNumbers(NGLTreeItem *parentItem) const;
|
|
|
|
void setCheckState(CheckedTreeItem *parentItem, const QSet<int> &checkedParticipants, Qt::CheckState cs);
|
|
|
|
QModelIndex indexFromParticipantId(int participantId, const CheckedTreeItem *cti) const;
|
|
int participantIdFromItem(NGLTreeItem *item) const;
|
|
int equipmentNumberFromItem(NGLTreeItem *item) const;
|
|
CheckedTreeItem *searchParticipant(const NGLTreeItem *parentItem, int participantId) const;
|
|
|
|
NGLTreeItem *createItem(const QVariant &data, const QIcon &icon) const override;
|
|
QVariant getItemData(const NGLTreeItem *item) const override;
|
|
|
|
public slots:
|
|
int insertParticipant(const QModelIndex &parent, ParticipantData participantData, bool bNewParticipant);
|
|
int onInsertRow(const QModelIndex &parent, const ParticipantData &participantData);
|
|
bool onUpdateRow(const QModelIndex &index, const ParticipantData &participantData);
|
|
bool onDeleteRow(const QModelIndex &idx, bool isFirstItem = true);
|
|
void onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType);
|
|
|
|
signals:
|
|
void internalDataChanged();
|
|
|
|
protected:
|
|
int m_partyId;
|
|
bool m_bRowsAreCheckable;
|
|
bool m_bUnitsSelectable;
|
|
std::vector<ParticipantManagement::ParticipantData> m_dataToDelete;
|
|
QTimer *m_missingSuperiorIdTimer;
|
|
QSet<int> m_missingSuperiorId;
|
|
QSet<int> m_usedTypeIds;
|
|
QSet<TypeClass> m_usedTypeClassIds;
|
|
FiringUnitValidator *m_firingUnitValidator;
|
|
};
|
|
|
|
|
|
//=============================================================================================================================
|
|
// PARTICIPANTTREEFILTERPROXYMODEL
|
|
//=============================================================================================================================
|
|
class PPMCOMMON_EXPORT ParticipantTreeFilterProxyModel : public LtsWidgets::LtsColumnFilterProxyModel
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
|
|
|
|
void setAllowedTypes(const QSet<int> &allowedTypes);
|
|
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
|
|
|
int partyId() const { return m_sourceModel ? m_sourceModel->partyId() : -1; }
|
|
|
|
protected:
|
|
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
|
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
|
bool filterTypeRecursive(const ParticipantEditModel::CheckedTreeItem *item) const;
|
|
#endif
|
|
|
|
private:
|
|
QSet<int> m_allowedTypes;
|
|
ParticipantEditModel *m_sourceModel{nullptr};
|
|
|
|
}; // class ParticipantTreeFilterProxyModel
|
|
|
|
|
|
//=============================================================================================================================
|
|
// PARTICIPANTTABLEFILTERPROXYMODEL
|
|
//=============================================================================================================================
|
|
/**
|
|
* @brief The ParticipantTableFilterProxyModel class enables a hierarchical tree model of
|
|
* participants to be treated like a flat table model.
|
|
*
|
|
* Important connect statements that must be implemented are:
|
|
* - LtsDataView::filterChanged -> onFilter()
|
|
* - LtsDataView::sortOrderChanged -> onSort()
|
|
* - ParticipantEditModel::internalDataChanged -> init()
|
|
* In order to keep the selection after sorting, LtsDataView::sortOrderChanged can be connected to
|
|
* another function that handles that and calls onSort() instead. Otherwise, after sorting, the same
|
|
* row will be selected with most likely a different tree item than the one selected before sorting.
|
|
*
|
|
* When using this model in parallel to a standard tree model, in order to have two views that are
|
|
* consistent with each other, additional connects and workarounds are necessary. Connects include:
|
|
* - LtsDataView::filterChanged -> some function that asserts consistency
|
|
* - LtsDataView::selectionChanged -> some function that asserts consistency
|
|
* An important workaround is required when the party is changed (s.
|
|
* ParticipantEdit::onPartyChanged).
|
|
*/
|
|
class PPMCOMMON_EXPORT ParticipantTableFilterProxyModel : public LtsWidgets::LtsColumnFilterProxyModel
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
struct SortData
|
|
{
|
|
bool isActive{false};
|
|
int column{-1};
|
|
Qt::SortOrder order{Qt::DescendingOrder};
|
|
bool ascending() const
|
|
{
|
|
return order == Qt::AscendingOrder;
|
|
}
|
|
bool descending() const
|
|
{
|
|
return order == Qt::DescendingOrder;
|
|
}
|
|
QString toString()
|
|
{
|
|
QString str{QStringLiteral("active=")};
|
|
str += isActive ? QStringLiteral("true") : QStringLiteral("false");
|
|
str += QStringLiteral(", column=") + QString::number(column) + QStringLiteral(", order=");
|
|
str += order == Qt::DescendingOrder ? QStringLiteral("Descending") : QStringLiteral("Ascending");
|
|
return str;
|
|
}
|
|
}; // struct SortData
|
|
|
|
explicit ParticipantTableFilterProxyModel(QObject *parent = nullptr);
|
|
|
|
void init();
|
|
void resetMapping();
|
|
void disableSorting() { m_sortData.isActive = false; }
|
|
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
|
|
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
|
|
QVariant data(const QModelIndex &index, int role) const override;
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
|
|
|
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;
|
|
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
|
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
|
QModelIndex parent(const QModelIndex &child) const override;
|
|
QModelIndex sibling(int row, int column, const QModelIndex &idx) const override;
|
|
|
|
bool isFilterActive() const { return m_isFilterActive; }
|
|
bool hasChildren(const QModelIndex &parent) const override;
|
|
|
|
SortData sortData() const { return m_sortData; }
|
|
|
|
protected:
|
|
bool lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const override;
|
|
bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override;
|
|
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
|
bool filterAcceptsRowInternal(int sourceRow, const QModelIndex &sourceParent) const;
|
|
|
|
private:
|
|
/**
|
|
* @brief mapTreeToTable initializes m_mapFromSource and m_mapToSource. Do NOT USE this method
|
|
* directly! Call init() instead.
|
|
* @param parent index of the parent in the source model
|
|
* @param row parent's child at rowth position
|
|
* @return current row count
|
|
*/
|
|
int mapTreeToTable(const QModelIndex &parent = QModelIndex(), int row = 0);
|
|
|
|
public slots:
|
|
void onFilter();
|
|
void onSort(int column, Qt::SortOrder order);
|
|
|
|
private:
|
|
QHash<int, QModelIndex> m_mapToSource;
|
|
QHash<QModelIndex, int> m_mapFromSource;
|
|
QHash<int, QModelIndex> m_mapToSourceInternal;
|
|
QHash<QModelIndex, int> m_mapFromSourceInternal;
|
|
QHash<int, QModelIndex> m_mapToSourceFiltered;
|
|
QHash<QModelIndex, int> m_mapFromSourceFiltered;
|
|
QVector<int> m_sortMap;
|
|
|
|
bool m_isFilterActive{false};
|
|
SortData m_sortData;
|
|
|
|
ParticipantEditModel *m_sourceModel{nullptr};
|
|
|
|
NGL::INGLLogger &m_logger;
|
|
}; // class ParticipantTableFilterProxyModel
|
|
|
|
} //namespace ParticipantManagement
|
|
|
|
Q_DECLARE_METATYPE(ParticipantManagement::ParticipantData)
|