diff --git a/res/controllers/Hercules_DJControl_Inpulse_200.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_200.midi.xml index 5ce8c9ae3a1..b9d10873f59 100644 --- a/res/controllers/Hercules_DJControl_Inpulse_200.midi.xml +++ b/res/controllers/Hercules_DJControl_Inpulse_200.midi.xml @@ -1107,6 +1107,18 @@ + + + + [Library] + ScrollVertical + Scroll Vertical (SHIFT + Browser Knob) + 0xB3 + 0x01 + + + + diff --git a/src/library/trackset/crate/cratetablemodel.cpp b/src/library/trackset/crate/cratetablemodel.cpp index 60eb14eed34..28388f4bfb1 100644 --- a/src/library/trackset/crate/cratetablemodel.cpp +++ b/src/library/trackset/crate/cratetablemodel.cpp @@ -168,6 +168,17 @@ int CrateTableModel::addTracks( return trackIds.size(); } +bool CrateTableModel::isLocked() { + Crate crate; + if (!m_pTrackCollectionManager->internalCollection() + ->crates() + .readCrateById(m_selectedCrate, &crate)) { + qWarning() << "Failed to read create" << m_selectedCrate; + return false; + } + return crate.isLocked(); +} + void CrateTableModel::removeTracks(const QModelIndexList& indices) { VERIFY_OR_DEBUG_ASSERT(m_selectedCrate.isValid()) { return; diff --git a/src/library/trackset/crate/cratetablemodel.h b/src/library/trackset/crate/cratetablemodel.h index 32760e32fb4..fed1f1d4dc3 100644 --- a/src/library/trackset/crate/cratetablemodel.h +++ b/src/library/trackset/crate/cratetablemodel.h @@ -20,6 +20,7 @@ class CrateTableModel final : public TrackSetTableModel { void removeTracks(const QModelIndexList& indices) final; /// Returns the number of unsuccessful additions. int addTracks(const QModelIndex& index, const QList& locations) final; + bool isLocked() final; Capabilities getCapabilities() const final; QString modelKey(bool noSearch) const override; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 0332b90fe4b..fff5254d98f 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -904,9 +904,13 @@ void WTrackTableView::hideOrRemoveSelectedTracks() { } TrackModel::Capability cap; + // Hide is the primary action if allowed. Else we test for remove capability if (pTrackModel->hasCapabilities(TrackModel::Capability::Hide)) { cap = TrackModel::Capability::Hide; - } else if (pTrackModel->hasCapabilities(TrackModel::Capability::Remove)) { + } else if (pTrackModel->isLocked()) { // Locked playlists and crates + return; + } + if (pTrackModel->hasCapabilities(TrackModel::Capability::Remove)) { cap = TrackModel::Capability::Remove; } else if (pTrackModel->hasCapabilities(TrackModel::Capability::RemoveCrate)) { cap = TrackModel::Capability::RemoveCrate;