| 760 | } |
| 761 | |
| 762 | bool CatalogModel::removeDataset(DatasetId dataset_id, bool tombstone) { |
| 763 | std::vector<QString> keys; |
| 764 | for (const auto& [key, item] : impl_->items) { |
| 765 | if (item.dataset_id == dataset_id) { |
| 766 | keys.push_back(key); |
| 767 | } |
| 768 | } |
| 769 | if (keys.empty()) { |
| 770 | return false; |
| 771 | } |
| 772 | // Whole-dataset tombstone (vs removeItems' per-name blacklist): rebuildFromDatastore |
| 773 | // hides this id until a reload mints a new DatasetId or restoreDataset un-hides it. |
| 774 | // Skipped for a real "Remove Dataset": the caller erases the engine/object data too, so |
| 775 | // there is nothing left to hide and no soft-delete state should accumulate. |
| 776 | if (tombstone) { |
| 777 | impl_->removed_datasets.insert(dataset_id); |
| 778 | } |
| 779 | impl_->removed_names_per_dataset.erase(dataset_id); |
| 780 | for (const QString& key : keys) { |
| 781 | impl_->items.erase(key); |
| 782 | } |
| 783 | // Empty catalog: one cleared() (views reset in O(1)); otherwise one batched |
| 784 | // itemsRemoved so consumers react once, not per key. |
| 785 | if (impl_->items.empty()) { |
| 786 | emit cleared(); |
| 787 | } else { |
| 788 | emit itemsRemoved(QStringList(keys.begin(), keys.end())); |
| 789 | } |
| 790 | return true; |
| 791 | } |
| 792 | |
| 793 | } // namespace PJ |