diff options
author | Uwe Klotz <uklotz@mixxx.org> | 2020-07-13 01:17:57 +0200 |
---|---|---|
committer | Uwe Klotz <uklotz@mixxx.org> | 2020-07-13 01:17:57 +0200 |
commit | 7d71d75d753a98d9d2abec37818f440470a4248d (patch) | |
tree | c3749e50b9b34a57e0d18a48e265b47cadb1383a | |
parent | 4d11c82f6e3ba780b1db037dfce92cb48f7668ad (diff) | |
parent | f6210f4d84c13792fdbe022feb5a4d586bf0fa9d (diff) |
Merge branch '2.3' of git@github.com:mixxxdj/mixxx.git
-rw-r--r-- | src/library/dao/trackdao.cpp | 11 | ||||
-rw-r--r-- | src/library/librarycontrol.cpp | 20 | ||||
-rw-r--r-- | src/library/librarycontrol.h | 4 | ||||
-rw-r--r-- | src/track/track.cpp | 27 | ||||
-rw-r--r-- | src/track/track.h | 5 | ||||
-rw-r--r-- | src/widget/wtracktableview.cpp | 12 | ||||
-rw-r--r-- | src/widget/wtracktableview.h | 4 |
7 files changed, 71 insertions, 12 deletions
diff --git a/src/library/dao/trackdao.cpp b/src/library/dao/trackdao.cpp index 86f24fe5ed..25d5a6691f 100644 --- a/src/library/dao/trackdao.cpp +++ b/src/library/dao/trackdao.cpp @@ -687,6 +687,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) { @@ -741,6 +745,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( @@ -808,8 +813,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/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<ControlPushButton>( + ConfigKey("[Library]", "AutoDjAddReplace")); + connect(m_pAutoDjAddReplace.get(), + &ControlPushButton::valueChanged, + this, + &LibraryControl::slotAutoDjAddReplace); + // Sort controls m_pSortColumn = std::make_unique<ControlEncoder>(ConfigKey("[Library]", "sort_column")); m_pSortOrder = std::make_unique<ControlPushButton>(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..dd8046c89e 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); @@ -129,9 +130,10 @@ class LibraryControl : public QObject { // Control to choose the currently selected item in focused widget (double click) std::unique_ptr<ControlObject> m_pGoToItem; - // Add to Auto-Dj Cueue + // Add to Auto-Dj Queue std::unique_ptr<ControlObject> m_pAutoDjAddTop; std::unique_ptr<ControlObject> m_pAutoDjAddBottom; + std::unique_ptr<ControlObject> m_pAutoDjAddReplace; // Controls to sort the track view std::unique_ptr<ControlEncoder> m_pSortColumn; diff --git a/src/track/track.cpp b/src/track/track.cpp index 506359209b..16c1459759 100644 --- a/src/track/track.cpp +++ b/src/track/track.cpp @@ -681,21 +681,31 @@ 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 } - m_record.setId(std::move(id)); + m_record.setId(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() { QMutexLocker lock(&m_qMutex); m_record.setId(TrackId()); + for (const auto pCue : qAsConst(m_cuePoints)) { + pCue->setTrackId(TrackId()); + } } void Track::setURL(const QString& url) { @@ -838,16 +848,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(); } @@ -861,6 +873,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; } @@ -874,11 +887,6 @@ void Track::removeCuesOfType(mixxx::CueType type) { } } -QList<CuePointer> Track::getCuePoints() const { - QMutexLocker lock(&m_qMutex); - return m_cuePoints; -} - void Track::setCuePoints(const QList<CuePointer>& cuePoints) { // While this method could be called from any thread, // associated Cue objects should always live on the @@ -951,6 +959,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 diff --git a/src/track/track.h b/src/track/track.h index 97d2b95066..56b920fedb 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<CuePointer> getCuePoints() const; + QList<CuePointer> getCuePoints() const { + // Copying implicitly shared collections is thread-safe + return m_cuePoints; + } void setCuePoints(const QList<CuePointer>& cuePoints); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index fdc409ae47..da1f43bfb8 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(); |