Add possibility to download album covers automatically when playing a track without one. To activate: right click on now playing widget and select "Search automatically".

This commit is contained in:
Andreas 2013-12-30 23:50:57 +01:00
parent 26971cfd74
commit 98ad9dbda6
4 changed files with 108 additions and 1 deletions

View File

@ -63,6 +63,10 @@ AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget* parent)
unset_cover_ = new QAction(IconLoader::Load("list-remove"), tr("Unset cover"), this);
show_cover_ = new QAction(IconLoader::Load("zoom-in"), tr("Show fullsize..."), this);
search_cover_auto_ = new QAction(IconLoader::Load("find"), tr("Search automatically"), this);
search_cover_auto_->setCheckable(true);
search_cover_auto_->setChecked(false);
separator_ = new QAction(this);
separator_->setSeparator(true);
}
@ -77,6 +81,9 @@ void AlbumCoverChoiceController::SetApplication(Application* app) {
cover_fetcher_ = new AlbumCoverFetcher(app_->cover_providers(), this);
cover_searcher_ = new AlbumCoverSearcher(QIcon(":/nocover.png"), app, this);
cover_searcher_->Init(cover_fetcher_);
connect(cover_fetcher_, SIGNAL(AlbumCoverFetched(quint64,QImage,CoverSearchStatistics)),
this, SLOT(AlbumCoverFetched(quint64,QImage,CoverSearchStatistics)));
}
QList<QAction*> AlbumCoverChoiceController::GetAllActions() {
@ -204,6 +211,27 @@ void AlbumCoverChoiceController::ShowCover(const Song& song) {
dialog->show();
}
void AlbumCoverChoiceController::SearchCoverAutomatically(const Song& song) {
qint64 id = cover_fetcher_->FetchAlbumCover(song.artist(), song.album());
cover_fetching_tasks_[id] = song;
}
void AlbumCoverChoiceController::AlbumCoverFetched(quint64 id,
const QImage &image,
const CoverSearchStatistics &statistics) {
Song song;
if (cover_fetching_tasks_.contains(id)) {
song = cover_fetching_tasks_.take(id);
}
if (!image.isNull()) {
QString cover = SaveCoverInCache(song.artist(), song.album(), image);
SaveCover(&song, cover);
}
emit AutomaticCoverSearchDone();
}
void AlbumCoverChoiceController::SaveCover(Song* song, const QString &cover) {
if(song->is_valid() && song->id() != -1) {
song->set_art_manual(cover);

View File

@ -27,6 +27,7 @@ class AlbumCoverFetcher;
class AlbumCoverSearcher;
class Application;
class CoverFromURLDialog;
class CoverSearchStatistics;
class QFileDialog;
class Song;
@ -52,6 +53,7 @@ class AlbumCoverChoiceController : public QWidget {
QAction* search_for_cover_action() const { return search_for_cover_; }
QAction* unset_cover_action() const { return unset_cover_; }
QAction* show_cover_action() const { return show_cover_; }
QAction* search_cover_auto_action() const { return search_cover_auto_; }
// Returns QAction* for every operation implemented by this controller.
// The list contains QAction* for:
@ -91,6 +93,9 @@ class AlbumCoverChoiceController : public QWidget {
// Shows the cover of given song in it's original size.
void ShowCover(const Song& song);
// Search for covers automatically
void SearchCoverAutomatically(const Song& song);
// Saves the chosen cover as manual cover path of this song in library.
void SaveCover(Song* song, const QString& cover);
@ -103,6 +108,13 @@ class AlbumCoverChoiceController : public QWidget {
static bool CanAcceptDrag(const QDragEnterEvent* e);
signals:
void AutomaticCoverSearchDone();
private slots:
void AlbumCoverFetched(quint64 id, const QImage& image,
const CoverSearchStatistics& statistics);
private:
QString GetInitialPathForFileDialog(const Song& song,
const QString& filename);
@ -124,6 +136,9 @@ private:
QAction* search_for_cover_;
QAction* unset_cover_;
QAction* show_cover_;
QAction* search_cover_auto_;
QMap<quint64, Song> cover_fetching_tasks_;
};
#endif // ALBUMCOVERCHOICECONTROLLER_H

View File

@ -72,6 +72,7 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
details_(new QTextDocument(this)),
previous_track_opacity_(0.0),
bask_in_his_glory_action_(NULL),
downloading_covers_(false),
aww_(false),
kittens_(NULL),
pending_kitten_(0)
@ -80,6 +81,7 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
QSettings s;
s.beginGroup(kSettingsGroup);
mode_ = Mode(s.value("mode", SmallSongDetails).toInt());
album_cover_choice_controller_->search_cover_auto_action()->setChecked(s.value("search_for_cover_auto", false).toBool());
// Accept drops for setting album art
setAcceptDrops(true);
@ -96,6 +98,9 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
QList<QAction*> actions = album_cover_choice_controller_->GetAllActions();
// Here we add the search automatically action, too!
actions.append(album_cover_choice_controller_->search_cover_auto_action());
connect(album_cover_choice_controller_->cover_from_file_action(),
SIGNAL(triggered()), this, SLOT(LoadCoverFromFile()));
connect(album_cover_choice_controller_->cover_to_file_action(),
@ -108,6 +113,8 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
SIGNAL(triggered()), this, SLOT(UnsetCover()));
connect(album_cover_choice_controller_->show_cover_action(),
SIGNAL(triggered()), this, SLOT(ShowCover()));
connect(album_cover_choice_controller_->search_cover_auto_action(),
SIGNAL(triggered()), this, SLOT(SearchCoverAutomatically()));
menu_->addActions(actions);
menu_->addSeparator();
@ -129,6 +136,9 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
fade_animation_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
UpdateHeight();
connect(album_cover_choice_controller_, SIGNAL(AutomaticCoverSearchDone()),
this, SLOT(AutomaticCoverSearchDone()));
}
NowPlayingWidget::~NowPlayingWidget() {
@ -233,9 +243,10 @@ void NowPlayingWidget::KittenLoaded(quint64 id, const QImage& image) {
}
}
void NowPlayingWidget::AlbumArtLoaded(const Song& metadata, const QString&,
void NowPlayingWidget::AlbumArtLoaded(const Song& metadata, const QString& uri,
const QImage& image) {
metadata_ = metadata;
downloading_covers_ = false;
if (aww_) {
pending_kitten_ = kittens_->LoadKitten(app_->current_art_loader()->options());
@ -243,6 +254,9 @@ void NowPlayingWidget::AlbumArtLoaded(const Song& metadata, const QString&,
}
SetImage(image);
// Search for cover automatically?
GetCoverAutomatically();
}
void NowPlayingWidget::SetImage(const QImage& image) {
@ -301,6 +315,9 @@ void NowPlayingWidget::DrawContents(QPainter *p) {
} else {
// Draw the cover
p->drawPixmap(0, 0, small_ideal_height_, small_ideal_height_, cover_);
if (downloading_covers_) {
p->drawPixmap(small_ideal_height_ - 18, 6, 16, 16, spinner_animation_->currentPixmap());
}
}
// Draw the details
@ -321,6 +338,9 @@ void NowPlayingWidget::DrawContents(QPainter *p) {
p->drawPixmap(x_offset, kTopBorder, total_size, total_size, hypnotoad_->currentPixmap());
} else {
p->drawPixmap(x_offset, kTopBorder, total_size, total_size, cover_);
if (downloading_covers_) {
p->drawPixmap(total_size - 31, 40, 16, 16, spinner_animation_->currentPixmap());
}
}
// Work out how high the text is going to be
@ -454,6 +474,15 @@ void NowPlayingWidget::ShowCover() {
album_cover_choice_controller_->ShowCover(metadata_);
}
void NowPlayingWidget::SearchCoverAutomatically() {
QSettings s;
s.beginGroup(kSettingsGroup);
s.setValue("search_for_cover_auto", album_cover_choice_controller_->search_cover_auto_action()->isChecked());
// Search for cover automatically?
GetCoverAutomatically();
}
void NowPlayingWidget::Bask() {
big_hypnotoad_.reset(new FullscreenHypnotoad);
big_hypnotoad_->showFullScreen();
@ -472,3 +501,31 @@ void NowPlayingWidget::dropEvent(QDropEvent* e) {
QWidget::dropEvent(e);
}
bool NowPlayingWidget::GetCoverAutomatically() {
// Search for cover automatically?
bool search = album_cover_choice_controller_->search_cover_auto_action()->isChecked() &&
!metadata_.has_manually_unset_cover() &&
metadata_.art_automatic().isEmpty() &&
metadata_.art_manual().isEmpty();
if (search) {
qLog(Debug) << "GetCoverAutomatically";
downloading_covers_ = true;
album_cover_choice_controller_->SearchCoverAutomatically(metadata_);
// Show a spinner animation
spinner_animation_.reset(new QMovie(":/spinner.gif", QByteArray(), this));
connect(spinner_animation_.get(), SIGNAL(updated(const QRect&)), SLOT(update()));
spinner_animation_->start();
update();
}
return search;
}
void NowPlayingWidget::AutomaticCoverSearchDone() {
downloading_covers_ = false;
spinner_animation_.reset();
update();
}

View File

@ -99,9 +99,12 @@ private slots:
void SearchForCover();
void UnsetCover();
void ShowCover();
void SearchCoverAutomatically();
void Bask();
void AutomaticCoverSearchDone();
private:
void CreateModeAction(Mode mode, const QString& text, QActionGroup* group,
QSignalMapper* mapper);
@ -110,6 +113,7 @@ private:
void DrawContents(QPainter* p);
void SetImage(const QImage& image);
void ScaleCover();
bool GetCoverAutomatically();
private:
Application* app_;
@ -144,6 +148,9 @@ private:
boost::scoped_ptr<QMovie> hypnotoad_;
boost::scoped_ptr<FullscreenHypnotoad> big_hypnotoad_;
boost::scoped_ptr<QMovie> spinner_animation_;
bool downloading_covers_;
bool aww_;
KittenLoader* kittens_;
quint64 pending_kitten_;