#include "LogViewModels.hpp" #include #include #include namespace N_LogView { int ParticipantModel::rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : m_particpants.size(); } int ParticipantModel::columnCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : 3; } QVariant ParticipantModel::data(const QModelIndex &index, int role) const { if (index.isValid() && index.row() < m_particpants.size()) { const auto &p = m_particpants.at(index.row()); if (role == Qt::DisplayRole) { switch (index.column()) { case 0: return p.first; case 1: return p.second; case 2: return m_particpantMap.value(p.first); default: break; } } if (role == Qt::ToolTipRole) { switch (index.column()) { case 0: return tr("hex: 0x%1").arg(p.first, 4, 16, QLatin1Char('0')); case 1: return tr("hex: 0x%1").arg(p.second, 4, 16, QLatin1Char('0')); default: break; } } if (role == Qt::BackgroundColorRole) { if (p.first == 0) return QVariant(); if (m_participantHeatmap.isEmpty()) updateHeatMap(); return m_participantHeatmap.value(p.first); } } return QVariant(); } QVariant ParticipantModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case 0: return tr("Equip. No."); case 1: return tr("ISSI"); case 2: return tr("#"); default: break; } } return QAbstractTableModel::headerData(section, orientation, role); } void ParticipantModel::clearParticipants() { beginResetModel(); m_particpantMap.clear(); m_particpants.clear(); m_participantHeatmap.clear(); endResetModel(); } bool ParticipantModel::addUpdateParticipants(const QVector &eqIds, const QVector &issis, const QVector &numberOfTelegrams) { QVector > newParticpants; for (int i = 0; i < eqIds.size(); ++i) { const int eqId = eqIds.at(i); const int issi = issis.at(i); const int cntTelegrams = numberOfTelegrams.at(i); auto it = m_particpantMap.find(eqId); if (it != m_particpantMap.end()) { it.value() = cntTelegrams; continue; } newParticpants.push_back(qMakePair(eqId, issi)); m_particpantMap[eqId] = cntTelegrams; } if (!newParticpants.isEmpty()) { beginInsertRows(QModelIndex(), m_particpants.size(), m_particpants.size() + newParticpants.size() - 1); m_particpants.append(newParticpants); endInsertRows(); } m_participantHeatmap.clear(); return true; } void ParticipantModel::updateHeatMap() const { int maxNumberOfTelegrams = 0; for (auto it = m_particpantMap.begin(); it != m_particpantMap.end(); ++it) { if (it.key() == 0) continue; maxNumberOfTelegrams = std::max(it.value(), maxNumberOfTelegrams); } const QColor backgroundColor = QGuiApplication::palette().base().color(); const QColor redColor = Qt::red; for (auto it = m_particpantMap.begin(); it != m_particpantMap.end(); ++it) { const int eqId = it.key(); if (eqId == 0) continue; const int nbrTelegrams = it.value(); QColor curColor; double percent = static_cast(nbrTelegrams) / maxNumberOfTelegrams; curColor.setRed(backgroundColor.red() - ((backgroundColor.red() - redColor.red()) * percent)); curColor.setGreen(backgroundColor.green() - ((backgroundColor.green() - redColor.green()) * percent)); curColor.setBlue(backgroundColor.blue() - ((backgroundColor.blue() - redColor.blue()) * percent)); m_participantHeatmap[eqId] = curColor; } } int TelegramModel::rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : m_telegrams.size(); } int TelegramModel::columnCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : 6; } QVariant TelegramModel::data(const QModelIndex &index, int role) const { if (index.isValid() && index.row() < m_telegrams.size()) { if (role == Qt::DisplayRole) { const QSharedPointer &telegram = m_telegrams.at(index.row()); switch (index.column()) { case 0: return telegram->getDestinationText(); case 1: return telegram->getName(); case 2: return telegram->getParticipantId(); case 3: return telegram->getLogTimeText(); case 4: return telegram->getGpsTimeText(); case 5: return telegram->getDelay(); } } if (role == Qt::DecorationRole) { const QSharedPointer telegram = m_telegrams.at(index.row()); switch (index.column()) { case 0: return telegram->getIcon(); default: break; } } if (role == Qt::ToolTipRole) { const QSharedPointer telegram = m_telegrams.at(index.row()); switch (index.column()) { case 1: return telegram->getToolTipText(LogViewTelegram::e_ColName); case 3: return telegram->getToolTipText(LogViewTelegram::e_ColLogTime); case 4: return telegram->getToolTipText(LogViewTelegram::e_ColGpsTime); default: break; } } } return QVariant(); } QVariant TelegramModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole) { switch (section) { case 0: return tr("Dest."); case 1: return tr("Description"); case 2: return tr("Equip. No."); case 3: return tr("Send/Recieve time"); case 4: return tr("GPS time"); case 5: return tr("Delay"); default: break; } } } return QAbstractTableModel::headerData(section, orientation, role); } void TelegramModel::clearTelegrams() { beginResetModel(); m_telegrams.clear(); endResetModel(); } void TelegramModel::appendTelegrams(const QVector > &telegrams) { if (telegrams.isEmpty()) return; beginInsertRows(QModelIndex(), m_telegrams.size(), m_telegrams.size() + telegrams.size() - 1); m_telegrams += telegrams; endInsertRows(); } void TelegramModel::appendTelegram(const QSharedPointer &telegram) { beginInsertRows(QModelIndex(), m_telegrams.size(), m_telegrams.size()); m_telegrams.push_back(telegram); endInsertRows(); } QSharedPointer TelegramModel::telegram(int row) const { if (row >= 0 && row < m_telegrams.size()) return m_telegrams.at(row); return QSharedPointer(); } void TelegramProxyModel::setFilterByEquipmentIds(bool bFilterByEquipmentIds) { if (m_bFilterByEquipmentIds == bFilterByEquipmentIds) return; m_bFilterByEquipmentIds = bFilterByEquipmentIds; invalidateFilter(); } void TelegramProxyModel::setAllowedEquipmentIds(const std::set &allowedEquipmentIds) { if (m_allowedEquipmentIds == allowedEquipmentIds) return; m_allowedEquipmentIds = allowedEquipmentIds; invalidateFilter(); } void TelegramProxyModel::setFilteredCentralTelegramIds(const std::set &filteredCentralTelegramIds) { if (m_filteredCentralTelegramIds == filteredCentralTelegramIds) return; m_filteredCentralTelegramIds = filteredCentralTelegramIds; invalidateFilter(); } void TelegramProxyModel::setFilteredTetraTelegramIds(const std::set &filteredTetraTelegramIds) { if (m_filteredTetraTelegramIds == filteredTetraTelegramIds) return; m_filteredTetraTelegramIds = filteredTetraTelegramIds; invalidateFilter(); } void TelegramProxyModel::setFilteredWlsTelegramIds(const std::set &filteredWlsTelegramIds) { if (m_filteredWlsTelegramIds == filteredWlsTelegramIds) return; m_filteredWlsTelegramIds = filteredWlsTelegramIds; invalidateFilter(); } void TelegramProxyModel::setFilterCentralTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction, bool bFilter) { std::set curFilter = m_filterCentralTelegrams; if (bFilter) curFilter.insert(direction); else curFilter.erase(direction); if (curFilter == m_filterCentralTelegrams) return; m_filterCentralTelegrams = curFilter; invalidateFilter(); } void TelegramProxyModel::setFilterTetraTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction, bool bFilter) { std::set curFilter = m_filterTetraTelegrams; if (bFilter) curFilter.insert(direction); else curFilter.erase(direction); if (curFilter == m_filterTetraTelegrams) return; m_filterTetraTelegrams = curFilter; invalidateFilter(); } void TelegramProxyModel::setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::E_PDU_Type pduType, bool bFilter) { std::set curFilter = m_filterTetraPDU; if (bFilter) curFilter.insert(pduType); else curFilter.erase(pduType); if (curFilter == m_filterTetraPDU) return; m_filterTetraPDU = curFilter; invalidateFilter(); } void TelegramProxyModel::setFilterWlsTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction, bool bFilter) { std::set curFilter = m_filterWlsTelegrams; if (bFilter) curFilter.insert(direction); else curFilter.erase(direction); if (curFilter == m_filterWlsTelegrams) return; m_filterWlsTelegrams = curFilter; invalidateFilter(); } void TelegramProxyModel::setFilterTetraLogin(bool bFilter) { if (m_bFilterLoginTelegrams == bFilter) return; m_bFilterLoginTelegrams = bFilter; invalidateFilter(); } void TelegramProxyModel::setFilterTetraFragmented(bool bFilter) { if (m_bFilterFragmentedTelegrams == bFilter) return; m_bFilterFragmentedTelegrams = bFilter; invalidateFilter(); } QSharedPointer TelegramProxyModel::telegram(int row) const { const TelegramModel *tm = qobject_cast(sourceModel()); if (!tm) return {}; const int srcRow = mapToSource(index(row, 0)).row(); return tm->telegram(srcRow); } bool TelegramProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { if (left.column() != right.column()) return QSortFilterProxyModel::lessThan(left, right); const TelegramModel *tm = qobject_cast(sourceModel()); if (!tm) return QSortFilterProxyModel::lessThan(left, right); QSharedPointer teleLeft = tm->telegram(left.row()); QSharedPointer teleRight = tm->telegram(right.row()); if (!teleLeft || !teleRight) return QSortFilterProxyModel::lessThan(left, right); switch (left.column()) { case 0: return teleLeft->getDestination() < teleRight->getDestination(); case 1: return teleLeft->getName() < teleRight->getName(); case 2: return teleLeft->getParticipantId() < teleRight->getParticipantId(); case 3: return teleLeft->getLogTime() < teleRight->getLogTime(); case 4: return teleLeft->getGpsTime() < teleRight->getGpsTime(); case 5: return teleLeft->getDelay() < teleRight->getDelay(); } return QSortFilterProxyModel::lessThan(left, right); } bool TelegramProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { const TelegramModel *tm = qobject_cast(sourceModel()); if (!tm) return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); QSharedPointer tele = tm->telegram(source_row); if (!tele) return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); if (m_bFilterByEquipmentIds) { int equipId = tele->getParticipantId(); if (m_allowedEquipmentIds.find(equipId) == m_allowedEquipmentIds.end()) return false; } switch (tele->getProtocol()) { case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral: if (!m_filteredCentralTelegramIds.empty()) { const int telegramId = tele->getTelId(); if (m_filteredCentralTelegramIds.find(telegramId) != m_filteredCentralTelegramIds.end()) return false; } if (!m_filterCentralTelegrams.empty()) { N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction = tele->getDirection(); if (m_filterCentralTelegrams.find(direction) != m_filterCentralTelegrams.end()) return false; } break; case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolTetra: { if (!m_filteredTetraTelegramIds.empty()) { const int telegramId = tele->getTelId(); if (m_filteredTetraTelegramIds.find(telegramId) != m_filteredTetraTelegramIds.end()) return false; } if (!m_filterTetraTelegrams.empty()) { N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction = tele->getDirection(); if (m_filterTetraTelegrams.find(direction) != m_filterTetraTelegrams.end()) return false; } const N_CoPrtCnv::CoPrtCnvRadioTelegram *tetraTelegram = tele->getTetraTelegram(); if (tetraTelegram) { if (!m_filterTetraPDU.empty()) { N_CoPrtCnv::CoPrtCnvRadioTelegram::E_PDU_Type pduType = tetraTelegram->getPDU_Type(); if (m_filterTetraPDU.find(pduType) != m_filterTetraPDU.end()) return false; } if (m_bFilterLoginTelegrams) { if (tetraTelegram->isLoginTelegram()) return false; } if (m_bFilterFragmentedTelegrams) { if (!tetraTelegram->isLoginTelegram() && !tetraTelegram->isNormalTelegram()) return false; } } break; } case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolWls: if (!m_filteredWlsTelegramIds.empty()) { const int telegramId = tele->getTelId(); if (m_filteredWlsTelegramIds.find(telegramId) != m_filteredWlsTelegramIds.end()) return false; } if (!m_filterWlsTelegrams.empty()) { N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction = tele->getDirection(); if (m_filterWlsTelegrams.find(direction) != m_filterWlsTelegrams.end()) return false; } break; default: break; } return true; } }