mirror of
https://github.com/clementine-player/Clementine
synced 2024-12-14 10:24:19 +01:00
Show all the artist info at once rather than as it arrives, make resizing the text areas smoother, remove duplicate biogoraphies.
This commit is contained in:
parent
7e39bfece2
commit
547a009d73
@ -26,14 +26,47 @@ ArtistInfoFetcher::ArtistInfoFetcher(QObject* parent)
|
||||
|
||||
void ArtistInfoFetcher::AddProvider(ArtistInfoProvider* provider) {
|
||||
providers_ << provider;
|
||||
connect(provider, SIGNAL(ImageReady(int,QUrl)), SIGNAL(ImageReady(int,QUrl)));
|
||||
connect(provider, SIGNAL(InfoReady(int,CollapsibleInfoPane::Data)), SIGNAL(InfoReady(int,CollapsibleInfoPane::Data)));
|
||||
connect(provider, SIGNAL(ImageReady(int,QUrl)), SLOT(ImageReady(int,QUrl)));
|
||||
connect(provider, SIGNAL(InfoReady(int,CollapsibleInfoPane::Data)), SLOT(InfoReady(int,CollapsibleInfoPane::Data)));
|
||||
connect(provider, SIGNAL(Finished(int)), SLOT(ProviderFinished(int)));
|
||||
}
|
||||
|
||||
int ArtistInfoFetcher::FetchInfo(const QString& artist) {
|
||||
const int id = next_id_ ++;
|
||||
results_[id] = Result();
|
||||
|
||||
foreach (ArtistInfoProvider* provider, providers_) {
|
||||
waiting_for_[id].append(provider);
|
||||
provider->FetchInfo(id, artist);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void ArtistInfoFetcher::ImageReady(int id, const QUrl& url) {
|
||||
if (!results_.contains(id))
|
||||
return;
|
||||
results_[id].images_ << url;
|
||||
}
|
||||
|
||||
void ArtistInfoFetcher::InfoReady(int id, const CollapsibleInfoPane::Data& data) {
|
||||
if (!results_.contains(id))
|
||||
return;
|
||||
results_[id].info_ << data;
|
||||
}
|
||||
|
||||
void ArtistInfoFetcher::ProviderFinished(int id) {
|
||||
if (!results_.contains(id))
|
||||
return;
|
||||
if (!waiting_for_.contains(id))
|
||||
return;
|
||||
|
||||
ArtistInfoProvider* provider = qobject_cast<ArtistInfoProvider*>(sender());
|
||||
if (!waiting_for_[id].contains(provider))
|
||||
return;
|
||||
|
||||
waiting_for_[id].removeAll(provider);
|
||||
if (waiting_for_[id].isEmpty()) {
|
||||
emit ResultReady(id, results_.take(id));
|
||||
waiting_for_.remove(id);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#ifndef ARTISTINFOFETCHER_H
|
||||
#define ARTISTINFOFETCHER_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
@ -30,11 +31,20 @@ class ArtistInfoFetcher : public QObject {
|
||||
public:
|
||||
ArtistInfoFetcher(QObject* parent = 0);
|
||||
|
||||
struct Result {
|
||||
QList<QUrl> images_;
|
||||
QList<CollapsibleInfoPane::Data> info_;
|
||||
};
|
||||
|
||||
int FetchInfo(const QString& artist);
|
||||
|
||||
signals:
|
||||
void ResultReady(int id, const ArtistInfoFetcher::Result& result);
|
||||
|
||||
private slots:
|
||||
void ImageReady(int id, const QUrl& url);
|
||||
void InfoReady(int id, const CollapsibleInfoPane::Data&);
|
||||
void InfoReady(int id, const CollapsibleInfoPane::Data& data);
|
||||
void ProviderFinished(int id);
|
||||
|
||||
private:
|
||||
void AddProvider(ArtistInfoProvider* provider);
|
||||
@ -42,6 +52,9 @@ private:
|
||||
private:
|
||||
QList<ArtistInfoProvider*> providers_;
|
||||
|
||||
QMap<int, Result> results_;
|
||||
QMap<int, QList<ArtistInfoProvider*> > waiting_for_;
|
||||
|
||||
int next_id_;
|
||||
};
|
||||
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
signals:
|
||||
void ImageReady(int id, const QUrl& url);
|
||||
void InfoReady(int id, const CollapsibleInfoPane::Data& data);
|
||||
void Finished(int id);
|
||||
};
|
||||
|
||||
#endif // ARTISTINFOPROVIDER_H
|
||||
|
@ -34,8 +34,8 @@ ArtistInfoView::ArtistInfoView(NetworkAccessManager* network, QWidget *parent)
|
||||
image_view_(NULL),
|
||||
section_container_(NULL)
|
||||
{
|
||||
connect(fetcher_, SIGNAL(ImageReady(int,QUrl)), SLOT(ImageReady(int,QUrl)));
|
||||
connect(fetcher_, SIGNAL(InfoReady(int,CollapsibleInfoPane::Data)), SLOT(InfoReady(int,CollapsibleInfoPane::Data)));
|
||||
connect(fetcher_, SIGNAL(ResultReady(int,ArtistInfoFetcher::Result)),
|
||||
SLOT(ResultReady(int,ArtistInfoFetcher::Result)));
|
||||
|
||||
// Add the top-level scroll area
|
||||
setLayout(new QVBoxLayout);
|
||||
@ -88,8 +88,14 @@ bool ArtistInfoView::NeedsUpdate(const Song& old_metadata, const Song& new_metad
|
||||
}
|
||||
|
||||
void ArtistInfoView::Update(const Song& metadata) {
|
||||
Clear();
|
||||
current_request_id_ = fetcher_->FetchInfo(metadata.artist());
|
||||
}
|
||||
|
||||
void ArtistInfoView::ResultReady(int id, const ArtistInfoFetcher::Result& result) {
|
||||
if (id != current_request_id_)
|
||||
return;
|
||||
|
||||
Clear();
|
||||
|
||||
// Image view goes at the top
|
||||
image_view_ = new PrettyImageView(network_);
|
||||
@ -102,20 +108,12 @@ void ArtistInfoView::Update(const Song& metadata) {
|
||||
section_container_->layout()->setSpacing(1);
|
||||
section_container_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
container_->insertWidget(1, section_container_);
|
||||
}
|
||||
|
||||
void ArtistInfoView::ImageReady(int id, const QUrl& url) {
|
||||
if (id != current_request_id_)
|
||||
return;
|
||||
|
||||
image_view_->AddImage(url);
|
||||
}
|
||||
|
||||
void ArtistInfoView::InfoReady(int id, const CollapsibleInfoPane::Data& data) {
|
||||
if (id != current_request_id_) {
|
||||
delete data.contents_;
|
||||
return;
|
||||
foreach (const QUrl& url, result.images_) {
|
||||
image_view_->AddImage(url);
|
||||
}
|
||||
|
||||
AddSection(new CollapsibleInfoPane(data, this));
|
||||
foreach (const CollapsibleInfoPane::Data& data, result.info_) {
|
||||
AddSection(new CollapsibleInfoPane(data, this));
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#ifndef ARTISTINFOVIEW_H
|
||||
#define ARTISTINFOVIEW_H
|
||||
|
||||
#include "artistinfofetcher.h"
|
||||
#include "collapsibleinfopane.h"
|
||||
#include "songinfobase.h"
|
||||
|
||||
@ -42,8 +43,7 @@ private:
|
||||
void Clear();
|
||||
|
||||
private slots:
|
||||
void ImageReady(int id, const QUrl& url);
|
||||
void InfoReady(int id, const CollapsibleInfoPane::Data& data);
|
||||
void ResultReady(int id, const ArtistInfoFetcher::Result& result);
|
||||
|
||||
private:
|
||||
ArtistInfoFetcher* fetcher_;
|
||||
|
@ -24,6 +24,8 @@
|
||||
struct EchoNestArtistInfo::Request {
|
||||
Request(int id) : id_(id), artist_(new Echonest::Artist) {}
|
||||
|
||||
bool is_finished() const { return pending_replies_.isEmpty(); }
|
||||
|
||||
int id_;
|
||||
boost::scoped_ptr<Echonest::Artist> artist_;
|
||||
QList<QNetworkReply*> pending_replies_;
|
||||
@ -33,7 +35,6 @@ EchoNestArtistInfo::EchoNestArtistInfo(QObject* parent)
|
||||
: ArtistInfoProvider(parent)
|
||||
{
|
||||
site_relevance_["wikipedia"] = 100;
|
||||
site_relevance_["last.fm"] = 60;
|
||||
site_relevance_["lastfm"] = 60;
|
||||
site_relevance_["amazon"] = 30;
|
||||
|
||||
@ -41,7 +42,6 @@ EchoNestArtistInfo::EchoNestArtistInfo(QObject* parent)
|
||||
site_icons_["aol"] = QIcon(":/providers/aol.png");
|
||||
site_icons_["cdbaby"] = QIcon(":/providers/cdbaby.png");
|
||||
site_icons_["lastfm"] = QIcon(":/last.fm/as.png");
|
||||
site_icons_["last.fm"] = QIcon(":/last.fm/as.png");
|
||||
site_icons_["mog"] = QIcon(":/providers/mog.png");
|
||||
site_icons_["mtvmusic"] = QIcon(":/providers/mtvmusic.png");
|
||||
site_icons_["myspace"] = QIcon(":/providers/myspace.png");
|
||||
@ -77,7 +77,7 @@ EchoNestArtistInfo::RequestPtr EchoNestArtistInfo::ReplyFinished(QNetworkReply*
|
||||
|
||||
request->pending_replies_.removeAll(reply);
|
||||
|
||||
if (request->pending_replies_.isEmpty()) {
|
||||
if (request->is_finished()) {
|
||||
requests_.removeAll(request);
|
||||
}
|
||||
|
||||
@ -93,6 +93,9 @@ void EchoNestArtistInfo::ImagesFinished() {
|
||||
foreach (const Echonest::ArtistImage& image, request->artist_->images()) {
|
||||
emit ImageReady(request->id_, image.url());
|
||||
}
|
||||
|
||||
if (request->is_finished())
|
||||
emit Finished(request->id_);
|
||||
}
|
||||
|
||||
void EchoNestArtistInfo::BiographiesFinished() {
|
||||
@ -101,19 +104,21 @@ void EchoNestArtistInfo::BiographiesFinished() {
|
||||
QSet<QString> already_seen;
|
||||
|
||||
foreach (const Echonest::Biography& bio, request->artist_->biographies()) {
|
||||
if (already_seen.contains(bio.text()))
|
||||
QString canonical_site = bio.site().toLower();
|
||||
canonical_site.replace(QRegExp("[^a-z]"),"");
|
||||
|
||||
if (already_seen.contains(canonical_site))
|
||||
continue;
|
||||
already_seen.insert(bio.text());
|
||||
already_seen.insert(canonical_site);
|
||||
|
||||
CollapsibleInfoPane::Data data;
|
||||
data.title_ = tr("Biography from %1").arg(bio.site());
|
||||
data.type_ = CollapsibleInfoPane::Data::Type_Biography;
|
||||
|
||||
const QString site = bio.site().toLower();
|
||||
if (site_relevance_.contains(site))
|
||||
data.relevance_ = site_relevance_[site];
|
||||
if (site_icons_.contains(site))
|
||||
data.icon_ = site_icons_[site];
|
||||
if (site_relevance_.contains(canonical_site))
|
||||
data.relevance_ = site_relevance_[canonical_site];
|
||||
if (site_icons_.contains(canonical_site))
|
||||
data.icon_ = site_icons_[canonical_site];
|
||||
|
||||
AutoSizedTextEdit* editor = new AutoSizedTextEdit;
|
||||
editor->setHtml(bio.text());
|
||||
@ -121,4 +126,7 @@ void EchoNestArtistInfo::BiographiesFinished() {
|
||||
|
||||
emit InfoReady(request->id_, data);
|
||||
}
|
||||
|
||||
if (request->is_finished())
|
||||
emit Finished(request->id_);
|
||||
}
|
||||
|
@ -19,7 +19,8 @@
|
||||
#include <QWheelEvent>
|
||||
|
||||
AutoSizedTextEdit::AutoSizedTextEdit(QWidget* parent)
|
||||
: QTextEdit(parent)
|
||||
: QTextEdit(parent),
|
||||
last_width_(-1)
|
||||
{
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
@ -27,6 +28,9 @@ AutoSizedTextEdit::AutoSizedTextEdit(QWidget* parent)
|
||||
|
||||
void AutoSizedTextEdit::resizeEvent(QResizeEvent* e) {
|
||||
const int w = qMax(100, width());
|
||||
if (w == last_width_)
|
||||
return;
|
||||
last_width_ = w;
|
||||
|
||||
document()->setTextWidth(w);
|
||||
setMinimumHeight(document()->size().height());
|
||||
|
@ -30,6 +30,9 @@ public:
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* e);
|
||||
void wheelEvent(QWheelEvent* e);
|
||||
|
||||
private:
|
||||
int last_width_;
|
||||
};
|
||||
|
||||
#endif // AUTOSIZEDTEXTEDIT_H
|
||||
|
Loading…
Reference in New Issue
Block a user