From 82142751de39be3b4b05895f0fadb50a3481bd69 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sun, 23 Aug 2020 19:37:24 +0200 Subject: [PATCH] Improve playlist autoscrolling Fixes #420 --- src/core/mainwindow.cpp | 24 ++++++++-------- src/core/mainwindow.h | 3 +- src/core/player.cpp | 47 +++++++++++++++++--------------- src/core/player.h | 16 ++++++----- src/playlist/playlist.cpp | 13 +++++---- src/playlist/playlist.h | 13 +++++++-- src/playlist/playlistmanager.cpp | 2 +- src/playlist/playlistmanager.h | 2 +- src/playlist/playlistview.cpp | 21 +++++++------- src/playlist/playlistview.h | 6 ++-- 10 files changed, 81 insertions(+), 66 deletions(-) diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp index 106b9af7c..88765ee14 100644 --- a/src/core/mainwindow.cpp +++ b/src/core/mainwindow.cpp @@ -548,11 +548,11 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd connect(app_->playlist_manager(), SIGNAL(EditingFinished(QModelIndex)), SLOT(PlaylistEditFinished(QModelIndex))); connect(app_->playlist_manager(), SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString))); connect(app_->playlist_manager(), SIGNAL(SummaryTextChanged(QString)), ui_->playlist_summary, SLOT(setText(QString))); - connect(app_->playlist_manager(), SIGNAL(PlayRequested(QModelIndex)), SLOT(PlayIndex(QModelIndex))); + connect(app_->playlist_manager(), SIGNAL(PlayRequested(QModelIndex, Playlist::AutoScroll)), SLOT(PlayIndex(QModelIndex, Playlist::AutoScroll))); connect(ui_->playlist->view(), SIGNAL(doubleClicked(QModelIndex)), SLOT(PlaylistDoubleClick(QModelIndex))); - connect(ui_->playlist->view(), SIGNAL(PlayItem(QModelIndex)), SLOT(PlayIndex(QModelIndex))); - connect(ui_->playlist->view(), SIGNAL(PlayPause()), app_->player(), SLOT(PlayPause())); + connect(ui_->playlist->view(), SIGNAL(PlayItem(QModelIndex, Playlist::AutoScroll)), SLOT(PlayIndex(QModelIndex, Playlist::AutoScroll))); + connect(ui_->playlist->view(), SIGNAL(PlayPause(Playlist::AutoScroll)), app_->player(), SLOT(PlayPause(Playlist::AutoScroll))); connect(ui_->playlist->view(), SIGNAL(RightClicked(QPoint, QModelIndex)), SLOT(PlaylistRightClick(QPoint, QModelIndex))); connect(ui_->playlist->view(), SIGNAL(SeekForward()), app_->player(), SLOT(SeekForward())); connect(ui_->playlist->view(), SIGNAL(SeekBackward()), app_->player(), SLOT(SeekBackward())); @@ -1364,7 +1364,7 @@ void MainWindow::ResumePlaybackSeek(const int playback_position) { } -void MainWindow::PlayIndex(const QModelIndex &idx) { +void MainWindow::PlayIndex(const QModelIndex &idx, Playlist::AutoScroll autoscroll) { if (!idx.isValid()) return; @@ -1375,7 +1375,7 @@ void MainWindow::PlayIndex(const QModelIndex &idx) { } app_->playlist_manager()->SetActiveToCurrent(); - app_->player()->PlayAt(row, Engine::Manual, true); + app_->player()->PlayAt(row, Engine::Manual, autoscroll, true); } @@ -1392,13 +1392,13 @@ void MainWindow::PlaylistDoubleClick(const QModelIndex &idx) { switch (doubleclick_playlist_addmode_) { case BehaviourSettingsPage::PlaylistAddBehaviour_Play: app_->playlist_manager()->SetActiveToCurrent(); - app_->player()->PlayAt(row, Engine::Manual, true); + app_->player()->PlayAt(row, Engine::Manual, Playlist::AutoScroll_Never, true); break; case BehaviourSettingsPage::PlaylistAddBehaviour_Enqueue: app_->playlist_manager()->current()->queue()->ToggleTracks(QModelIndexList() << idx); if (app_->player()->GetState() != Engine::Playing) { - app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), Engine::Manual, true); + app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), Engine::Manual, Playlist::AutoScroll_Never, true); } break; } @@ -1870,10 +1870,10 @@ void MainWindow::PlaylistRightClick(const QPoint &global_pos, const QModelIndex void MainWindow::PlaylistPlay() { if (app_->playlist_manager()->current()->current_row() == playlist_menu_index_.row()) { - app_->player()->PlayPause(); + app_->player()->PlayPause(Playlist::AutoScroll_Never); } else { - PlayIndex(playlist_menu_index_); + PlayIndex(playlist_menu_index_, Playlist::AutoScroll_Never); } } @@ -2161,7 +2161,7 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) { } break; case CommandlineOptions::Player_PlayPause: - app_->player()->PlayPause(); + app_->player()->PlayPause(Playlist::AutoScroll_Maybe); break; case CommandlineOptions::Player_Pause: app_->player()->Pause(); @@ -2236,7 +2236,7 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) { app_->player()->SeekTo(app_->player()->engine()->position_nanosec() / kNsecPerSec + options.seek_by()); } - if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), Engine::Manual, true); + if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), Engine::Manual, Playlist::AutoScroll_Maybe, true); if (options.show_osd()) app_->player()->ShowOSD(); @@ -2740,7 +2740,7 @@ void MainWindow::ShowConsole() { void MainWindow::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Space) { - app_->player()->PlayPause(); + app_->player()->PlayPause(Playlist::AutoScroll_Never); event->accept(); } else if (event->key() == Qt::Key_Left) { diff --git a/src/core/mainwindow.h b/src/core/mainwindow.h index 7449cff91..2c1ff84ec 100644 --- a/src/core/mainwindow.h +++ b/src/core/mainwindow.h @@ -56,6 +56,7 @@ #include "mac_startup.h" #include "osd/osdbase.h" #include "collection/collectionmodel.h" +#include "playlist/playlist.h" #include "playlist/playlistitem.h" #include "settings/settingsdialog.h" #include "settings/behavioursettingspage.h" @@ -173,7 +174,7 @@ class MainWindow : public QMainWindow, public PlatformInterface { void ChangeCollectionQueryMode(QAction *action); - void PlayIndex(const QModelIndex &idx); + void PlayIndex(const QModelIndex &idx, Playlist::AutoScroll autoscroll); void PlaylistDoubleClick(const QModelIndex &idx); void StopAfterCurrent(); diff --git a/src/core/player.cpp b/src/core/player.cpp index 51a977b26..ffffff431 100644 --- a/src/core/player.cpp +++ b/src/core/player.cpp @@ -81,6 +81,7 @@ Player::Player(Application *app, QObject *parent) analyzer_(nullptr), equalizer_(nullptr), stream_change_type_(Engine::First), + autoscroll_(Playlist::AutoScroll_Maybe), last_state_(Engine::Empty), nb_errors_received_(0), volume_before_mute_(100), @@ -265,7 +266,7 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { case UrlHandler::LoadResult::NoMoreTracks: qLog(Debug) << "URL handler for" << result.original_url_ << "said no more tracks" << is_current; - if (is_current) NextItem(stream_change_type_); + if (is_current) NextItem(stream_change_type_, autoscroll_); break; case UrlHandler::LoadResult::TrackAvailable: { @@ -321,7 +322,7 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { if (update) { if (is_current) { item->SetTemporaryMetadata(song); - app_->playlist_manager()->active()->InformOfCurrentSongChange(); + app_->playlist_manager()->active()->InformOfCurrentSongChange(autoscroll_); } else if (is_next) { next_item->SetTemporaryMetadata(song); @@ -352,17 +353,17 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { } -void Player::Next() { NextInternal(Engine::Manual); } +void Player::Next() { NextInternal(Engine::Manual, Playlist::AutoScroll_Always); } -void Player::NextInternal(const Engine::TrackChangeFlags change) { +void Player::NextInternal(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) { - if (HandleStopAfter()) return; + if (HandleStopAfter(autoscroll)) return; - NextItem(change); + NextItem(change, autoscroll); } -void Player::NextItem(const Engine::TrackChangeFlags change) { +void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) { Playlist *active_playlist = app_->playlist_manager()->active(); @@ -391,17 +392,17 @@ void Player::NextItem(const Engine::TrackChangeFlags change) { return; } - PlayAt(i, change, false); + PlayAt(i, change, autoscroll, false); } -bool Player::HandleStopAfter() { +bool Player::HandleStopAfter(const Playlist::AutoScroll autoscroll) { if (app_->playlist_manager()->active()->stop_after_current()) { // Find what the next track would've been, and mark that one as current so it plays next time the user presses Play. const int next_row = app_->playlist_manager()->active()->next_row(); if (next_row != -1) { - app_->playlist_manager()->active()->set_current_row(next_row, true); + app_->playlist_manager()->active()->set_current_row(next_row, autoscroll, true); } app_->playlist_manager()->active()->StopAfter(-1); @@ -419,13 +420,13 @@ void Player::TrackEnded() { app_->playlist_manager()->collection_backend()->IncrementPlayCountAsync(current_item_->Metadata().id()); } - if (HandleStopAfter()) return; + if (HandleStopAfter(Playlist::AutoScroll_Maybe)) return; - NextInternal(Engine::Auto); + NextInternal(Engine::Auto, Playlist::AutoScroll_Maybe); } -void Player::PlayPause() { +void Player::PlayPause(Playlist::AutoScroll autoscroll) { switch (engine_->state()) { case Engine::Paused: @@ -451,7 +452,7 @@ void Player::PlayPause() { int i = app_->playlist_manager()->active()->current_row(); if (i == -1) i = app_->playlist_manager()->active()->last_played_row(); if (i == -1) i = 0; - PlayAt(i, Engine::First, true); + PlayAt(i, Engine::First, autoscroll, true); break; } } @@ -496,21 +497,21 @@ void Player::PreviousItem(const Engine::TrackChangeFlags change) { QDateTime now = QDateTime::currentDateTime(); if (last_pressed_previous_.isValid() && last_pressed_previous_.secsTo(now) >= 2) { last_pressed_previous_ = now; - PlayAt(app_->playlist_manager()->active()->current_row(), change, false); + PlayAt(app_->playlist_manager()->active()->current_row(), change, Playlist::AutoScroll_Always, false); return; } last_pressed_previous_ = now; } int i = app_->playlist_manager()->active()->previous_row(ignore_repeat_track); - app_->playlist_manager()->active()->set_current_row(i); + app_->playlist_manager()->active()->set_current_row(i, Playlist::AutoScroll_Always); if (i == -1) { Stop(); - PlayAt(i, change, true); + PlayAt(i, change, Playlist::AutoScroll_Always, true); return; } - PlayAt(i, change, false); + PlayAt(i, change, Playlist::AutoScroll_Always, false); } @@ -558,7 +559,7 @@ void Player::SetVolume(const int value) { int Player::GetVolume() const { return engine_->volume(); } -void Player::PlayAt(const int index, Engine::TrackChangeFlags change, const bool reshuffle) { +void Player::PlayAt(const int index, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle) { if (current_item_ && change == Engine::Manual && engine_->position_nanosec() != engine_->length_nanosec()) { emit TrackSkipped(current_item_); @@ -569,7 +570,7 @@ void Player::PlayAt(const int index, Engine::TrackChangeFlags change, const bool } if (reshuffle) app_->playlist_manager()->active()->ReshuffleIndices(); - app_->playlist_manager()->active()->set_current_row(index); + app_->playlist_manager()->active()->set_current_row(index, autoscroll); if (app_->playlist_manager()->active()->current_row() == -1) { // Maybe index didn't exist in the playlist. return; @@ -583,12 +584,13 @@ void Player::PlayAt(const int index, Engine::TrackChangeFlags change, const bool if (loading_async_.contains(url)) return; stream_change_type_ = change; + autoscroll_ = autoscroll; HandleLoadResult(url_handlers_[url.scheme()]->StartLoading(url)); } else { qLog(Debug) << "Playing song" << current_item_->Metadata().title() << url; if (current_item_->HasTemporaryMetadata()) { - app_->playlist_manager()->active()->InformOfCurrentSongChange(); + app_->playlist_manager()->active()->InformOfCurrentSongChange(autoscroll); } engine_->Play(url, current_item_->Url(), change, current_item_->Metadata().has_cue(), current_item_->effective_beginning_nanosec(), current_item_->effective_end_nanosec()); } @@ -743,6 +745,7 @@ void Player::TrackAboutToEnd() { // Get the actual track URL rather than the stream URL. if (url_handlers_.contains(url.scheme())) { if (loading_async_.contains(url)) return; + autoscroll_ = Playlist::AutoScroll_Maybe; UrlHandler::LoadResult result = url_handlers_[url.scheme()]->StartLoading(url); switch (result.type_) { case UrlHandler::LoadResult::Error: @@ -781,7 +784,7 @@ void Player::InvalidSongRequested(const QUrl &url) { return; } - NextItem(Engine::Auto); + NextItem(Engine::Auto, Playlist::AutoScroll_Maybe); } diff --git a/src/core/player.h b/src/core/player.h index 702b8f2b9..4d3093032 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -37,6 +37,7 @@ #include "urlhandler.h" #include "engine/engine_fwd.h" #include "engine/enginetype.h" +#include "playlist/playlist.h" #include "playlist/playlistitem.h" #include "settings/behavioursettingspage.h" @@ -72,10 +73,10 @@ class PlayerInterface : public QObject { virtual void ReloadSettings() = 0; // Manual track change to the specified track - virtual void PlayAt(const int row, Engine::TrackChangeFlags change, const bool reshuffle) = 0; + virtual void PlayAt(const int index, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle) = 0; // If there's currently a song playing, pause it, otherwise play the track that was playing last, or the first one on the playlist - virtual void PlayPause() = 0; + virtual void PlayPause(Playlist::AutoScroll autoscroll = Playlist::AutoScroll_Always) = 0; virtual void RestartOrPrevious() = 0; // Skips this track. Might load more of the current radio station. @@ -158,8 +159,8 @@ class Player : public PlayerInterface { public slots: void ReloadSettings() override; - void PlayAt(const int row, Engine::TrackChangeFlags change, const bool reshuffle) override; - void PlayPause() override; + void PlayAt(const int index, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle) override; + void PlayPause(Playlist::AutoScroll autoscroll = Playlist::AutoScroll_Always) override; void RestartOrPrevious() override; void Next() override; void Previous() override; @@ -191,10 +192,10 @@ class Player : public PlayerInterface { void TrackAboutToEnd(); void TrackEnded(); // Play the next item on the playlist - disregarding radio stations like last.fm that might have more tracks. - void NextItem(const Engine::TrackChangeFlags change); + void NextItem(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll); void PreviousItem(const Engine::TrackChangeFlags change); - void NextInternal(const Engine::TrackChangeFlags); + void NextInternal(const Engine::TrackChangeFlags, const Playlist::AutoScroll autoscroll); void FatalError(); void ValidSongRequested(const QUrl&); @@ -205,7 +206,7 @@ class Player : public PlayerInterface { private: // Returns true if we were supposed to stop after this track. - bool HandleStopAfter(); + bool HandleStopAfter(const Playlist::AutoScroll autoscroll); private: Application *app_; @@ -221,6 +222,7 @@ class Player : public PlayerInterface { PlaylistItemPtr current_item_; Engine::TrackChangeFlags stream_change_type_; + Playlist::AutoScroll autoscroll_; Engine::State last_state_; int nb_errors_received_; diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp index 3149d8fc8..582cfe888 100644 --- a/src/playlist/playlist.cpp +++ b/src/playlist/playlist.cpp @@ -580,7 +580,7 @@ int Playlist::previous_row(const bool ignore_repeat_track) const { } -void Playlist::set_current_row(const int i, const bool is_stopping) { +void Playlist::set_current_row(const int i, const AutoScroll autoscroll, const bool is_stopping) { QModelIndex old_current_item_index = current_item_index_; @@ -631,7 +631,7 @@ void Playlist::set_current_row(const int i, const bool is_stopping) { } if (current_item_index_.isValid() && !is_stopping) { - InformOfCurrentSongChange(); + InformOfCurrentSongChange(autoscroll); } if (current_item_index_.isValid()) { @@ -927,7 +927,7 @@ void Playlist::InsertItems(const PlaylistItemList &itemsIn, const int pos, const undo_stack_->push(new PlaylistUndoCommands::InsertItems(this, items, pos, enqueue, enqueue_next)); } - if (play_now) emit PlayRequested(index(start, 0)); + if (play_now) emit PlayRequested(index(start, 0), AutoScroll_Maybe); } @@ -1507,7 +1507,7 @@ void Playlist::SetStreamMetadata(const QUrl &url, const Song &song, const bool m } else { update_scrobble_point = true; - InformOfCurrentSongChange(); + InformOfCurrentSongChange(AutoScroll_Never); } if (update_scrobble_point) UpdateScrobblePoint(); @@ -1613,7 +1613,7 @@ void Playlist::ReloadItems(const QList &rows) { item->Reload(); if (row == current_row()) { - InformOfCurrentSongChange(); + InformOfCurrentSongChange(AutoScroll_Never); } else { emit dataChanged(index(row, 0), index(row, ColumnCount - 1)); @@ -1829,7 +1829,7 @@ void Playlist::ItemChanged(PlaylistItemPtr item) { } -void Playlist::InformOfCurrentSongChange() { +void Playlist::InformOfCurrentSongChange(const AutoScroll autoscroll) { emit dataChanged(index(current_item_index_.row(), 0), index(current_item_index_.row(), ColumnCount - 1)); @@ -1837,6 +1837,7 @@ void Playlist::InformOfCurrentSongChange() { const Song metadata(current_item_metadata()); if (metadata.is_valid()) { emit CurrentSongChanged(metadata); + emit MaybeAutoscroll(autoscroll); } } diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h index 2ed43d131..4c5286eff 100644 --- a/src/playlist/playlist.h +++ b/src/playlist/playlist.h @@ -145,6 +145,12 @@ class Playlist : public QAbstractListModel { Path_Ask_User, // Only used in preferences: to ask user which of the previous values he wants to use. }; + enum AutoScroll { + AutoScroll_Never, + AutoScroll_Maybe, + AutoScroll_Always + }; + static const char *kCddaMimeType; static const char *kRowsMimetype; static const char *kPlayNowMimetype; @@ -250,7 +256,7 @@ class Playlist : public QAbstractListModel { void StopAfter(const int row); void ReloadItems(const QList &rows); - void InformOfCurrentSongChange(); + void InformOfCurrentSongChange(const AutoScroll autoscroll); // Registers an object which will get notifications when new songs are about to be inserted into this playlist. void AddSongInsertVetoListener(SongInsertVetoListener *listener); @@ -279,7 +285,7 @@ class Playlist : public QAbstractListModel { static bool ComparePathDepths(Qt::SortOrder, PlaylistItemPtr, PlaylistItemPtr); public slots: - void set_current_row(const int i, const bool is_stopping = false); + void set_current_row(const int i, const AutoScroll autoscroll = AutoScroll_Maybe, const bool is_stopping = false); void Paused(); void Playing(); void Stopped(); @@ -309,7 +315,8 @@ class Playlist : public QAbstractListModel { void CurrentSongChanged(Song metadata); void SongMetadataChanged(Song metadata); void EditingFinished(QModelIndex idx); - void PlayRequested(QModelIndex idx); + void PlayRequested(QModelIndex idx, Playlist::AutoScroll autoscroll); + void MaybeAutoscroll(Playlist::AutoScroll autoscroll); // Signals that the underlying list of items was changed, meaning that something was added to it, removed from it or the ordering changed. void PlaylistChanged(); diff --git a/src/playlist/playlistmanager.cpp b/src/playlist/playlistmanager.cpp index baaf28b7d..fc90131c9 100644 --- a/src/playlist/playlistmanager.cpp +++ b/src/playlist/playlistmanager.cpp @@ -149,7 +149,7 @@ Playlist *PlaylistManager::AddPlaylist(const int id, const QString &name, const connect(ret, SIGNAL(PlaylistChanged()), SLOT(UpdateSummaryText())); connect(ret, SIGNAL(EditingFinished(QModelIndex)), SIGNAL(EditingFinished(QModelIndex))); connect(ret, SIGNAL(Error(QString)), SIGNAL(Error(QString))); - connect(ret, SIGNAL(PlayRequested(QModelIndex)), SIGNAL(PlayRequested(QModelIndex))); + connect(ret, SIGNAL(PlayRequested(QModelIndex, Playlist::AutoScroll)), SIGNAL(PlayRequested(QModelIndex, Playlist::AutoScroll))); connect(playlist_container_->view(), SIGNAL(ColumnAlignmentChanged(ColumnAlignmentMap)), ret, SLOT(SetColumnAlignment(ColumnAlignmentMap))); connect(app_->current_albumcover_loader(), SIGNAL(AlbumCoverLoaded(Song, AlbumCoverLoaderResult)), ret, SLOT(AlbumCoverLoaded(Song, AlbumCoverLoaderResult))); diff --git a/src/playlist/playlistmanager.h b/src/playlist/playlistmanager.h index 279cf5fa6..dcfd39e04 100644 --- a/src/playlist/playlistmanager.h +++ b/src/playlist/playlistmanager.h @@ -125,7 +125,7 @@ class PlaylistManagerInterface : public QObject { // Signals that one of manager's playlists has changed (new items, new ordering etc.) - the argument shows which. void PlaylistChanged(Playlist *playlist); void EditingFinished(QModelIndex idx); - void PlayRequested(QModelIndex idx); + void PlayRequested(QModelIndex idx, Playlist::AutoScroll autoscroll); }; class PlaylistManager : public PlaylistManagerInterface { diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp index 01809279b..e8f2bf66f 100644 --- a/src/playlist/playlistview.cpp +++ b/src/playlist/playlistview.cpp @@ -266,7 +266,7 @@ void PlaylistView::SetItemDelegates() { void PlaylistView::SetPlaylist(Playlist *playlist) { if (playlist_) { - disconnect(playlist_, SIGNAL(CurrentSongChanged(Song)), this, SLOT(MaybeAutoscroll())); + disconnect(playlist_, SIGNAL(MaybeAutoscroll(Playlist::AutoScroll)), this, SLOT(MaybeAutoscroll(Playlist::AutoScroll))); disconnect(playlist_, SIGNAL(destroyed()), this, SLOT(PlaylistDestroyed())); disconnect(playlist_, SIGNAL(QueueChanged()), this, SLOT(update())); } @@ -279,7 +279,7 @@ void PlaylistView::SetPlaylist(Playlist *playlist) { JumpToLastPlayedTrack(); connect(playlist_, SIGNAL(RestoreFinished()), SLOT(JumpToLastPlayedTrack())); - connect(playlist_, SIGNAL(CurrentSongChanged(Song)), SLOT(MaybeAutoscroll())); + connect(playlist_, SIGNAL(MaybeAutoscroll(Playlist::AutoScroll)), SLOT(MaybeAutoscroll(Playlist::AutoScroll))); connect(playlist_, SIGNAL(destroyed()), SLOT(PlaylistDestroyed())); connect(playlist_, SIGNAL(QueueChanged()), SLOT(update())); @@ -530,7 +530,7 @@ void PlaylistView::showEvent(QShowEvent *) { if (currently_glowing_ && glow_enabled_) glow_timer_.start(1500 / kGlowIntensitySteps, this); - MaybeAutoscroll(); + MaybeAutoscroll(Playlist::AutoScroll_Maybe); } @@ -559,7 +559,7 @@ void PlaylistView::keyPressEvent(QKeyEvent *event) { CopyCurrentSongToClipboard(); } else if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { - if (currentIndex().isValid()) emit PlayItem(currentIndex()); + if (currentIndex().isValid()) emit PlayItem(currentIndex(), Playlist::AutoScroll_Never); event->accept(); } else if (event->modifiers() != Qt::ControlModifier && event->key() == Qt::Key_Space) { @@ -767,25 +767,26 @@ void PlaylistView::InhibitAutoscrollTimeout() { inhibit_autoscroll_ = false; } -void PlaylistView::MaybeAutoscroll() { - if (!inhibit_autoscroll_) JumpToCurrentlyPlayingTrack(); +void PlaylistView::MaybeAutoscroll(const Playlist::AutoScroll autoscroll) { + if (autoscroll == Playlist::AutoScroll_Always || (autoscroll == Playlist::AutoScroll_Maybe && !inhibit_autoscroll_)) JumpToCurrentlyPlayingTrack(); } void PlaylistView::JumpToCurrentlyPlayingTrack() { Q_ASSERT(playlist_); - // Usage of the "Jump to the currently playing track" action shall enable autoscroll - inhibit_autoscroll_ = false; - if (playlist_->current_row() == -1) return; QModelIndex current = playlist_->proxy()->mapFromSource(playlist_->index(playlist_->current_row(), 0)); if (!current.isValid()) return; - currently_autoscrolling_ = true; + if (visibleRegion().boundingRect().contains(visualRect(current))) return; + + // Usage of the "Jump to the currently playing track" action shall enable autoscroll + inhibit_autoscroll_ = false; // Scroll to the item + currently_autoscrolling_ = true; scrollTo(current, QAbstractItemView::PositionAtCenter); currently_autoscrolling_ = false; diff --git a/src/playlist/playlistview.h b/src/playlist/playlistview.h index 17ba6ec07..2d1050e4c 100644 --- a/src/playlist/playlistview.h +++ b/src/playlist/playlistview.h @@ -123,8 +123,8 @@ class PlaylistView : public QTreeView { void edit(const QModelIndex &idx) { return QAbstractItemView::edit(idx); } signals: - void PlayItem(QModelIndex idx); - void PlayPause(); + void PlayItem(QModelIndex idx, Playlist::AutoScroll autoscroll); + void PlayPause(Playlist::AutoScroll autoscroll = Playlist::AutoScroll_Never); void RightClicked(QPoint global_pos, QModelIndex idx); void SeekForward(); void SeekBackward(); @@ -164,7 +164,7 @@ class PlaylistView : public QTreeView { private slots: void InhibitAutoscrollTimeout(); - void MaybeAutoscroll(); + void MaybeAutoscroll(const Playlist::AutoScroll autoscroll); void InvalidateCachedCurrentPixmap(); void PlaylistDestroyed(); void StretchChanged(const bool stretch);