#include #include #include #include #include #include #include #include #include namespace scwx { namespace qt { namespace model { static const std::string logPrefix_ = "scwx::qt::model::marker_model"; static const auto logger_ = scwx::util::Logger::Create(logPrefix_); static const int iconSize_ = 30; static constexpr int kFirstColumn = static_cast(MarkerModel::Column::Latitude); static constexpr int kLastColumn = static_cast(MarkerModel::Column::Name); static constexpr int kNumColumns = kLastColumn - kFirstColumn + 1; class MarkerModel::Impl { public: explicit Impl() {} ~Impl() = default; std::shared_ptr markerManager_ { manager::MarkerManager::Instance()}; std::vector markerIds_; }; MarkerModel::MarkerModel(QObject* parent) : QAbstractTableModel(parent), p(std::make_unique()) { connect(p->markerManager_.get(), &manager::MarkerManager::MarkersInitialized, this, &MarkerModel::HandleMarkersInitialized); connect(p->markerManager_.get(), &manager::MarkerManager::MarkerAdded, this, &MarkerModel::HandleMarkerAdded); connect(p->markerManager_.get(), &manager::MarkerManager::MarkerChanged, this, &MarkerModel::HandleMarkerChanged); connect(p->markerManager_.get(), &manager::MarkerManager::MarkerRemoved, this, &MarkerModel::HandleMarkerRemoved); } MarkerModel::~MarkerModel() = default; int MarkerModel::rowCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : static_cast(p->markerIds_.size()); } int MarkerModel::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : kNumColumns; } Qt::ItemFlags MarkerModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QAbstractTableModel::flags(index); return flags; } QVariant MarkerModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || index.row() < 0 || static_cast(index.row()) >= p->markerIds_.size()) { logger_->debug("Failed to get data index {}", index.row()); return QVariant(); } types::MarkerId id = p->markerIds_[index.row()]; std::optional markerInfo = p->markerManager_->get_marker(id); if (!markerInfo) { logger_->debug("Failed to get data index {} id {}", index.row(), id); return QVariant(); } switch(index.column()) { case static_cast(Column::Name): if (role == Qt::ItemDataRole::DisplayRole || role == Qt::ItemDataRole::ToolTipRole) { return QString::fromStdString(markerInfo->name); } break; case static_cast(Column::Latitude): if (role == Qt::ItemDataRole::DisplayRole || role == Qt::ItemDataRole::ToolTipRole) { return QString::fromStdString( common::GetLatitudeString(markerInfo->latitude)); } break; case static_cast(Column::Longitude): if (role == Qt::ItemDataRole::DisplayRole || role == Qt::ItemDataRole::ToolTipRole) { return QString::fromStdString( common::GetLongitudeString(markerInfo->longitude)); } break; break; case static_cast(Column::Icon): if (role == Qt::ItemDataRole::DisplayRole) { std::optional icon = p->markerManager_->get_icon(markerInfo->iconName); if (icon) { return QString::fromStdString(icon->shortName); } else { return {}; } } else if (role == Qt::ItemDataRole::DecorationRole) { std::optional icon = p->markerManager_->get_icon(markerInfo->iconName); if (icon) { return util::modulateColors(icon->qIcon, QSize(iconSize_, iconSize_), QColor(markerInfo->iconColor[0], markerInfo->iconColor[1], markerInfo->iconColor[2], markerInfo->iconColor[3])); } else { return {}; } } break; default: break; } return QVariant(); } std::optional MarkerModel::getId(int index) { if (index < 0 || static_cast(index) >= p->markerIds_.size()) { return {}; } return p->markerIds_[index]; } QVariant MarkerModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::ItemDataRole::DisplayRole) { if (orientation == Qt::Horizontal) { switch (section) { case static_cast(Column::Name): return tr("Name"); case static_cast(Column::Latitude): return tr("Latitude"); case static_cast(Column::Longitude): return tr("Longitude"); case static_cast(Column::Icon): return tr("Icon"); default: break; } } } return QVariant(); } bool MarkerModel::setData(const QModelIndex&, const QVariant&, int) { return false; } void MarkerModel::HandleMarkersInitialized(size_t count) { if (count == 0) { return; } const int index = static_cast(count - 1); p->markerIds_.reserve(count); beginInsertRows(QModelIndex(), 0, index); p->markerManager_->for_each( [this](const types::MarkerInfo& info) { p->markerIds_.push_back(info.id); }); endInsertRows(); } void MarkerModel::HandleMarkerAdded(types::MarkerId id) { std::optional index = p->markerManager_->get_index(id); if (!index) { return; } const int newIndex = static_cast(*index); beginInsertRows(QModelIndex(), newIndex, newIndex); auto it = std::next(p->markerIds_.begin(), newIndex); p->markerIds_.emplace(it, id); endInsertRows(); } void MarkerModel::HandleMarkerChanged(types::MarkerId id) { auto it = std::find(p->markerIds_.begin(), p->markerIds_.end(), id); if (it == p->markerIds_.end()) { return; } const int changedIndex = std::distance(p->markerIds_.begin(), it); QModelIndex topLeft = createIndex(changedIndex, kFirstColumn); QModelIndex bottomRight = createIndex(changedIndex, kLastColumn); Q_EMIT dataChanged(topLeft, bottomRight); } void MarkerModel::HandleMarkerRemoved(types::MarkerId id) { auto it = std::find(p->markerIds_.begin(), p->markerIds_.end(), id); if (it == p->markerIds_.end()) { return; } const int removedIndex = std::distance(p->markerIds_.begin(), it); beginRemoveRows(QModelIndex(), removedIndex, removedIndex); p->markerIds_.erase(it); endRemoveRows(); } } // namespace model } // namespace qt } // namespace scwx