From 9241ba67b3369eeb23b0dce962011795b0f6b466 Mon Sep 17 00:00:00 2001 From: Pavel Potocek Date: Tue, 31 Jan 2017 16:22:58 +0100 Subject: Add an option to replace the autoDJ queue with the selected tracks --- src/library/dao/playlistdao.cpp | 47 ++++++++++++++++++++++++++-------- src/library/dao/playlistdao.h | 11 +++++++- src/library/dlganalysis.cpp | 8 ++++-- src/library/dlganalysis.h | 3 ++- src/library/librarycontrol.cpp | 2 +- src/library/libraryview.h | 3 ++- src/library/recording/dlgrecording.cpp | 8 ++++-- src/library/recording/dlgrecording.h | 3 ++- src/widget/wtracktableview.cpp | 37 +++++++++++++++++--------- src/widget/wtracktableview.h | 10 +++++--- 10 files changed, 98 insertions(+), 34 deletions(-) diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp index 50aa06c9c8..f3dc6ed6b7 100644 --- a/src/library/dao/playlistdao.cpp +++ b/src/library/dao/playlistdao.cpp @@ -246,6 +246,25 @@ bool PlaylistDAO::isPlaylistLocked(const int playlistId) const { return false; } +bool PlaylistDAO::clearPlaylist(const int playlistId) { + ScopedTransaction transaction(m_database); + QSqlQuery query(m_database); + query.prepare("DELETE FROM PlaylistTracks WHERE playlist_id = :id"); + query.bindValue(":id", playlistId); + if (!query.exec()) { + LOG_FAILED_QUERY(query); + return false; + } + transaction.commit(); + emit(changed(playlistId)); + return true; +} + +bool PlaylistDAO::replaceTracksInPlaylist(const QList& trackIds, const int playlistId) { + return clearPlaylist(playlistId) + && appendTracksToPlaylist(trackIds, playlistId); +} + bool PlaylistDAO::appendTracksToPlaylist(const QList& trackIds, const int playlistId) { // qDebug() << "PlaylistDAO::appendTracksToPlaylist" // << QThread::currentThread() << m_database.connectionName(); @@ -1011,21 +1030,29 @@ void PlaylistDAO::setAutoDJProcessor(AutoDJProcessor* pAutoDJProcessor) { m_pAutoDJProcessor = pAutoDJProcessor; } -void PlaylistDAO::sendToAutoDJ(const QList& trackIds, bool bTop) { +void PlaylistDAO::sendToAutoDJ(const QList& trackIds, AutoDJSendLoc loc) { int iAutoDJPlaylistId = getPlaylistIdFromName(AUTODJ_TABLE); if (iAutoDJPlaylistId == -1) { return; } - if (bTop) { - int position = 1; - if (m_pAutoDJProcessor && m_pAutoDJProcessor->nextTrackLoaded()) { - // Load track to position two because position one is - // already loaded to the player - position = 2; + + switch (loc) { + case AutoDJSendLoc::TOP: { + int position = 1; + if (m_pAutoDJProcessor && m_pAutoDJProcessor->nextTrackLoaded()) { + // Load track to position two because position one is + // already loaded to the player + position = 2; + } + insertTracksIntoPlaylist(trackIds, iAutoDJPlaylistId, position); + break; } - insertTracksIntoPlaylist(trackIds, iAutoDJPlaylistId, position); - } else { - appendTracksToPlaylist(trackIds, iAutoDJPlaylistId); + case AutoDJSendLoc::BOTTOM: + appendTracksToPlaylist(trackIds, iAutoDJPlaylistId); + break; + case AutoDJSendLoc::REPLACE: + replaceTracksInPlaylist(trackIds, iAutoDJPlaylistId); + break; } } diff --git a/src/library/dao/playlistdao.h b/src/library/dao/playlistdao.h index dd5a221493..caeb014f6d 100644 --- a/src/library/dao/playlistdao.h +++ b/src/library/dao/playlistdao.h @@ -40,6 +40,12 @@ class PlaylistDAO : public QObject, public virtual DAO { PLHT_UNKNOWN = -1 }; + enum class AutoDJSendLoc { + TOP, + BOTTOM, + REPLACE, + }; + PlaylistDAO(QSqlDatabase& database); virtual ~PlaylistDAO(); @@ -57,6 +63,8 @@ class PlaylistDAO : public QObject, public virtual DAO { bool setPlaylistLocked(const int playlistId, const bool locked); // Find out the state of a playlist lock bool isPlaylistLocked(const int playlistId) const; + // Replace all tracks in a playlist by a new list of tracks + bool replaceTracksInPlaylist(const QList& trackIds, const int playlistId); // Append a list of tracks to a playlist bool appendTracksToPlaylist(const QList& trackIds, const int playlistId); // Append a track to a playlist @@ -108,7 +116,7 @@ class PlaylistDAO : public QObject, public virtual DAO { void getPlaylistsTrackIsIn(TrackId trackId, QSet* playlistSet) const; void setAutoDJProcessor(AutoDJProcessor* pAutoDJProcessor); - void sendToAutoDJ(const QList& trackIds, bool bTop); + void sendToAutoDJ(const QList& trackIds, AutoDJSendLoc loc); signals: void added(int playlistId); @@ -120,6 +128,7 @@ class PlaylistDAO : public QObject, public virtual DAO { void lockChanged(int playlistId); private: + bool clearPlaylist(const int playlistId); void removeTracksFromPlaylistsInner(const QStringList& idList); void searchForDuplicateTrack(const int fromPosition, const int toPosition, diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index 4c07e30a42..b1762357b9 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -88,15 +88,19 @@ void DlgAnalysis::loadSelectedTrackToGroup(QString group, bool play) { m_pAnalysisLibraryTableView->loadSelectedTrackToGroup(group, play); } -void DlgAnalysis::slotSendToAutoDJ() { +void DlgAnalysis::slotSendToAutoDJBottom() { // append to auto DJ - m_pAnalysisLibraryTableView->slotSendToAutoDJ(); + m_pAnalysisLibraryTableView->slotSendToAutoDJBottom(); } void DlgAnalysis::slotSendToAutoDJTop() { m_pAnalysisLibraryTableView->slotSendToAutoDJTop(); } +void DlgAnalysis::slotSendToAutoDJReplace() { + m_pAnalysisLibraryTableView->slotSendToAutoDJReplace(); +} + void DlgAnalysis::moveSelection(int delta) { m_pAnalysisLibraryTableView->moveSelection(delta); } diff --git a/src/library/dlganalysis.h b/src/library/dlganalysis.h index 012fadaffa..67c4a67664 100644 --- a/src/library/dlganalysis.h +++ b/src/library/dlganalysis.h @@ -25,8 +25,9 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis, public virtual Libra bool hasFocus() const override; void loadSelectedTrack() override; void loadSelectedTrackToGroup(QString group, bool play) override; - void slotSendToAutoDJ() override; + void slotSendToAutoDJBottom() override; void slotSendToAutoDJTop() override; + void slotSendToAutoDJReplace() override; void moveSelection(int delta) override; inline const QString currentSearch() { return m_pAnalysisLibraryTableModel->currentSearch(); diff --git a/src/library/librarycontrol.cpp b/src/library/librarycontrol.cpp index 2a0c239272..d3d13e3472 100644 --- a/src/library/librarycontrol.cpp +++ b/src/library/librarycontrol.cpp @@ -285,7 +285,7 @@ void LibraryControl::slotAutoDjAddBottom(double v) { if (!activeView) { return; } - activeView->slotSendToAutoDJ(); + activeView->slotSendToAutoDJBottom(); } } diff --git a/src/library/libraryview.h b/src/library/libraryview.h index 1e5a5c03a2..7be3d9d1e5 100644 --- a/src/library/libraryview.h +++ b/src/library/libraryview.h @@ -22,8 +22,9 @@ class LibraryView { // track. Does nothing otherwise. virtual void loadSelectedTrack() {}; - virtual void slotSendToAutoDJ() {}; + virtual void slotSendToAutoDJBottom() {}; virtual void slotSendToAutoDJTop() {}; + virtual void slotSendToAutoDJReplace() {}; // If applicable, requests that the LibraryView load the selected track to // the specified group. Does nothing otherwise. diff --git a/src/library/recording/dlgrecording.cpp b/src/library/recording/dlgrecording.cpp index d55326b90c..e23af25779 100644 --- a/src/library/recording/dlgrecording.cpp +++ b/src/library/recording/dlgrecording.cpp @@ -89,14 +89,18 @@ void DlgRecording::loadSelectedTrack() { m_pTrackTableView->loadSelectedTrack(); } -void DlgRecording::slotSendToAutoDJ() { - m_pTrackTableView->slotSendToAutoDJ(); +void DlgRecording::slotSendToAutoDJBottom() { + m_pTrackTableView->slotSendToAutoDJBottom(); } void DlgRecording::slotSendToAutoDJTop() { m_pTrackTableView->slotSendToAutoDJTop(); } +void DlgRecording::slotSendToAutoDJReplace() { + m_pTrackTableView->slotSendToAutoDJReplace(); +} + void DlgRecording::loadSelectedTrackToGroup(QString group, bool play) { m_pTrackTableView->loadSelectedTrackToGroup(group, play); } diff --git a/src/library/recording/dlgrecording.h b/src/library/recording/dlgrecording.h index caf8fd0547..56c8d9e4aa 100644 --- a/src/library/recording/dlgrecording.h +++ b/src/library/recording/dlgrecording.h @@ -28,8 +28,9 @@ class DlgRecording : public QWidget, public Ui::DlgRecording, public virtual Lib void onShow() override; bool hasFocus() const override; void loadSelectedTrack() override; - void slotSendToAutoDJ() override; + void slotSendToAutoDJBottom() override; void slotSendToAutoDJTop() override; + void slotSendToAutoDJReplace() override; void loadSelectedTrackToGroup(QString group, bool play) override; void moveSelection(int delta) override; inline const QString currentSearch() { return m_proxyModel.currentSearch(); } diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 4e1834ec5c..4d0c8ea9de 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -14,7 +14,6 @@ #include "library/coverartcache.h" #include "library/dlgtrackinfo.h" #include "library/librarytablemodel.h" -#include "library/trackcollection.h" #include "control/controlobject.h" #include "control/controlproxy.h" #include "track/track.h" @@ -117,8 +116,9 @@ WTrackTableView::~WTrackTableView() { delete m_pReloadMetadataAct; delete m_pReloadMetadataFromMusicBrainzAct; delete m_pAddToPreviewDeck; - delete m_pAutoDJAct; + delete m_pAutoDJBottomAct; delete m_pAutoDJTopAct; + delete m_pAutoDJReplaceAct; delete m_pRemoveAct; delete m_pHideAct; delete m_pUnhideAct; @@ -383,13 +383,18 @@ void WTrackTableView::createActions() { connect(m_pFileBrowserAct, SIGNAL(triggered()), this, SLOT(slotOpenInFileBrowser())); - m_pAutoDJAct = new QAction(tr("Add to Auto DJ Queue (bottom)"), this); - connect(m_pAutoDJAct, SIGNAL(triggered()), this, SLOT(slotSendToAutoDJ())); + m_pAutoDJBottomAct = new QAction(tr("Add to Auto-DJ Queue (bottom)"), this); + connect(m_pAutoDJBottomAct, SIGNAL(triggered()), + this, SLOT(slotSendToAutoDJBottom())); m_pAutoDJTopAct = new QAction(tr("Add to Auto DJ Queue (top)"), this); connect(m_pAutoDJTopAct, SIGNAL(triggered()), this, SLOT(slotSendToAutoDJTop())); + m_pAutoDJReplaceAct = new QAction(tr("Add to Auto-DJ Queue (replace)"), this); + connect(m_pAutoDJReplaceAct, SIGNAL(triggered()), + this, SLOT(slotSendToAutoDJReplace())); + m_pReloadMetadataAct = new QAction(tr("Reload Metadata from File"), this); connect(m_pReloadMetadataAct, SIGNAL(triggered()), this, SLOT(slotReloadTrackMetadata())); @@ -465,11 +470,14 @@ void WTrackTableView::slotMouseDoubleClicked(const QModelIndex &index) { } switch (action) { case DlgPrefLibrary::ADD_TRACK_BOTTOM: - sendToAutoDJ(false); // add track to Auto-DJ Queue (bottom) + sendToAutoDJ(PlaylistDAO::AutoDJSendLoc::BOTTOM); // add track to Auto-DJ Queue (bottom) break; case DlgPrefLibrary::ADD_TRACK_TOP: - sendToAutoDJ(true); // add track to Auto-DJ Queue (top) + sendToAutoDJ(PlaylistDAO::AutoDJSendLoc::TOP); // add track to Auto-DJ Queue (top) break; + // case DlgPrefLibrary::ADD_TRACK_REPLACE: + // sendToAutoDJ(PlaylistDAO::AutoDJSendLoc::REPLACE); + // break; default: // load track to next available deck TrackModel* trackModel = getTrackModel(); TrackPointer pTrack; @@ -726,8 +734,9 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { m_pMenu->clear(); if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_ADDTOAUTODJ)) { - m_pMenu->addAction(m_pAutoDJAct); + m_pMenu->addAction(m_pAutoDJBottomAct); m_pMenu->addAction(m_pAutoDJTopAct); + m_pMenu->addAction(m_pAutoDJReplaceAct); m_pMenu->addSeparator(); } @@ -1305,16 +1314,20 @@ void WTrackTableView::loadSelectedTrackToGroup(QString group, bool play) { loadSelectionToGroup(group, play); } -void WTrackTableView::slotSendToAutoDJ() { +void WTrackTableView::slotSendToAutoDJBottom() { // append to auto DJ - sendToAutoDJ(false); // bTop = false + sendToAutoDJ(PlaylistDAO::AutoDJSendLoc::BOTTOM); } void WTrackTableView::slotSendToAutoDJTop() { - sendToAutoDJ(true); // bTop = true + sendToAutoDJ(PlaylistDAO::AutoDJSendLoc::TOP); +} + +void WTrackTableView::slotSendToAutoDJReplace() { + sendToAutoDJ(PlaylistDAO::AutoDJSendLoc::REPLACE); } -void WTrackTableView::sendToAutoDJ(bool bTop) { +void WTrackTableView::sendToAutoDJ(PlaylistDAO::AutoDJSendLoc loc) { if (!modelHasCapabilities(TrackModel::TRACKMODELCAPS_ADDTOAUTODJ)) { return; } @@ -1343,7 +1356,7 @@ void WTrackTableView::sendToAutoDJ(bool bTop) { m_pTrackCollection->getTrackDAO().unhideTracks(trackIds); // TODO(XXX): Care whether the append succeeded. - playlistDao.sendToAutoDJ(trackIds, bTop); + playlistDao.sendToAutoDJ(trackIds, loc); } void WTrackTableView::slotReloadTrackMetadata() { diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 0363e026e2..f230628097 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -9,6 +9,7 @@ #include "library/coverart.h" #include "library/dlgtagfetcher.h" #include "library/libraryview.h" +#include "library/trackcollection.h" #include "library/trackmodel.h" // Can't forward declare enums #include "track/track.h" #include "util/duration.h" @@ -44,8 +45,9 @@ class WTrackTableView : public WLibraryTableView { void slotPurge(); void onSearchStarting(); void onSearchCleared(); - void slotSendToAutoDJ() override; + void slotSendToAutoDJBottom() override; void slotSendToAutoDJTop() override; + void slotSendToAutoDJReplace() override; private slots: void slotRemove(); @@ -79,7 +81,8 @@ class WTrackTableView : public WLibraryTableView { void slotTagFetcherClosed(); private: - void sendToAutoDJ(bool bTop); + + void sendToAutoDJ(PlaylistDAO::AutoDJSendLoc loc); void showTrackInfo(QModelIndex index); void showDlgTagFetcher(QModelIndex index); void createActions(); @@ -128,8 +131,9 @@ class WTrackTableView : public WLibraryTableView { QAction* m_pAddToPreviewDeck; // Send to Auto-DJ Action - QAction *m_pAutoDJAct; + QAction *m_pAutoDJBottomAct; QAction *m_pAutoDJTopAct; + QAction *m_pAutoDJReplaceAct; // Remove from table QAction *m_pRemoveAct; -- cgit v1.2.3