diff --git a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp index ff3da32f..9f233d9d 100644 --- a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp @@ -314,6 +314,33 @@ void PlacefileManager::LoadFile(const std::string& filename) }); } +void PlacefileManager::RemoveUrl(const std::string& urlString) +{ + std::unique_lock lock(p->placefileRecordLock_); + + // Determine if the placefile has been loaded previously + auto it = std::find_if(p->placefileRecords_.begin(), + p->placefileRecords_.end(), + [&urlString](auto& record) + { return record->name_ == urlString; }); + if (it == p->placefileRecords_.end()) + { + logger_->debug("Placefile doesn't exist: {}", urlString); + return; + } + + // Placefile exists, proceed with removing + logger_->info("RemoveUrl: {}", urlString); + + // Remove record + p->placefileRecords_.erase(it); + p->placefileRecordMap_.erase(urlString); + + lock.unlock(); + + Q_EMIT PlacefileRemoved(urlString); +} + void PlacefileManager::Impl::PlacefileRecord::Update() { logger_->debug("Update: {}", name_); diff --git a/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp b/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp index c2cf2d45..eaa9c21b 100644 --- a/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp @@ -39,11 +39,13 @@ public: void AddUrl(const std::string& urlString); void LoadFile(const std::string& filename); + void RemoveUrl(const std::string& urlString); static std::shared_ptr Instance(); signals: void PlacefileEnabled(const std::string& name, bool enabled); + void PlacefileRemoved(const std::string& name); void PlacefileRenamed(const std::string& oldName, const std::string& newName); void PlacefileUpdated(const std::string& name); diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 212b8b34..bfb2284a 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -227,6 +227,19 @@ void MapWidgetImpl::ConnectSignals() } widget_->update(); }); + connect(placefileManager_.get(), + &manager::PlacefileManager::PlacefileRemoved, + widget_, + [this](const std::string& name) + { + if (enabledPlacefiles_.contains(name)) + { + // Placefile removed, remove layer + enabledPlacefiles_.erase(name); + RemovePlacefileLayer(name); + } + widget_->update(); + }); connect(placefileManager_.get(), &manager::PlacefileManager::PlacefileRenamed, widget_, diff --git a/scwx-qt/source/scwx/qt/model/placefile_model.cpp b/scwx-qt/source/scwx/qt/model/placefile_model.cpp index 87d81c28..5ad286a1 100644 --- a/scwx-qt/source/scwx/qt/model/placefile_model.cpp +++ b/scwx-qt/source/scwx/qt/model/placefile_model.cpp @@ -45,6 +45,11 @@ PlacefileModel::PlacefileModel(QObject* parent) : this, &PlacefileModel::HandlePlacefileUpdate); + connect(p->placefileManager_.get(), + &manager::PlacefileManager::PlacefileRemoved, + this, + &PlacefileModel::HandlePlacefileRemoved); + connect(p->placefileManager_.get(), &manager::PlacefileManager::PlacefileRenamed, this, @@ -292,6 +297,24 @@ bool PlacefileModel::setData(const QModelIndex& index, return true; } +void PlacefileModel::HandlePlacefileRemoved(const std::string& name) +{ + auto it = + std::find(p->placefileNames_.begin(), p->placefileNames_.end(), name); + + if (it != p->placefileNames_.end()) + { + // Placefile exists, delete row + const int row = std::distance(p->placefileNames_.begin(), it); + QModelIndex topLeft = createIndex(row, kFirstColumn); + QModelIndex bottomRight = createIndex(row, kLastColumn); + + beginRemoveRows(QModelIndex(), row, row); + p->placefileNames_.erase(it); + endRemoveRows(); + } +} + void PlacefileModel::HandlePlacefileRenamed(const std::string& oldName, const std::string& newName) { diff --git a/scwx-qt/source/scwx/qt/model/placefile_model.hpp b/scwx-qt/source/scwx/qt/model/placefile_model.hpp index f4f01167..5dc4fa14 100644 --- a/scwx-qt/source/scwx/qt/model/placefile_model.hpp +++ b/scwx-qt/source/scwx/qt/model/placefile_model.hpp @@ -45,6 +45,7 @@ public: int role = Qt::EditRole) override; public slots: + void HandlePlacefileRemoved(const std::string& name); void HandlePlacefileRenamed(const std::string& oldName, const std::string& newName); void HandlePlacefileUpdate(const std::string& name); diff --git a/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp b/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp index c5f73945..51679e0f 100644 --- a/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/placefile_settings_widget.cpp @@ -31,8 +31,9 @@ public: leftElidedItemDelegate_ {new LeftElidedItemDelegate(self_)} { placefileProxyModel_->setSourceModel(placefileModel_); - placefileProxyModel_->setSortRole(types::SortRole); - placefileProxyModel_->setFilterCaseSensitivity(Qt::CaseInsensitive); + placefileProxyModel_->setSortRole(types::ItemDataRole::SortRole); + placefileProxyModel_->setFilterCaseSensitivity( + Qt::CaseSensitivity::CaseInsensitive); placefileProxyModel_->setFilterKeyColumn(-1); } ~PlacefileSettingsWidgetImpl() = default; @@ -57,6 +58,8 @@ PlacefileSettingsWidget::PlacefileSettingsWidget(QWidget* parent) : { ui->setupUi(this); + ui->removeButton->setEnabled(false); + ui->placefileView->setModel(p->placefileProxyModel_); auto placefileViewHeader = ui->placefileView->header(); @@ -89,6 +92,31 @@ void PlacefileSettingsWidgetImpl::ConnectSignals() self_, [this]() { openUrlDialog_->open(); }); + QObject::connect(self_->ui->removeButton, + &QPushButton::clicked, + self_, + [this]() + { + auto selectionModel = + self_->ui->placefileView->selectionModel(); + + // Get selected URL string + QModelIndex selected = + selectionModel + ->selectedRows(static_cast( + model::PlacefileModel::Column::Placefile)) + .first(); + QVariant data = self_->ui->placefileView->model()->data( + selected, types::ItemDataRole::SortRole); + std::string urlString = data.toString().toStdString(); + + // Remove Placefile + if (!urlString.empty()) + { + placefileManager_->RemoveUrl(urlString); + } + }); + QObject::connect( openUrlDialog_, &OpenUrlDialog::accepted, @@ -100,6 +128,25 @@ void PlacefileSettingsWidgetImpl::ConnectSignals() &QLineEdit::textChanged, placefileProxyModel_, &QSortFilterProxyModel::setFilterWildcard); + + QObject::connect( + self_->ui->placefileView->selectionModel(), + &QItemSelectionModel::selectionChanged, + self_, + [this](const QItemSelection& selected, const QItemSelection& deselected) + { + if (selected.size() == 0 && deselected.size() == 0) + { + // Items which stay selected but change their index are not + // included in selected and deselected. Thus, this signal might + // be emitted with both selected and deselected empty, if only + // the indices of selected items change. + return; + } + + bool itemSelected = selected.size() > 0; + self_->ui->removeButton->setEnabled(itemSelected); + }); } } // namespace ui