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:
parent
26971cfd74
commit
98ad9dbda6
@ -63,6 +63,10 @@ AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget* parent)
|
|||||||
unset_cover_ = new QAction(IconLoader::Load("list-remove"), tr("Unset cover"), this);
|
unset_cover_ = new QAction(IconLoader::Load("list-remove"), tr("Unset cover"), this);
|
||||||
show_cover_ = new QAction(IconLoader::Load("zoom-in"), tr("Show fullsize..."), 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_ = new QAction(this);
|
||||||
separator_->setSeparator(true);
|
separator_->setSeparator(true);
|
||||||
}
|
}
|
||||||
@ -77,6 +81,9 @@ void AlbumCoverChoiceController::SetApplication(Application* app) {
|
|||||||
cover_fetcher_ = new AlbumCoverFetcher(app_->cover_providers(), this);
|
cover_fetcher_ = new AlbumCoverFetcher(app_->cover_providers(), this);
|
||||||
cover_searcher_ = new AlbumCoverSearcher(QIcon(":/nocover.png"), app, this);
|
cover_searcher_ = new AlbumCoverSearcher(QIcon(":/nocover.png"), app, this);
|
||||||
cover_searcher_->Init(cover_fetcher_);
|
cover_searcher_->Init(cover_fetcher_);
|
||||||
|
|
||||||
|
connect(cover_fetcher_, SIGNAL(AlbumCoverFetched(quint64,QImage,CoverSearchStatistics)),
|
||||||
|
this, SLOT(AlbumCoverFetched(quint64,QImage,CoverSearchStatistics)));
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QAction*> AlbumCoverChoiceController::GetAllActions() {
|
QList<QAction*> AlbumCoverChoiceController::GetAllActions() {
|
||||||
@ -204,6 +211,27 @@ void AlbumCoverChoiceController::ShowCover(const Song& song) {
|
|||||||
dialog->show();
|
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) {
|
void AlbumCoverChoiceController::SaveCover(Song* song, const QString &cover) {
|
||||||
if(song->is_valid() && song->id() != -1) {
|
if(song->is_valid() && song->id() != -1) {
|
||||||
song->set_art_manual(cover);
|
song->set_art_manual(cover);
|
||||||
|
@ -27,6 +27,7 @@ class AlbumCoverFetcher;
|
|||||||
class AlbumCoverSearcher;
|
class AlbumCoverSearcher;
|
||||||
class Application;
|
class Application;
|
||||||
class CoverFromURLDialog;
|
class CoverFromURLDialog;
|
||||||
|
class CoverSearchStatistics;
|
||||||
class QFileDialog;
|
class QFileDialog;
|
||||||
class Song;
|
class Song;
|
||||||
|
|
||||||
@ -52,6 +53,7 @@ class AlbumCoverChoiceController : public QWidget {
|
|||||||
QAction* search_for_cover_action() const { return search_for_cover_; }
|
QAction* search_for_cover_action() const { return search_for_cover_; }
|
||||||
QAction* unset_cover_action() const { return unset_cover_; }
|
QAction* unset_cover_action() const { return unset_cover_; }
|
||||||
QAction* show_cover_action() const { return show_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.
|
// Returns QAction* for every operation implemented by this controller.
|
||||||
// The list contains QAction* for:
|
// The list contains QAction* for:
|
||||||
@ -91,6 +93,9 @@ class AlbumCoverChoiceController : public QWidget {
|
|||||||
// Shows the cover of given song in it's original size.
|
// Shows the cover of given song in it's original size.
|
||||||
void ShowCover(const Song& song);
|
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.
|
// Saves the chosen cover as manual cover path of this song in library.
|
||||||
void SaveCover(Song* song, const QString& cover);
|
void SaveCover(Song* song, const QString& cover);
|
||||||
|
|
||||||
@ -103,6 +108,13 @@ class AlbumCoverChoiceController : public QWidget {
|
|||||||
|
|
||||||
static bool CanAcceptDrag(const QDragEnterEvent* e);
|
static bool CanAcceptDrag(const QDragEnterEvent* e);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void AutomaticCoverSearchDone();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void AlbumCoverFetched(quint64 id, const QImage& image,
|
||||||
|
const CoverSearchStatistics& statistics);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString GetInitialPathForFileDialog(const Song& song,
|
QString GetInitialPathForFileDialog(const Song& song,
|
||||||
const QString& filename);
|
const QString& filename);
|
||||||
@ -124,6 +136,9 @@ private:
|
|||||||
QAction* search_for_cover_;
|
QAction* search_for_cover_;
|
||||||
QAction* unset_cover_;
|
QAction* unset_cover_;
|
||||||
QAction* show_cover_;
|
QAction* show_cover_;
|
||||||
|
QAction* search_cover_auto_;
|
||||||
|
|
||||||
|
QMap<quint64, Song> cover_fetching_tasks_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ALBUMCOVERCHOICECONTROLLER_H
|
#endif // ALBUMCOVERCHOICECONTROLLER_H
|
||||||
|
@ -72,6 +72,7 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
|
|||||||
details_(new QTextDocument(this)),
|
details_(new QTextDocument(this)),
|
||||||
previous_track_opacity_(0.0),
|
previous_track_opacity_(0.0),
|
||||||
bask_in_his_glory_action_(NULL),
|
bask_in_his_glory_action_(NULL),
|
||||||
|
downloading_covers_(false),
|
||||||
aww_(false),
|
aww_(false),
|
||||||
kittens_(NULL),
|
kittens_(NULL),
|
||||||
pending_kitten_(0)
|
pending_kitten_(0)
|
||||||
@ -80,6 +81,7 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
|
|||||||
QSettings s;
|
QSettings s;
|
||||||
s.beginGroup(kSettingsGroup);
|
s.beginGroup(kSettingsGroup);
|
||||||
mode_ = Mode(s.value("mode", SmallSongDetails).toInt());
|
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
|
// Accept drops for setting album art
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
@ -96,6 +98,9 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
|
|||||||
|
|
||||||
QList<QAction*> actions = album_cover_choice_controller_->GetAllActions();
|
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(),
|
connect(album_cover_choice_controller_->cover_from_file_action(),
|
||||||
SIGNAL(triggered()), this, SLOT(LoadCoverFromFile()));
|
SIGNAL(triggered()), this, SLOT(LoadCoverFromFile()));
|
||||||
connect(album_cover_choice_controller_->cover_to_file_action(),
|
connect(album_cover_choice_controller_->cover_to_file_action(),
|
||||||
@ -108,6 +113,8 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
|
|||||||
SIGNAL(triggered()), this, SLOT(UnsetCover()));
|
SIGNAL(triggered()), this, SLOT(UnsetCover()));
|
||||||
connect(album_cover_choice_controller_->show_cover_action(),
|
connect(album_cover_choice_controller_->show_cover_action(),
|
||||||
SIGNAL(triggered()), this, SLOT(ShowCover()));
|
SIGNAL(triggered()), this, SLOT(ShowCover()));
|
||||||
|
connect(album_cover_choice_controller_->search_cover_auto_action(),
|
||||||
|
SIGNAL(triggered()), this, SLOT(SearchCoverAutomatically()));
|
||||||
|
|
||||||
menu_->addActions(actions);
|
menu_->addActions(actions);
|
||||||
menu_->addSeparator();
|
menu_->addSeparator();
|
||||||
@ -129,6 +136,9 @@ NowPlayingWidget::NowPlayingWidget(QWidget* parent)
|
|||||||
fade_animation_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
|
fade_animation_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
|
||||||
|
|
||||||
UpdateHeight();
|
UpdateHeight();
|
||||||
|
|
||||||
|
connect(album_cover_choice_controller_, SIGNAL(AutomaticCoverSearchDone()),
|
||||||
|
this, SLOT(AutomaticCoverSearchDone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
NowPlayingWidget::~NowPlayingWidget() {
|
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) {
|
const QImage& image) {
|
||||||
metadata_ = metadata;
|
metadata_ = metadata;
|
||||||
|
downloading_covers_ = false;
|
||||||
|
|
||||||
if (aww_) {
|
if (aww_) {
|
||||||
pending_kitten_ = kittens_->LoadKitten(app_->current_art_loader()->options());
|
pending_kitten_ = kittens_->LoadKitten(app_->current_art_loader()->options());
|
||||||
@ -243,6 +254,9 @@ void NowPlayingWidget::AlbumArtLoaded(const Song& metadata, const QString&,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetImage(image);
|
SetImage(image);
|
||||||
|
|
||||||
|
// Search for cover automatically?
|
||||||
|
GetCoverAutomatically();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NowPlayingWidget::SetImage(const QImage& image) {
|
void NowPlayingWidget::SetImage(const QImage& image) {
|
||||||
@ -301,6 +315,9 @@ void NowPlayingWidget::DrawContents(QPainter *p) {
|
|||||||
} else {
|
} else {
|
||||||
// Draw the cover
|
// Draw the cover
|
||||||
p->drawPixmap(0, 0, small_ideal_height_, small_ideal_height_, 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
|
// Draw the details
|
||||||
@ -321,6 +338,9 @@ void NowPlayingWidget::DrawContents(QPainter *p) {
|
|||||||
p->drawPixmap(x_offset, kTopBorder, total_size, total_size, hypnotoad_->currentPixmap());
|
p->drawPixmap(x_offset, kTopBorder, total_size, total_size, hypnotoad_->currentPixmap());
|
||||||
} else {
|
} else {
|
||||||
p->drawPixmap(x_offset, kTopBorder, total_size, total_size, cover_);
|
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
|
// Work out how high the text is going to be
|
||||||
@ -454,6 +474,15 @@ void NowPlayingWidget::ShowCover() {
|
|||||||
album_cover_choice_controller_->ShowCover(metadata_);
|
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() {
|
void NowPlayingWidget::Bask() {
|
||||||
big_hypnotoad_.reset(new FullscreenHypnotoad);
|
big_hypnotoad_.reset(new FullscreenHypnotoad);
|
||||||
big_hypnotoad_->showFullScreen();
|
big_hypnotoad_->showFullScreen();
|
||||||
@ -472,3 +501,31 @@ void NowPlayingWidget::dropEvent(QDropEvent* e) {
|
|||||||
|
|
||||||
QWidget::dropEvent(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();
|
||||||
|
}
|
||||||
|
@ -99,9 +99,12 @@ private slots:
|
|||||||
void SearchForCover();
|
void SearchForCover();
|
||||||
void UnsetCover();
|
void UnsetCover();
|
||||||
void ShowCover();
|
void ShowCover();
|
||||||
|
void SearchCoverAutomatically();
|
||||||
|
|
||||||
void Bask();
|
void Bask();
|
||||||
|
|
||||||
|
void AutomaticCoverSearchDone();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateModeAction(Mode mode, const QString& text, QActionGroup* group,
|
void CreateModeAction(Mode mode, const QString& text, QActionGroup* group,
|
||||||
QSignalMapper* mapper);
|
QSignalMapper* mapper);
|
||||||
@ -110,6 +113,7 @@ private:
|
|||||||
void DrawContents(QPainter* p);
|
void DrawContents(QPainter* p);
|
||||||
void SetImage(const QImage& image);
|
void SetImage(const QImage& image);
|
||||||
void ScaleCover();
|
void ScaleCover();
|
||||||
|
bool GetCoverAutomatically();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Application* app_;
|
Application* app_;
|
||||||
@ -144,6 +148,9 @@ private:
|
|||||||
boost::scoped_ptr<QMovie> hypnotoad_;
|
boost::scoped_ptr<QMovie> hypnotoad_;
|
||||||
boost::scoped_ptr<FullscreenHypnotoad> big_hypnotoad_;
|
boost::scoped_ptr<FullscreenHypnotoad> big_hypnotoad_;
|
||||||
|
|
||||||
|
boost::scoped_ptr<QMovie> spinner_animation_;
|
||||||
|
bool downloading_covers_;
|
||||||
|
|
||||||
bool aww_;
|
bool aww_;
|
||||||
KittenLoader* kittens_;
|
KittenLoader* kittens_;
|
||||||
quint64 pending_kitten_;
|
quint64 pending_kitten_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user