From 9241ba67b3369eeb23b0dce962011795b0f6b466 Mon Sep 17 00:00:00 2001 From: Pavel Potocek Date: Tue, 31 Jan 2017 16:22:58 +0100 Subject: [PATCH 1/4] 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 50aa06c9c8f3..f3dc6ed6b748 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 dd5a22149397..caeb014f6d8d 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 4c07e30a4295..b1762357b9c1 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 012fadaffabc..67c4a676649b 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 2a0c239272a3..d3d13e3472a4 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 1e5a5c03a289..7be3d9d1e528 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 d55326b90c0d..e23af2577942 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 caf8fd054722..56c8d9e4aa19 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 4e1834ec5c6a..4d0c8ea9de0b 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 0363e026e2ff..f2306280970e 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; From 20cd1149536834c293e52d4550695ad1dd1b81a1 Mon Sep 17 00:00:00 2001 From: Pavel Potocek Date: Tue, 31 Jan 2017 17:11:36 +0100 Subject: [PATCH 2/4] When replacing the queue, retain the first track if it is in the deck. --- src/library/dao/playlistdao.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp index f3dc6ed6b748..8a4f97038581 100644 --- a/src/library/dao/playlistdao.cpp +++ b/src/library/dao/playlistdao.cpp @@ -247,10 +247,14 @@ bool PlaylistDAO::isPlaylistLocked(const int playlistId) const { } bool PlaylistDAO::clearPlaylist(const int playlistId) { + int position = + (m_pAutoDJProcessor && m_pAutoDJProcessor->nextTrackLoaded()) ? 2 : 1; ScopedTransaction transaction(m_database); QSqlQuery query(m_database); - query.prepare("DELETE FROM PlaylistTracks WHERE playlist_id = :id"); + query.prepare("DELETE FROM PlaylistTracks " + "WHERE playlist_id=:id AND position>=:pos"); query.bindValue(":id", playlistId); + query.bindValue(":pos", position); if (!query.exec()) { LOG_FAILED_QUERY(query); return false; @@ -1039,12 +1043,10 @@ void PlaylistDAO::sendToAutoDJ(const QList& trackIds, AutoDJSendLoc loc 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; - } + // If the first song is already loaded to the player, + // load tracks to position two + int position = (m_pAutoDJProcessor && + m_pAutoDJProcessor->nextTrackLoaded()) ? 2 : 1; insertTracksIntoPlaylist(trackIds, iAutoDJPlaylistId, position); break; } From ff7e7f0cb913c47d3d98c64feb51656428de722f Mon Sep 17 00:00:00 2001 From: Pavel Potocek Date: Tue, 31 Jan 2017 17:49:16 +0100 Subject: [PATCH 3/4] Fix comments --- src/library/dao/playlistdao.cpp | 1 + src/widget/wtracktableview.cpp | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp index 8a4f97038581..7061e4e3c1be 100644 --- a/src/library/dao/playlistdao.cpp +++ b/src/library/dao/playlistdao.cpp @@ -247,6 +247,7 @@ bool PlaylistDAO::isPlaylistLocked(const int playlistId) const { } bool PlaylistDAO::clearPlaylist(const int playlistId) { + // Retain the first track if it is loaded in a deck int position = (m_pAutoDJProcessor && m_pAutoDJProcessor->nextTrackLoaded()) ? 2 : 1; ScopedTransaction transaction(m_database); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 4d0c8ea9de0b..46baa59833ee 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -475,9 +475,6 @@ void WTrackTableView::slotMouseDoubleClicked(const QModelIndex &index) { case DlgPrefLibrary::ADD_TRACK_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; From 8baaa18133fdac17440d95a17bf09b2a564d01e9 Mon Sep 17 00:00:00 2001 From: Pavel Potocek Date: Tue, 31 Jan 2017 18:14:15 +0100 Subject: [PATCH 4/4] Remove `replaceTracksInPlaylist`, rename `clearPlaylist` and move the autoDJ logic to `sendToAutoDJ`. --- src/library/dao/playlistdao.cpp | 26 ++++++++++---------------- src/library/dao/playlistdao.h | 4 +--- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp index 7061e4e3c1be..665bb28ac93e 100644 --- a/src/library/dao/playlistdao.cpp +++ b/src/library/dao/playlistdao.cpp @@ -246,16 +246,14 @@ bool PlaylistDAO::isPlaylistLocked(const int playlistId) const { return false; } -bool PlaylistDAO::clearPlaylist(const int playlistId) { +bool PlaylistDAO::removeTracksFromPlaylist(const int playlistId, const int startIndex) { // Retain the first track if it is loaded in a deck - int position = - (m_pAutoDJProcessor && m_pAutoDJProcessor->nextTrackLoaded()) ? 2 : 1; ScopedTransaction transaction(m_database); QSqlQuery query(m_database); query.prepare("DELETE FROM PlaylistTracks " "WHERE playlist_id=:id AND position>=:pos"); query.bindValue(":id", playlistId); - query.bindValue(":pos", position); + query.bindValue(":pos", startIndex); if (!query.exec()) { LOG_FAILED_QUERY(query); return false; @@ -265,11 +263,6 @@ bool PlaylistDAO::clearPlaylist(const int 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(); @@ -1041,21 +1034,22 @@ void PlaylistDAO::sendToAutoDJ(const QList& trackIds, AutoDJSendLoc loc return; } + // If the first track is already loaded to the player, + // alter the playlist only below the first track + int position = + (m_pAutoDJProcessor && m_pAutoDJProcessor->nextTrackLoaded()) ? 2 : 1; switch (loc) { - case AutoDJSendLoc::TOP: { - // If the first song is already loaded to the player, - // load tracks to position two - int position = (m_pAutoDJProcessor && - m_pAutoDJProcessor->nextTrackLoaded()) ? 2 : 1; + case AutoDJSendLoc::TOP: insertTracksIntoPlaylist(trackIds, iAutoDJPlaylistId, position); break; - } case AutoDJSendLoc::BOTTOM: appendTracksToPlaylist(trackIds, iAutoDJPlaylistId); break; case AutoDJSendLoc::REPLACE: - replaceTracksInPlaylist(trackIds, iAutoDJPlaylistId); + if (removeTracksFromPlaylist(iAutoDJPlaylistId, position)) { + appendTracksToPlaylist(trackIds, iAutoDJPlaylistId); + } break; } } diff --git a/src/library/dao/playlistdao.h b/src/library/dao/playlistdao.h index caeb014f6d8d..6347955963d1 100644 --- a/src/library/dao/playlistdao.h +++ b/src/library/dao/playlistdao.h @@ -63,8 +63,6 @@ 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 @@ -128,7 +126,7 @@ class PlaylistDAO : public QObject, public virtual DAO { void lockChanged(int playlistId); private: - bool clearPlaylist(const int playlistId); + bool removeTracksFromPlaylist(const int playlistId, const int startIndex); void removeTracksFromPlaylistsInner(const QStringList& idList); void searchForDuplicateTrack(const int fromPosition, const int toPosition,