From 69a347aec59787185ac6f5fb40124ee6b67b3ca3 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sun, 12 Jul 2020 18:24:41 +0200 Subject: Fix debug assertion when storing Cue objects without track id --- src/track/track.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/track/track.cpp b/src/track/track.cpp index d05cfb1bf9..8a4c321681 100644 --- a/src/track/track.cpp +++ b/src/track/track.cpp @@ -689,8 +689,11 @@ void Track::initId(TrackId id) { return; // abort } m_record.setId(std::move(id)); + for (const auto pCue : qAsConst(m_cuePoints)) { + pCue->setTrackId(id); + } // Changing the Id does not make the track dirty because the Id is always - // generated by the Database itself. + // generated by the database itself. } void Track::resetId() { -- cgit v1.2.3 From 72b6b645494dd39fe53ea5a219aa84d1cdb76293 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sun, 12 Jul 2020 18:58:22 +0200 Subject: Avoid unneeded locking --- src/track/track.cpp | 5 ----- src/track/track.h | 5 ++++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/track/track.cpp b/src/track/track.cpp index 8a4c321681..41d8984282 100644 --- a/src/track/track.cpp +++ b/src/track/track.cpp @@ -877,11 +877,6 @@ void Track::removeCuesOfType(mixxx::CueType type) { } } -QList Track::getCuePoints() const { - QMutexLocker lock(&m_qMutex); - return m_cuePoints; -} - void Track::setCuePoints(const QList& cuePoints) { // While this method could be called from any thread, // associated Cue objects should always live on the diff --git a/src/track/track.h b/src/track/track.h index 8d4f8e33a5..24a3466217 100644 --- a/src/track/track.h +++ b/src/track/track.h @@ -268,7 +268,10 @@ class Track : public QObject { CuePointer findCueById(int id) const; void removeCue(const CuePointer& pCue); void removeCuesOfType(mixxx::CueType); - QList getCuePoints() const; + QList getCuePoints() const { + // Copying implicitly shared collections is thread-safe + return m_cuePoints; + } void setCuePoints(const QList& cuePoints); -- cgit v1.2.3 From d3fdf11d0f5ee324c0199ae836878c355d28da61 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sun, 12 Jul 2020 18:58:54 +0200 Subject: Reset track id of cue objects when removing from track --- src/track/track.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/track/track.cpp b/src/track/track.cpp index 41d8984282..2748ed3b0d 100644 --- a/src/track/track.cpp +++ b/src/track/track.cpp @@ -841,16 +841,18 @@ CuePointer Track::findCueById(int id) const { } void Track::removeCue(const CuePointer& pCue) { - if (pCue == nullptr) { + if (!pCue) { return; } QMutexLocker lock(&m_qMutex); + DEBUG_ASSERT(pCue->getTrackId() == m_record.getId()); disconnect(pCue.get(), 0, this, 0); m_cuePoints.removeOne(pCue); if (pCue->getType() == mixxx::CueType::MainCue) { m_record.setCuePoint(CuePosition()); } + pCue->setTrackId(TrackId()); markDirtyAndUnlock(&lock); emit cuesUpdated(); } @@ -864,6 +866,7 @@ void Track::removeCuesOfType(mixxx::CueType type) { // FIXME: Why does this only work for the Hotcue Type? if (pCue->getType() == type) { disconnect(pCue.get(), 0, this, 0); + pCue->setTrackId(TrackId()); it.remove(); dirty = true; } @@ -949,6 +952,7 @@ void Track::setCuePointsMarkDirtyAndUnlock( // disconnect existing cue points for (const auto& pCue: m_cuePoints) { disconnect(pCue.get(), 0, this, 0); + pCue->setTrackId(TrackId()); } m_cuePoints = cuePoints; // connect new cue points -- cgit v1.2.3 From bca579f514efe34ee458cddd38bd0fcb4dd925f5 Mon Sep 17 00:00:00 2001 From: Be Date: Sun, 12 Jul 2020 14:09:29 -0500 Subject: fix [Library], AutoDjAddBottom/Top ControlObjects These were broken in #2612. --- src/widget/wtracktableview.cpp | 12 ++++++++++++ src/widget/wtracktableview.h | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index d3768f2dc0..bcb8b47f1f 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -839,6 +839,18 @@ void WTrackTableView::addToAutoDJ(PlaylistDAO::AutoDJSendLoc loc) { playlistDao.addTracksToAutoDJQueue(trackIds, loc); } +void WTrackTableView::slotAddToAutoDJBottom() { + addToAutoDJ(PlaylistDAO::AutoDJSendLoc::BOTTOM); +} + +void WTrackTableView::slotAddToAutoDJTop() { + addToAutoDJ(PlaylistDAO::AutoDJSendLoc::TOP); +} + +void WTrackTableView::slotAddToAutoDJReplace() { + addToAutoDJ(PlaylistDAO::AutoDJSendLoc::REPLACE); +} + void WTrackTableView::doSortByColumn(int headerSection, Qt::SortOrder sortOrder) { TrackModel* trackModel = getTrackModel(); QAbstractItemModel* itemModel = model(); diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 2e5af79b43..f00d982ab0 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -56,6 +56,10 @@ class WTrackTableView : public WLibraryTableView { void slotUnhide(); void slotPurge(); + void slotAddToAutoDJBottom() override; + void slotAddToAutoDJTop() override; + void slotAddToAutoDJReplace() override; + private slots: void doSortByColumn(int headerSection, Qt::SortOrder sortOrder); void applySortingIfVisible(); -- cgit v1.2.3 From 698f0508557e766441583f687fcf78b38e656b35 Mon Sep 17 00:00:00 2001 From: Be Date: Sun, 12 Jul 2020 14:10:03 -0500 Subject: add [Library], AutoDjAddReplace ControlObject --- src/library/librarycontrol.cpp | 20 ++++++++++++++++++++ src/library/librarycontrol.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/src/library/librarycontrol.cpp b/src/library/librarycontrol.cpp index d1e9d6579f..fb1e5da22a 100644 --- a/src/library/librarycontrol.cpp +++ b/src/library/librarycontrol.cpp @@ -156,6 +156,13 @@ LibraryControl::LibraryControl(Library* pLibrary) this, &LibraryControl::slotAutoDjAddBottom); + m_pAutoDjAddReplace = std::make_unique( + ConfigKey("[Library]", "AutoDjAddReplace")); + connect(m_pAutoDjAddReplace.get(), + &ControlPushButton::valueChanged, + this, + &LibraryControl::slotAutoDjAddReplace); + // Sort controls m_pSortColumn = std::make_unique(ConfigKey("[Library]", "sort_column")); m_pSortOrder = std::make_unique(ConfigKey("[Library]", "sort_order")); @@ -409,6 +416,19 @@ void LibraryControl::slotAutoDjAddBottom(double v) { } } +void LibraryControl::slotAutoDjAddReplace(double v) { + if (!m_pLibraryWidget) { + return; + } + if (v > 0) { + auto activeView = m_pLibraryWidget->getActiveView(); + if (!activeView) { + return; + } + activeView->slotAddToAutoDJReplace(); + } +} + void LibraryControl::slotSelectNextTrack(double v) { if (v > 0) { slotSelectTrack(1); diff --git a/src/library/librarycontrol.h b/src/library/librarycontrol.h index 6c438942c5..845342d3e7 100644 --- a/src/library/librarycontrol.h +++ b/src/library/librarycontrol.h @@ -85,6 +85,7 @@ class LibraryControl : public QObject { void slotLoadSelectedIntoFirstStopped(double v); void slotAutoDjAddTop(double v); void slotAutoDjAddBottom(double v); + void slotAutoDjAddReplace(double v); void maybeCreateGroupController(const QString& group); void slotNumDecksChanged(double v); @@ -132,6 +133,7 @@ class LibraryControl : public QObject { // Add to Auto-Dj Cueue std::unique_ptr m_pAutoDjAddTop; std::unique_ptr m_pAutoDjAddBottom; + std::unique_ptr m_pAutoDjAddReplace; // Controls to sort the track view std::unique_ptr m_pSortColumn; -- cgit v1.2.3 From d7dd56f2506f47e5428a388c65ea67136193165a Mon Sep 17 00:00:00 2001 From: Be Date: Sun, 12 Jul 2020 14:58:18 -0500 Subject: fix typo --- src/library/librarycontrol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/librarycontrol.h b/src/library/librarycontrol.h index 845342d3e7..dd8046c89e 100644 --- a/src/library/librarycontrol.h +++ b/src/library/librarycontrol.h @@ -130,7 +130,7 @@ class LibraryControl : public QObject { // Control to choose the currently selected item in focused widget (double click) std::unique_ptr m_pGoToItem; - // Add to Auto-Dj Cueue + // Add to Auto-Dj Queue std::unique_ptr m_pAutoDjAddTop; std::unique_ptr m_pAutoDjAddBottom; std::unique_ptr m_pAutoDjAddReplace; -- cgit v1.2.3 From ae2988b6feb4c1a73b398bab21ffebcc397a9701 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sun, 12 Jul 2020 22:43:08 +0200 Subject: TrackDAO: Initialize track id immediately after (re-)insert --- src/library/dao/trackdao.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/library/dao/trackdao.cpp b/src/library/dao/trackdao.cpp index 9f0f66a4dd..1e25c690ef 100644 --- a/src/library/dao/trackdao.cpp +++ b/src/library/dao/trackdao.cpp @@ -585,6 +585,10 @@ TrackId TrackDAO::addTracksAddTrack(const TrackPointer& pTrack, bool unremove) { trackId = TrackId(m_pQueryLibrarySelect->value(m_queryLibraryIdColumn)); DEBUG_ASSERT(trackId.isValid()); } + VERIFY_OR_DEBUG_ASSERT(trackId.isValid()) { + return TrackId(); + } + pTrack->initId(trackId); // Track already included in library, but maybe marked as deleted bool mixxx_deleted = m_pQueryLibrarySelect->value(m_queryLibraryMixxxDeletedColumn).toBool(); if (unremove && mixxx_deleted) { @@ -630,6 +634,7 @@ TrackId TrackDAO::addTracksAddTrack(const TrackPointer& pTrack, bool unremove) { VERIFY_OR_DEBUG_ASSERT(trackId.isValid()) { return TrackId(); } + pTrack->initId(trackId); pTrack->setDateAdded(trackDateAdded); m_analysisDao.saveTrackAnalyses( -- cgit v1.2.3 From 0068b27c94a38f259b1ce4b9a4c42cf2be812879 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sun, 12 Jul 2020 22:57:12 +0200 Subject: Account for duplicate initialization of track id --- src/library/dao/trackdao.cpp | 6 +++++- src/track/track.cpp | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/library/dao/trackdao.cpp b/src/library/dao/trackdao.cpp index 1e25c690ef..6aced66316 100644 --- a/src/library/dao/trackdao.cpp +++ b/src/library/dao/trackdao.cpp @@ -702,8 +702,12 @@ TrackPointer TrackDAO::addTracksAddFile(const TrackFile& trackFile, bool unremov // GlobalTrackCache will be unlocked implicitly return TrackPointer(); } - cacheResolver.initTrackIdAndUnlockCache(newTrackId); + // The track object has already been initialized with the + // database id, but the cache is not aware of this yet. + // Re-initializing the track object with the same id again + // from within the cache scope is allowed. DEBUG_ASSERT(pTrack->getId() == newTrackId); + cacheResolver.initTrackIdAndUnlockCache(newTrackId); // Only newly inserted tracks must be marked as clean! // Existing or unremoved tracks have not been added to // m_tracksAddedSet and will keep their dirty flag unchanged. diff --git a/src/track/track.cpp b/src/track/track.cpp index 2748ed3b0d..8912185938 100644 --- a/src/track/track.cpp +++ b/src/track/track.cpp @@ -681,9 +681,13 @@ TrackId Track::getId() const { void Track::initId(TrackId id) { QMutexLocker lock(&m_qMutex); + DEBUG_ASSERT(id.isValid()); + if (m_record.getId() == id) { + return; + } // The track's id must be set only once and immediately after // the object has been created. - VERIFY_OR_DEBUG_ASSERT(!m_record.getId().isValid() || (m_record.getId() == id)) { + VERIFY_OR_DEBUG_ASSERT(!m_record.getId().isValid()) { kLogger.warning() << "Cannot change id from" << m_record.getId() << "to" << id; return; // abort -- cgit v1.2.3 From aa6f31c1b7be794dff3f284e0e1a1c631fb8b291 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sun, 12 Jul 2020 22:57:56 +0200 Subject: Fix invalid std::move parameter passing --- src/track/track.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/track/track.cpp b/src/track/track.cpp index 8912185938..2f460fcf88 100644 --- a/src/track/track.cpp +++ b/src/track/track.cpp @@ -692,7 +692,7 @@ void Track::initId(TrackId id) { << m_record.getId() << "to" << id; return; // abort } - m_record.setId(std::move(id)); + m_record.setId(id); for (const auto pCue : qAsConst(m_cuePoints)) { pCue->setTrackId(id); } -- cgit v1.2.3 From 4c2df6d235c449155df161a4fd6e7be7c39df37f Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sun, 12 Jul 2020 22:59:04 +0200 Subject: Reset track id of cue points --- src/track/track.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/track/track.cpp b/src/track/track.cpp index 2f460fcf88..5da5f35b8f 100644 --- a/src/track/track.cpp +++ b/src/track/track.cpp @@ -703,6 +703,9 @@ void Track::initId(TrackId id) { void Track::resetId() { QMutexLocker lock(&m_qMutex); m_record.setId(TrackId()); + for (const auto pCue : qAsConst(m_cuePoints)) { + pCue->setTrackId(TrackId()); + } } void Track::setURL(const QString& url) { -- cgit v1.2.3