From f629d3731530bdfd512a53887abb48b9756087d2 Mon Sep 17 00:00:00 2001 From: Antonio Russo Date: Sat, 24 Feb 2018 11:23:24 -0500 Subject: [PATCH 01/17] Hide TrackSliderPopup on exit from popup The previous behavior exited on leaving TrackSliderSlider, which causes the popup to flicker, as it is shown and hidden rapidly. --- src/widgets/tracksliderpopup.cpp | 5 +++++ src/widgets/tracksliderpopup.h | 1 + src/widgets/tracksliderslider.cpp | 5 ----- src/widgets/tracksliderslider.h | 1 - 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/widgets/tracksliderpopup.cpp b/src/widgets/tracksliderpopup.cpp index d6e9fbc06..b450816e4 100644 --- a/src/widgets/tracksliderpopup.cpp +++ b/src/widgets/tracksliderpopup.cpp @@ -66,6 +66,11 @@ void TrackSliderPopup::paintEvent(QPaintEvent*) { p.drawPixmap(0, 0, pixmap_); } +void TrackSliderPopup::leaveEvent(QEvent* e) { + QWidget::leaveEvent(e); + hide(); +} + void TrackSliderPopup::UpdatePixmap() { const int text_width = qMax(font_metrics_.width(text_), small_font_metrics_.width(small_text_)); diff --git a/src/widgets/tracksliderpopup.h b/src/widgets/tracksliderpopup.h index 97d7d5f7b..a9d3bffce 100644 --- a/src/widgets/tracksliderpopup.h +++ b/src/widgets/tracksliderpopup.h @@ -33,6 +33,7 @@ class TrackSliderPopup : public QWidget { protected: void paintEvent(QPaintEvent*); + void leaveEvent(QEvent*); private: static const int kTextMargin; diff --git a/src/widgets/tracksliderslider.cpp b/src/widgets/tracksliderslider.cpp index 5d05e891e..3ab84c599 100644 --- a/src/widgets/tracksliderslider.cpp +++ b/src/widgets/tracksliderslider.cpp @@ -103,11 +103,6 @@ void TrackSliderSlider::enterEvent(QEvent* e) { } } -void TrackSliderSlider::leaveEvent(QEvent* e) { - QSlider::leaveEvent(e); - popup_->hide(); -} - void TrackSliderSlider::keyPressEvent(QKeyEvent* event) { if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Down) { emit SeekBackward(); diff --git a/src/widgets/tracksliderslider.h b/src/widgets/tracksliderslider.h index 6340ce651..a528e857c 100644 --- a/src/widgets/tracksliderslider.h +++ b/src/widgets/tracksliderslider.h @@ -39,7 +39,6 @@ signals: void mouseMoveEvent(QMouseEvent* e); void wheelEvent(QWheelEvent *e); void enterEvent(QEvent*); - void leaveEvent(QEvent*); void keyPressEvent(QKeyEvent* event); private slots: From 9929450cc23e08705b24a7a25c4a14efbae19857 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Sat, 24 Feb 2018 22:35:27 +0000 Subject: [PATCH 02/17] Revert "Hide TrackSliderPopup on exit from popup" This reverts commit f629d3731530bdfd512a53887abb48b9756087d2. --- src/widgets/tracksliderpopup.cpp | 5 ----- src/widgets/tracksliderpopup.h | 1 - src/widgets/tracksliderslider.cpp | 5 +++++ src/widgets/tracksliderslider.h | 1 + 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/widgets/tracksliderpopup.cpp b/src/widgets/tracksliderpopup.cpp index b450816e4..d6e9fbc06 100644 --- a/src/widgets/tracksliderpopup.cpp +++ b/src/widgets/tracksliderpopup.cpp @@ -66,11 +66,6 @@ void TrackSliderPopup::paintEvent(QPaintEvent*) { p.drawPixmap(0, 0, pixmap_); } -void TrackSliderPopup::leaveEvent(QEvent* e) { - QWidget::leaveEvent(e); - hide(); -} - void TrackSliderPopup::UpdatePixmap() { const int text_width = qMax(font_metrics_.width(text_), small_font_metrics_.width(small_text_)); diff --git a/src/widgets/tracksliderpopup.h b/src/widgets/tracksliderpopup.h index a9d3bffce..97d7d5f7b 100644 --- a/src/widgets/tracksliderpopup.h +++ b/src/widgets/tracksliderpopup.h @@ -33,7 +33,6 @@ class TrackSliderPopup : public QWidget { protected: void paintEvent(QPaintEvent*); - void leaveEvent(QEvent*); private: static const int kTextMargin; diff --git a/src/widgets/tracksliderslider.cpp b/src/widgets/tracksliderslider.cpp index 3ab84c599..5d05e891e 100644 --- a/src/widgets/tracksliderslider.cpp +++ b/src/widgets/tracksliderslider.cpp @@ -103,6 +103,11 @@ void TrackSliderSlider::enterEvent(QEvent* e) { } } +void TrackSliderSlider::leaveEvent(QEvent* e) { + QSlider::leaveEvent(e); + popup_->hide(); +} + void TrackSliderSlider::keyPressEvent(QKeyEvent* event) { if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Down) { emit SeekBackward(); diff --git a/src/widgets/tracksliderslider.h b/src/widgets/tracksliderslider.h index a528e857c..6340ce651 100644 --- a/src/widgets/tracksliderslider.h +++ b/src/widgets/tracksliderslider.h @@ -39,6 +39,7 @@ signals: void mouseMoveEvent(QMouseEvent* e); void wheelEvent(QWheelEvent *e); void enterEvent(QEvent*); + void leaveEvent(QEvent*); void keyPressEvent(QKeyEvent* event); private slots: From 1732e56fe6e6d6df5e0f5aa71f0f1ce924e4fa78 Mon Sep 17 00:00:00 2001 From: Antonio Russo Date: Sat, 24 Feb 2018 15:23:41 -0500 Subject: [PATCH 03/17] Hide TrackSliderPopup on appropriate leaveEvent The previous fix introduces a regression on some platforms which did not generate a leaveEvent with the TrackSliderPopup was displayed. Logic is introduced to identify bonafide mouse motion out of the TrackSliderSlider. --- src/widgets/tracksliderslider.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/widgets/tracksliderslider.cpp b/src/widgets/tracksliderslider.cpp index 5d05e891e..3c5d21191 100644 --- a/src/widgets/tracksliderslider.cpp +++ b/src/widgets/tracksliderslider.cpp @@ -105,7 +105,11 @@ void TrackSliderSlider::enterEvent(QEvent* e) { void TrackSliderSlider::leaveEvent(QEvent* e) { QSlider::leaveEvent(e); - popup_->hide(); + // On some (but not all) systems, displaying the TrackSliderPopup + // generates a leaveEvent. Ensure that this leaveEvent is genuine. + if (!geometry().contains(mapFromGlobal(QCursor::pos()))) { + popup_->hide(); + } } void TrackSliderSlider::keyPressEvent(QKeyEvent* event) { From c9d954f8a3076a1f16d1dda0c79f1d006e3c8df5 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sun, 4 Mar 2018 15:13:34 +0100 Subject: [PATCH 04/17] Fix bug in covermanager not saving album cover to DB. (#6011) * Fix bug in covermanager not saving album cover to DB. --- src/library/librarybackend.cpp | 6 +++--- src/ui/albumcovermanager.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/library/librarybackend.cpp b/src/library/librarybackend.cpp index c8b54044c..dced2a2d8 100644 --- a/src/library/librarybackend.cpp +++ b/src/library/librarybackend.cpp @@ -967,7 +967,7 @@ void LibraryBackend::UpdateManualAlbumArt(const QString& artist, query.SetColumnSpec("ROWID, " + Song::kColumnSpec); query.AddWhere("album", album); - if (!albumartist.isNull()) { + if (!albumartist.isNull() && !albumartist.isEmpty()) { query.AddWhere("albumartist", albumartist); } else if (!artist.isNull()) { query.AddWhere("artist", artist); @@ -987,7 +987,7 @@ void LibraryBackend::UpdateManualAlbumArt(const QString& artist, QString( "UPDATE %1 SET art_manual = :art" " WHERE album = :album AND unavailable = 0").arg(songs_table_)); - if (!albumartist.isNull()) { + if (!albumartist.isNull() && !albumartist.isEmpty()) { sql += " AND albumartist = :albumartist"; } else if (!artist.isNull()) { sql += " AND artist = :artist"; @@ -996,7 +996,7 @@ void LibraryBackend::UpdateManualAlbumArt(const QString& artist, QSqlQuery q(sql, db); q.bindValue(":art", art); q.bindValue(":album", album); - if (!albumartist.isNull()) { + if (!albumartist.isNull() && !albumartist.isEmpty()) { q.bindValue(":albumartist", albumartist); } else if (!artist.isNull()) { q.bindValue(":artist", artist); diff --git a/src/ui/albumcovermanager.cpp b/src/ui/albumcovermanager.cpp index b79a9bcdc..3aca92112 100644 --- a/src/ui/albumcovermanager.cpp +++ b/src/ui/albumcovermanager.cpp @@ -750,7 +750,7 @@ void AlbumCoverManager::LoadSelectedToPlaylist() { void AlbumCoverManager::SaveAndSetCover(QListWidgetItem* item, const QImage& image) { const QString artist = item->data(Role_ArtistName).toString(); - const QString albumartist = item->data(Role_ArtistName).toString(); + const QString albumartist = item->data(Role_AlbumArtistName).toString(); const QString album = item->data(Role_AlbumName).toString(); QString path = From ddfa5e63f1ef0e243a007efbe576fceb9b2442e8 Mon Sep 17 00:00:00 2001 From: Pulfer Date: Sun, 11 Mar 2018 04:35:09 +1000 Subject: [PATCH 05/17] Fix channels loading for DI.fm services after API domain changes (#6023) --- src/internet/digitally/digitallyimportedclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internet/digitally/digitallyimportedclient.cpp b/src/internet/digitally/digitallyimportedclient.cpp index 9609301d6..c5aeb8f84 100644 --- a/src/internet/digitally/digitallyimportedclient.cpp +++ b/src/internet/digitally/digitallyimportedclient.cpp @@ -38,7 +38,7 @@ const char* DigitallyImportedClient::kAuthUrl = "http://api.audioaddict.com/v1/%1/members/authenticate"; const char* DigitallyImportedClient::kChannelListUrl = - "http://api.v2.audioaddict.com/v1/%1/mobile/" + "http://api.audioaddict.com/v1/%1/mobile/" "batch_update?asset_group_key=mobile_icons&stream_set_key="; DigitallyImportedClient::DigitallyImportedClient(const QString& service_name, From c3a7920cb43e56f670c6ade09b1ab7552e22dad5 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sat, 10 Mar 2018 00:09:22 +0100 Subject: [PATCH 06/17] Don't use empty URL's from LastFM. --- src/covers/lastfmcoverprovider.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/covers/lastfmcoverprovider.cpp b/src/covers/lastfmcoverprovider.cpp index a83cc71e3..545e2511f 100644 --- a/src/covers/lastfmcoverprovider.cpp +++ b/src/covers/lastfmcoverprovider.cpp @@ -60,6 +60,7 @@ void LastFmCoverProvider::QueryFinished(QNetworkReply* reply, int id) { result.description = element["artist"].text() + " - " + element["name"].text(); result.image_url = QUrl(element["image size=extralarge"].text()); + if (result.image_url.isEmpty()) continue; results << result; } } else { From de23c3181f5305a1aac9b44e20f6d971b280686a Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sat, 10 Mar 2018 00:11:04 +0100 Subject: [PATCH 07/17] Fix resume playback on start not working. --- src/ui/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 5832942d7..b383b7126 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -1412,7 +1412,7 @@ void MainWindow::closeEvent(QCloseEvent* event) { event->ignore(); SetHiddenInTray(true); } else { - QApplication::quit(); + Exit(); } } From c393926be6be0f242407a128b77d38e72bc676b7 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sat, 10 Mar 2018 00:12:36 +0100 Subject: [PATCH 08/17] Fix background not loading. --- src/playlist/playlistview.cpp | 5 ++++- src/playlist/playlistview.h | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp index 7346c2e9e..c0ceaa96e 100644 --- a/src/playlist/playlistview.cpp +++ b/src/playlist/playlistview.cpp @@ -112,7 +112,9 @@ PlaylistView::PlaylistView(QWidget* parent) upgrading_from_qheaderview_(false), read_only_settings_(true), upgrading_from_version_(-1), + background_initialized_(false), background_image_type_(Default), + //background_image_filename_("_"), blur_radius_(kDefaultBlurRadius), opacity_level_(kDefaultOpacityLevel), previous_background_image_opacity_(0.0), @@ -1127,10 +1129,11 @@ void PlaylistView::ReloadSettings() { // set_background_image when it is not needed, as this will cause the fading // animation to start again. This also avoid to do useless // "force_background_redraw". - if (background_image_filename != background_image_filename_ || + if (background_initialized_ == false || background_image_filename != background_image_filename_ || background_type != background_image_type_ || blur_radius_ != blur_radius || opacity_level_ != opacity_level) { // Store background properties + background_initialized_ = true; background_image_type_ = background_type; background_image_filename_ = background_image_filename; blur_radius_ = blur_radius; diff --git a/src/playlist/playlistview.h b/src/playlist/playlistview.h index 8784ba83a..beea33ea3 100644 --- a/src/playlist/playlistview.h +++ b/src/playlist/playlistview.h @@ -195,15 +195,17 @@ signals: bool read_only_settings_; int upgrading_from_version_; + bool background_initialized_; BackgroundImageType background_image_type_; + // Used if background image is a filemane + QString background_image_filename_; // Stores the background image to be displayed. As we want this image to be // particular (in terms of format, opacity), you should probably use // set_background_image_type instead of modifying background_image_ directly QImage background_image_; int blur_radius_; int opacity_level_; - // Used if background image is a filemane - QString background_image_filename_; + QImage current_song_cover_art_; QPixmap cached_scaled_background_image_; From d33ac6ef819b402d9a2ef7c1d44c278874d88192 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sat, 10 Mar 2018 00:14:08 +0100 Subject: [PATCH 09/17] Fix background not loading. --- src/playlist/playlistview.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp index c0ceaa96e..beec95e33 100644 --- a/src/playlist/playlistview.cpp +++ b/src/playlist/playlistview.cpp @@ -114,7 +114,6 @@ PlaylistView::PlaylistView(QWidget* parent) upgrading_from_version_(-1), background_initialized_(false), background_image_type_(Default), - //background_image_filename_("_"), blur_radius_(kDefaultBlurRadius), opacity_level_(kDefaultOpacityLevel), previous_background_image_opacity_(0.0), From e52c7f6475a989fb83aa74fe11298c2e81ba30b4 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sun, 11 Mar 2018 00:04:49 +0100 Subject: [PATCH 10/17] Fix formatting --- src/playlist/playlistview.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp index beec95e33..389163d48 100644 --- a/src/playlist/playlistview.cpp +++ b/src/playlist/playlistview.cpp @@ -1128,7 +1128,8 @@ void PlaylistView::ReloadSettings() { // set_background_image when it is not needed, as this will cause the fading // animation to start again. This also avoid to do useless // "force_background_redraw". - if (background_initialized_ == false || background_image_filename != background_image_filename_ || + if (background_initialized_ == false || + background_image_filename != background_image_filename_ || background_type != background_image_type_ || blur_radius_ != blur_radius || opacity_level_ != opacity_level) { // Store background properties From 6e387c2578fb7862130ccab4fd1f0caf0a830e49 Mon Sep 17 00:00:00 2001 From: Mark Furneaux Date: Sun, 18 Mar 2018 14:43:44 -0400 Subject: [PATCH 11/17] Initial playlist implementation --- src/playlist/queue.cpp | 12 ++++++++++++ src/playlist/queue.h | 1 + src/ui/mainwindow.cpp | 19 +++++++++++++++++++ src/ui/mainwindow.h | 2 ++ 4 files changed, 34 insertions(+) diff --git a/src/playlist/queue.cpp b/src/playlist/queue.cpp index 76d620a73..6e59c35b1 100644 --- a/src/playlist/queue.cpp +++ b/src/playlist/queue.cpp @@ -151,6 +151,18 @@ void Queue::ToggleTracks(const QModelIndexList& source_indexes) { } } +void Queue::InsertFirst(const QModelIndexList& source_indexes) { + const int rows = source_indexes.count(); + // Enqueue the tracks at the beginning + beginInsertRows(QModelIndex(), 0, rows - 1); + int offset = 0; + for (const QModelIndex& source_index : source_indexes) { + source_indexes_.insert(offset, QPersistentModelIndex(source_index)); + offset++; + } + endInsertRows(); +} + int Queue::PositionOf(const QModelIndex& source_index) const { return mapFromSource(source_index).row(); } diff --git a/src/playlist/queue.h b/src/playlist/queue.h index de1edefd2..77751f0f5 100644 --- a/src/playlist/queue.h +++ b/src/playlist/queue.h @@ -39,6 +39,7 @@ class Queue : public QAbstractProxyModel { // Modify the queue int TakeNext(); void ToggleTracks(const QModelIndexList& source_indexes); + void InsertFirst(const QModelIndexList& source_indexes); void Clear(); void Move(const QList& proxy_rows, int pos); void MoveUp(int row); diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index b383b7126..4c24d00b2 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -677,6 +677,9 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, playlist_queue_ = playlist_menu_->addAction("", this, SLOT(PlaylistQueue())); playlist_queue_->setShortcut(QKeySequence("Ctrl+D")); ui_->playlist->addAction(playlist_queue_); + playlist_queue_play_next_ = playlist_menu_->addAction("", this, SLOT(PlaylistQueuePlayNext())); + playlist_queue_play_next_->setShortcut(QKeySequence("Ctrl+Shift+D")); + ui_->playlist->addAction(playlist_queue_play_next_); playlist_skip_ = playlist_menu_->addAction("", this, SLOT(PlaylistSkip())); ui_->playlist->addAction(playlist_skip_); playlist_menu_->addSeparator(); @@ -1760,6 +1763,11 @@ void MainWindow::PlaylistRightClick(const QPoint& global_pos, else playlist_queue_->setText(tr("Toggle queue status")); + if (in_queue == 0 && not_in_queue == 1) + playlist_queue_play_next_->setText(tr("Play next")); + else if (in_queue == 0 && not_in_queue > 1) + playlist_queue_play_next_->setText(tr("Play selected tracks next")); + if (in_skipped == 1 && not_in_skipped == 0) playlist_skip_->setText(tr("Unskip track")); else if (in_skipped > 1 && not_in_skipped == 0) @@ -2500,6 +2508,17 @@ void MainWindow::PlaylistQueue() { app_->playlist_manager()->current()->queue()->ToggleTracks(indexes); } +void MainWindow::PlaylistQueuePlayNext() { + QModelIndexList indexes; + for (const QModelIndex& proxy_index : + ui_->playlist->view()->selectionModel()->selectedRows()) { + indexes << app_->playlist_manager()->current()->proxy()->mapToSource( + proxy_index); + } + + app_->playlist_manager()->current()->queue()->InsertFirst(indexes); +} + void MainWindow::PlaylistSkip() { QModelIndexList indexes; for (const QModelIndex& proxy_index : diff --git a/src/ui/mainwindow.h b/src/ui/mainwindow.h index 03709ed8a..86f07aad9 100644 --- a/src/ui/mainwindow.h +++ b/src/ui/mainwindow.h @@ -162,6 +162,7 @@ signals: void PlaylistPlay(); void PlaylistStopAfter(); void PlaylistQueue(); + void PlaylistQueuePlayNext(); void PlaylistSkip(); void PlaylistRemoveCurrent(); void PlaylistEditFinished(const QModelIndex& index); @@ -361,6 +362,7 @@ signals: QAction* playlist_delete_; QAction* playlist_open_in_browser_; QAction* playlist_queue_; + QAction* playlist_queue_play_next_; QAction* playlist_skip_; QAction* playlist_add_to_another_; QList playlistitem_actions_; From a789ce82cabc7717118f90b888b473bdda1653b6 Mon Sep 17 00:00:00 2001 From: Mark Furneaux Date: Sun, 18 Mar 2018 22:03:04 -0400 Subject: [PATCH 12/17] Allow playing of tracks already in queue --- src/playlist/queue.cpp | 11 +++++++++++ src/ui/mainwindow.cpp | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/playlist/queue.cpp b/src/playlist/queue.cpp index 6e59c35b1..6c3d88ed6 100644 --- a/src/playlist/queue.cpp +++ b/src/playlist/queue.cpp @@ -152,6 +152,17 @@ void Queue::ToggleTracks(const QModelIndexList& source_indexes) { } void Queue::InsertFirst(const QModelIndexList& source_indexes) { + for (const QModelIndex& source_index : source_indexes) { + QModelIndex proxy_index = mapFromSource(source_index); + if (proxy_index.isValid()) { + // Already in the queue, so remove it to be reinserted later + const int row = proxy_index.row(); + beginRemoveRows(QModelIndex(), row, row); + source_indexes_.removeAt(row); + endRemoveRows(); + } + } + const int rows = source_indexes.count(); // Enqueue the tracks at the beginning beginInsertRows(QModelIndex(), 0, rows - 1); diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 4c24d00b2..fffab3a16 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -1763,10 +1763,10 @@ void MainWindow::PlaylistRightClick(const QPoint& global_pos, else playlist_queue_->setText(tr("Toggle queue status")); - if (in_queue == 0 && not_in_queue == 1) - playlist_queue_play_next_->setText(tr("Play next")); - else if (in_queue == 0 && not_in_queue > 1) + if (all > 1) playlist_queue_play_next_->setText(tr("Play selected tracks next")); + else + playlist_queue_play_next_->setText(tr("Play next")); if (in_skipped == 1 && not_in_skipped == 0) playlist_skip_->setText(tr("Unskip track")); From 3626d8496470b98c3492b03fb106f63d962436d0 Mon Sep 17 00:00:00 2001 From: Mark Furneaux Date: Sun, 18 Mar 2018 22:44:00 -0400 Subject: [PATCH 13/17] Add play next from library --- src/core/mimedata.h | 6 +- src/library/libraryview.cpp | 11 ++++ src/library/libraryview.h | 2 + src/playlist/playlist.cpp | 76 ++++++++++++++---------- src/playlist/playlist.h | 20 +++---- src/playlist/playlistundocommands.cpp | 6 +- src/playlist/playlistundocommands.h | 4 +- src/playlist/songloaderinserter.cpp | 6 +- src/playlist/songloaderinserter.h | 5 +- src/smartplaylists/generatorinserter.cpp | 3 +- src/smartplaylists/generatorinserter.h | 3 +- src/ui/mainwindow.cpp | 2 + 12 files changed, 89 insertions(+), 55 deletions(-) diff --git a/src/core/mimedata.h b/src/core/mimedata.h index 6c4e88420..471574807 100644 --- a/src/core/mimedata.h +++ b/src/core/mimedata.h @@ -27,12 +27,13 @@ class MimeData : public QMimeData { Q_OBJECT public: - MimeData(bool clear = false, bool play_now = false, bool enqueue = false, + MimeData(bool clear = false, bool play_now = false, bool enqueue = false, bool enqueue_next_now = false, bool open_in_new_playlist = false) : override_user_settings_(false), clear_first_(clear), play_now_(play_now), enqueue_now_(enqueue), + enqueue_next_now_(enqueue_next_now), open_in_new_playlist_(open_in_new_playlist), name_for_new_playlist_(QString()), from_doubleclick_(false) {} @@ -53,6 +54,9 @@ class MimeData : public QMimeData { // If this is set then the items are added to the queue after being inserted. bool enqueue_now_; + // If this is set then the items are added to the beginning of the queue after being inserted. + bool enqueue_next_now_; + // If this is set then the items are inserted into a newly created playlist. bool open_in_new_playlist_; diff --git a/src/library/libraryview.cpp b/src/library/libraryview.cpp index 9297d0b4e..1def6bfb8 100644 --- a/src/library/libraryview.cpp +++ b/src/library/libraryview.cpp @@ -392,6 +392,9 @@ void LibraryView::contextMenuEvent(QContextMenuEvent* e) { add_to_playlist_enqueue_ = context_menu_->addAction( IconLoader::Load("go-next", IconLoader::Base), tr("Queue track"), this, SLOT(AddToPlaylistEnqueue())); + add_to_playlist_enqueue_next_ = context_menu_->addAction( + IconLoader::Load("go-next", IconLoader::Base), tr("Play next"), this, + SLOT(AddToPlaylistEnqueueNext())); context_menu_->addSeparator(); search_for_this_ = context_menu_->addAction( IconLoader::Load("system-search", IconLoader::Base), @@ -616,6 +619,14 @@ void LibraryView::AddToPlaylistEnqueue() { emit AddToPlaylistSignal(data); } +void LibraryView::AddToPlaylistEnqueueNext() { + QMimeData* data = model()->mimeData(selectedIndexes()); + if (MimeData* mime_data = qobject_cast(data)) { + mime_data->enqueue_next_now_ = true; + } + emit AddToPlaylistSignal(data); +} + void LibraryView::OpenInNewPlaylist() { QMimeData* data = model()->mimeData(selectedIndexes()); if (MimeData* mime_data = qobject_cast(data)) { diff --git a/src/library/libraryview.h b/src/library/libraryview.h index a747d0aa0..46945cb2d 100644 --- a/src/library/libraryview.h +++ b/src/library/libraryview.h @@ -92,6 +92,7 @@ signals: void Load(); void AddToPlaylist(); void AddToPlaylistEnqueue(); + void AddToPlaylistEnqueueNext(); void OpenInNewPlaylist(); void Organise(); void CopyToDevice(); @@ -131,6 +132,7 @@ signals: QAction* load_; QAction* add_to_playlist_; QAction* add_to_playlist_enqueue_; + QAction* add_to_playlist_enqueue_next_; QAction* open_in_new_playlist_; QAction* organise_; QAction* copy_to_device_; diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp index 80a17807e..ac69dd2c6 100644 --- a/src/playlist/playlist.cpp +++ b/src/playlist/playlist.cpp @@ -152,14 +152,14 @@ Playlist::~Playlist() { template void Playlist::InsertSongItems(const SongList& songs, int pos, bool play_now, - bool enqueue) { + bool enqueue, bool enqueue_next) { PlaylistItemList items; for (const Song& song : songs) { items << PlaylistItemPtr(new T(song)); } - InsertItems(items, pos, play_now, enqueue); + InsertItems(items, pos, play_now, enqueue, enqueue_next); } QVariant Playlist::headerData(int section, Qt::Orientation, int role) const { @@ -703,7 +703,7 @@ void Playlist::InsertDynamicItems(int count) { connect(inserter, SIGNAL(PlayRequested(QModelIndex)), SIGNAL(PlayRequested(QModelIndex))); - inserter->Load(this, -1, false, false, dynamic_playlist_, count); + inserter->Load(this, -1, false, false, false, dynamic_playlist_, count); } Qt::ItemFlags Playlist::flags(const QModelIndex& index) const { @@ -733,12 +733,14 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, bool play_now = false; bool enqueue_now = false; + bool enqueue_next_now = false; if (const MimeData* mime_data = qobject_cast(data)) { if (mime_data->clear_first_) { Clear(); } play_now = mime_data->play_now_; enqueue_now = mime_data->enqueue_now_; + enqueue_next_now = mime_data->enqueue_next_now_; } if (const SongMimeData* song_data = qobject_cast(data)) { @@ -748,33 +750,33 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, if (song_data->backend && song_data->backend->songs_table() == Library::kSongsTable) InsertSongItems(song_data->songs, row, play_now, - enqueue_now); + enqueue_now, enqueue_next_now); else if (song_data->backend && song_data->backend->songs_table() == MagnatuneService::kSongsTable) InsertSongItems(song_data->songs, row, play_now, - enqueue_now); + enqueue_now, enqueue_next_now); else if (song_data->backend && song_data->backend->songs_table() == JamendoService::kSongsTable) InsertSongItems(song_data->songs, row, play_now, - enqueue_now); + enqueue_now, enqueue_next_now); else InsertSongItems(song_data->songs, row, play_now, - enqueue_now); + enqueue_now, enqueue_next_now); } else if (const InternetMimeData* internet_data = qobject_cast(data)) { // Dragged from the Internet pane InsertInternetItems(internet_data->model, internet_data->indexes, row, - play_now, enqueue_now); + play_now, enqueue_now, enqueue_next_now); } else if (const InternetSongMimeData* internet_song_data = qobject_cast(data)) { InsertInternetItems(internet_song_data->service, internet_song_data->songs, - row, play_now, enqueue_now); + row, play_now, enqueue_now, enqueue_next_now); } else if (const GeneratorMimeData* generator_data = qobject_cast(data)) { - InsertSmartPlaylist(generator_data->generator_, row, play_now, enqueue_now); + InsertSmartPlaylist(generator_data->generator_, row, play_now, enqueue_now, enqueue_next_now); } else if (const PlaylistItemMimeData* item_data = qobject_cast(data)) { - InsertItems(item_data->items_, row, play_now, enqueue_now); + InsertItems(item_data->items_, row, play_now, enqueue_now, enqueue_next_now); } else if (data->hasFormat(kRowsMimetype)) { // Dragged from the playlist // Rearranging it is tricky... @@ -809,7 +811,7 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, if (items.count() > kUndoItemLimit) { // Too big to keep in the undo stack. Also clear the stack because it // might have been invalidated. - InsertItemsWithoutUndo(items, row, false); + InsertItemsWithoutUndo(items, row, false, false); undo_stack_->clear(); } else { undo_stack_->push( @@ -828,26 +830,26 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, SongLoaderInserter* inserter = new SongLoaderInserter( task_manager_, library_, backend_->app()->player()); connect(inserter, SIGNAL(Error(QString)), SIGNAL(Error(QString))); - inserter->LoadAudioCD(this, row, play_now, enqueue_now); + inserter->LoadAudioCD(this, row, play_now, enqueue_now, enqueue_next_now); } else if (data->hasUrls()) { // URL list dragged from the file list or some other app - InsertUrls(data->urls(), row, play_now, enqueue_now); + InsertUrls(data->urls(), row, play_now, enqueue_now, enqueue_next_now); } return true; } void Playlist::InsertUrls(const QList& urls, int pos, bool play_now, - bool enqueue) { + bool enqueue, bool enqueue_next) { SongLoaderInserter* inserter = new SongLoaderInserter( task_manager_, library_, backend_->app()->player()); connect(inserter, SIGNAL(Error(QString)), SIGNAL(Error(QString))); - inserter->Load(this, pos, play_now, enqueue, urls); + inserter->Load(this, pos, play_now, enqueue, enqueue_next, urls); } void Playlist::InsertSmartPlaylist(GeneratorPtr generator, int pos, - bool play_now, bool enqueue) { + bool play_now, bool enqueue, bool enqueue_next) { // Hack: If the generator hasn't got a library set then use the main one if (!generator->library()) { generator->set_library(library_); @@ -857,7 +859,7 @@ void Playlist::InsertSmartPlaylist(GeneratorPtr generator, int pos, new GeneratorInserter(task_manager_, library_, this); connect(inserter, SIGNAL(Error(QString)), SIGNAL(Error(QString))); - inserter->Load(this, pos, play_now, enqueue, generator); + inserter->Load(this, pos, play_now, enqueue, enqueue_next, generator); if (generator->is_dynamic()) { TurnOnDynamicPlaylist(generator); @@ -976,7 +978,7 @@ void Playlist::MoveItemsWithoutUndo(int start, const QList& dest_rows) { } void Playlist::InsertItems(const PlaylistItemList& itemsIn, int pos, - bool play_now, bool enqueue) { + bool play_now, bool enqueue, bool enqueue_next) { if (itemsIn.isEmpty()) return; PlaylistItemList items = itemsIn; @@ -1026,18 +1028,18 @@ void Playlist::InsertItems(const PlaylistItemList& itemsIn, int pos, if (items.count() > kUndoItemLimit) { // Too big to keep in the undo stack. Also clear the stack because it // might have been invalidated. - InsertItemsWithoutUndo(items, pos, enqueue); + InsertItemsWithoutUndo(items, pos, enqueue, enqueue_next); undo_stack_->clear(); } else { undo_stack_->push( - new PlaylistUndoCommands::InsertItems(this, items, pos, enqueue)); + new PlaylistUndoCommands::InsertItems(this, items, pos, enqueue, enqueue_next)); } if (play_now) emit PlayRequested(index(start, 0)); } void Playlist::InsertItemsWithoutUndo(const PlaylistItemList& items, int pos, - bool enqueue) { + bool enqueue, bool enqueue_next) { if (items.isEmpty()) return; const int start = pos == -1 ? items_.count() : pos; @@ -1072,22 +1074,30 @@ void Playlist::InsertItemsWithoutUndo(const PlaylistItemList& items, int pos, queue_->ToggleTracks(indexes); } + if (enqueue_next) { + QModelIndexList indexes; + for (int i = start; i <= end; ++i) { + indexes << index(i, 0); + } + queue_->InsertFirst(indexes); + } + Save(); ReshuffleIndices(); } void Playlist::InsertLibraryItems(const SongList& songs, int pos, bool play_now, - bool enqueue) { - InsertSongItems(songs, pos, play_now, enqueue); + bool enqueue, bool enqueue_next) { + InsertSongItems(songs, pos, play_now, enqueue, enqueue_next); } void Playlist::InsertSongs(const SongList& songs, int pos, bool play_now, - bool enqueue) { - InsertSongItems(songs, pos, play_now, enqueue); + bool enqueue, bool enqueue_next) { + InsertSongItems(songs, pos, play_now, enqueue, enqueue_next); } void Playlist::InsertSongsOrLibraryItems(const SongList& songs, int pos, - bool play_now, bool enqueue) { + bool play_now, bool enqueue, bool enqueue_next) { PlaylistItemList items; for (const Song& song : songs) { if (song.is_library_song()) { @@ -1096,12 +1106,12 @@ void Playlist::InsertSongsOrLibraryItems(const SongList& songs, int pos, items << PlaylistItemPtr(new SongPlaylistItem(song)); } } - InsertItems(items, pos, play_now, enqueue); + InsertItems(items, pos, play_now, enqueue, enqueue_next); } void Playlist::InsertInternetItems(const InternetModel* model, const QModelIndexList& items, int pos, - bool play_now, bool enqueue) { + bool play_now, bool enqueue, bool enqueue_next) { PlaylistItemList playlist_items; QList song_urls; @@ -1120,23 +1130,23 @@ void Playlist::InsertInternetItems(const InternetModel* model, } if (!song_urls.isEmpty()) { - InsertUrls(song_urls, pos, play_now, enqueue); + InsertUrls(song_urls, pos, play_now, enqueue, enqueue_next); play_now = false; } - InsertItems(playlist_items, pos, play_now, enqueue); + InsertItems(playlist_items, pos, play_now, enqueue, enqueue_next); } void Playlist::InsertInternetItems(InternetService* service, const SongList& songs, int pos, - bool play_now, bool enqueue) { + bool play_now, bool enqueue, bool enqueue_next) { PlaylistItemList playlist_items; for (const Song& song : songs) { playlist_items << shared_ptr( new InternetPlaylistItem(service, song)); } - InsertItems(playlist_items, pos, play_now, enqueue); + InsertItems(playlist_items, pos, play_now, enqueue, enqueue_next); } void Playlist::UpdateItems(const SongList& songs) { diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h index fefc970e2..ad42721a1 100644 --- a/src/playlist/playlist.h +++ b/src/playlist/playlist.h @@ -235,18 +235,18 @@ class Playlist : public QAbstractListModel { // Changing the playlist void InsertItems(const PlaylistItemList& items, int pos = -1, - bool play_now = false, bool enqueue = false); + bool play_now = false, bool enqueue = false, bool enqueue_next = false); void InsertLibraryItems(const SongList& items, int pos = -1, - bool play_now = false, bool enqueue = false); + bool play_now = false, bool enqueue = false, bool enqueue_next = false); void InsertSongs(const SongList& items, int pos = -1, bool play_now = false, - bool enqueue = false); + bool enqueue = false, bool enqueue_next = false); void InsertSongsOrLibraryItems(const SongList& items, int pos = -1, - bool play_now = false, bool enqueue = false); + bool play_now = false, bool enqueue = false, bool enqueue_next = false); void InsertSmartPlaylist(smart_playlists::GeneratorPtr gen, int pos = -1, - bool play_now = false, bool enqueue = false); + bool play_now = false, bool enqueue = false, bool enqueue_next = false); void InsertInternetItems(InternetService* service, const SongList& songs, int pos = -1, bool play_now = false, - bool enqueue = false); + bool enqueue = false, bool enqueue_next = false); void ReshuffleIndices(); // If this playlist contains the current item, this method will apply the @@ -335,7 +335,7 @@ class Playlist : public QAbstractListModel { void SetColumnAlignment(const ColumnAlignmentMap& alignment); void InsertUrls(const QList& urls, int pos = -1, bool play_now = false, - bool enqueue = false); + bool enqueue = false, bool enqueue_next = false); // Removes items with given indices from the playlist. This operation is not // undoable. void RemoveItemsWithoutUndo(const QList& indices); @@ -366,18 +366,18 @@ signals: void InsertInternetItems(const InternetModel* model, const QModelIndexList& items, int pos, bool play_now, - bool enqueue); + bool enqueue, bool enqueue_next = false); template void InsertSongItems(const SongList& songs, int pos, bool play_now, - bool enqueue); + bool enqueue, bool enqueue_next = false); void InsertDynamicItems(int count); // Modify the playlist without changing the undo stack. These are used by // our friends in PlaylistUndoCommands void InsertItemsWithoutUndo(const PlaylistItemList& items, int pos, - bool enqueue = false); + bool enqueue = false, bool enqueue_next = false); PlaylistItemList RemoveItemsWithoutUndo(int pos, int count); void MoveItemsWithoutUndo(const QList& source_rows, int pos); void MoveItemWithoutUndo(int source, int dest); diff --git a/src/playlist/playlistundocommands.cpp b/src/playlist/playlistundocommands.cpp index 8e70ef4c3..f2c467773 100644 --- a/src/playlist/playlistundocommands.cpp +++ b/src/playlist/playlistundocommands.cpp @@ -23,13 +23,13 @@ namespace PlaylistUndoCommands { Base::Base(Playlist* playlist) : QUndoCommand(0), playlist_(playlist) {} InsertItems::InsertItems(Playlist* playlist, const PlaylistItemList& items, - int pos, bool enqueue) - : Base(playlist), items_(items), pos_(pos), enqueue_(enqueue) { + int pos, bool enqueue, bool enqueue_next) + : Base(playlist), items_(items), pos_(pos), enqueue_(enqueue), enqueue_next_(enqueue_next) { setText(tr("add %n songs", "", items_.count())); } void InsertItems::redo() { - playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_); + playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_, enqueue_next_); } void InsertItems::undo() { diff --git a/src/playlist/playlistundocommands.h b/src/playlist/playlistundocommands.h index f2860e9a6..09b379ec0 100644 --- a/src/playlist/playlistundocommands.h +++ b/src/playlist/playlistundocommands.h @@ -40,8 +40,7 @@ class Base : public QUndoCommand { class InsertItems : public Base { public: - InsertItems(Playlist* playlist, const PlaylistItemList& items, int pos, - bool enqueue = false); + InsertItems(Playlist* playlist, const PlaylistItemList& items, int pos, bool enqueue = false, bool enqueue_next = false); void undo(); void redo(); @@ -56,6 +55,7 @@ class InsertItems : public Base { PlaylistItemList items_; int pos_; bool enqueue_; + bool enqueue_next_; }; class RemoveItems : public Base { diff --git a/src/playlist/songloaderinserter.cpp b/src/playlist/songloaderinserter.cpp index 031c64518..04e87d18e 100644 --- a/src/playlist/songloaderinserter.cpp +++ b/src/playlist/songloaderinserter.cpp @@ -37,11 +37,12 @@ SongLoaderInserter::SongLoaderInserter(TaskManager* task_manager, SongLoaderInserter::~SongLoaderInserter() { qDeleteAll(pending_); } void SongLoaderInserter::Load(Playlist* destination, int row, bool play_now, - bool enqueue, const QList& urls) { + bool enqueue, bool enqueue_next, const QList& urls) { destination_ = destination; row_ = row; play_now_ = play_now; enqueue_ = enqueue; + enqueue_next_ = enqueue_next; connect(destination, SIGNAL(destroyed()), SLOT(DestinationDestroyed())); connect(this, SIGNAL(PreloadFinished()), SLOT(InsertSongs())); @@ -78,11 +79,12 @@ void SongLoaderInserter::Load(Playlist* destination, int row, bool play_now, // In the meantime, MusicBrainz will be queried to get songs' metadata. // AudioCDTagsLoaded will be called next, and playlist's items will be updated. void SongLoaderInserter::LoadAudioCD(Playlist* destination, int row, - bool play_now, bool enqueue) { + bool play_now, bool enqueue, bool enqueue_next) { destination_ = destination; row_ = row; play_now_ = play_now; enqueue_ = enqueue; + enqueue_next_ = enqueue_next; SongLoader* loader = new SongLoader(library_, player_, this); NewClosure(loader, SIGNAL(AudioCDTracksLoaded()), diff --git a/src/playlist/songloaderinserter.h b/src/playlist/songloaderinserter.h index 14b3783a6..ea264198c 100644 --- a/src/playlist/songloaderinserter.h +++ b/src/playlist/songloaderinserter.h @@ -39,9 +39,9 @@ class SongLoaderInserter : public QObject { LibraryBackendInterface* library, const Player* player); ~SongLoaderInserter(); - void Load(Playlist* destination, int row, bool play_now, bool enqueue, + void Load(Playlist* destination, int row, bool play_now, bool enqueue, bool enqueue_next, const QList& urls); - void LoadAudioCD(Playlist* destination, int row, bool play_now, bool enqueue); + void LoadAudioCD(Playlist* destination, int row, bool play_now, bool enqueue, bool enqueue_now); signals: void Error(const QString& message); @@ -64,6 +64,7 @@ signals: int row_; bool play_now_; bool enqueue_; + bool enqueue_next_; SongList songs_; diff --git a/src/smartplaylists/generatorinserter.cpp b/src/smartplaylists/generatorinserter.cpp index d57ce0bfd..f732ec4f2 100644 --- a/src/smartplaylists/generatorinserter.cpp +++ b/src/smartplaylists/generatorinserter.cpp @@ -43,7 +43,7 @@ static PlaylistItemList Generate(GeneratorPtr generator, int dynamic_count) { } void GeneratorInserter::Load(Playlist* destination, int row, bool play_now, - bool enqueue, GeneratorPtr generator, + bool enqueue, bool enqueue_next, GeneratorPtr generator, int dynamic_count) { task_id_ = task_manager_->StartTask(tr("Loading smart playlist")); @@ -51,6 +51,7 @@ void GeneratorInserter::Load(Playlist* destination, int row, bool play_now, row_ = row; play_now_ = play_now; enqueue_ = enqueue; + enqueue_next_ = enqueue_next; is_dynamic_ = generator->is_dynamic(); connect(generator.get(), SIGNAL(Error(QString)), SIGNAL(Error(QString))); diff --git a/src/smartplaylists/generatorinserter.h b/src/smartplaylists/generatorinserter.h index 2ededc94e..1d3df5fd0 100644 --- a/src/smartplaylists/generatorinserter.h +++ b/src/smartplaylists/generatorinserter.h @@ -40,7 +40,7 @@ class GeneratorInserter : public QObject { GeneratorInserter(TaskManager* task_manager, LibraryBackend* library, QObject* parent); - void Load(Playlist* destination, int row, bool play_now, bool enqueue, + void Load(Playlist* destination, int row, bool play_now, bool enqueue, bool enqueue_next, GeneratorPtr generator, int dynamic_count = 0); signals: @@ -59,6 +59,7 @@ signals: int row_; bool play_now_; bool enqueue_; + bool enqueue_next_; bool is_dynamic_; }; diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index fffab3a16..7f83ec39d 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -1782,6 +1782,8 @@ void MainWindow::PlaylistRightClick(const QPoint& global_pos, else playlist_queue_->setIcon(IconLoader::Load("go-next", IconLoader::Base)); + playlist_queue_play_next_->setIcon(IconLoader::Load("go-next", IconLoader::Base)); + if (!index.isValid()) { ui_->action_selection_set_value->setVisible(false); ui_->action_edit_value->setVisible(false); From 2793cfa7fba2f1bbab37e7790bb22fd82ae47a2d Mon Sep 17 00:00:00 2001 From: Mark Furneaux Date: Sat, 14 Apr 2018 16:31:48 -0400 Subject: [PATCH 14/17] Add to loaderinserter --- src/playlist/songloaderinserter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/playlist/songloaderinserter.cpp b/src/playlist/songloaderinserter.cpp index 04e87d18e..4078c00fa 100644 --- a/src/playlist/songloaderinserter.cpp +++ b/src/playlist/songloaderinserter.cpp @@ -121,7 +121,7 @@ void SongLoaderInserter::InsertSongs() { // Insert songs (that haven't been completely loaded) to allow user to see // and play them while not loaded completely if (destination_) { - destination_->InsertSongsOrLibraryItems(songs_, row_, play_now_, enqueue_); + destination_->InsertSongsOrLibraryItems(songs_, row_, play_now_, enqueue_, enqueue_next_); } } From d28a3184372a2b556b446b498c2d2a99df03f1c4 Mon Sep 17 00:00:00 2001 From: Mark Furneaux Date: Sat, 14 Apr 2018 16:57:06 -0400 Subject: [PATCH 15/17] Clang format --- src/core/mimedata.h | 7 +++-- src/library/libraryview.cpp | 12 ++++---- src/playlist/playlist.cpp | 30 ++++++++++++-------- src/playlist/playlist.h | 12 +++++--- src/playlist/playlistundocommands.cpp | 8 ++++-- src/playlist/playlistundocommands.h | 3 +- src/playlist/queue.cpp | 36 ++++++++++++------------ src/playlist/songloaderinserter.cpp | 9 ++++-- src/playlist/songloaderinserter.h | 9 +++--- src/smartplaylists/generatorinserter.cpp | 4 +-- src/smartplaylists/generatorinserter.h | 6 ++-- src/ui/mainwindow.cpp | 28 +++++++++--------- 12 files changed, 94 insertions(+), 70 deletions(-) diff --git a/src/core/mimedata.h b/src/core/mimedata.h index 471574807..3d2c2aeab 100644 --- a/src/core/mimedata.h +++ b/src/core/mimedata.h @@ -27,8 +27,8 @@ class MimeData : public QMimeData { Q_OBJECT public: - MimeData(bool clear = false, bool play_now = false, bool enqueue = false, bool enqueue_next_now = false, - bool open_in_new_playlist = false) + MimeData(bool clear = false, bool play_now = false, bool enqueue = false, + bool enqueue_next_now = false, bool open_in_new_playlist = false) : override_user_settings_(false), clear_first_(clear), play_now_(play_now), @@ -54,7 +54,8 @@ class MimeData : public QMimeData { // If this is set then the items are added to the queue after being inserted. bool enqueue_now_; - // If this is set then the items are added to the beginning of the queue after being inserted. + // If this is set then the items are added to the beginning of the queue after + // being inserted. bool enqueue_next_now_; // If this is set then the items are inserted into a newly created playlist. diff --git a/src/library/libraryview.cpp b/src/library/libraryview.cpp index 1def6bfb8..e09efb34f 100644 --- a/src/library/libraryview.cpp +++ b/src/library/libraryview.cpp @@ -394,7 +394,7 @@ void LibraryView::contextMenuEvent(QContextMenuEvent* e) { SLOT(AddToPlaylistEnqueue())); add_to_playlist_enqueue_next_ = context_menu_->addAction( IconLoader::Load("go-next", IconLoader::Base), tr("Play next"), this, - SLOT(AddToPlaylistEnqueueNext())); + SLOT(AddToPlaylistEnqueueNext())); context_menu_->addSeparator(); search_for_this_ = context_menu_->addAction( IconLoader::Load("system-search", IconLoader::Base), @@ -620,11 +620,11 @@ void LibraryView::AddToPlaylistEnqueue() { } void LibraryView::AddToPlaylistEnqueueNext() { - QMimeData* data = model()->mimeData(selectedIndexes()); - if (MimeData* mime_data = qobject_cast(data)) { - mime_data->enqueue_next_now_ = true; - } - emit AddToPlaylistSignal(data); + QMimeData* data = model()->mimeData(selectedIndexes()); + if (MimeData* mime_data = qobject_cast(data)) { + mime_data->enqueue_next_now_ = true; + } + emit AddToPlaylistSignal(data); } void LibraryView::OpenInNewPlaylist() { diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp index ac69dd2c6..817ad5351 100644 --- a/src/playlist/playlist.cpp +++ b/src/playlist/playlist.cpp @@ -773,10 +773,12 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, row, play_now, enqueue_now, enqueue_next_now); } else if (const GeneratorMimeData* generator_data = qobject_cast(data)) { - InsertSmartPlaylist(generator_data->generator_, row, play_now, enqueue_now, enqueue_next_now); + InsertSmartPlaylist(generator_data->generator_, row, play_now, enqueue_now, + enqueue_next_now); } else if (const PlaylistItemMimeData* item_data = qobject_cast(data)) { - InsertItems(item_data->items_, row, play_now, enqueue_now, enqueue_next_now); + InsertItems(item_data->items_, row, play_now, enqueue_now, + enqueue_next_now); } else if (data->hasFormat(kRowsMimetype)) { // Dragged from the playlist // Rearranging it is tricky... @@ -849,7 +851,8 @@ void Playlist::InsertUrls(const QList& urls, int pos, bool play_now, } void Playlist::InsertSmartPlaylist(GeneratorPtr generator, int pos, - bool play_now, bool enqueue, bool enqueue_next) { + bool play_now, bool enqueue, + bool enqueue_next) { // Hack: If the generator hasn't got a library set then use the main one if (!generator->library()) { generator->set_library(library_); @@ -1031,8 +1034,8 @@ void Playlist::InsertItems(const PlaylistItemList& itemsIn, int pos, InsertItemsWithoutUndo(items, pos, enqueue, enqueue_next); undo_stack_->clear(); } else { - undo_stack_->push( - new PlaylistUndoCommands::InsertItems(this, items, pos, enqueue, enqueue_next)); + undo_stack_->push(new PlaylistUndoCommands::InsertItems( + this, items, pos, enqueue, enqueue_next)); } if (play_now) emit PlayRequested(index(start, 0)); @@ -1077,7 +1080,7 @@ void Playlist::InsertItemsWithoutUndo(const PlaylistItemList& items, int pos, if (enqueue_next) { QModelIndexList indexes; for (int i = start; i <= end; ++i) { - indexes << index(i, 0); + indexes << index(i, 0); } queue_->InsertFirst(indexes); } @@ -1088,16 +1091,19 @@ void Playlist::InsertItemsWithoutUndo(const PlaylistItemList& items, int pos, void Playlist::InsertLibraryItems(const SongList& songs, int pos, bool play_now, bool enqueue, bool enqueue_next) { - InsertSongItems(songs, pos, play_now, enqueue, enqueue_next); + InsertSongItems(songs, pos, play_now, enqueue, + enqueue_next); } void Playlist::InsertSongs(const SongList& songs, int pos, bool play_now, bool enqueue, bool enqueue_next) { - InsertSongItems(songs, pos, play_now, enqueue, enqueue_next); + InsertSongItems(songs, pos, play_now, enqueue, + enqueue_next); } void Playlist::InsertSongsOrLibraryItems(const SongList& songs, int pos, - bool play_now, bool enqueue, bool enqueue_next) { + bool play_now, bool enqueue, + bool enqueue_next) { PlaylistItemList items; for (const Song& song : songs) { if (song.is_library_song()) { @@ -1111,7 +1117,8 @@ void Playlist::InsertSongsOrLibraryItems(const SongList& songs, int pos, void Playlist::InsertInternetItems(const InternetModel* model, const QModelIndexList& items, int pos, - bool play_now, bool enqueue, bool enqueue_next) { + bool play_now, bool enqueue, + bool enqueue_next) { PlaylistItemList playlist_items; QList song_urls; @@ -1139,7 +1146,8 @@ void Playlist::InsertInternetItems(const InternetModel* model, void Playlist::InsertInternetItems(InternetService* service, const SongList& songs, int pos, - bool play_now, bool enqueue, bool enqueue_next) { + bool play_now, bool enqueue, + bool enqueue_next) { PlaylistItemList playlist_items; for (const Song& song : songs) { playlist_items << shared_ptr( diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h index ad42721a1..ed2041040 100644 --- a/src/playlist/playlist.h +++ b/src/playlist/playlist.h @@ -235,15 +235,19 @@ class Playlist : public QAbstractListModel { // Changing the playlist void InsertItems(const PlaylistItemList& items, int pos = -1, - bool play_now = false, bool enqueue = false, bool enqueue_next = false); + bool play_now = false, bool enqueue = false, + bool enqueue_next = false); void InsertLibraryItems(const SongList& items, int pos = -1, - bool play_now = false, bool enqueue = false, bool enqueue_next = false); + bool play_now = false, bool enqueue = false, + bool enqueue_next = false); void InsertSongs(const SongList& items, int pos = -1, bool play_now = false, bool enqueue = false, bool enqueue_next = false); void InsertSongsOrLibraryItems(const SongList& items, int pos = -1, - bool play_now = false, bool enqueue = false, bool enqueue_next = false); + bool play_now = false, bool enqueue = false, + bool enqueue_next = false); void InsertSmartPlaylist(smart_playlists::GeneratorPtr gen, int pos = -1, - bool play_now = false, bool enqueue = false, bool enqueue_next = false); + bool play_now = false, bool enqueue = false, + bool enqueue_next = false); void InsertInternetItems(InternetService* service, const SongList& songs, int pos = -1, bool play_now = false, bool enqueue = false, bool enqueue_next = false); diff --git a/src/playlist/playlistundocommands.cpp b/src/playlist/playlistundocommands.cpp index f2c467773..38d876c1b 100644 --- a/src/playlist/playlistundocommands.cpp +++ b/src/playlist/playlistundocommands.cpp @@ -24,12 +24,16 @@ Base::Base(Playlist* playlist) : QUndoCommand(0), playlist_(playlist) {} InsertItems::InsertItems(Playlist* playlist, const PlaylistItemList& items, int pos, bool enqueue, bool enqueue_next) - : Base(playlist), items_(items), pos_(pos), enqueue_(enqueue), enqueue_next_(enqueue_next) { + : Base(playlist), + items_(items), + pos_(pos), + enqueue_(enqueue), + enqueue_next_(enqueue_next) { setText(tr("add %n songs", "", items_.count())); } void InsertItems::redo() { - playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_, enqueue_next_); + playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_, enqueue_next_); } void InsertItems::undo() { diff --git a/src/playlist/playlistundocommands.h b/src/playlist/playlistundocommands.h index 09b379ec0..af83268e1 100644 --- a/src/playlist/playlistundocommands.h +++ b/src/playlist/playlistundocommands.h @@ -40,7 +40,8 @@ class Base : public QUndoCommand { class InsertItems : public Base { public: - InsertItems(Playlist* playlist, const PlaylistItemList& items, int pos, bool enqueue = false, bool enqueue_next = false); + InsertItems(Playlist* playlist, const PlaylistItemList& items, int pos, + bool enqueue = false, bool enqueue_next = false); void undo(); void redo(); diff --git a/src/playlist/queue.cpp b/src/playlist/queue.cpp index 6c3d88ed6..d66e3e03f 100644 --- a/src/playlist/queue.cpp +++ b/src/playlist/queue.cpp @@ -152,26 +152,26 @@ void Queue::ToggleTracks(const QModelIndexList& source_indexes) { } void Queue::InsertFirst(const QModelIndexList& source_indexes) { - for (const QModelIndex& source_index : source_indexes) { - QModelIndex proxy_index = mapFromSource(source_index); - if (proxy_index.isValid()) { - // Already in the queue, so remove it to be reinserted later - const int row = proxy_index.row(); - beginRemoveRows(QModelIndex(), row, row); - source_indexes_.removeAt(row); - endRemoveRows(); - } + for (const QModelIndex& source_index : source_indexes) { + QModelIndex proxy_index = mapFromSource(source_index); + if (proxy_index.isValid()) { + // Already in the queue, so remove it to be reinserted later + const int row = proxy_index.row(); + beginRemoveRows(QModelIndex(), row, row); + source_indexes_.removeAt(row); + endRemoveRows(); } + } - const int rows = source_indexes.count(); - // Enqueue the tracks at the beginning - beginInsertRows(QModelIndex(), 0, rows - 1); - int offset = 0; - for (const QModelIndex& source_index : source_indexes) { - source_indexes_.insert(offset, QPersistentModelIndex(source_index)); - offset++; - } - endInsertRows(); + const int rows = source_indexes.count(); + // Enqueue the tracks at the beginning + beginInsertRows(QModelIndex(), 0, rows - 1); + int offset = 0; + for (const QModelIndex& source_index : source_indexes) { + source_indexes_.insert(offset, QPersistentModelIndex(source_index)); + offset++; + } + endInsertRows(); } int Queue::PositionOf(const QModelIndex& source_index) const { diff --git a/src/playlist/songloaderinserter.cpp b/src/playlist/songloaderinserter.cpp index 4078c00fa..d6ebca740 100644 --- a/src/playlist/songloaderinserter.cpp +++ b/src/playlist/songloaderinserter.cpp @@ -37,7 +37,8 @@ SongLoaderInserter::SongLoaderInserter(TaskManager* task_manager, SongLoaderInserter::~SongLoaderInserter() { qDeleteAll(pending_); } void SongLoaderInserter::Load(Playlist* destination, int row, bool play_now, - bool enqueue, bool enqueue_next, const QList& urls) { + bool enqueue, bool enqueue_next, + const QList& urls) { destination_ = destination; row_ = row; play_now_ = play_now; @@ -79,7 +80,8 @@ void SongLoaderInserter::Load(Playlist* destination, int row, bool play_now, // In the meantime, MusicBrainz will be queried to get songs' metadata. // AudioCDTagsLoaded will be called next, and playlist's items will be updated. void SongLoaderInserter::LoadAudioCD(Playlist* destination, int row, - bool play_now, bool enqueue, bool enqueue_next) { + bool play_now, bool enqueue, + bool enqueue_next) { destination_ = destination; row_ = row; play_now_ = play_now; @@ -121,7 +123,8 @@ void SongLoaderInserter::InsertSongs() { // Insert songs (that haven't been completely loaded) to allow user to see // and play them while not loaded completely if (destination_) { - destination_->InsertSongsOrLibraryItems(songs_, row_, play_now_, enqueue_, enqueue_next_); + destination_->InsertSongsOrLibraryItems(songs_, row_, play_now_, enqueue_, + enqueue_next_); } } diff --git a/src/playlist/songloaderinserter.h b/src/playlist/songloaderinserter.h index ea264198c..f0266cefe 100644 --- a/src/playlist/songloaderinserter.h +++ b/src/playlist/songloaderinserter.h @@ -39,11 +39,12 @@ class SongLoaderInserter : public QObject { LibraryBackendInterface* library, const Player* player); ~SongLoaderInserter(); - void Load(Playlist* destination, int row, bool play_now, bool enqueue, bool enqueue_next, - const QList& urls); - void LoadAudioCD(Playlist* destination, int row, bool play_now, bool enqueue, bool enqueue_now); + void Load(Playlist* destination, int row, bool play_now, bool enqueue, + bool enqueue_next, const QList& urls); + void LoadAudioCD(Playlist* destination, int row, bool play_now, bool enqueue, + bool enqueue_now); -signals: + signals: void Error(const QString& message); void PreloadFinished(); void EffectiveLoadFinished(const SongList& songs); diff --git a/src/smartplaylists/generatorinserter.cpp b/src/smartplaylists/generatorinserter.cpp index f732ec4f2..ddc2d7adc 100644 --- a/src/smartplaylists/generatorinserter.cpp +++ b/src/smartplaylists/generatorinserter.cpp @@ -43,8 +43,8 @@ static PlaylistItemList Generate(GeneratorPtr generator, int dynamic_count) { } void GeneratorInserter::Load(Playlist* destination, int row, bool play_now, - bool enqueue, bool enqueue_next, GeneratorPtr generator, - int dynamic_count) { + bool enqueue, bool enqueue_next, + GeneratorPtr generator, int dynamic_count) { task_id_ = task_manager_->StartTask(tr("Loading smart playlist")); destination_ = destination; diff --git a/src/smartplaylists/generatorinserter.h b/src/smartplaylists/generatorinserter.h index 1d3df5fd0..c96370105 100644 --- a/src/smartplaylists/generatorinserter.h +++ b/src/smartplaylists/generatorinserter.h @@ -40,10 +40,10 @@ class GeneratorInserter : public QObject { GeneratorInserter(TaskManager* task_manager, LibraryBackend* library, QObject* parent); - void Load(Playlist* destination, int row, bool play_now, bool enqueue, bool enqueue_next, - GeneratorPtr generator, int dynamic_count = 0); + void Load(Playlist* destination, int row, bool play_now, bool enqueue, + bool enqueue_next, GeneratorPtr generator, int dynamic_count = 0); -signals: + signals: void Error(const QString& message); void PlayRequested(const QModelIndex& index); diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 7f83ec39d..ab8600288 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -677,7 +677,8 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, playlist_queue_ = playlist_menu_->addAction("", this, SLOT(PlaylistQueue())); playlist_queue_->setShortcut(QKeySequence("Ctrl+D")); ui_->playlist->addAction(playlist_queue_); - playlist_queue_play_next_ = playlist_menu_->addAction("", this, SLOT(PlaylistQueuePlayNext())); + playlist_queue_play_next_ = + playlist_menu_->addAction("", this, SLOT(PlaylistQueuePlayNext())); playlist_queue_play_next_->setShortcut(QKeySequence("Ctrl+Shift+D")); ui_->playlist->addAction(playlist_queue_play_next_); playlist_skip_ = playlist_menu_->addAction("", this, SLOT(PlaylistSkip())); @@ -1763,10 +1764,10 @@ void MainWindow::PlaylistRightClick(const QPoint& global_pos, else playlist_queue_->setText(tr("Toggle queue status")); - if (all > 1) - playlist_queue_play_next_->setText(tr("Play selected tracks next")); - else - playlist_queue_play_next_->setText(tr("Play next")); + if (all > 1) + playlist_queue_play_next_->setText(tr("Play selected tracks next")); + else + playlist_queue_play_next_->setText(tr("Play next")); if (in_skipped == 1 && not_in_skipped == 0) playlist_skip_->setText(tr("Unskip track")); @@ -1782,7 +1783,8 @@ void MainWindow::PlaylistRightClick(const QPoint& global_pos, else playlist_queue_->setIcon(IconLoader::Load("go-next", IconLoader::Base)); - playlist_queue_play_next_->setIcon(IconLoader::Load("go-next", IconLoader::Base)); + playlist_queue_play_next_->setIcon( + IconLoader::Load("go-next", IconLoader::Base)); if (!index.isValid()) { ui_->action_selection_set_value->setVisible(false); @@ -2511,14 +2513,14 @@ void MainWindow::PlaylistQueue() { } void MainWindow::PlaylistQueuePlayNext() { - QModelIndexList indexes; - for (const QModelIndex& proxy_index : - ui_->playlist->view()->selectionModel()->selectedRows()) { - indexes << app_->playlist_manager()->current()->proxy()->mapToSource( - proxy_index); - } + QModelIndexList indexes; + for (const QModelIndex& proxy_index : + ui_->playlist->view()->selectionModel()->selectedRows()) { + indexes << app_->playlist_manager()->current()->proxy()->mapToSource( + proxy_index); + } - app_->playlist_manager()->current()->queue()->InsertFirst(indexes); + app_->playlist_manager()->current()->queue()->InsertFirst(indexes); } void MainWindow::PlaylistSkip() { From 37912a87b89461d637b077503c8db5026b05e20a Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Tue, 1 May 2018 19:29:47 +0200 Subject: [PATCH 16/17] Fix WavPack playback (#6048) --- ext/libclementine-remote/remotecontrolmessages.proto | 1 + ext/libclementine-tagreader/tagreader.cpp | 3 +++ ext/libclementine-tagreader/tagreadermessages.proto | 1 + src/core/song.cpp | 6 +++++- src/core/song.h | 1 + 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ext/libclementine-remote/remotecontrolmessages.proto b/ext/libclementine-remote/remotecontrolmessages.proto index b3f26d422..f1ebc3219 100644 --- a/ext/libclementine-remote/remotecontrolmessages.proto +++ b/ext/libclementine-remote/remotecontrolmessages.proto @@ -104,6 +104,7 @@ message SongMetadata { TRUEAUDIO = 11; CDDA = 12; OGGOPUS = 13; + WAVPACK = 14; STREAM = 99; } diff --git a/ext/libclementine-tagreader/tagreader.cpp b/ext/libclementine-tagreader/tagreader.cpp index 4440fd159..208c9758e 100644 --- a/ext/libclementine-tagreader/tagreader.cpp +++ b/ext/libclementine-tagreader/tagreader.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include @@ -659,6 +660,8 @@ pb::tagreader::SongMetadata_Type TagReader::GuessFileType( return pb::tagreader::SongMetadata_Type_WAV; if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_TRUEAUDIO; + if (dynamic_cast(fileref->file())) + return pb::tagreader::SongMetadata_Type_WAVPACK; return pb::tagreader::SongMetadata_Type_UNKNOWN; } diff --git a/ext/libclementine-tagreader/tagreadermessages.proto b/ext/libclementine-tagreader/tagreadermessages.proto index 0e9322ec2..857dc4914 100644 --- a/ext/libclementine-tagreader/tagreadermessages.proto +++ b/ext/libclementine-tagreader/tagreadermessages.proto @@ -16,6 +16,7 @@ message SongMetadata { TRUEAUDIO = 11; CDDA = 12; OGGOPUS = 13; + WAVPACK = 14; STREAM = 99; } diff --git a/src/core/song.cpp b/src/core/song.cpp index 6f4e1192a..32b645dff 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -427,6 +427,8 @@ QString Song::TextForFiletype(FileType type) { return QObject::tr("AIFF"); case Song::Type_Wav: return QObject::tr("Wav"); + case Song::Type_WavPack: + return QObject::tr("WavPack"); case Song::Type_TrueAudio: return QObject::tr("TrueAudio"); case Song::Type_Cdda: @@ -447,6 +449,7 @@ bool Song::IsFileLossless() const { case Song::Type_Flac: case Song::Type_OggFlac: case Song::Type_Wav: + case Song::Type_WavPack: return true; default: return false; @@ -673,7 +676,8 @@ void Song::InitFromFilePartial(const QString& filename) { if (suffix == "mp3" || suffix == "ogg" || suffix == "flac" || suffix == "mpc" || suffix == "m4a" || suffix == "aac" || suffix == "wma" || suffix == "mp4" || suffix == "spx" || - suffix == "wav" || suffix == "opus" || suffix == "m4b") { + suffix == "wav" || suffix == "opus" || suffix == "m4b" || + suffix == "wv") { d->valid_ = true; } else { d->valid_ = false; diff --git a/src/core/song.h b/src/core/song.h index ace966ec1..d3667e49f 100644 --- a/src/core/song.h +++ b/src/core/song.h @@ -101,6 +101,7 @@ class Song { Type_TrueAudio = 11, Type_Cdda = 12, Type_OggOpus = 13, + Type_WavPack = 14, Type_Stream = 99, }; static QString TextForFiletype(FileType type); From 5bd2c77c58d0f0a208c28cdb238041707dfaed2d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 13 May 2018 19:02:33 +0200 Subject: [PATCH 17/17] Fix compilation with GCC 8 (#6053) --- src/internet/spotify/spotifyblobdownloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internet/spotify/spotifyblobdownloader.cpp b/src/internet/spotify/spotifyblobdownloader.cpp index b6e3f2b64..3c6339209 100644 --- a/src/internet/spotify/spotifyblobdownloader.cpp +++ b/src/internet/spotify/spotifyblobdownloader.cpp @@ -221,7 +221,7 @@ bool SpotifyBlobDownloader::CheckSignature( return false; } } - } catch (std::exception e) { + } catch (std::exception& e) { // This should only happen if we fail to parse our own key. qLog(Debug) << "Verifying spotify blob signature failed:" << e.what(); return false;