feat: expand toolbar now-playing context menu to full track actions

- Replace bare "Go to Album"/"Go to Artist" with the full unified menu:
  Play next, Add to queue, Add to favorites, Open album/artist with
  names, Add to playlist submenu — all with icons
- Wire up new favTrackRequested/addToPlaylistRequested signals through
  MainWindow
- Pass user playlists to toolbar so the submenu is populated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
joren
2026-04-01 00:17:41 +02:00
parent d1a2bed593
commit 9f178a1cc3
3 changed files with 71 additions and 7 deletions

View File

@@ -347,6 +347,15 @@ void MainWindow::connectToolbarSignals()
connect(m_toolBar, &MainToolBar::albumRequested, this, &MainWindow::onSearchAlbumSelected); connect(m_toolBar, &MainToolBar::albumRequested, this, &MainWindow::onSearchAlbumSelected);
connect(m_toolBar, &MainToolBar::artistRequested, this, &MainWindow::onSearchArtistSelected); connect(m_toolBar, &MainToolBar::artistRequested, this, &MainWindow::onSearchArtistSelected);
connect(m_toolBar, &MainToolBar::addToPlaylistRequested,
this, [this](qint64 trackId, qint64 playlistId) {
m_backend->addTrackToPlaylist(playlistId, trackId);
statusBar()->showMessage(tr("Adding track to playlist…"), 3000);
});
connect(m_toolBar, &MainToolBar::favTrackRequested,
this, [this](qint64 trackId) {
m_backend->addFavTrack(trackId);
});
} }
void MainWindow::setupMenuBar() void MainWindow::setupMenuBar()
@@ -629,4 +638,5 @@ void MainWindow::onUserPlaylistsChanged(const QVector<QPair<qint64, QString>> &p
m_userPlaylists = playlists; m_userPlaylists = playlists;
m_content->tracksList()->setUserPlaylists(playlists); m_content->tracksList()->setUserPlaylists(playlists);
m_sidePanel->searchTab()->setUserPlaylists(playlists); m_sidePanel->searchTab()->setUserPlaylists(playlists);
m_toolBar->setUserPlaylists(playlists);
} }

View File

@@ -41,15 +41,62 @@ MainToolBar::MainToolBar(QobuzBackend *backend, PlayQueue *queue, QWidget *paren
connect(m_trackLabel, &QLabel::customContextMenuRequested, connect(m_trackLabel, &QLabel::customContextMenuRequested,
this, [this](const QPoint &pos) { this, [this](const QPoint &pos) {
if (m_currentTrack.isEmpty()) return; if (m_currentTrack.isEmpty()) return;
QMenu menu(this);
const qint64 trackId = static_cast<qint64>(m_currentTrack["id"].toDouble());
const QString albumId = m_currentTrack["album"].toObject()["id"].toString(); const QString albumId = m_currentTrack["album"].toObject()["id"].toString();
const QString albumTitle = m_currentTrack["album"].toObject()["title"].toString();
const qint64 artistId = static_cast<qint64>( const qint64 artistId = static_cast<qint64>(
m_currentTrack["performer"].toObject()["id"].toDouble()); m_currentTrack["performer"].toObject()["id"].toDouble());
if (!albumId.isEmpty()) const QString artistName = m_currentTrack["performer"].toObject()["name"].toString();
menu.addAction(tr("Go to Album"), this, [this, albumId] { emit albumRequested(albumId); });
if (artistId > 0) QMenu menu(this);
menu.addAction(tr("Go to Artist"), this, [this, artistId] { emit artistRequested(artistId); });
if (!menu.isEmpty()) auto *playNext = menu.addAction(QIcon(":/res/icons/media-skip-forward.svg"), tr("Play next"));
auto *addQueue = menu.addAction(QIcon(":/res/icons/media-playlist-append.svg"), tr("Add to queue"));
menu.addSeparator();
auto *addFav = menu.addAction(QIcon(":/res/icons/starred-symbolic.svg"), tr("Add to favorites"));
connect(addFav, &QAction::triggered, this, [this, trackId] {
emit favTrackRequested(trackId);
});
if (!albumId.isEmpty() || artistId > 0)
menu.addSeparator();
if (!albumId.isEmpty()) {
auto *openAlbum = menu.addAction(
QIcon(":/res/icons/view-media-album-cover.svg"),
tr("Open album: %1").arg(QString(albumTitle).replace(QLatin1Char('&'), QStringLiteral("&&"))));
connect(openAlbum, &QAction::triggered, this, [this, albumId] {
emit albumRequested(albumId);
});
}
if (artistId > 0) {
auto *openArtist = menu.addAction(
QIcon(":/res/icons/view-media-artist.svg"),
tr("Open artist: %1").arg(QString(artistName).replace(QLatin1Char('&'), QStringLiteral("&&"))));
connect(openArtist, &QAction::triggered, this, [this, artistId] {
emit artistRequested(artistId);
});
}
if (!m_userPlaylists.isEmpty()) {
menu.addSeparator();
auto *plMenu = menu.addMenu(QIcon(":/res/icons/media-playlist-append.svg"), tr("Add to playlist"));
for (const auto &pl : m_userPlaylists) {
auto *act = plMenu->addAction(QString(pl.second).replace(QLatin1Char('&'), QStringLiteral("&&")));
connect(act, &QAction::triggered, this, [this, trackId, plId = pl.first] {
emit addToPlaylistRequested(trackId, plId);
});
}
}
connect(playNext, &QAction::triggered, this, [this] {
m_queue->playNext(m_currentTrack);
});
connect(addQueue, &QAction::triggered, this, [this] {
m_queue->addToQueue(m_currentTrack);
});
menu.exec(m_trackLabel->mapToGlobal(pos)); menu.exec(m_trackLabel->mapToGlobal(pos));
}); });

View File

@@ -12,6 +12,7 @@
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QJsonObject> #include <QJsonObject>
#include <QPair>
#include <QVector> #include <QVector>
class MainToolBar : public QToolBar class MainToolBar : public QToolBar
@@ -27,11 +28,15 @@ public:
void setQueueToggleChecked(bool checked); void setQueueToggleChecked(bool checked);
void setSearchToggleChecked(bool checked); void setSearchToggleChecked(bool checked);
void setUserPlaylists(const QVector<QPair<qint64, QString>> &playlists) { m_userPlaylists = playlists; }
signals: signals:
void searchToggled(bool visible); void searchToggled(bool visible);
void queueToggled(bool visible); void queueToggled(bool visible);
void albumRequested(const QString &albumId); void albumRequested(const QString &albumId);
void artistRequested(qint64 artistId); void artistRequested(qint64 artistId);
void addToPlaylistRequested(qint64 trackId, qint64 playlistId);
void favTrackRequested(qint64 trackId);
protected: protected:
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
@@ -93,5 +98,7 @@ private:
qint64 m_pendingSeekStartedMs = 0; qint64 m_pendingSeekStartedMs = 0;
bool m_fetchingAutoplay = false; bool m_fetchingAutoplay = false;
QVector<QPair<qint64, QString>> m_userPlaylists;
void requestAutoplaySuggestions(); void requestAutoplaySuggestions();
}; };