From e32eb63819917e06a3919f2a18ccba2e2ea2c8ef Mon Sep 17 00:00:00 2001 From: ronso0 Date: Fri, 16 Aug 2024 16:43:31 +0200 Subject: [PATCH 1/7] Playlists: paint sidebar items bold immediateley after dropping tracks --- src/library/trackset/baseplaylistfeature.cpp | 2 ++ src/library/trackset/baseplaylistfeature.h | 2 +- src/library/trackset/playlistfeature.cpp | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/library/trackset/baseplaylistfeature.cpp b/src/library/trackset/baseplaylistfeature.cpp index b8c0eaa48f4..b8187939bc0 100644 --- a/src/library/trackset/baseplaylistfeature.cpp +++ b/src/library/trackset/baseplaylistfeature.cpp @@ -772,6 +772,7 @@ void BasePlaylistFeature::updateChildModel(const QSet& playlistIds) { label = fetchPlaylistLabel(id); pChild->setLabel(label); decorateChild(pChild, id); + markTreeItem(pChild); } } } else { @@ -780,6 +781,7 @@ void BasePlaylistFeature::updateChildModel(const QSet& playlistIds) { label = fetchPlaylistLabel(id); pTreeItem->setLabel(label); decorateChild(pTreeItem, id); + markTreeItem(pTreeItem); } } } diff --git a/src/library/trackset/baseplaylistfeature.h b/src/library/trackset/baseplaylistfeature.h index 036529e15a8..0783a2f8868 100644 --- a/src/library/trackset/baseplaylistfeature.h +++ b/src/library/trackset/baseplaylistfeature.h @@ -117,6 +117,7 @@ class BasePlaylistFeature : public BaseTrackSetFeature { PlaylistTableModel* m_pPlaylistTableModel; QSet m_playlistIdsOfSelectedTrack; const QString m_countsDurationTableName; + TrackId m_selectedTrackId; private slots: void slotTrackSelected(TrackId trackId); @@ -129,7 +130,6 @@ class BasePlaylistFeature : public BaseTrackSetFeature { void markTreeItem(TreeItem* pTreeItem); QString fetchPlaylistLabel(int playlistId); - TrackId m_selectedTrackId; const bool m_keepHiddenTracks; }; diff --git a/src/library/trackset/playlistfeature.cpp b/src/library/trackset/playlistfeature.cpp index b8f2d33a121..c6b0292a232 100644 --- a/src/library/trackset/playlistfeature.cpp +++ b/src/library/trackset/playlistfeature.cpp @@ -265,6 +265,9 @@ void PlaylistFeature::slotPlaylistContentOrLockChanged(const QSet& playlist idsToBeUpdated.insert(playlistId); } } + // Update the playlists set to allow toggling bold correctly after + // tracks have been dropped on sidebar items + m_playlistDao.getPlaylistsTrackIsIn(m_selectedTrackId, &m_playlistIdsOfSelectedTrack); updateChildModel(idsToBeUpdated); } From 5177b7c3033b319afd325baee84e3105510444c9 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 22 Aug 2024 16:09:11 +0200 Subject: [PATCH 2/7] (fix) Playlists: update sidebar when dragging tracks into the playlist table fixes #13590 --- src/library/dao/playlistdao.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp index 1aa9539ec91..86e31cee344 100644 --- a/src/library/dao/playlistdao.cpp +++ b/src/library/dao/playlistdao.cpp @@ -796,6 +796,7 @@ int PlaylistDAO::insertTracksIntoPlaylist(const QList& trackIds, emit trackAdded(playlistId, trackId, insertPositon++); } emit tracksAdded(QSet{playlistId}); + emit playlistContentChanged(QSet{playlistId}); return numTracksAdded; } From dd4b814491eb84852207aafded95cc255c390c7f Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 29 Aug 2024 15:22:54 +0200 Subject: [PATCH 3/7] (fix) Track File Export: fix clean up overwrite dialog (had duplicate buttons) --- src/library/export/trackexportdlg.cpp | 37 ++++++++++++++------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/library/export/trackexportdlg.cpp b/src/library/export/trackexportdlg.cpp index 80e0896c5db..bfe85e9c254 100644 --- a/src/library/export/trackexportdlg.cpp +++ b/src/library/export/trackexportdlg.cpp @@ -68,29 +68,30 @@ void TrackExportDlg::slotAskOverwriteMode( QMessageBox::Warning, tr("Overwrite Existing File?"), tr("\"%1\" already exists, overwrite?").arg(filename), - QMessageBox::Cancel | QMessageBox::No | QMessageBox::NoToAll - | QMessageBox::Yes | QMessageBox::YesToAll); - question_box.setDefaultButton(QMessageBox::No); - question_box.addButton(tr("&Overwrite"), QMessageBox::YesRole); - question_box.addButton(tr("Over&write All"), QMessageBox::YesRole); - question_box.addButton(tr("&Skip"), QMessageBox::NoRole); - question_box.addButton(tr("Skip &All"), QMessageBox::NoRole); + QMessageBox::Cancel); - switch (question_box.exec()) { - case QMessageBox::No: + QPushButton* pSkip = question_box.addButton( + tr("&Skip"), QMessageBox::NoRole); + QPushButton* pSkipAll = question_box.addButton( + tr("Skip &All"), QMessageBox::NoRole); + QPushButton* pOverwrite = question_box.addButton( + tr("&Overwrite"), QMessageBox::YesRole); + QPushButton* pOverwriteAll = question_box.addButton( + tr("Over&write All"), QMessageBox::YesRole); + question_box.setDefaultButton(pSkip); + + question_box.exec(); + auto* pBtn = question_box.clickedButton(); + if (pBtn == pSkip) { promise->set_value(TrackExportWorker::OverwriteAnswer::SKIP); - return; - case QMessageBox::NoToAll: + } else if (pBtn == pSkipAll) { promise->set_value(TrackExportWorker::OverwriteAnswer::SKIP_ALL); - return; - case QMessageBox::Yes: + } else if (pBtn == pOverwrite) { promise->set_value(TrackExportWorker::OverwriteAnswer::OVERWRITE); - return; - case QMessageBox::YesToAll: + } else if (pBtn == pOverwriteAll) { promise->set_value(TrackExportWorker::OverwriteAnswer::OVERWRITE_ALL); - return; - case QMessageBox::Cancel: - default: + } else { + // Cancel promise->set_value(TrackExportWorker::OverwriteAnswer::CANCEL); } } From 9954c0257833536f32812fc014f44596bf617d8f Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 29 Aug 2024 15:24:07 +0200 Subject: [PATCH 4/7] (fix) Crates: use right-clicked crate, not selected crate (might be null) --- src/library/export/trackexportworker.cpp | 3 +++ src/library/trackset/baseplaylistfeature.cpp | 6 +++++- src/library/trackset/crate/cratefeature.cpp | 14 +++++++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/library/export/trackexportworker.cpp b/src/library/export/trackexportworker.cpp index d83a8a850dc..c808ec5bd26 100644 --- a/src/library/export/trackexportworker.cpp +++ b/src/library/export/trackexportworker.cpp @@ -26,6 +26,9 @@ QMap createCopylist(const TrackPointerList& tracks) { // efficiently. QMap copylist; for (const auto& pTrack : tracks) { + VERIFY_OR_DEBUG_ASSERT(pTrack != nullptr) { + continue; + } auto fileInfo = pTrack->getFileInfo(); if (fileInfo.resolveCanonicalLocation().isEmpty()) { qWarning() diff --git a/src/library/trackset/baseplaylistfeature.cpp b/src/library/trackset/baseplaylistfeature.cpp index b8c0eaa48f4..185ee1e70c9 100644 --- a/src/library/trackset/baseplaylistfeature.cpp +++ b/src/library/trackset/baseplaylistfeature.cpp @@ -632,7 +632,11 @@ void BasePlaylistFeature::slotExportTrackFiles() { TrackPointerList tracks; for (int i = 0; i < rows; ++i) { QModelIndex index = pPlaylistTableModel->index(i, 0); - tracks.push_back(pPlaylistTableModel->getTrack(index)); + auto pTrack = pPlaylistTableModel->getTrack(index); + VERIFY_OR_DEBUG_ASSERT(pTrack != nullptr) { + continue; + } + tracks.push_back(pTrack); } TrackExportWizard track_export(nullptr, m_pConfig, tracks); diff --git a/src/library/trackset/crate/cratefeature.cpp b/src/library/trackset/crate/cratefeature.cpp index 6b6fbbfce84..777726258c0 100644 --- a/src/library/trackset/crate/cratefeature.cpp +++ b/src/library/trackset/crate/cratefeature.cpp @@ -833,17 +833,25 @@ void CrateFeature::slotExportPlaylist() { } void CrateFeature::slotExportTrackFiles() { + CrateId crateId(crateIdFromIndex(m_lastRightClickedIndex)); + if (!crateId.isValid()) { + return; + } // Create a new table model since the main one might have an active search. QScopedPointer pCrateTableModel( new CrateTableModel(this, m_pLibrary->trackCollectionManager())); - pCrateTableModel->selectCrate(m_crateTableModel.selectedCrate()); + pCrateTableModel->selectCrate(crateId); pCrateTableModel->select(); int rows = pCrateTableModel->rowCount(); TrackPointerList trackpointers; for (int i = 0; i < rows; ++i) { - QModelIndex index = m_crateTableModel.index(i, 0); - trackpointers.push_back(m_crateTableModel.getTrack(index)); + QModelIndex index = pCrateTableModel->index(i, 0); + auto pTrack = pCrateTableModel->getTrack(index); + VERIFY_OR_DEBUG_ASSERT(pTrack != nullptr) { + continue; + } + trackpointers.push_back(pTrack); } TrackExportWizard track_export(nullptr, m_pConfig, trackpointers); From faefe21fc2a96ce8b897042b7335ce7fab05d773 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 29 Aug 2024 15:25:03 +0200 Subject: [PATCH 5/7] (fix) Track File Export: abort if no tracks are selected --- src/library/export/trackexportwizard.cpp | 5 +++++ src/library/trackset/baseplaylistfeature.cpp | 4 ++++ src/library/trackset/crate/cratefeature.cpp | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/src/library/export/trackexportwizard.cpp b/src/library/export/trackexportwizard.cpp index fb0288e5541..4c6a9e40cc3 100644 --- a/src/library/export/trackexportwizard.cpp +++ b/src/library/export/trackexportwizard.cpp @@ -14,6 +14,11 @@ void TrackExportWizard::exportTracks() { } bool TrackExportWizard::selectDestinationDirectory() { + if (m_tracks.isEmpty()) { + qInfo() << "TrackExportWizard: No tracks to export, cancel."; + return false; + } + QString lastExportDirectory = m_pConfig->getValue( ConfigKey("[Library]", "LastTrackCopyDirectory"), QStandardPaths::writableLocation(QStandardPaths::MusicLocation)); diff --git a/src/library/trackset/baseplaylistfeature.cpp b/src/library/trackset/baseplaylistfeature.cpp index 185ee1e70c9..d29e21f8dfa 100644 --- a/src/library/trackset/baseplaylistfeature.cpp +++ b/src/library/trackset/baseplaylistfeature.cpp @@ -639,6 +639,10 @@ void BasePlaylistFeature::slotExportTrackFiles() { tracks.push_back(pTrack); } + if (tracks.isEmpty()) { + return; + } + TrackExportWizard track_export(nullptr, m_pConfig, tracks); track_export.exportTracks(); } diff --git a/src/library/trackset/crate/cratefeature.cpp b/src/library/trackset/crate/cratefeature.cpp index 777726258c0..d31764bcfc4 100644 --- a/src/library/trackset/crate/cratefeature.cpp +++ b/src/library/trackset/crate/cratefeature.cpp @@ -854,6 +854,10 @@ void CrateFeature::slotExportTrackFiles() { trackpointers.push_back(pTrack); } + if (trackpointers.isEmpty()) { + return; + } + TrackExportWizard track_export(nullptr, m_pConfig, trackpointers); track_export.exportTracks(); } From ece92f1e1b7593b13e357b6b1f7eb8ab9bea1e85 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 29 Aug 2024 15:25:46 +0200 Subject: [PATCH 6/7] Track File Export: use mixxx::Logger --- src/library/export/trackexportworker.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/library/export/trackexportworker.cpp b/src/library/export/trackexportworker.cpp index c808ec5bd26..62de53ec459 100644 --- a/src/library/export/trackexportworker.cpp +++ b/src/library/export/trackexportworker.cpp @@ -5,9 +5,12 @@ #include "moc_trackexportworker.cpp" #include "track/track.h" +#include "util/logger.h" namespace { +const mixxx::Logger kLogger("TrackExportWorker"); + QString rewriteFilename(const mixxx::FileInfo& fileinfo, int index) { // We don't have total control over the inputs, so definitely // don't use .arg().arg().arg(). @@ -31,7 +34,7 @@ QMap createCopylist(const TrackPointerList& tracks) { } auto fileInfo = pTrack->getFileInfo(); if (fileInfo.resolveCanonicalLocation().isEmpty()) { - qWarning() + kLogger.warning() << "File not found or inaccessible while exporting" << fileInfo; // Skip file @@ -54,7 +57,7 @@ QMap createCopylist(const TrackPointerList& tracks) { break; } if (++duplicateCounter >= 10000) { - qWarning() + kLogger.warning() << "Failed to generate a unique file name from" << fileName << "while exporting" @@ -103,7 +106,7 @@ void TrackExportWorker::copyFile( switch (makeOverwriteRequest(dest_path)) { case OverwriteAnswer::SKIP: case OverwriteAnswer::SKIP_ALL: - qDebug() << "skipping" << sourceFilename; + kLogger.debug() << "skipping" << sourceFilename; return; case OverwriteAnswer::OVERWRITE: case OverwriteAnswer::OVERWRITE_ALL: @@ -115,32 +118,32 @@ void TrackExportWorker::copyFile( } break; case OverwriteMode::SKIP_ALL: - qDebug() << "skipping" << sourceFilename; + kLogger.debug() << "skipping" << sourceFilename; return; case OverwriteMode::OVERWRITE_ALL:; } // Remove the existing file in preparation for overwriting. QFile dest_file(dest_path); - qDebug() << "Removing existing file" << dest_path; + kLogger.debug() << "removing existing file" << dest_path; if (!dest_file.remove()) { const QString error_message = tr( "Error removing file %1: %2. Stopping.").arg( dest_path, dest_file.errorString()); - qWarning() << error_message; + kLogger.warning() << error_message; m_errorMessage = error_message; stop(); return; } } - qDebug() << "Copying" << sourceFilename << "to" << dest_path; + kLogger.debug() << "copying" << sourceFilename << "to" << dest_path; QFile source_file(sourceFilename); if (!source_file.copy(dest_path)) { const QString error_message = tr( "Error exporting track %1 to %2: %3. Stopping.").arg( sourceFilename, dest_path, source_file.errorString()); - qWarning() << error_message; + kLogger.warning() << error_message; m_errorMessage = error_message; stop(); return; @@ -167,7 +170,7 @@ TrackExportWorker::OverwriteAnswer TrackExportWorker::makeOverwriteRequest( } if (!mode_future.valid()) { - qWarning() << "TrackExportWorker::makeOverwriteRequest invalid answer from future"; + kLogger.warning() << "invalid answer from future"; m_errorMessage = tr("Error exporting tracks"); stop(); return OverwriteAnswer::CANCEL; From 1f438caecebd0613ca7777ce0add3ebde916f84f Mon Sep 17 00:00:00 2001 From: ronso0 Date: Tue, 3 Sep 2024 01:50:08 +0200 Subject: [PATCH 7/7] (fix) WTrackTableView: assert we have a selection model, add getSelectedRows(), early exit slotGuiTick50ms() --- src/library/trackmodel.h | 1 - src/widget/wtracktableview.cpp | 85 +++++++++++++++++++++------------- src/widget/wtracktableview.h | 3 ++ 3 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/library/trackmodel.h b/src/library/trackmodel.h index c811114709a..643c9856285 100644 --- a/src/library/trackmodel.h +++ b/src/library/trackmodel.h @@ -217,7 +217,6 @@ class TrackModel { /// @brief modelKey returns a unique identifier for the model /// @param noSearch don't include the current search in the key - /// @param baseOnly return only a identifier for the whole subsystem virtual QString modelKey(bool noSearch) const = 0; virtual bool getRequireConfirmationToHideRemoveTracks() { diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index d036bb31cfa..92b12a265a1 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -107,6 +107,11 @@ void WTrackTableView::selectionChanged( } void WTrackTableView::slotGuiTick50ms(double /*unused*/) { + if (!isVisible()) { + // Don't proceed if this isn't visible. + return; + } + // if the user is stopped in the same row for more than 0.1 s, // we load un-cached cover arts as well. mixxx::Duration timeDelta = mixxx::Time::elapsed() - m_lastUserAction; @@ -116,7 +121,7 @@ void WTrackTableView::slotGuiTick50ms(double /*unused*/) { // slows down scrolling performance so we wait until the user has // stopped interacting first. if (m_selectionChangedSinceLastGuiTick) { - const QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.size() == 1 && indices.first().isValid()) { // A single track has been selected TrackModel* trackModel = getTrackModel(); @@ -401,7 +406,7 @@ TrackModel::SortColumnId WTrackTableView::getColumnIdFromCurrentIndex() { } void WTrackTableView::assignPreviousTrackColor() { - QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.isEmpty()) { return; } @@ -422,7 +427,7 @@ void WTrackTableView::assignPreviousTrackColor() { } void WTrackTableView::assignNextTrackColor() { - QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.isEmpty()) { return; } @@ -443,7 +448,7 @@ void WTrackTableView::assignNextTrackColor() { } void WTrackTableView::slotPurge() { - QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.isEmpty()) { return; } @@ -457,7 +462,7 @@ void WTrackTableView::slotPurge() { } void WTrackTableView::slotDeleteTracksFromDisk() { - QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.isEmpty()) { return; } @@ -468,7 +473,7 @@ void WTrackTableView::slotDeleteTracksFromDisk() { } void WTrackTableView::slotUnhide() { - QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.isEmpty()) { return; } @@ -505,7 +510,10 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { } event->accept(); // Update track indices in context menu - QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); + if (indices.isEmpty()) { + return; + } m_pTrackMenu->loadTrackModelIndices(indices); saveCurrentIndex(); @@ -576,7 +584,7 @@ void WTrackTableView::mouseMoveEvent(QMouseEvent* pEvent) { if (DragAndDropHelper::mouseMoveInitiatesDrag(pEvent)) { // Iterate over selected rows and append each item's location url to a list. QList locations; - const QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); for (const QModelIndex& index : indices) { if (!index.isValid()) { @@ -635,13 +643,18 @@ void WTrackTableView::dragMoveEvent(QDragMoveEvent * event) { // Drag-and-drop "drop" event. Occurs when something is dropped onto the track table view void WTrackTableView::dropEvent(QDropEvent * event) { TrackModel* trackModel = getTrackModel(); - // We only do things to the TrackModel in this method so if we don't have // one we should just bail. if (!trackModel) { return; } + QItemSelectionModel* pSelectionModel = selectionModel(); + VERIFY_OR_DEBUG_ASSERT(pSelectionModel != nullptr) { + qWarning() << "No selection model available"; + return; + } + if (!event->mimeData()->hasUrls() || trackModel->isLocked()) { event->ignore(); return; @@ -684,7 +697,7 @@ void WTrackTableView::dropEvent(QDropEvent * event) { // Save a list of row (just plain ints) so we don't get screwed over // when the QModelIndexes all become invalid (eg. after moveTrack() // or addTrack()) - const QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); QList selectedRows; for (const QModelIndex& idx : indices) { @@ -764,13 +777,13 @@ void WTrackTableView::dropEvent(QDropEvent * event) { // Highlight the moved rows again (restoring the selection) //QModelIndex newSelectedIndex = destIndex; for (int i = 0; i < selectedRowCount; i++) { - this->selectionModel()->select(model()->index(selectionRestoreStartRow + i, 0), - QItemSelectionModel::Select | QItemSelectionModel::Rows); + pSelectionModel->select(model()->index(selectionRestoreStartRow + i, 0), + QItemSelectionModel::Select | QItemSelectionModel::Rows); } } else { // Drag and drop inside Mixxx is only for few rows, bulks happen here // Reset the selected tracks (if you had any tracks highlighted, it // clears them) - this->selectionModel()->clear(); + pSelectionModel->clear(); // Have to do this here because the index is invalid after // addTrack @@ -811,9 +824,9 @@ void WTrackTableView::dropEvent(QDropEvent * event) { // reordering. (eg. crates don't support reordering/indexes) if (trackModel->hasCapabilities(TrackModel::Capability::Reorder)) { for (int i = selectionStartRow; i < selectionStartRow + numNewRows; i++) { - this->selectionModel()->select(model()->index(i, 0), - QItemSelectionModel::Select | - QItemSelectionModel::Rows); + pSelectionModel->select(model()->index(i, 0), + QItemSelectionModel::Select | + QItemSelectionModel::Rows); } } } @@ -823,6 +836,15 @@ void WTrackTableView::dropEvent(QDropEvent * event) { verticalScrollBar()->setValue(vScrollBarPos); } +QModelIndexList WTrackTableView::getSelectedRows() const { + QItemSelectionModel* pSelectionModel = selectionModel(); + VERIFY_OR_DEBUG_ASSERT(pSelectionModel != nullptr) { + qWarning() << "No selection model available"; + return {}; + } + return pSelectionModel->selectedRows(); +} + TrackModel* WTrackTableView::getTrackModel() const { TrackModel* trackModel = dynamic_cast(model()); return trackModel; @@ -842,7 +864,7 @@ void WTrackTableView::keyPressEvent(QKeyEvent* event) { if (event->modifiers().testFlag(Qt::NoModifier)) { slotMouseDoubleClicked(currentIndex()); } else if ((event->modifiers() & kPropertiesShortcutModifier)) { - QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.length() == 1) { m_pTrackMenu->loadTrackModelIndices(indices); m_pTrackMenu->slotShowDlgTrackInfo(); @@ -902,7 +924,7 @@ void WTrackTableView::resizeEvent(QResizeEvent* event) { } void WTrackTableView::hideOrRemoveSelectedTracks() { - QModelIndexList indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.isEmpty()) { return; } @@ -997,7 +1019,7 @@ void WTrackTableView::hideOrRemoveSelectedTracks() { } void WTrackTableView::activateSelectedTrack() { - auto indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.isEmpty()) { return; } @@ -1005,7 +1027,7 @@ void WTrackTableView::activateSelectedTrack() { } void WTrackTableView::loadSelectedTrackToGroup(const QString& group, bool play) { - auto indices = selectionModel()->selectedRows(); + const QModelIndexList indices = getSelectedRows(); if (indices.isEmpty()) { return; } @@ -1045,21 +1067,14 @@ void WTrackTableView::loadSelectedTrackToGroup(const QString& group, bool play) } QList WTrackTableView::getSelectedTrackIds() const { - QList trackIds; - - QItemSelectionModel* pSelectionModel = selectionModel(); - VERIFY_OR_DEBUG_ASSERT(pSelectionModel != nullptr) { - qWarning() << "No selected tracks available"; - return trackIds; - } - TrackModel* pTrackModel = getTrackModel(); VERIFY_OR_DEBUG_ASSERT(pTrackModel != nullptr) { qWarning() << "No selected tracks available"; - return trackIds; + return {}; } - const QModelIndexList rows = selectionModel()->selectedRows(); + const QModelIndexList rows = getSelectedRows(); + QList trackIds; trackIds.reserve(rows.size()); for (const QModelIndex& row: rows) { const TrackId trackId = pTrackModel->getTrackId(row); @@ -1234,8 +1249,12 @@ void WTrackTableView::doSortByColumn(int headerSection, Qt::SortOrder sortOrder) sortByColumn(headerSection, sortOrder); - QItemSelectionModel* currentSelection = selectionModel(); - currentSelection->reset(); // remove current selection + QItemSelectionModel* pSelectionModel = selectionModel(); + VERIFY_OR_DEBUG_ASSERT(pSelectionModel != nullptr) { + qWarning() << "No selection model available"; + return; + } + pSelectionModel->reset(); // remove current selection // Find previously selected tracks and store respective rows for reselection. QMap selectedRows; @@ -1276,7 +1295,7 @@ void WTrackTableView::doSortByColumn(int headerSection, Qt::SortOrder sortOrder) while (i.hasNext()) { i.next(); QModelIndex tl = itemModel->index(i.key(), 0); - currentSelection->select(tl, QItemSelectionModel::Rows | QItemSelectionModel::Select); + pSelectionModel->select(tl, QItemSelectionModel::Rows | QItemSelectionModel::Select); } // This seems to be broken since at least Qt 5.12: no scrolling is issued diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 7b2d82204d7..8124aaae7fc 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -111,6 +111,9 @@ class WTrackTableView : public WLibraryTableView { // when dragging. void mouseMoveEvent(QMouseEvent *pEvent) override; + // Returns the list of selected rows, or an empty list if none are selected. + QModelIndexList getSelectedRows() const; + // Returns the current TrackModel, or returns NULL if none is set. TrackModel* getTrackModel() const;