/** * @RDE_HEADER@ * AreaModel * $Id$ * $HeadURL$ * $Author$ * Created by Norbert Thoden, NLE, 2020-06-29 */ #include "tgt_area_model.h" #include "tgt_common.h" #include #include #include #include // pixelMetric #include namespace TargetManagement { //--------------------------------- // AreaModel //--------------------------------- AreaModel::AreaModel(QObject *parent) : BaseClass( { tr("Id"), tr("Name"), // main config tr("Center"), tr("Width"), tr("Height"), }, parent) , m_logger(getLogger("AreaModel")) {} bool AreaModel::initModel(const std::shared_ptr &tgtDtc) { m_tgt_dtc = tgtDtc; // insert Model const QMap areas = m_tgt_dtc->shootbackAreas(); INFO_LOG(m_logger) << "initModel - #AreaModel: " << areas.size(); connect(m_tgt_dtc.get(), &Interface::Dtc::shootbackAreaChanged, this, &AreaModel::onShootbackAreaChanged); auto cb = [this](const TargetManagement::ShootbackArea & d) { onShootbackAreaChanged(d, DataModification::eAdded); }; m_tgt_dtc->shootbackAreas(cb); // updateColumnFilter connect(this, &AreaModel::rowsInserted, this, &AreaModel::updateColumnFilter); connect(this, &AreaModel::rowsRemoved, this, &AreaModel::updateColumnFilter); connect(this, &AreaModel::modelReset, this, &AreaModel::updateColumnFilter); // in case of changing value like hitsToKill: connect(this, &AreaModel::dataChanged, this, &AreaModel::updateColumnFilter); updateColumnFilter(); return true; } QVariant AreaModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole && orientation == Qt::Horizontal) { // a few QSet ==> const auto processString = [](const QSet &usedXYCont) -> QVariant { LtsWidgets::ComboboxFilterContent cfc; cfc.data.reserve(usedXYCont.size()); LtsWidgets::ComboboxFilterData cfd; for (const QString &value : usedXYCont) { cfd.data = value; cfd.text = value; cfc.data.push_back(cfd); } cfc.sortItems = true; return cfc.toVariant(); }; if (section == Name) return processString(m_usedNames); } return BaseClass::headerData(section, orientation, role); } QVariant AreaModel::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::ShootbackArea &shootbackArea = m_vecData.at(index.row()); if (role == Qt::BackgroundRole) { if ((index.column() == Center) && ((shootbackArea.position().lat() <= 0) || (shootbackArea.position().lon() <= 0))) return getWarningBackgroundRole(); // orange if (index.column() == Width && shootbackArea.width() <= 0) return getWarningBackgroundRole(); // orange if (index.column() == Height && shootbackArea.height() <= 0) return getWarningBackgroundRole(); // orange } else if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole) { if (index.column() == Name) return QString::fromStdString(shootbackArea.name()); } switch (index.column()) { case Id: return shootbackArea.id(); case Name: return QString::fromStdString(shootbackArea.name()); case Center: { const Core::GeoPosition2D &pos = shootbackArea.position(); return LtsCoordTrans::mgrsFromGeographic(pos.lon(), pos.lat()); } case Width: return shootbackArea.width(); case Height: return shootbackArea.height(); } // switch return QVariant(); } void AreaModel::onShootbackAreaChanged(const TargetManagement::ShootbackArea &data, const DataModification modType) { BaseClass::onDataChanged(data, modType); emit signalAreaNamesChanged(); } void AreaModel::updateColumnFilter() { m_usedNames.clear(); for (const ShootbackArea &item : qAsConst(m_vecData)) m_usedNames.insert(QString::fromStdString(item.name())); } // -------------------------------------------------------- // AreaProxyModel // -------------------------------------------------------- void AreaProxyModel::setSourceModel(QAbstractItemModel *sourceModel) { m_sourceModel = qobject_cast(sourceModel); BaseClass::setSourceModel(sourceModel); } bool AreaProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { if (!m_sourceModel || 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::ShootbackArea &left = m_sourceModel->m_vecData.at(source_left.row()); const TargetManagement::ShootbackArea &right = m_sourceModel->m_vecData.at(source_right.row()); switch (source_left.column()) { case AreaModel::Columns::Id: return left.id() < right.id(); case AreaModel::Columns::Name: return left.name() < right.name(); case AreaModel::Columns::Width: return left.width() < right.width(); case AreaModel::Columns::Height: return left.height() < right.height(); case AreaModel::Columns::Center: // QString compare return LtsUtils::lessThan(source_left.data(), source_right.data()); } return BaseClass::lessThan(source_left, source_right); } } // namespace TargetManagement