Improve album cover loader, lyrics search and streaming support

- Improve album cover loader
- Add album cover loader result struct
- Move album cover thumbnail scaling to album cover loader
- Make init art manual look for album cover images in song directory
- Make album cover search work for songs outside of collection and
  streams
- Make album cover search work based on artist + title if album is not
  present
- Update art manual in playlist for local files, devices and CDDA
- Make lyrics search work for streams
- Add stream dialog to menu
- Remove dead code in InternetSearchModel
- Simplify code in InternetSearchView
This commit is contained in:
Jonas Kvinge
2020-04-20 18:03:18 +02:00
parent ab2ffd9ac1
commit a2c0e4d4b1
77 changed files with 1057 additions and 584 deletions

View File

@@ -57,7 +57,8 @@ ContextAlbum::ContextAlbum(QWidget *parent) :
cover_loader_options_.desired_height_ = 600;
cover_loader_options_.pad_output_image_ = true;
cover_loader_options_.scale_output_image_ = true;
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_strawberry_));
QPair<QImage, QImage> images = AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_strawberry_);
pixmap_current_ = QPixmap::fromImage(images.first);
connect(timeline_fade_, SIGNAL(valueChanged(qreal)), SLOT(FadePreviousTrack(qreal)));
timeline_fade_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
@@ -89,7 +90,7 @@ void ContextAlbum::DrawImage(QPainter *p) {
if (width() != prev_width_) {
cover_loader_options_.desired_height_ = width() - kWidgetSpacing;
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_original_));
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_original_).first);
prev_width_ = width();
}
@@ -118,7 +119,7 @@ void ContextAlbum::FadePreviousTrack(const qreal value) {
void ContextAlbum::ScaleCover() {
cover_loader_options_.desired_height_ = width() - kWidgetSpacing;
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_original_));
pixmap_current_ = QPixmap::fromImage(AlbumCoverLoader::ScaleAndPad(cover_loader_options_, image_original_).first);
prev_width_ = width();
update();

View File

@@ -48,11 +48,11 @@
#include "playlist/playlistmanager.h"
#include "playlist/songmimedata.h"
#include "covermanager/albumcoverloader.h"
#include "covermanager/albumcoverloaderoptions.h"
#include "covermanager/albumcoverloaderresult.h"
#include "contextalbumsmodel.h"
using std::bind;
using std::sort;
using std::placeholders::_1;
using std::placeholders::_2;
@@ -71,7 +71,7 @@ ContextAlbumsModel::ContextAlbumsModel(CollectionBackend *backend, Application *
cover_loader_options_.pad_output_image_ = true;
cover_loader_options_.scale_output_image_ = true;
connect(app_->album_cover_loader(), SIGNAL(ImageLoaded(quint64, QUrl, QImage)), SLOT(AlbumCoverLoaded(quint64, QUrl, QImage)));
connect(app_->album_cover_loader(), SIGNAL(AlbumCoverLoaded(quint64, AlbumCoverLoaderResult)), SLOT(AlbumCoverLoaded(quint64, AlbumCoverLoaderResult)));
QIcon nocover = IconLoader::Load("cdcase");
no_cover_icon_ = nocover.pixmap(nocover.availableSizes().last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
@@ -146,9 +146,7 @@ QVariant ContextAlbumsModel::AlbumIcon(const QModelIndex &index) {
}
void ContextAlbumsModel::AlbumCoverLoaded(const quint64 id, const QUrl &cover_url, const QImage &image) {
Q_UNUSED(cover_url);
void ContextAlbumsModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) {
if (!pending_art_.contains(id)) return;
@@ -161,13 +159,13 @@ void ContextAlbumsModel::AlbumCoverLoaded(const quint64 id, const QUrl &cover_ur
pending_cache_keys_.remove(cache_key);
// Insert this image in the cache.
if (image.isNull()) {
if (result.image_scaled.isNull()) {
// Set the no_cover image so we don't continually try to load art.
QPixmapCache::insert(cache_key, no_cover_icon_);
}
else {
QPixmap image_pixmap;
image_pixmap = QPixmap::fromImage(image);
image_pixmap = QPixmap::fromImage(result.image_scaled);
QPixmapCache::insert(cache_key, image_pixmap);
}

View File

@@ -45,6 +45,7 @@
#include "collection/collectionitem.h"
#include "collection/sqlrow.h"
#include "covermanager/albumcoverloaderoptions.h"
#include "covermanager/albumcoverloaderresult.h"
class QMimeData;
@@ -99,7 +100,7 @@ class ContextAlbumsModel : public SimpleTreeModel<CollectionItem> {
void LazyPopulate(CollectionItem *item, bool signal);
private slots:
void AlbumCoverLoaded(const quint64 id, const QUrl &cover_url, const QImage &image);
void AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result);
private:
QueryResult RunQuery(CollectionItem *parent);

View File

@@ -124,6 +124,7 @@ ContextView::ContextView(QWidget *parent) :
label_device_icon_(new QLabel(this)),
label_engine_icon_(new QLabel(this)),
spacer_bottom_(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding)),
lyrics_tried_(false),
lyrics_id_(-1),
prev_width_(0)
{
@@ -365,19 +366,22 @@ void ContextView::Error() {}
void ContextView::SongChanged(const Song &song) {
if (widget_stacked_->currentWidget() == widget_play_ && song_playing_.is_valid() && song == song_playing_) {
if (widget_stacked_->currentWidget() == widget_play_ && song_playing_.is_valid() && song == song_playing_ && song.title() == song_playing_.title() && song.album() == song_playing_.album() && song.artist() == song_playing_.artist()) {
UpdateSong(song);
}
else {
song_prev_ = song_playing_;
song_playing_ = song;
lyrics_ = song.lyrics();
lyrics_id_ = -1;
song_playing_ = song;
lyrics_tried_ = false;
SetSong();
if (lyrics_.isEmpty() && action_show_lyrics_->isChecked() && !song.artist().isEmpty() && !song.title().isEmpty()) {
lyrics_fetcher_->Clear();
lyrics_id_ = lyrics_fetcher_->Search(song.effective_albumartist(), song.album(), song.title());
}
}
if (lyrics_.isEmpty() && action_show_lyrics_->isChecked() && !song.artist().isEmpty() && !song.title().isEmpty() && !lyrics_tried_ && lyrics_id_ == -1) {
lyrics_fetcher_->Clear();
lyrics_tried_ = true;
lyrics_id_ = lyrics_fetcher_->Search(song.effective_albumartist(), song.album(), song.title());
}
}
@@ -684,9 +688,7 @@ void ContextView::dropEvent(QDropEvent *e) {
}
void ContextView::AlbumCoverLoaded(const Song &song, const QUrl &cover_url, const QImage &image) {
Q_UNUSED(cover_url);
void ContextView::AlbumCoverLoaded(const Song &song, const QImage &image) {
if (song != song_playing_ || image == image_original_) return;

View File

@@ -91,7 +91,7 @@ class ContextView : public QWidget {
void Stopped();
void Error();
void SongChanged(const Song &song);
void AlbumCoverLoaded(const Song &song, const QUrl &cover_url, const QImage &image);
void AlbumCoverLoaded(const Song &song, const QImage &image);
void FadeStopFinished();
void UpdateLyrics(const quint64 id, const QString &provider, const QString &lyrics);
@@ -164,6 +164,7 @@ class ContextView : public QWidget {
Song song_playing_;
Song song_prev_;
QImage image_original_;
bool lyrics_tried_;
qint64 lyrics_id_;
QString lyrics_;
QString title_fmt_;