diff --git a/.clang-tidy b/.clang-tidy index 602e3d0c..3c98e81d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -10,4 +10,6 @@ Checks: - '-misc-include-cleaner' - '-misc-non-private-member-variables-in-classes' - '-modernize-use-trailing-return-type' + - '-bugprone-easily-swappable-parameters' + - '-modernize-return-braced-init-list' FormatStyle: 'file' diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index cf25cbcb..a9214d03 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -203,9 +203,7 @@ void MarkerManager::Impl::ReadMarkerSettings() } } - util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas( - 2048, 2048); // Should this code be moved to ResourceManager? + ResourceManager::BuildAtlas(); logger_->debug("{} location marker entries", markerRecords_.size()); } @@ -239,7 +237,7 @@ MarkerManager::Impl::GetMarkerByName(const std::string& name) MarkerManager::MarkerManager() : p(std::make_unique(this)) { - const std::vector defaultMarkerIcons_ { + static const std::vector defaultMarkerIcons_ { types::MarkerIconInfo(types::ImageTexture::LocationMarker, -1, -1), types::MarkerIconInfo(types::ImageTexture::LocationPin, 6, 16), types::MarkerIconInfo(types::ImageTexture::LocationCrosshair, -1, -1), @@ -256,7 +254,7 @@ MarkerManager::MarkerManager() : p(std::make_unique(this)) p->InitializeMarkerSettings(); boost::asio::post(p->threadPool_, - [this, defaultMarkerIcons_]() + [this]() { try { @@ -454,9 +452,7 @@ void MarkerManager::add_icon(const std::string& name, bool startup) if (!startup) { - util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas( - 2048, 2048); // Should this code be moved to ResourceManager? + ResourceManager::BuildAtlas(); Q_EMIT IconAdded(name); } } @@ -465,9 +461,10 @@ std::optional MarkerManager::get_icon(const std::string& name) { const std::shared_lock lock(p->markerIconsLock_); - if (p->markerIcons_.contains(name)) + auto it = p->markerIcons_.find(name); + if (it != p->markerIcons_.end()) { - return p->markerIcons_.at(name); + return it->second; } return {}; diff --git a/scwx-qt/source/scwx/qt/manager/resource_manager.cpp b/scwx-qt/source/scwx/qt/manager/resource_manager.cpp index 443d771b..5299d6ff 100644 --- a/scwx-qt/source/scwx/qt/manager/resource_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/resource_manager.cpp @@ -22,6 +22,9 @@ namespace ResourceManager static const std::string logPrefix_ = "scwx::qt::manager::resource_manager"; static const auto logger_ = scwx::util::Logger::Create(logPrefix_); +static const size_t atlasWidth = 2048; +static const size_t atlasHeight = 2048; + static void LoadFonts(); static void LoadTextures(); @@ -68,8 +71,7 @@ LoadImageResources(const std::vector& urlStrings) if (!images.empty()) { - util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas(2048, 2048); + BuildAtlas(); } return images; @@ -103,7 +105,13 @@ static void LoadTextures() GetTexturePath(lineTexture)); } - textureAtlas.BuildAtlas(2048, 2048); + BuildAtlas(); +} + +void BuildAtlas() +{ + util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); + textureAtlas.BuildAtlas(atlasWidth, atlasHeight); } } // namespace ResourceManager diff --git a/scwx-qt/source/scwx/qt/manager/resource_manager.hpp b/scwx-qt/source/scwx/qt/manager/resource_manager.hpp index 00658891..ec7cf65e 100644 --- a/scwx-qt/source/scwx/qt/manager/resource_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/resource_manager.hpp @@ -22,6 +22,7 @@ std::shared_ptr LoadImageResource(const std::string& urlString); std::vector> LoadImageResources(const std::vector& urlStrings); +void BuildAtlas(); } // namespace ResourceManager } // namespace manager diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 9c68a68a..c5c07b56 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -219,7 +219,7 @@ public: std::shared_ptr layerModel_ { model::LayerModel::Instance()}; - std::shared_ptr editMarkerDialog_; + ui::EditMarkerDialog* editMarkerDialog_; std::shared_ptr hotkeyManager_ { manager::HotkeyManager::Instance()}; @@ -286,7 +286,10 @@ MapWidget::MapWidget(std::size_t id, const QMapLibre::Settings& settings) : ImGui_ImplQt_RegisterWidget(this); - p->editMarkerDialog_ = std::make_shared(this); + // Qt parent deals with memory management + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) + p->editMarkerDialog_ = new ui::EditMarkerDialog(this); + p->ConnectSignals(); } diff --git a/scwx-qt/source/scwx/qt/map/marker_layer.cpp b/scwx-qt/source/scwx/qt/map/marker_layer.cpp index a0ac668f..ba7f3e27 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -77,9 +77,21 @@ void MarkerLayer::Impl::ReloadMarkers() const std::shared_ptr icon = geoIcons_->AddIcon(); + const std::string latitudeString = + common::GetLatitudeString(marker.latitude); + const std::string longitudeString = + common::GetLongitudeString(marker.longitude); + + const std::string hoverText = + marker.name != "" ? + fmt::format( + "{}\n{}, {}", marker.name, latitudeString, longitudeString) : + fmt::format("{}, {}", latitudeString, longitudeString); + + geoIcons_->SetIconTexture(icon, marker.iconName, 0); geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); - geoIcons_->SetIconHoverText(icon, marker.name); + geoIcons_->SetIconHoverText(icon, hoverText); geoIcons_->SetIconModulate(icon, marker.iconColor); geoIcons_->RegisterEventHandler( icon, diff --git a/scwx-qt/source/scwx/qt/model/marker_model.cpp b/scwx-qt/source/scwx/qt/model/marker_model.cpp index 32294de0..77fb7ab7 100644 --- a/scwx-qt/source/scwx/qt/model/marker_model.cpp +++ b/scwx-qt/source/scwx/qt/model/marker_model.cpp @@ -129,7 +129,20 @@ QVariant MarkerModel::data(const QModelIndex& index, int role) const break; break; case static_cast(Column::Icon): - if (role == Qt::ItemDataRole::DecorationRole) + 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); diff --git a/scwx-qt/source/scwx/qt/types/marker_types.hpp b/scwx-qt/source/scwx/qt/types/marker_types.hpp index 09f9a06b..f8b1c710 100644 --- a/scwx-qt/source/scwx/qt/types/marker_types.hpp +++ b/scwx-qt/source/scwx/qt/types/marker_types.hpp @@ -2,31 +2,29 @@ #include -#include #include +#include +#include #include +#include #include -namespace scwx -{ -namespace qt -{ -namespace types +namespace scwx::qt::types { using MarkerId = std::uint64_t; struct MarkerInfo { - MarkerInfo(const std::string& name, + MarkerInfo(std::string name, double latitude, double longitude, - const std::string& iconName, + std::string iconName, const boost::gil::rgba8_pixel_t& iconColor) : - name {name}, + name {std::move(name)}, latitude {latitude}, longitude {longitude}, - iconName {iconName}, + iconName {std::move(iconName)}, iconColor {iconColor} { } @@ -41,6 +39,7 @@ struct MarkerInfo struct MarkerIconInfo { + // Initializer for default icons (which use a texture) explicit MarkerIconInfo(types::ImageTexture texture, std::int32_t hotX, std::int32_t hotY) : @@ -51,14 +50,19 @@ struct MarkerIconInfo qIcon {QIcon(QString::fromStdString(path))}, image {} { + auto qName = QString::fromStdString(name); + QStringList parts = qName.split("location-"); + shortName = parts.last().toStdString(); } + // Initializer for custom icons (which use a file path) explicit MarkerIconInfo(const std::string& path, std::int32_t hotX, std::int32_t hotY, std::shared_ptr image) : name {path}, path {path}, + shortName {QFileInfo(path.c_str()).fileName().toStdString()}, hotX {hotX}, hotY {hotY}, qIcon {QIcon(QString::fromStdString(path))}, @@ -68,12 +72,11 @@ struct MarkerIconInfo std::string name; std::string path; + std::string shortName; std::int32_t hotX; std::int32_t hotY; QIcon qIcon; std::optional> image; }; -} // namespace types -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::types diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index e186a4df..a6aaa4d4 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -17,11 +17,7 @@ #include #include -namespace scwx -{ -namespace qt -{ -namespace ui +namespace scwx::qt::ui { static const std::string logPrefix_ = "scwx::qt::ui::edit_marker_dialog"; @@ -71,9 +67,10 @@ EditMarkerDialog::EditMarkerDialog(QWidget* parent) : for (auto& markerIcon : p->markerManager_->get_icons()) { - ui->iconComboBox->addItem(markerIcon.second.qIcon, - QString(""), - QString::fromStdString(markerIcon.second.name)); + ui->iconComboBox->addItem( + markerIcon.second.qIcon, + QString::fromStdString(markerIcon.second.shortName), + QString::fromStdString(markerIcon.second.name)); } p->deleteButton_ = ui->buttonBox->addButton("Delete", QDialogButtonBox::DestructiveRole); @@ -154,7 +151,8 @@ types::MarkerInfo EditMarkerDialog::get_marker_info() const void EditMarkerDialog::Impl::show_color_dialog() { - + // WA_DeleteOnClose manages memory + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) auto* dialog = new QColorDialog(self_); dialog->setAttribute(Qt::WA_DeleteOnClose); @@ -184,7 +182,7 @@ void EditMarkerDialog::Impl::show_icon_file_dialog() auto* dialog = new QFileDialog(self_); dialog->setFileMode(QFileDialog::ExistingFile); - dialog->setNameFilters({"Icon (*.png *.svg)", "All (*)"}); + dialog->setNameFilters({"Icon (*.png *.svg)", "All Files (*)"}); dialog->setAttribute(Qt::WA_DeleteOnClose); QObject::connect(dialog, @@ -256,6 +254,11 @@ void EditMarkerDialog::Impl::connect_signals() } } }); + + connect(self_->ui->buttonBox->button(QDialogButtonBox::Apply), + &QAbstractButton::clicked, + self_, + [this]() { handle_accepted(); }); } void EditMarkerDialog::Impl::set_icon_color(const std::string& color) @@ -276,7 +279,9 @@ void EditMarkerDialog::Impl::set_icon_color(const std::string& color) if (i < 0) { iconComboBox->addItem( - icon, QString(""), QString::fromStdString(markerIcon.second.name)); + icon, + QString::fromStdString(markerIcon.second.shortName), + QString::fromStdString(markerIcon.second.name)); } else { @@ -306,6 +311,4 @@ void EditMarkerDialog::Impl::handle_rejected() } } -} // namespace ui -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::ui diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp index 6c6f6e6c..c20ebe27 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp @@ -8,11 +8,7 @@ namespace Ui class EditMarkerDialog; } -namespace scwx -{ -namespace qt -{ -namespace ui +namespace scwx::qt::ui { class EditMarkerDialog : public QDialog { @@ -35,6 +31,4 @@ private: Ui::EditMarkerDialog* ui; }; -} // namespace ui -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::ui diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui index 3bfad9a6..d3d47500 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui @@ -101,7 +101,7 @@ Qt::Orientation::Horizontal - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok diff --git a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp index cc98302d..b3ba8440 100644 --- a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp @@ -23,15 +23,21 @@ class MarkerSettingsWidgetImpl { public: explicit MarkerSettingsWidgetImpl(MarkerSettingsWidget* self) : - self_ {self}, - markerModel_ {new model::MarkerModel(self_)} + self_ {self}, + markerModel_ {new model::MarkerModel(self_)}, + proxyModel_ {new QSortFilterProxyModel(self_)} { + proxyModel_->setSourceModel(markerModel_); + proxyModel_->setSortRole(Qt::DisplayRole); // TODO types::SortRole + proxyModel_->setFilterCaseSensitivity(Qt::CaseInsensitive); + proxyModel_->setFilterKeyColumn(-1); } void ConnectSignals(); - MarkerSettingsWidget* self_; - model::MarkerModel* markerModel_; + MarkerSettingsWidget* self_; + model::MarkerModel* markerModel_; + QSortFilterProxyModel* proxyModel_; std::shared_ptr markerManager_ { manager::MarkerManager::Instance()}; std::shared_ptr editMarkerDialog_ {nullptr}; @@ -46,7 +52,7 @@ MarkerSettingsWidget::MarkerSettingsWidget(QWidget* parent) : ui->setupUi(this); ui->removeButton->setEnabled(false); - ui->markerView->setModel(p->markerModel_); + ui->markerView->setModel(p->proxyModel_); p->editMarkerDialog_ = std::make_shared(this); diff --git a/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp b/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp index 007ceb47..c205ce88 100644 --- a/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp +++ b/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp @@ -6,11 +6,7 @@ #include #include -namespace scwx -{ -namespace qt -{ -namespace util +namespace scwx::qt::util { void modulateColors_(QImage& image, const QColor& color) @@ -20,6 +16,9 @@ void modulateColors_(QImage& image, const QColor& color) QRgb* line = reinterpret_cast(image.scanLine(y)); for (int x = 0; x < image.width(); ++x) { + // This is pulled from Qt Documentation + // https://doc.qt.io/qt-6/qimage.html#scanLine + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) QRgb& rgb = line[x]; /* clang-format off * NOLINTBEGIN(cppcoreguidelines-narrowing-conversions, bugprone-narrowing-conversions) @@ -62,6 +61,4 @@ QIcon modulateColors(const QIcon& icon, const QSize& size, const QColor& color) return QIcon(pixmap); } -} // namespace util -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::util diff --git a/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp b/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp index c54b852f..35326293 100644 --- a/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp +++ b/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp @@ -6,17 +6,11 @@ #include #include -namespace scwx -{ -namespace qt -{ -namespace util +namespace scwx::qt::util { QImage modulateColors(const QImage& image, const QColor& color); QPixmap modulateColors(const QPixmap& pixmap, const QColor& color); QIcon modulateColors(const QIcon& icon, const QSize& size, const QColor& color); -} // namespace util -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::util