summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/library/autodj/autodjprocessor.cpp2
-rw-r--r--src/library/banshee/bansheefeature.cpp6
-rw-r--r--src/library/banshee/bansheeplaylistmodel.cpp4
-rw-r--r--src/library/banshee/bansheeplaylistmodel.h2
-rw-r--r--src/library/playlisttablemodel.cpp13
-rw-r--r--src/library/playlisttablemodel.h2
-rw-r--r--src/library/trackset/baseplaylistfeature.cpp21
-rw-r--r--src/library/trackset/playlistfeature.cpp2
-rw-r--r--src/library/trackset/setlogfeature.cpp243
-rw-r--r--src/library/trackset/setlogfeature.h7
-rw-r--r--src/track/track.cpp10
-rw-r--r--src/track/track.h2
12 files changed, 197 insertions, 117 deletions
diff --git a/src/library/autodj/autodjprocessor.cpp b/src/library/autodj/autodjprocessor.cpp
index e55e9f6f9a..57014e0641 100644
--- a/src/library/autodj/autodjprocessor.cpp
+++ b/src/library/autodj/autodjprocessor.cpp
@@ -122,7 +122,7 @@ AutoDJProcessor::AutoDJProcessor(
m_transitionTime(kTransitionPreferenceDefault) {
m_pAutoDJTableModel = new PlaylistTableModel(this, pTrackCollectionManager,
"mixxx.db.model.autodj");
- m_pAutoDJTableModel->setTableModel(iAutoDJPlaylistId);
+ m_pAutoDJTableModel->selectPlaylist(iAutoDJPlaylistId);
m_pAutoDJTableModel->select();
m_pShufflePlaylist = new ControlPushButton(
diff --git a/src/library/banshee/bansheefeature.cpp b/src/library/banshee/bansheefeature.cpp
index 860b0d555f..df329cf19f 100644
--- a/src/library/banshee/bansheefeature.cpp
+++ b/src/library/banshee/bansheefeature.cpp
@@ -110,7 +110,7 @@ void BansheeFeature::activate() {
emit featureLoadingFinished(this);
}
- m_pBansheePlaylistModel->setTableModel(0); // Gets the master playlist
+ m_pBansheePlaylistModel->selectPlaylist(0); // Loads the master playlist
emit showTrackModel(m_pBansheePlaylistModel);
emit enableCoverArtDisplay(false);
}
@@ -120,7 +120,7 @@ void BansheeFeature::activateChild(const QModelIndex& index) {
int playlistID = item->getData().toInt();
if (playlistID > 0) {
qDebug() << "Activating " << item->getLabel();
- m_pBansheePlaylistModel->setTableModel(playlistID);
+ m_pBansheePlaylistModel->selectPlaylist(playlistID);
emit showTrackModel(m_pBansheePlaylistModel);
emit enableCoverArtDisplay(false);
}
@@ -141,7 +141,7 @@ void BansheeFeature::appendTrackIdsFromRightClickIndex(QList<TrackId>* trackIds,
new BansheePlaylistModel(this,
m_pLibrary->trackCollectionManager(),
&m_connection);
- pPlaylistModelToAdd->setTableModel(playlistID);
+ pPlaylistModelToAdd->selectPlaylist(playlistID);
pPlaylistModelToAdd->select();
// Copy Tracks
diff --git a/src/library/banshee/bansheeplaylistmodel.cpp b/src/library/banshee/bansheeplaylistmodel.cpp
index 0115f1e63f..8326d91fc1 100644
--- a/src/library/banshee/bansheeplaylistmodel.cpp
+++ b/src/library/banshee/bansheeplaylistmodel.cpp
@@ -86,8 +86,8 @@ void BansheePlaylistModel::dropTempTable() {
}
}
-void BansheePlaylistModel::setTableModel(int playlistId) {
- //qDebug() << "BansheePlaylistModel::setTableModel" << this << playlistId;
+void BansheePlaylistModel::selectPlaylist(int playlistId) {
+ // qDebug() << "BansheePlaylistModel::selectPlaylist" << this << playlistId;
if (m_playlistId == playlistId) {
qDebug() << "Already focused on playlist " << playlistId;
return;
diff --git a/src/library/banshee/bansheeplaylistmodel.h b/src/library/banshee/bansheeplaylistmodel.h
index 261a673363..868a85cfb0 100644
--- a/src/library/banshee/bansheeplaylistmodel.h
+++ b/src/library/banshee/bansheeplaylistmodel.h
@@ -16,7 +16,7 @@ class BansheePlaylistModel final : public BaseSqlTableModel {
BansheePlaylistModel(QObject* pParent, TrackCollectionManager* pTrackCollectionManager, BansheeDbConnection* pConnection);
~BansheePlaylistModel() final;
- void setTableModel(int playlistId);
+ void selectPlaylist(int playlistId);
TrackPointer getTrack(const QModelIndex& index) const final;
TrackId getTrackId(const QModelIndex& index) const final;
diff --git a/src/library/playlisttablemodel.cpp b/src/library/playlisttablemodel.cpp
index db7f37a0ed..c8ce2dead4 100644
--- a/src/library/playlisttablemodel.cpp
+++ b/src/library/playlisttablemodel.cpp
@@ -121,8 +121,8 @@ void PlaylistTableModel::initSortColumnMapping() {
}
}
-void PlaylistTableModel::setTableModel(int playlistId) {
- //qDebug() << "PlaylistTableModel::setTableModel" << playlistId;
+void PlaylistTableModel::selectPlaylist(int playlistId) {
+ // qDebug() << "PlaylistTableModel::selectPlaylist" << playlistId;
if (m_iPlaylistId == playlistId) {
qDebug() << "Already focused on playlist " << playlistId;
return;
@@ -354,12 +354,11 @@ TrackModel::Capabilities PlaylistTableModel::getCapabilities() const {
} else {
caps |= Capability::Remove;
}
- if (PlaylistDAO::PLHT_SET_LOG ==
- m_pTrackCollectionManager->internalCollection()
+ if (m_pTrackCollectionManager->internalCollection()
->getPlaylistDAO()
- .getHiddenType(m_iPlaylistId)) {
- // Disable track reordering for history playlists
- caps &= ~(Capability::ReceiveDrops | Capability::Reorder | Capability::RemovePlaylist);
+ .getHiddenType(m_iPlaylistId) == PlaylistDAO::PLHT_SET_LOG) {
+ // Disable track reordering and adding tracks via drag'n'drop for history playlists
+ caps &= ~(Capability::ReceiveDrops | Capability::Reorder);
}
bool locked = m_pTrackCollectionManager->internalCollection()->getPlaylistDAO().isPlaylistLocked(m_iPlaylistId);
if (locked) {
diff --git a/src/library/playlisttablemodel.h b/src/library/playlisttablemodel.h
index 6aa31ba06d..bc68c9cf7c 100644
--- a/src/library/playlisttablemodel.h
+++ b/src/library/playlisttablemodel.h
@@ -10,7 +10,7 @@ class PlaylistTableModel final : public TrackSetTableModel {
PlaylistTableModel(QObject* parent, TrackCollectionManager* pTrackCollectionManager, const char* settingsNamespace, bool keepDeletedTracks = false);
~PlaylistTableModel() final = default;
- void setTableModel(int playlistId = -1);
+ void selectPlaylist(int playlistId = -1 /* kInvalidPlaylistId */);
int getPlaylist() const {
return m_iPlaylistId;
}
diff --git a/src/library/trackset/baseplaylistfeature.cpp b/src/library/trackset/baseplaylistfeature.cpp
index 46da3f8619..30ca7cc4a9 100644
--- a/src/library/trackset/baseplaylistfeature.cpp
+++ b/src/library/trackset/baseplaylistfeature.cpp
@@ -201,32 +201,30 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) {
//qDebug() << "BasePlaylistFeature::activateChild()" << index;
int playlistId = playlistIdFromIndex(index);
if (playlistId == kInvalidPlaylistId) {
- // This happens if user clicks on group nodes.
- // Doesn't apply to YEAR nodes in the history feature, they are linked to
- // a dummy playlist.
+ // may happen during initialization
return;
}
m_lastClickedIndex = index;
m_lastRightClickedIndex = QModelIndex();
emit saveModelState();
- m_pPlaylistTableModel->setTableModel(playlistId);
+ m_pPlaylistTableModel->selectPlaylist(playlistId);
emit showTrackModel(m_pPlaylistTableModel);
emit enableCoverArtDisplay(true);
}
void BasePlaylistFeature::activatePlaylist(int playlistId) {
+ // qDebug() << "BasePlaylistFeature::activatePlaylist()" << playlistId << index;
VERIFY_OR_DEBUG_ASSERT(playlistId != kInvalidPlaylistId) {
return;
}
QModelIndex index = indexFromPlaylistId(playlistId);
- //qDebug() << "BasePlaylistFeature::activatePlaylist()" << playlistId << index;
VERIFY_OR_DEBUG_ASSERT(index.isValid()) {
return;
}
m_lastClickedIndex = index;
m_lastRightClickedIndex = QModelIndex();
emit saveModelState();
- m_pPlaylistTableModel->setTableModel(playlistId);
+ m_pPlaylistTableModel->selectPlaylist(playlistId);
emit showTrackModel(m_pPlaylistTableModel);
emit enableCoverArtDisplay(true);
// Update selection
@@ -470,13 +468,13 @@ void BasePlaylistFeature::slotImportPlaylistFile(const QString& playlistFile,
// Create a temporary PlaylistTableModel for the Playlist the entries shall be imported to.
// This is used as a proxy object to write to the database.
- // We cannot use m_pPlaylistTableModel since it might have another playlist selected which
+ // We cannot use m_pPlaylistTableModel since it might have another playlist selected which
// is not the playlist that received the right-click.
QScopedPointer<PlaylistTableModel> pPlaylistTableModel(
new PlaylistTableModel(this,
m_pLibrary->trackCollectionManager(),
"mixxx.db.model.playlist_export"));
- pPlaylistTableModel->setTableModel(playlistId);
+ pPlaylistTableModel->selectPlaylist(playlistId);
pPlaylistTableModel->setSort(
pPlaylistTableModel->fieldIndex(
ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION),
@@ -585,7 +583,7 @@ void BasePlaylistFeature::slotExportPlaylist() {
"mixxx.db.model.playlist_export"));
emit saveModelState();
- pPlaylistTableModel->setTableModel(playlistId);
+ pPlaylistTableModel->selectPlaylist(playlistId);
pPlaylistTableModel->setSort(
pPlaylistTableModel->fieldIndex(
ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION),
@@ -631,7 +629,7 @@ void BasePlaylistFeature::slotExportTrackFiles() {
"mixxx.db.model.playlist_export"));
emit saveModelState();
- pPlaylistTableModel->setTableModel(playlistId);
+ pPlaylistTableModel->selectPlaylist(playlistId);
pPlaylistTableModel->setSort(pPlaylistTableModel->fieldIndex(
ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION),
Qt::AscendingOrder);
@@ -720,7 +718,8 @@ void BasePlaylistFeature::htmlLinkClicked(const QUrl& link) {
}
void BasePlaylistFeature::updateChildModel(const QSet<int>& playlistIds) {
- // qDebug() << "BasePlaylistFeature::updateChildModel";
+ // qDebug() << "BasePlaylistFeature::updateChildModel() for"
+ // << playlistIds.count() << "playlist(s)";
if (playlistIds.isEmpty()) {
return;
}
diff --git a/src/library/trackset/playlistfeature.cpp b/src/library/trackset/playlistfeature.cpp
index 435442a31f..a9142bb738 100644
--- a/src/library/trackset/playlistfeature.cpp
+++ b/src/library/trackset/playlistfeature.cpp
@@ -296,7 +296,7 @@ void PlaylistFeature::slotPlaylistTableChanged(int playlistId) {
clearChildModel();
QModelIndex newIndex = constructChildModel(selectedPlaylistId);
- if (newIndex.isValid()) {
+ if (selectedPlaylistId != kInvalidPlaylistId && newIndex.isValid()) {
// If a child index was selected and we got a new valid index select that.
// Else (root item was selected or for some reason no index could be created)
// there's nothing to do: either no child was selected earlier, or the root
diff --git a/src/library/trackset/setlogfeature.cpp b/src/library/trackset/setlogfeature.cpp
index 54f1c4d5a9..83bc757cc7 100644
--- a/src/library/trackset/setlogfeature.cpp
+++ b/src/library/trackset/setlogfeature.cpp
@@ -39,8 +39,8 @@ SetlogFeature::SetlogFeature(
/*keep deleted tracks*/ true),
QStringLiteral("SETLOGHOME"),
QStringLiteral("history")),
- m_playlistId(kInvalidPlaylistId),
- m_placeholderId(kInvalidPlaylistId),
+ m_currentPlaylistId(kInvalidPlaylistId),
+ m_yearNodeId(kInvalidPlaylistId),
m_pLibrary(pLibrary),
m_pConfig(pConfig) {
// remove unneeded entries
@@ -48,13 +48,11 @@ SetlogFeature::SetlogFeature(
// Create empty placeholder playlist for YEAR items
QString placeholderName = "historyPlaceholder";
- m_placeholderId = m_playlistDao.createUniquePlaylist(&placeholderName,
+ m_yearNodeId = m_playlistDao.createUniquePlaylist(&placeholderName,
PlaylistDAO::PLHT_UNKNOWN);
- VERIFY_OR_DEBUG_ASSERT(m_placeholderId != kInvalidPlaylistId) {
- qWarning() << "Failed to create empty History placeholder playlist!";
- }
+ DEBUG_ASSERT(m_yearNodeId != kInvalidPlaylistId);
// just to be safe
- m_playlistDao.setPlaylistLocked(m_placeholderId, true);
+ m_playlistDao.setPlaylistLocked(m_yearNodeId, true);
//construct child model
m_pSidebarModel->setRootItem(TreeItem::newRoot(this));
@@ -66,6 +64,12 @@ SetlogFeature::SetlogFeature(
this,
&SetlogFeature::slotJoinWithPrevious);
+ m_pMarkTracksPlayedAction = new QAction(tr("Mark all tracks played)"), this);
+ connect(m_pMarkTracksPlayedAction,
+ &QAction::triggered,
+ this,
+ &SetlogFeature::slotMarkAllTracksPlayed);
+
m_pStartNewPlaylist = new QAction(tr("Finish current and start new"), this);
connect(m_pStartNewPlaylist,
&QAction::triggered,
@@ -131,10 +135,10 @@ void SetlogFeature::slotDeletePlaylist() {
return;
}
int playlistId = playlistIdFromIndex(m_lastRightClickedIndex);
- if (playlistId == m_playlistId) {
+ if (playlistId == m_currentPlaylistId) {
// the current setlog must not be deleted
return;
- } else if (playlistId == m_placeholderId) {
+ } else if (playlistId == m_yearNodeId) {
// this is a YEAR node
slotDeleteAllUnlockedChildPlaylists();
} else {
@@ -164,15 +168,8 @@ void SetlogFeature::onRightClickChild(const QPoint& globalPos, const QModelIndex
return;
}
- bool locked = m_playlistDao.isPlaylistLocked(playlistId);
- m_pDeletePlaylistAction->setEnabled(!locked);
- m_pRenamePlaylistAction->setEnabled(!locked);
- m_pJoinWithPreviousAction->setEnabled(!locked);
-
- m_pLockPlaylistAction->setText(locked ? tr("Unlock") : tr("Lock"));
-
QMenu menu(m_pSidebarWidget);
- if (playlistId == m_placeholderId) {
+ if (playlistId == m_yearNodeId) {
// this is a YEAR item
menu.addAction(m_pLockAllChildPlaylists);
menu.addAction(m_pUnlockAllChildPlaylists);
@@ -184,30 +181,32 @@ void SetlogFeature::onRightClickChild(const QPoint& globalPos, const QModelIndex
m_pDeletePlaylistAction->setEnabled(!locked);
m_pRenamePlaylistAction->setEnabled(!locked);
m_pJoinWithPreviousAction->setEnabled(!locked);
-
m_pLockPlaylistAction->setText(locked ? tr("Unlock") : tr("Lock"));
+
menu.addAction(m_pAddToAutoDJAction);
menu.addAction(m_pAddToAutoDJTopAction);
menu.addSeparator();
menu.addAction(m_pRenamePlaylistAction);
- if (playlistId != m_playlistId) {
+ if (playlistId != m_currentPlaylistId) {
// Todays playlist should not be locked or deleted
menu.addAction(m_pDeletePlaylistAction);
menu.addAction(m_pLockPlaylistAction);
+ menu.addAction(m_pMarkTracksPlayedAction);
}
if (index.sibling(index.row() + 1, index.column()).isValid()) {
// The very first (oldest) setlog cannot be joint
menu.addAction(m_pJoinWithPreviousAction);
}
- if (playlistId == m_playlistId) {
+ if (playlistId == m_currentPlaylistId) {
// Todays playlists can change !
m_pStartNewPlaylist->setEnabled(
- m_playlistDao.tracksInPlaylist(m_playlistId) > 0);
+ m_playlistDao.tracksInPlaylist(m_currentPlaylistId) > 0);
menu.addAction(m_pStartNewPlaylist);
}
menu.addSeparator();
menu.addAction(m_pExportPlaylistAction);
}
+
menu.exec(globalPos);
}
@@ -217,6 +216,7 @@ void SetlogFeature::onRightClickChild(const QPoint& globalPos, const QModelIndex
/// Use a custom model in the history for grouping by year
/// @param selectedId row which should be selected
QModelIndex SetlogFeature::constructChildModel(int selectedId) {
+ // qDebug() << "SetlogFeature::constructChildModel() id:" << selectedId;
// Setup the sidebar playlist model
QSqlTableModel playlistTableModel(this,
m_pLibrary->trackCollectionManager()->internalCollection()->database());
@@ -270,7 +270,7 @@ QModelIndex SetlogFeature::constructChildModel(int selectedId) {
// create YEAR item the playlist will sorted into
// store id of empty placeholder playlist
auto pNewGroupItem = std::make_unique<TreeItem>(
- QString::number(yearCreated), m_placeholderId);
+ QString::number(yearCreated), m_yearNodeId);
pGroupItem = pNewGroupItem.get();
groups.insert(yearCreated, pGroupItem);
itemList.push_back(std::move(pNewGroupItem));
@@ -319,7 +319,7 @@ QString SetlogFeature::fetchPlaylistLabel(int playlistId) {
}
void SetlogFeature::decorateChild(TreeItem* item, int playlistId) {
- if (playlistId == m_playlistId) {
+ if (playlistId == m_currentPlaylistId) {
item->setIcon(QIcon(":/images/library/ic_library_history_current.svg"));
} else if (m_playlistDao.isPlaylistLocked(playlistId)) {
item->setIcon(QIcon(":/images/library/ic_library_locked.svg"));
@@ -346,10 +346,10 @@ void SetlogFeature::slotGetNewPlaylist() {
}
//qDebug() << "Creating session history playlist name:" << set_log_name;
- m_playlistId = m_playlistDao.createPlaylist(
+ m_currentPlaylistId = m_playlistDao.createPlaylist(
set_log_name, PlaylistDAO::PLHT_SET_LOG);
- if (m_playlistId == kInvalidPlaylistId) {
+ if (m_currentPlaylistId == kInvalidPlaylistId) {
qDebug() << "Setlog playlist Creation Failed";
qDebug() << "An unknown error occurred while creating playlist: "
<< set_log_name;
@@ -358,62 +358,104 @@ void SetlogFeature::slotGetNewPlaylist() {
}
// reload child model again because the 'added' signal fired by PlaylistDAO
- // might have triggered slotPlaylistTableChanged() before m_playlistId was set,
+ // might have triggered slotPlaylistTableChanged() before m_currentPlaylistId was set,
// which causes the wrong playlist being decorated as 'current'
- slotPlaylistTableChanged(m_playlistId);
+ slotPlaylistTableChanged(m_currentPlaylistId);
}
void SetlogFeature::slotJoinWithPrevious() {
- //qDebug() << "slotJoinWithPrevious() row:" << m_lastRightClickedIndex.data();
+ // qDebug() << "SetlogFeature::slotJoinWithPrevious() row:" << m_lastRightClickedIndex.data();
+ if (!m_lastRightClickedIndex.isValid()) {
+ return;
+ }
- if (m_lastRightClickedIndex.isValid()) {
- int currentPlaylistId = m_playlistDao.getPlaylistIdFromName(
- m_lastRightClickedIndex.data().toString());
+ int clickedPlaylistId = playlistIdFromIndex(m_lastRightClickedIndex);
+ if (clickedPlaylistId == kInvalidPlaylistId) {
+ return;
+ }
- if (currentPlaylistId >= 0) {
- bool locked = m_playlistDao.isPlaylistLocked(currentPlaylistId);
+ bool locked = m_playlistDao.isPlaylistLocked(clickedPlaylistId);
+ if (locked) {
+ qDebug() << "Aborting playlist join because playlist"
+ << clickedPlaylistId << "is locked.";
+ return;
+ }
- if (locked) {
- qDebug() << "Skipping playlist deletion because playlist"
- << currentPlaylistId << "is locked.";
- return;
- }
+ // Add every track from right-clicked playlist to that with the next smaller ID
+ int previousPlaylistId = m_playlistDao.getPreviousPlaylist(
+ clickedPlaylistId, PlaylistDAO::PLHT_SET_LOG);
+ if (previousPlaylistId == kInvalidPlaylistId) {
+ qDebug() << "Aborting playlist join because playlist"
+ << clickedPlaylistId << "because there's no previous playlist.";
+ return;
+ }
- // Add every track from right-clicked playlist to that with the next smaller ID
- int previousPlaylistId = m_playlistDao.getPreviousPlaylist(
- currentPlaylistId, PlaylistDAO::PLHT_SET_LOG);
- if (previousPlaylistId >= 0) {
- m_pPlaylistTableModel->setTableModel(previousPlaylistId);
-
- if (currentPlaylistId == m_playlistId) {
- // mark all the Tracks in the previous Playlist as played
-
- m_pPlaylistTableModel->select();
- int rows = m_pPlaylistTableModel->rowCount();
- for (int i = 0; i < rows; ++i) {
- QModelIndex index = m_pPlaylistTableModel->index(i, 0);
- if (index.isValid()) {
- TrackPointer track =
- m_pPlaylistTableModel->getTrack(index);
- // Do not update the play count, just set played status.
- PlayCounter playCounter(track->getPlayCounter());
- playCounter.triggerLastPlayedNow();
- track->setPlayCounter(playCounter);
- }
- }
-
- // Change current setlog
- m_playlistId = previousPlaylistId;
- }
- qDebug() << "slotJoinWithPrevious() current:"
- << currentPlaylistId
- << " previous:" << previousPlaylistId;
- if (m_playlistDao.copyPlaylistTracks(
- currentPlaylistId, previousPlaylistId)) {
- m_playlistDao.deletePlaylist(currentPlaylistId);
- }
+ // Right-clicked playlist may not be loaded. Use a temporary model to
+ // keep sidebar selection and table view in sync
+ QScopedPointer<PlaylistTableModel> pPlaylistTableModel(
+ new PlaylistTableModel(this,
+ m_pLibrary->trackCollectionManager(),
+ "mixxx.db.model.playlist_export"));
+ pPlaylistTableModel->selectPlaylist(previousPlaylistId);
+
+ if (clickedPlaylistId == m_currentPlaylistId) {
+ // mark all the Tracks in the previous Playlist as played
+ pPlaylistTableModel->select();
+ int rows = pPlaylistTableModel->rowCount();
+ for (int i = 0; i < rows; ++i) {
+ QModelIndex index = pPlaylistTableModel->index(i, 0);
+ if (index.isValid()) {
+ TrackPointer pTrack = pPlaylistTableModel->getTrack(index);
+ DEBUG_ASSERT(pTrack != nullptr);
+ // Do not update the play count, just set played status.
+ pTrack->updatePlayedStatusKeepPlayCount(true);
}
}
+
+ // Change current setlog
+ m_currentPlaylistId = previousPlaylistId;
+ }
+ qDebug() << "slotJoinWithPrevious() current:"
+ << clickedPlaylistId
+ << " previous:" << previousPlaylistId;
+ if (m_playlistDao.copyPlaylistTracks(clickedPlaylistId, previousPlaylistId)) {
+ m_playlistDao.deletePlaylist(clickedPlaylistId);
+ }
+}
+
+void SetlogFeature::slotMarkAllTracksPlayed() {
+ // qDebug() << "SetlogFeature::slotMarkAllTracksPlayed()";
+ if (!m_lastRightClickedIndex.isValid()) {
+ return;
+ }
+
+ int clickedPlaylistId = playlistIdFromIndex(m_lastRightClickedIndex);
+ if (clickedPlaylistId == kInvalidPlaylistId) {
+ return;
+ }
+
+ if (clickedPlaylistId == m_currentPlaylistId) {
+ return;
+ }
+
+ // Right-clicked playlist may not be loaded. Use a temporary model to
+ // keep sidebar selection and table view in sync
+ QScopedPointer<PlaylistTableModel> pPlaylistTableModel(
+ new PlaylistTableModel(this,
+ m_pLibrary->trackCollectionManager(),
+ "mixxx.db.model.playlist_export"));
+ pPlaylistTableModel->selectPlaylist(clickedPlaylistId);
+ // mark all the Tracks in the previous Playlist as played
+ pPlaylistTableModel->select();
+ int rows = pPlaylistTableModel->rowCount();
+ for (int i = 0; i < rows; ++i) {
+ QModelIndex index = pPlaylistTableModel->index(i, 0);
+ if (index.isValid()) {
+ TrackPointer pTrack = pPlaylistTableModel->getTrack(index);
+ DEBUG_ASSERT(pTrack != nullptr);
+ // Do not update the play count, just set played status.
+ pTrack->updatePlayedStatusKeepPlayCount(true);
+ }
}
}
@@ -555,7 +597,7 @@ void SetlogFeature::slotPlayingTrackChanged(TrackPointer currentPlayingTrack) {
return;
}
- if (m_pPlaylistTableModel->getPlaylist() == m_playlistId) {
+ if (m_pPlaylistTableModel->getPlaylist() == m_currentPlaylistId) {
// View needs a refresh
bool hasActiveView = false;
@@ -580,12 +622,12 @@ void SetlogFeature::slotPlayingTrackChanged(TrackPointer currentPlayingTrack) {
} else {
// TODO(XXX): Care whether the append succeeded.
m_playlistDao.appendTrackToPlaylist(
- currentPlayingTrackId, m_playlistId);
+ currentPlayingTrackId, m_currentPlaylistId);
}
}
void SetlogFeature::slotPlaylistTableChanged(int playlistId) {
- //qDebug() << "updateChildModel() playlistId:" << playlistId;
+ // qDebug() << "SetlogFeature::slotPlaylistTableChanged() id:" << playlistId;
PlaylistDAO::HiddenType type = m_playlistDao.getHiddenType(playlistId);
if (type != PlaylistDAO::PLHT_SET_LOG &&
type != PlaylistDAO::PLHT_UNKNOWN) { // deleted Playlist
@@ -598,8 +640,8 @@ void SetlogFeature::slotPlaylistTableChanged(int playlistId) {
bool rootWasSelected = false;
if (isChildIndexSelectedInSidebar(m_lastClickedIndex)) {
// a child index was selected (actual playlist or YEAR item)
- int lastClickedPlaylistId = m_pPlaylistTableModel->getPlaylist();
- if (lastClickedPlaylistId == m_placeholderId) {
+ int lastClickedPlaylistId = playlistIdFromIndex(m_lastClickedIndex);
+ if (lastClickedPlaylistId == m_yearNodeId) {
// a YEAR item was selected
selectedYearIndexRow = m_lastClickedIndex.row();
} else if (playlistId == lastClickedPlaylistId &&
@@ -639,7 +681,6 @@ void SetlogFeature::slotPlaylistTableChanged(int playlistId) {
if (newIndex.isValid()) {
emit featureSelect(this, newIndex);
activateChild(newIndex);
- return;
} else if (rootWasSelected) {
// calling featureSelect with invalid index will select the root item
emit featureSelect(this, newIndex);
@@ -648,7 +689,8 @@ void SetlogFeature::slotPlaylistTableChanged(int playlistId) {
}
void SetlogFeature::slotPlaylistContentOrLockChanged(const QSet<int>& playlistIds) {
- // qDebug() << "slotPlaylistContentOrLockChanged() playlistId:" << playlistId;
+ // qDebug() << "slotPlaylistContentOrLockChanged() for"
+ // << playlistIds.count() << "playlist(s)";
QSet<int> idsToBeUpdated;
for (const auto playlistId : qAsConst(playlistIds)) {
if (m_playlistDao.getHiddenType(playlistId) == PlaylistDAO::PLHT_SET_LOG) {
@@ -667,9 +709,31 @@ void SetlogFeature::slotPlaylistTableRenamed(int playlistId, const QString& newN
}
void SetlogFeature::activate() {
- // The root item was clicked, so actuvate the current playlist.
+ // The root item was clicked, so activate the current playlist.
m_lastClickedIndex = m_pSidebarModel->getRootIndex();
- activatePlaylist(m_playlistId);
+ m_lastRightClickedIndex = QModelIndex();
+ activatePlaylist(m_currentPlaylistId);
+}
+
+void SetlogFeature::activateChild(const QModelIndex& index) {
+ // qDebug() << "SetlogFeature::activateChild()" << index;
+ int playlistId = playlistIdFromIndex(index);
+ if (playlistId == kInvalidPlaylistId) {
+ // may happen during initialization
+ return;
+ }
+ m_lastClickedIndex = index;
+ m_lastRightClickedIndex = QModelIndex();
+ emit saveModelState();
+ m_pPlaylistTableModel->selectPlaylist(playlistId);
+ emit showTrackModel(m_pPlaylistTableModel);
+ if (playlistId == m_yearNodeId) {
+ // Disable search and cover art for YEAR items
+ emit disableSearch();
+ emit enableCoverArtDisplay(false);
+ } else {
+ emit enableCoverArtDisplay(true);
+ }
}
void SetlogFeature::activatePlaylist(int playlistId) {
@@ -682,22 +746,25 @@ void SetlogFeature::activatePlaylist(int playlistId) {
return;
}
emit saveModelState();
- m_pPlaylistTableModel->setTableModel(playlistId);
+ m_pPlaylistTableModel->selectPlaylist(playlistId);
emit showTrackModel(m_pPlaylistTableModel);
- emit enableCoverArtDisplay(true);
- // Update sidebar selection only if this is a child, incl. current playlist.
+ // Update sidebar selection only if this is a child, incl. current playlist
+ // and YEAR nodes.
// indexFromPlaylistId() can't be used because, in case the root item was
// selected, that would switch to the 'current' child.
if (m_lastClickedIndex != m_pSidebarModel->getRootIndex()) {
m_lastClickedIndex = index;
+ m_lastRightClickedIndex = QModelIndex();
emit featureSelect(this, index);
- // redundant
- // activateChild(index);
- // TODO(ronso0) Disable search for YEAR items
- // emit disableSearch();
- // emit enableCoverArtDisplay(false);
+ if (playlistId == m_yearNodeId) {
+ // Disable search and cover art for YEAR items
+ emit disableSearch();
+ emit enableCoverArtDisplay(false);
+ return;
+ }
}
+ emit enableCoverArtDisplay(true);
}
QString SetlogFeature::getRootViewHtml() const {
diff --git a/src/library/trackset/setlogfeature.h b/src/library/trackset/setlogfeature.h
index 9d6c622920..c25babad3c 100644
--- a/src/library/trackset/setlogfeature.h
+++ b/src/library/trackset/setlogfeature.h
@@ -27,11 +27,13 @@ class SetlogFeature : public BasePlaylistFeature {
void onRightClick(const QPoint& globalPos) override;
void onRightClickChild(const QPoint& globalPos, const QModelIndex& index) override;
void slotJoinWithPrevious();
+ void slotMarkAllTracksPlayed();
void slotLockAllChildPlaylists();
void slotUnlockAllChildPlaylists();
void slotDeletePlaylist() override;
void slotGetNewPlaylist();
void activate() override;
+ void activateChild(const QModelIndex& index) override;
protected:
QModelIndex constructChildModel(int selectedId);
@@ -52,13 +54,14 @@ class SetlogFeature : public BasePlaylistFeature {
std::list<TrackId> m_recentTracks;
QAction* m_pJoinWithPreviousAction;
+ QAction* m_pMarkTracksPlayedAction;
QAction* m_pStartNewPlaylist;
QAction* m_pLockAllChildPlaylists;
QAction* m_pUnlockAllChildPlaylists;
QAction* m_pDeleteAllChildPlaylists;
- int m_playlistId;
- int m_placeholderId;
+ int m_currentPlaylistId;
+ int m_yearNodeId;
QPointer<WLibrary> m_libraryWidget;
Library* m_pLibrary;
diff --git a/src/track/track.cpp b/src/track/track.cpp
index d73054b7d9..fbc9a2f9ac 100644
--- a/src/track/track.cpp
+++ b/src/track/track.cpp
@@ -755,6 +755,16 @@ void Track::updatePlayCounter(bool bPlayed) {
}
}
+void Track::updatePlayedStatusKeepPlayCount(bool bPlayed) {
+ auto locked = lockMutex(&m_qMutex);
+ PlayCounter playCounter(m_record.getPlayCounter());
+ playCounter.setPlayedFlag(bPlayed);
+ if (compareAndSet(m_record.ptrPlayCounter(), playCounter)) {
+ markDirtyAndUnlock(&locked);
+ emit timesPlayedChanged();
+ }
+}
+
mixxx::RgbColor::optional_t Track::getColor() const {
const auto locked = lockMutex(&m_qMutex);
return m_record.getColor();
diff --git a/src/track/track.h b/src/track/track.h
index e3a960446b..76554eee88 100644
--- a/src/track/track.h
+++ b/src/track/track.h
@@ -248,6 +248,8 @@ class Track : public QObject {
}
// Sets played status and increments or decrements the play count
void updatePlayCounter(bool bPlayed = true);
+ // Sets played status but leaves play count untouched
+ void updatePlayedStatusKeepPlayCount(bool bPlayed);
// Only required for the times_played property
int getTimesPlayed() const {