refactor: split MainWindow constructor into focused setup methods
Extract the ~300-line constructor body into setupDocks(), setupScrobbler(), setupGapless(), setupMpris(), connectBackendSignals(), connectLibrarySignals(), connectContentSignals(), and connectToolbarSignals(). No behavioral changes; all signal/slot connections and widget creation remain identical. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,27 @@ MainWindow::MainWindow(QobuzBackend *backend, QWidget *parent)
|
|||||||
m_content = new MainContent(m_backend, m_queue, this);
|
m_content = new MainContent(m_backend, m_queue, this);
|
||||||
setCentralWidget(m_content);
|
setCentralWidget(m_content);
|
||||||
|
|
||||||
|
setupDocks();
|
||||||
|
setupMenuBar();
|
||||||
|
statusBar()->showMessage(tr("Ready"));
|
||||||
|
|
||||||
|
setupScrobbler();
|
||||||
|
setupGapless();
|
||||||
|
setupMpris();
|
||||||
|
connectBackendSignals();
|
||||||
|
connectLibrarySignals();
|
||||||
|
connectContentSignals();
|
||||||
|
connectToolbarSignals();
|
||||||
|
|
||||||
|
// Apply playback options from saved settings
|
||||||
|
m_backend->setReplayGain(AppSettings::instance().replayGainEnabled());
|
||||||
|
m_backend->setGapless(AppSettings::instance().gaplessEnabled());
|
||||||
|
|
||||||
|
tryRestoreSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setupDocks()
|
||||||
|
{
|
||||||
// ---- Library dock (left) ----
|
// ---- Library dock (left) ----
|
||||||
m_library = new List::Library(m_backend, this);
|
m_library = new List::Library(m_backend, this);
|
||||||
m_libraryDock = new QDockWidget(tr("Library"), this);
|
m_libraryDock = new QDockWidget(tr("Library"), this);
|
||||||
@@ -60,44 +81,95 @@ MainWindow::MainWindow(QobuzBackend *backend, QWidget *parent)
|
|||||||
m_sidePanel = new SidePanel::View(m_backend, m_queue, this);
|
m_sidePanel = new SidePanel::View(m_backend, m_queue, this);
|
||||||
m_sidePanel->hide();
|
m_sidePanel->hide();
|
||||||
addDockWidget(Qt::RightDockWidgetArea, m_sidePanel);
|
addDockWidget(Qt::RightDockWidgetArea, m_sidePanel);
|
||||||
|
}
|
||||||
|
|
||||||
setupMenuBar();
|
void MainWindow::setupScrobbler()
|
||||||
statusBar()->showMessage(tr("Ready"));
|
{
|
||||||
|
m_scrobbler = new LastFmScrobbler(this);
|
||||||
|
connect(m_backend, &QobuzBackend::trackChanged,
|
||||||
|
m_scrobbler, &LastFmScrobbler::onTrackStarted);
|
||||||
|
connect(m_backend, &QobuzBackend::positionChanged,
|
||||||
|
m_scrobbler, &LastFmScrobbler::onPositionChanged);
|
||||||
|
connect(m_backend, &QobuzBackend::trackFinished,
|
||||||
|
m_scrobbler, &LastFmScrobbler::onTrackFinished);
|
||||||
|
|
||||||
// ---- Scrobbler ----
|
// Scrobble the finished track during a gapless transition
|
||||||
m_scrobbler = new LastFmScrobbler(this);
|
connect(m_backend, &QobuzBackend::trackTransitioned,
|
||||||
connect(m_backend, &QobuzBackend::trackChanged,
|
m_scrobbler, &LastFmScrobbler::onTrackFinished);
|
||||||
m_scrobbler, &LastFmScrobbler::onTrackStarted);
|
}
|
||||||
connect(m_backend, &QobuzBackend::positionChanged,
|
|
||||||
m_scrobbler, &LastFmScrobbler::onPositionChanged);
|
|
||||||
connect(m_backend, &QobuzBackend::trackFinished,
|
|
||||||
m_scrobbler, &LastFmScrobbler::onTrackFinished);
|
|
||||||
|
|
||||||
// 1. Scrobble the finished track during a gapless transition
|
void MainWindow::setupGapless()
|
||||||
connect(m_backend, &QobuzBackend::trackTransitioned,
|
{
|
||||||
m_scrobbler, &LastFmScrobbler::onTrackFinished);
|
connect(m_backend, &QobuzBackend::positionChanged, this, [this](quint64 pos, quint64 dur) {
|
||||||
|
if (!AppSettings::instance().gaplessEnabled() || dur == 0) return;
|
||||||
|
|
||||||
// ---- Gapless Signal ----
|
// Trigger prefetch if we pass the 50% mark OR are within 60 seconds of the end
|
||||||
connect(m_backend, &QobuzBackend::positionChanged, this, [this](quint64 pos, quint64 dur) {
|
if ((pos > dur / 2) || (dur > 60 && (dur - pos) <= 60)) {
|
||||||
if (!AppSettings::instance().gaplessEnabled() || dur == 0) return;
|
if (!m_nextTrackPrefetched && m_queue->canGoNext()) {
|
||||||
|
m_nextTrackPrefetched = true; // Lock it so it only fires once
|
||||||
|
|
||||||
// Trigger prefetch if we pass the 50% mark OR are within 60 seconds of the end
|
const auto upcoming = m_queue->upcomingTracks(1);
|
||||||
if ((pos > dur / 2) || (dur > 60 && (dur - pos) <= 60)) {
|
if (!upcoming.isEmpty()) {
|
||||||
if (!m_nextTrackPrefetched && m_queue->canGoNext()) {
|
const qint64 nextId = static_cast<qint64>(upcoming.first()["id"].toDouble());
|
||||||
m_nextTrackPrefetched = true; // Lock it so it only fires once
|
if (nextId > 0) {
|
||||||
|
m_backend->prefetchTrack(nextId, AppSettings::instance().preferredFormat());
|
||||||
const auto upcoming = m_queue->upcomingTracks(1);
|
|
||||||
if (!upcoming.isEmpty()) {
|
|
||||||
const qint64 nextId = static_cast<qint64>(upcoming.first()["id"].toDouble());
|
|
||||||
if (nextId > 0) {
|
|
||||||
m_backend->prefetchTrack(nextId, AppSettings::instance().preferredFormat());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ---- Backend signals ----
|
void MainWindow::setupMpris()
|
||||||
|
{
|
||||||
|
#ifdef USE_DBUS
|
||||||
|
m_mpris = new Mpris(this);
|
||||||
|
connect(m_mpris->player(), &MprisPlayerAdaptor::playRequested, m_backend, [this] {
|
||||||
|
if (m_backend->state() == 2) m_backend->resume();
|
||||||
|
});
|
||||||
|
connect(m_mpris->player(), &MprisPlayerAdaptor::pauseRequested, m_backend, &QobuzBackend::pause);
|
||||||
|
connect(m_mpris->player(), &MprisPlayerAdaptor::playPauseRequested, m_backend, [this] {
|
||||||
|
if (m_backend->state() == 1)
|
||||||
|
m_backend->pause();
|
||||||
|
else
|
||||||
|
m_backend->resume();
|
||||||
|
});
|
||||||
|
connect(m_mpris->player(), &MprisPlayerAdaptor::stopRequested, m_backend, &QobuzBackend::stop);
|
||||||
|
connect(m_mpris->player(), &MprisPlayerAdaptor::nextRequested, this, [this] {
|
||||||
|
if (!m_queue->canGoNext()) return;
|
||||||
|
const qint64 id = static_cast<qint64>(m_queue->advance()["id"].toDouble());
|
||||||
|
if (id > 0) m_backend->playTrack(id);
|
||||||
|
});
|
||||||
|
connect(m_mpris->player(), &MprisPlayerAdaptor::previousRequested, this, [this] {
|
||||||
|
if (!m_queue->canGoPrev()) return;
|
||||||
|
const qint64 id = static_cast<qint64>(m_queue->stepBack()["id"].toDouble());
|
||||||
|
if (id > 0) m_backend->playTrack(id);
|
||||||
|
});
|
||||||
|
connect(m_mpris->player(), &MprisPlayerAdaptor::seekRequested, m_backend, [this](qlonglong offsetMicroseconds) {
|
||||||
|
qint64 newPos = m_backend->position() + (offsetMicroseconds / 1000000LL);
|
||||||
|
if (newPos < 0) newPos = 0;
|
||||||
|
m_backend->seek(newPos);
|
||||||
|
});
|
||||||
|
connect(m_mpris->player(), &MprisPlayerAdaptor::seekToRequested, m_backend, [this](qlonglong positionMicroseconds) {
|
||||||
|
m_backend->seek(positionMicroseconds / 1000000LL);
|
||||||
|
});
|
||||||
|
connect(m_mpris->player(), &MprisPlayerAdaptor::volumeChangeRequested, m_backend, [this](double vol) {
|
||||||
|
m_backend->setVolume(vol * 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_backend, &QobuzBackend::stateChanged, this, [this](const QString &state) {
|
||||||
|
if (state == "playing") m_mpris->player()->setPlaybackStatus("Playing");
|
||||||
|
else if (state == "paused") m_mpris->player()->setPlaybackStatus("Paused");
|
||||||
|
else m_mpris->player()->setPlaybackStatus("Stopped");
|
||||||
|
});
|
||||||
|
connect(m_backend, &QobuzBackend::positionChanged, this, [this](quint64 pos) {
|
||||||
|
m_mpris->player()->updatePosition(pos);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::connectBackendSignals()
|
||||||
|
{
|
||||||
connect(m_backend, &QobuzBackend::loginSuccess, this, &MainWindow::onLoginSuccess);
|
connect(m_backend, &QobuzBackend::loginSuccess, this, &MainWindow::onLoginSuccess);
|
||||||
connect(m_backend, &QobuzBackend::loginError, this, &MainWindow::onLoginError);
|
connect(m_backend, &QobuzBackend::loginError, this, &MainWindow::onLoginError);
|
||||||
connect(m_backend, &QobuzBackend::userLoaded, this, [this](const QJsonObject &user) {
|
connect(m_backend, &QobuzBackend::userLoaded, this, [this](const QJsonObject &user) {
|
||||||
@@ -145,8 +217,10 @@ MainWindow::MainWindow(QobuzBackend *backend, QWidget *parent)
|
|||||||
connect(m_backend, &QobuzBackend::error, this, [this](const QString &msg) {
|
connect(m_backend, &QobuzBackend::error, this, [this](const QString &msg) {
|
||||||
statusBar()->showMessage(tr("Error: %1").arg(msg), 6000);
|
statusBar()->showMessage(tr("Error: %1").arg(msg), 6000);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ---- Library signals ----
|
void MainWindow::connectLibrarySignals()
|
||||||
|
{
|
||||||
connect(m_library, &List::Library::userPlaylistIdsChanged,
|
connect(m_library, &List::Library::userPlaylistIdsChanged,
|
||||||
this, [this](const QSet<qint64> &playlistIds) {
|
this, [this](const QSet<qint64> &playlistIds) {
|
||||||
m_userPlaylistIds = playlistIds;
|
m_userPlaylistIds = playlistIds;
|
||||||
@@ -167,52 +241,6 @@ MainWindow::MainWindow(QobuzBackend *backend, QWidget *parent)
|
|||||||
m_backend->getFavTracks();
|
m_backend->getFavTracks();
|
||||||
statusBar()->showMessage(tr("Loading favorite tracks…"));
|
statusBar()->showMessage(tr("Loading favorite tracks…"));
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef USE_DBUS
|
|
||||||
m_mpris = new Mpris(this);
|
|
||||||
connect(m_mpris->player(), &MprisPlayerAdaptor::playRequested, m_backend, [this] {
|
|
||||||
if (m_backend->state() == 2) m_backend->resume();
|
|
||||||
});
|
|
||||||
connect(m_mpris->player(), &MprisPlayerAdaptor::pauseRequested, m_backend, &QobuzBackend::pause);
|
|
||||||
connect(m_mpris->player(), &MprisPlayerAdaptor::playPauseRequested, m_backend, [this] {
|
|
||||||
if (m_backend->state() == 1)
|
|
||||||
m_backend->pause();
|
|
||||||
else
|
|
||||||
m_backend->resume();
|
|
||||||
});
|
|
||||||
connect(m_mpris->player(), &MprisPlayerAdaptor::stopRequested, m_backend, &QobuzBackend::stop);
|
|
||||||
connect(m_mpris->player(), &MprisPlayerAdaptor::nextRequested, this, [this] {
|
|
||||||
if (!m_queue->canGoNext()) return;
|
|
||||||
const qint64 id = static_cast<qint64>(m_queue->advance()["id"].toDouble());
|
|
||||||
if (id > 0) m_backend->playTrack(id);
|
|
||||||
});
|
|
||||||
connect(m_mpris->player(), &MprisPlayerAdaptor::previousRequested, this, [this] {
|
|
||||||
if (!m_queue->canGoPrev()) return;
|
|
||||||
const qint64 id = static_cast<qint64>(m_queue->stepBack()["id"].toDouble());
|
|
||||||
if (id > 0) m_backend->playTrack(id);
|
|
||||||
});
|
|
||||||
connect(m_mpris->player(), &MprisPlayerAdaptor::seekRequested, m_backend, [this](qlonglong offsetMicroseconds) {
|
|
||||||
qint64 newPos = m_backend->position() + (offsetMicroseconds / 1000000LL);
|
|
||||||
if (newPos < 0) newPos = 0;
|
|
||||||
m_backend->seek(newPos);
|
|
||||||
});
|
|
||||||
connect(m_mpris->player(), &MprisPlayerAdaptor::seekToRequested, m_backend, [this](qlonglong positionMicroseconds) {
|
|
||||||
m_backend->seek(positionMicroseconds / 1000000LL);
|
|
||||||
});
|
|
||||||
connect(m_mpris->player(), &MprisPlayerAdaptor::volumeChangeRequested, m_backend, [this](double vol) {
|
|
||||||
m_backend->setVolume(vol * 100);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_backend, &QobuzBackend::stateChanged, this, [this](const QString &state) {
|
|
||||||
if (state == "playing") m_mpris->player()->setPlaybackStatus("Playing");
|
|
||||||
else if (state == "paused") m_mpris->player()->setPlaybackStatus("Paused");
|
|
||||||
else m_mpris->player()->setPlaybackStatus("Stopped");
|
|
||||||
});
|
|
||||||
connect(m_backend, &QobuzBackend::positionChanged, this, [this](quint64 pos) {
|
|
||||||
m_mpris->player()->updatePosition(pos);
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
|
|
||||||
connect(m_library, &List::Library::favAlbumsRequested, this, [this] {
|
connect(m_library, &List::Library::favAlbumsRequested, this, [this] {
|
||||||
m_showFavAlbumsOnLoad = true;
|
m_showFavAlbumsOnLoad = true;
|
||||||
m_backend->getFavAlbums();
|
m_backend->getFavAlbums();
|
||||||
@@ -236,7 +264,10 @@ MainWindow::MainWindow(QobuzBackend *backend, QWidget *parent)
|
|||||||
m_content->showPlaylistBrowser();
|
m_content->showPlaylistBrowser();
|
||||||
statusBar()->showMessage(tr("Browse Playlists"));
|
statusBar()->showMessage(tr("Browse Playlists"));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::connectContentSignals()
|
||||||
|
{
|
||||||
// ---- Track list → playback / playlist management ----
|
// ---- Track list → playback / playlist management ----
|
||||||
connect(m_content->tracksList(), &List::Tracks::playTrackRequested,
|
connect(m_content->tracksList(), &List::Tracks::playTrackRequested,
|
||||||
this, &MainWindow::onPlayTrackRequested);
|
this, &MainWindow::onPlayTrackRequested);
|
||||||
@@ -300,8 +331,10 @@ MainWindow::MainWindow(QobuzBackend *backend, QWidget *parent)
|
|||||||
// ---- Queue panel ----
|
// ---- Queue panel ----
|
||||||
connect(m_queuePanel, &QueuePanel::skipToTrackRequested,
|
connect(m_queuePanel, &QueuePanel::skipToTrackRequested,
|
||||||
this, &MainWindow::onPlayTrackRequested);
|
this, &MainWindow::onPlayTrackRequested);
|
||||||
|
}
|
||||||
|
|
||||||
// ---- Toolbar toggles ----
|
void MainWindow::connectToolbarSignals()
|
||||||
|
{
|
||||||
connect(m_toolBar, &MainToolBar::searchToggled, this, &MainWindow::onSearchToggled);
|
connect(m_toolBar, &MainToolBar::searchToggled, this, &MainWindow::onSearchToggled);
|
||||||
connect(m_toolBar, &MainToolBar::queueToggled,
|
connect(m_toolBar, &MainToolBar::queueToggled,
|
||||||
this, [this](bool v) { m_queuePanel->setVisible(v); });
|
this, [this](bool v) { m_queuePanel->setVisible(v); });
|
||||||
@@ -314,12 +347,6 @@ MainWindow::MainWindow(QobuzBackend *backend, QWidget *parent)
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
// Apply playback options from saved settings
|
|
||||||
m_backend->setReplayGain(AppSettings::instance().replayGainEnabled());
|
|
||||||
m_backend->setGapless(AppSettings::instance().gaplessEnabled());
|
|
||||||
|
|
||||||
tryRestoreSession();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupMenuBar()
|
void MainWindow::setupMenuBar()
|
||||||
|
|||||||
@@ -72,5 +72,13 @@ private:
|
|||||||
bool m_nextTrackPrefetched = false;
|
bool m_nextTrackPrefetched = false;
|
||||||
|
|
||||||
void setupMenuBar();
|
void setupMenuBar();
|
||||||
|
void setupDocks();
|
||||||
|
void setupScrobbler();
|
||||||
|
void setupGapless();
|
||||||
|
void setupMpris();
|
||||||
|
void connectBackendSignals();
|
||||||
|
void connectLibrarySignals();
|
||||||
|
void connectContentSignals();
|
||||||
|
void connectToolbarSignals();
|
||||||
void tryRestoreSession();
|
void tryRestoreSession();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user