From 36abad486baa477ba0f08f8f6e64f3fdae548d6f Mon Sep 17 00:00:00 2001 From: David Sansome Date: Sat, 12 Jun 2010 17:13:01 +0000 Subject: [PATCH] Add a dialog for manual searching of Last.fm album covers. Fixes issue #402 --- src/CMakeLists.txt | 3 + src/core/albumcoverfetcher.cpp | 70 +++++++++++++-- src/core/albumcoverfetcher.h | 13 +++ src/radio/lastfmconfig.ui | 3 + src/translations/ar.po | 8 +- src/translations/cs.po | 13 ++- src/translations/da.po | 13 ++- src/translations/de.po | 13 ++- src/translations/el.po | 13 ++- src/translations/en_CA.po | 13 ++- src/translations/en_GB.po | 13 ++- src/translations/es.po | 13 ++- src/translations/fi.po | 8 +- src/translations/fr.po | 13 ++- src/translations/gl.po | 8 +- src/translations/it.po | 13 ++- src/translations/kk.po | 8 +- src/translations/nb.po | 13 ++- src/translations/oc.po | 8 +- src/translations/pl.po | 13 ++- src/translations/pt.po | 13 ++- src/translations/pt_BR.po | 13 ++- src/translations/ro.po | 8 +- src/translations/ru.po | 13 ++- src/translations/sk.po | 13 ++- src/translations/sv.po | 13 ++- src/translations/tr.po | 8 +- src/translations/zh_CN.po | 8 +- src/translations/zh_TW.po | 8 +- src/ui/albumcovermanager.cpp | 81 ++++++++++++------ src/ui/albumcovermanager.h | 6 ++ src/ui/albumcovermanager.ui | 7 +- src/ui/albumcoversearcher.cpp | 134 +++++++++++++++++++++++++++++ src/ui/albumcoversearcher.h | 71 ++++++++++++++++ src/ui/albumcoversearcher.ui | 150 +++++++++++++++++++++++++++++++++ src/widgets/lineedit.h | 1 + 36 files changed, 743 insertions(+), 76 deletions(-) create mode 100644 src/ui/albumcoversearcher.cpp create mode 100644 src/ui/albumcoversearcher.h create mode 100644 src/ui/albumcoversearcher.ui diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 690e90048..a7247f947 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -105,6 +105,7 @@ set(SOURCES ui/addstreamdialog.cpp ui/albumcovermanager.cpp ui/albumcovermanagerlist.cpp + ui/albumcoversearcher.cpp ui/edittagdialog.cpp ui/equalizer.cpp ui/globalshortcutgrabber.cpp @@ -203,6 +204,7 @@ set(HEADERS ui/addstreamdialog.h ui/albumcovermanager.h ui/albumcovermanagerlist.h + ui/albumcoversearcher.h ui/edittagdialog.h ui/equalizer.h ui/globalshortcutgrabber.h @@ -248,6 +250,7 @@ set(UI ui/about.ui ui/addstreamdialog.ui ui/albumcovermanager.ui + ui/albumcoversearcher.ui ui/edittagdialog.ui ui/equalizer.ui ui/globalshortcutgrabber.ui diff --git a/src/core/albumcoverfetcher.cpp b/src/core/albumcoverfetcher.cpp index 9c225f385..5db74657e 100644 --- a/src/core/albumcoverfetcher.cpp +++ b/src/core/albumcoverfetcher.cpp @@ -43,15 +43,27 @@ quint64 AlbumCoverFetcher::FetchAlbumCover( request.artist = artist_name; request.id = next_id_ ++; - queued_requests_.enqueue(request); + AddRequest(request); + return request.id; +} + +quint64 AlbumCoverFetcher::SearchForCovers(const QString &query) { + QueuedRequest request; + request.query = query; + request.id = next_id_ ++; + + AddRequest(request); + return request.id; +} + +void AlbumCoverFetcher::AddRequest(QueuedRequest req) { + queued_requests_.enqueue(req); if (!request_starter_->isActive()) request_starter_->start(); if (active_requests_.count() < kMaxConcurrentRequests) StartRequests(); - - return request.id; } void AlbumCoverFetcher::Clear() { @@ -68,12 +80,22 @@ void AlbumCoverFetcher::StartRequests() { active_requests_.count() < kMaxConcurrentRequests) { QueuedRequest request = queued_requests_.dequeue(); - lastfm::Artist artist(request.artist); - lastfm::Album album(artist, request.album); + if (request.query.isEmpty()) { + lastfm::Artist artist(request.artist); + lastfm::Album album(artist, request.album); - QNetworkReply* reply = album.getInfo(); - connect(reply, SIGNAL(finished()), SLOT(AlbumGetInfoFinished())); - active_requests_.insert(reply, request.id); + QNetworkReply* reply = album.getInfo(); + connect(reply, SIGNAL(finished()), SLOT(AlbumGetInfoFinished())); + active_requests_.insert(reply, request.id); + } else { + QMap params; + params["method"] = "album.search"; + params["album"] = request.query; + + QNetworkReply* reply = lastfm::ws::post(params); + connect(reply, SIGNAL(finished()), SLOT(AlbumSearchFinished())); + active_requests_.insert(reply, request.id); + } } } @@ -101,6 +123,38 @@ void AlbumCoverFetcher::AlbumGetInfoFinished() { } } +void AlbumCoverFetcher::AlbumSearchFinished() { + QNetworkReply* reply = qobject_cast(sender()); + reply->deleteLater(); + quint64 id = active_requests_.take(reply); + + if (reply->error() != QNetworkReply::NoError) { + qDebug() << "Error" << reply->error(); + // TODO: retry request. + emit SearchFinished(id, SearchResults()); + return; + } + + try { + lastfm::XmlQuery query(lastfm::ws::parse(reply)); + + QList elements = query["results"]["albummatches"].children("album"); + SearchResults results; + foreach (const lastfm::XmlQuery& element, elements) { + SearchResult result; + result.album = element["name"].text(); + result.artist = element["artist"].text(); + result.image_url = element["image size=large"].text(); + results << result; + } + + emit SearchFinished(id, results); + } catch (std::runtime_error&) { + qDebug() << "Parse error"; + emit SearchFinished(id, SearchResults()); + } +} + void AlbumCoverFetcher::AlbumCoverFetchFinished() { QNetworkReply* reply = qobject_cast(sender()); reply->deleteLater(); diff --git a/src/core/albumcoverfetcher.h b/src/core/albumcoverfetcher.h index f0625839e..d5997c6c0 100644 --- a/src/core/albumcoverfetcher.h +++ b/src/core/albumcoverfetcher.h @@ -39,27 +39,40 @@ class AlbumCoverFetcher : public QObject { AlbumCoverFetcher(NetworkAccessManager* network, QObject* parent = 0); virtual ~AlbumCoverFetcher() {} + struct SearchResult { + QString artist; + QString album; + QString image_url; + }; + typedef QList SearchResults; + static const int kMaxConcurrentRequests; + quint64 SearchForCovers(const QString& query); quint64 FetchAlbumCover(const QString& artist, const QString& album); void Clear(); signals: void AlbumCoverFetched(quint64, const QImage& cover); + void SearchFinished(quint64, const AlbumCoverFetcher::SearchResults& results); private slots: void AlbumGetInfoFinished(); void AlbumCoverFetchFinished(); void StartRequests(); + void AlbumSearchFinished(); private: struct QueuedRequest { quint64 id; + QString query; QString artist; QString album; }; + void AddRequest(const QueuedRequest req); + QNetworkAccessManager* network_; quint64 next_id_; diff --git a/src/radio/lastfmconfig.ui b/src/radio/lastfmconfig.ui index 03f592e81..4583ec4f4 100644 --- a/src/radio/lastfmconfig.ui +++ b/src/radio/lastfmconfig.ui @@ -113,6 +113,9 @@ + + 0 + diff --git a/src/translations/ar.po b/src/translations/ar.po index d9e6d53ec..f24f0610c 100644 --- a/src/translations/ar.po +++ b/src/translations/ar.po @@ -1107,18 +1107,24 @@ msgstr "" msgid "Fetch automatically" msgstr "" -msgid "Choose manual cover..." +msgid "Load cover from disk..." msgstr "" msgid "Unset cover" msgstr "" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "" msgid "Fetch Missing Covers" msgstr "" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "" diff --git a/src/translations/cs.po b/src/translations/cs.po index f3c2284f5..cd6041987 100644 --- a/src/translations/cs.po +++ b/src/translations/cs.po @@ -1111,18 +1111,24 @@ msgstr "Zobrazit v plné velikosti..." msgid "Fetch automatically" msgstr "Automaticky stáhnout" -msgid "Choose manual cover..." -msgstr "Vybrat obal ručně..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Odebrat obal" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "POhled" msgid "Fetch Missing Covers" msgstr "Stáhnout chybějící obaly" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Upravit informaci o skladbách" @@ -1429,6 +1435,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Vybrat obal ručně..." + #~ msgid "Show section" #~ msgstr "Zobrazit skeci" diff --git a/src/translations/da.po b/src/translations/da.po index 224353ad5..768a81de0 100644 --- a/src/translations/da.po +++ b/src/translations/da.po @@ -1114,18 +1114,24 @@ msgstr "Vis i fuld størrelse..." msgid "Fetch automatically" msgstr "Hent automatisk" -msgid "Choose manual cover..." -msgstr "Vælg omslag manuelt..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Fravælg omslag" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Vis" msgid "Fetch Missing Covers" msgstr "Hent manglende omslag" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Redigér sporinformation" @@ -1432,6 +1438,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Vælg omslag manuelt..." + #~ msgid "Show section" #~ msgstr "Vis sektion" diff --git a/src/translations/de.po b/src/translations/de.po index c0ebcca2e..0e9b268c1 100644 --- a/src/translations/de.po +++ b/src/translations/de.po @@ -1113,18 +1113,24 @@ msgstr "Vollbild..." msgid "Fetch automatically" msgstr "Cover automatisch holen" -msgid "Choose manual cover..." -msgstr "Cover selbst auswählen..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Cover löschen" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Ansicht" msgid "Fetch Missing Covers" msgstr "Fehlende Cover holen" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Metadaten bearbeiten" @@ -1433,6 +1439,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Cover selbst auswählen..." + #~ msgid "Show section" #~ msgstr "Spalten" diff --git a/src/translations/el.po b/src/translations/el.po index 5d60f01e9..95d642d01 100644 --- a/src/translations/el.po +++ b/src/translations/el.po @@ -1117,18 +1117,24 @@ msgstr "Εμφάνισε σε πλήρες μέγεθος..." msgid "Fetch automatically" msgstr "Αυτόματο κατέβασμα" -msgid "Choose manual cover..." -msgstr "Επιλογή εξώφυλλου χειροκίνητα..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Αφαίρεση εξώφυλλου" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Προβολή" msgid "Fetch Missing Covers" msgstr "Κατέβασμα εξώφυλλων που λείπουν" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Τροποποίηση πληροφοριών κομματιού" @@ -1435,6 +1441,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Επιλογή εξώφυλλου χειροκίνητα..." + #~ msgid "Show section" #~ msgstr "Εμφάνιση τμήματος" diff --git a/src/translations/en_CA.po b/src/translations/en_CA.po index 382cabf55..7a09694f9 100644 --- a/src/translations/en_CA.po +++ b/src/translations/en_CA.po @@ -1112,18 +1112,24 @@ msgstr "Show fullsize..." msgid "Fetch automatically" msgstr "Fetch automatically" -msgid "Choose manual cover..." -msgstr "Choose manual cover..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Unset cover" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "View" msgid "Fetch Missing Covers" msgstr "Fetch Missing Covers" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Edit track information" @@ -1430,6 +1436,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Choose manual cover..." + #~ msgid "Show section" #~ msgstr "Show section" diff --git a/src/translations/en_GB.po b/src/translations/en_GB.po index d2d7e1b85..1773a06f1 100644 --- a/src/translations/en_GB.po +++ b/src/translations/en_GB.po @@ -1109,18 +1109,24 @@ msgstr "Show fullsize..." msgid "Fetch automatically" msgstr "Fetch automatically" -msgid "Choose manual cover..." -msgstr "Choose manual cover..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Unset cover" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "View" msgid "Fetch Missing Covers" msgstr "Fetch Missing Covers" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Edit track information" @@ -1427,6 +1433,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Choose manual cover..." + #~ msgid "Show section" #~ msgstr "Show section" diff --git a/src/translations/es.po b/src/translations/es.po index 9170a7e5e..cae01c0e9 100644 --- a/src/translations/es.po +++ b/src/translations/es.po @@ -1121,18 +1121,24 @@ msgstr "Mostrar carátula..." msgid "Fetch automatically" msgstr "Obtener carátula" -msgid "Choose manual cover..." -msgstr "Establecer carátula personalizada..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Quitar carátula" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Ver" msgid "Fetch Missing Covers" msgstr "Obtener Carátulas Faltantes" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Editar información de la pista" @@ -1441,6 +1447,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Establecer carátula personalizada..." + #~ msgid "Show section" #~ msgstr "Mostrar columna" diff --git a/src/translations/fi.po b/src/translations/fi.po index cd7641c90..a4cafaaf6 100644 --- a/src/translations/fi.po +++ b/src/translations/fi.po @@ -1107,18 +1107,24 @@ msgstr "" msgid "Fetch automatically" msgstr "" -msgid "Choose manual cover..." +msgid "Load cover from disk..." msgstr "" msgid "Unset cover" msgstr "" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "" msgid "Fetch Missing Covers" msgstr "" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "" diff --git a/src/translations/fr.po b/src/translations/fr.po index 3359d12a8..0d8d087f5 100644 --- a/src/translations/fr.po +++ b/src/translations/fr.po @@ -1117,18 +1117,24 @@ msgstr "Afficher en taille réelle..." msgid "Fetch automatically" msgstr "Récupérer automatiquement" -msgid "Choose manual cover..." -msgstr "Choisir une jaquette manuellement..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Enlever la jaquette" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Vue" msgid "Fetch Missing Covers" msgstr "Récupérer les jaquettes manquantes" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Modifier la description de la piste" @@ -1437,6 +1443,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Choisir une jaquette manuellement..." + #~ msgid "Show section" #~ msgstr "Montrer la colonne" diff --git a/src/translations/gl.po b/src/translations/gl.po index ee73b5dc6..6368956aa 100644 --- a/src/translations/gl.po +++ b/src/translations/gl.po @@ -1109,18 +1109,24 @@ msgstr "" msgid "Fetch automatically" msgstr "" -msgid "Choose manual cover..." +msgid "Load cover from disk..." msgstr "" msgid "Unset cover" msgstr "" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "" msgid "Fetch Missing Covers" msgstr "" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "" diff --git a/src/translations/it.po b/src/translations/it.po index 5cb94465e..fbb5d9da8 100644 --- a/src/translations/it.po +++ b/src/translations/it.po @@ -1118,18 +1118,24 @@ msgstr "Mostra a dimensioni originali..." msgid "Fetch automatically" msgstr "Scarica automaticamente" -msgid "Choose manual cover..." -msgstr "Scelta manuale copertina..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Rimuovi copertina" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Visualizza" msgid "Fetch Missing Covers" msgstr "Scarica copertine mancanti" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Modifica informazioni della traccia" @@ -1438,6 +1444,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Scelta manuale copertina..." + #~ msgid "Show section" #~ msgstr "Mostra sezione" diff --git a/src/translations/kk.po b/src/translations/kk.po index afdea3b30..07db30c48 100644 --- a/src/translations/kk.po +++ b/src/translations/kk.po @@ -1109,18 +1109,24 @@ msgstr "" msgid "Fetch automatically" msgstr "" -msgid "Choose manual cover..." +msgid "Load cover from disk..." msgstr "" msgid "Unset cover" msgstr "" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "" msgid "Fetch Missing Covers" msgstr "" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "" diff --git a/src/translations/nb.po b/src/translations/nb.po index 5695fe52b..688b3b608 100644 --- a/src/translations/nb.po +++ b/src/translations/nb.po @@ -1111,18 +1111,24 @@ msgstr "Vis i fullskjerm..." msgid "Fetch automatically" msgstr "Hent automatisk" -msgid "Choose manual cover..." -msgstr "Velg omslag manuelt..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Fjern omslaget" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Vis" msgid "Fetch Missing Covers" msgstr "Hent manglende omslag" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Redigér informasjon om sporet" @@ -1429,6 +1435,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Velg omslag manuelt..." + #~ msgid "Show section" #~ msgstr "Vis del" diff --git a/src/translations/oc.po b/src/translations/oc.po index f942a41ed..8fb820c78 100644 --- a/src/translations/oc.po +++ b/src/translations/oc.po @@ -1107,18 +1107,24 @@ msgstr "" msgid "Fetch automatically" msgstr "" -msgid "Choose manual cover..." +msgid "Load cover from disk..." msgstr "" msgid "Unset cover" msgstr "" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Afichatge" msgid "Fetch Missing Covers" msgstr "" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "" diff --git a/src/translations/pl.po b/src/translations/pl.po index 0af2f8296..f81385e12 100644 --- a/src/translations/pl.po +++ b/src/translations/pl.po @@ -1109,18 +1109,24 @@ msgstr "Pokaż w pełnej wielkości..." msgid "Fetch automatically" msgstr "Pobierz automatycznie" -msgid "Choose manual cover..." -msgstr "Wybierz okładkę ręcznie..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Usuń okładkę" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Pokaż" msgid "Fetch Missing Covers" msgstr "Pobierz brakujące okładki" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Edytuj informacje o utworze" @@ -1427,6 +1433,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Wybierz okładkę ręcznie..." + #~ msgid "Show section" #~ msgstr "Pokaż sekcję" diff --git a/src/translations/pt.po b/src/translations/pt.po index b5373e569..425ee6944 100644 --- a/src/translations/pt.po +++ b/src/translations/pt.po @@ -1113,18 +1113,24 @@ msgstr "Mostar tamanho total..." msgid "Fetch automatically" msgstr "Obter automaticamente" -msgid "Choose manual cover..." -msgstr "Escolher uma capa manualmente..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Sem capa" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Ver" msgid "Fetch Missing Covers" msgstr "Obter as Capas em Falta" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Editar a informação da faixa" @@ -1432,6 +1438,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Escolher uma capa manualmente..." + #~ msgid "Show section" #~ msgstr "Mostrar secção" diff --git a/src/translations/pt_BR.po b/src/translations/pt_BR.po index 234ede964..6a4f4ce56 100644 --- a/src/translations/pt_BR.po +++ b/src/translations/pt_BR.po @@ -1117,18 +1117,24 @@ msgstr "Exibir tamanho real..." msgid "Fetch automatically" msgstr "Buscar automaticamente" -msgid "Choose manual cover..." -msgstr "Escolher capa manualmente" +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Capa não fixada" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Exibir" msgid "Fetch Missing Covers" msgstr "Buscar as Capas que Faltam" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Editar informações da faixa" @@ -1435,6 +1441,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Escolher capa manualmente" + #~ msgid "Show section" #~ msgstr "Mostrar sessão" diff --git a/src/translations/ro.po b/src/translations/ro.po index c6eb5aa78..7558049bc 100644 --- a/src/translations/ro.po +++ b/src/translations/ro.po @@ -1108,18 +1108,24 @@ msgstr "" msgid "Fetch automatically" msgstr "Obține automat" -msgid "Choose manual cover..." +msgid "Load cover from disk..." msgstr "" msgid "Unset cover" msgstr "" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "" msgid "Fetch Missing Covers" msgstr "Obține copertele lipsă" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "" diff --git a/src/translations/ru.po b/src/translations/ru.po index 7c20954bf..29feffac5 100644 --- a/src/translations/ru.po +++ b/src/translations/ru.po @@ -1113,18 +1113,24 @@ msgstr "Показать полный размер..." msgid "Fetch automatically" msgstr "Выбирать автоматически" -msgid "Choose manual cover..." -msgstr "Укажите обложку вручную..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Удалить обложку" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Просмотр" msgid "Fetch Missing Covers" msgstr "Выберете пропущенные обложки" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Редактировать информацию" @@ -1432,6 +1438,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Укажите обложку вручную..." + #~ msgid "Show section" #~ msgstr "Показать секцию" diff --git a/src/translations/sk.po b/src/translations/sk.po index 68bbd006d..d15286a6f 100644 --- a/src/translations/sk.po +++ b/src/translations/sk.po @@ -1114,18 +1114,24 @@ msgstr "Ukázať celú veľkosť..." msgid "Fetch automatically" msgstr "Získavať automaticky" -msgid "Choose manual cover..." -msgstr "Vybrať obal ručne..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Nenastavený obal" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Zobraziť" msgid "Fetch Missing Covers" msgstr "Získať chýbajúce obaly" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Upravť informácie o skladbe" @@ -1432,6 +1438,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Vybrať obal ručne..." + #~ msgid "Show section" #~ msgstr "Zobraziť stĺpec" diff --git a/src/translations/sv.po b/src/translations/sv.po index a6c278c02..f45025f06 100644 --- a/src/translations/sv.po +++ b/src/translations/sv.po @@ -1114,18 +1114,24 @@ msgstr "Visa full storlek..." msgid "Fetch automatically" msgstr "Hämta automatiskt" -msgid "Choose manual cover..." -msgstr "Välj manuellt omslag..." +msgid "Load cover from disk..." +msgstr "" msgid "Unset cover" msgstr "Ta bort omslag" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "Visa" msgid "Fetch Missing Covers" msgstr "Hämta saknade omslag" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "Redigera spårinformation" @@ -1432,6 +1438,9 @@ msgstr "" msgid "Delay between visualisations" msgstr "" +#~ msgid "Choose manual cover..." +#~ msgstr "Välj manuellt omslag..." + #~ msgid "Show section" #~ msgstr "Visa kolumn" diff --git a/src/translations/tr.po b/src/translations/tr.po index f82ab3b04..36e8fd349 100644 --- a/src/translations/tr.po +++ b/src/translations/tr.po @@ -1107,18 +1107,24 @@ msgstr "" msgid "Fetch automatically" msgstr "" -msgid "Choose manual cover..." +msgid "Load cover from disk..." msgstr "" msgid "Unset cover" msgstr "" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "" msgid "Fetch Missing Covers" msgstr "" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "" diff --git a/src/translations/zh_CN.po b/src/translations/zh_CN.po index da6d4f0a7..7bc011937 100644 --- a/src/translations/zh_CN.po +++ b/src/translations/zh_CN.po @@ -1107,18 +1107,24 @@ msgstr "" msgid "Fetch automatically" msgstr "" -msgid "Choose manual cover..." +msgid "Load cover from disk..." msgstr "" msgid "Unset cover" msgstr "" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "" msgid "Fetch Missing Covers" msgstr "" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "" diff --git a/src/translations/zh_TW.po b/src/translations/zh_TW.po index 6a83b1407..091af5419 100644 --- a/src/translations/zh_TW.po +++ b/src/translations/zh_TW.po @@ -1107,18 +1107,24 @@ msgstr "" msgid "Fetch automatically" msgstr "" -msgid "Choose manual cover..." +msgid "Load cover from disk..." msgstr "" msgid "Unset cover" msgstr "" +msgid "Search for album covers..." +msgstr "" + msgid "View" msgstr "" msgid "Fetch Missing Covers" msgstr "" +msgid "Search" +msgstr "" + msgid "Edit track information" msgstr "" diff --git a/src/ui/albumcovermanager.cpp b/src/ui/albumcovermanager.cpp index e0df71089..768f0cd87 100644 --- a/src/ui/albumcovermanager.cpp +++ b/src/ui/albumcovermanager.cpp @@ -15,6 +15,7 @@ */ #include "albumcovermanager.h" +#include "albumcoversearcher.h" #include "iconloader.h" #include "ui_albumcovermanager.h" #include "core/albumcoverfetcher.h" @@ -48,6 +49,7 @@ AlbumCoverManager::AlbumCoverManager(NetworkAccessManager* network, network_(network), cover_loader_(new BackgroundThreadImplementation(this)), cover_fetcher_(new AlbumCoverFetcher(network, this)), + cover_searcher_(new AlbumCoverSearcher(this)), artist_icon_(IconLoader::Load("x-clementine-artist")), all_artists_icon_(IconLoader::Load("x-clementine-album")), context_menu_(new QMenu(this)), @@ -67,6 +69,7 @@ AlbumCoverManager::AlbumCoverManager(NetworkAccessManager* network, ui_->clear->setIcon(IconLoader::Load("edit-clear-locationbar-ltr")); ui_->view->setIcon(IconLoader::Load("view-choose")); ui_->fetch->setIcon(IconLoader::Load("download")); + ui_->action_search_manual->setIcon(IconLoader::Load("download")); ui_->action_add_to_playlist->setIcon(IconLoader::Load("media-playback-start")); ui_->action_load->setIcon(IconLoader::Load("media-playback-start")); @@ -110,7 +113,7 @@ void AlbumCoverManager::Init() { // Context menu context_menu_->addAction(ui_->action_show_fullsize); - context_menu_->addAction(ui_->action_fetch); + context_menu_->addAction(ui_->action_search_manual); context_menu_->addAction(ui_->action_choose_manual); context_menu_->addSeparator(); context_menu_->addAction(ui_->action_unset_cover); @@ -136,6 +139,7 @@ void AlbumCoverManager::Init() { connect(ui_->albums, SIGNAL(doubleClicked(QModelIndex)), SLOT(AlbumDoubleClicked(QModelIndex))); connect(ui_->action_add_to_playlist, SIGNAL(triggered()), SLOT(AddSelectedToPlaylist())); connect(ui_->action_load, SIGNAL(triggered()), SLOT(LoadSelectedToPlaylist())); + connect(ui_->action_search_manual, SIGNAL(triggered()), SLOT(SearchManual())); // Restore settings QSettings s; @@ -156,6 +160,8 @@ void AlbumCoverManager::CoverLoaderInitialised() { cover_loader_->Worker()->SetDefaultOutputImage(QImage(":nocover.png")); connect(cover_loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)), SLOT(CoverImageLoaded(quint64,QImage))); + + cover_searcher_->Init(cover_loader_->Worker(), cover_fetcher_); } void AlbumCoverManager::showEvent(QShowEvent *) { @@ -349,31 +355,7 @@ void AlbumCoverManager::AlbumCoverFetched(quint64 id, const QImage &image) { } else { got_covers_ ++; - const QString artist = item->data(Role_ArtistName).toString(); - const QString album = item->data(Role_AlbumName).toString(); - - // Hash the artist and album into a filename for the image - QCryptographicHash hash(QCryptographicHash::Sha1); - hash.addData(artist.toLower().toUtf8().constData()); - hash.addData(album.toLower().toUtf8().constData()); - - QString filename = hash.result().toHex() + ".jpg"; - QString path = AlbumCoverLoader::ImageCacheDir() + "/" + filename; - - // Make sure this directory exists first - QDir dir; - dir.mkdir(AlbumCoverLoader::ImageCacheDir()); - - // Save the image to disk - image.save(path, "JPG"); - - // Save the image in the database - backend_->UpdateManualAlbumArtAsync(artist, album, path); - - // Update the icon in our list - quint64 id = cover_loader_->Worker()->LoadImageAsync(QString(), path); - item->setData(Role_PathManual, path); - cover_loading_tasks_[id] = item; + SaveAndSetCover(item, image); } if (cover_fetching_tasks_.isEmpty()) @@ -382,6 +364,34 @@ void AlbumCoverManager::AlbumCoverFetched(quint64 id, const QImage &image) { UpdateStatusText(); } +void AlbumCoverManager::SaveAndSetCover(QListWidgetItem *item, const QImage &image) { + const QString artist = item->data(Role_ArtistName).toString(); + const QString album = item->data(Role_AlbumName).toString(); + + // Hash the artist and album into a filename for the image + QCryptographicHash hash(QCryptographicHash::Sha1); + hash.addData(artist.toLower().toUtf8().constData()); + hash.addData(album.toLower().toUtf8().constData()); + + QString filename = hash.result().toHex() + ".jpg"; + QString path = AlbumCoverLoader::ImageCacheDir() + "/" + filename; + + // Make sure this directory exists first + QDir dir; + dir.mkdir(AlbumCoverLoader::ImageCacheDir()); + + // Save the image to disk + image.save(path, "JPG"); + + // Save the image in the database + backend_->UpdateManualAlbumArtAsync(artist, album, path); + + // Update the icon in our list + quint64 id = cover_loader_->Worker()->LoadImageAsync(QString(), path); + item->setData(Role_PathManual, path); + cover_loading_tasks_[id] = item; +} + void AlbumCoverManager::UpdateStatusText() { QString message = tr("Got %1 covers out of %2 (%3 failed)") .arg(got_covers_).arg(jobs_).arg(missing_covers_); @@ -554,3 +564,22 @@ void AlbumCoverManager::LoadSelectedToPlaylist() { emit LoadSongsToPlaylist(GetSongsInAlbums( ui_->albums->selectionModel()->selectedIndexes())); } + +void AlbumCoverManager::SearchManual() { + if (context_menu_items_.isEmpty()) + return; + + // Get something sensible to stick in the search box + QString query = context_menu_items_[0]->data(Role_ArtistName).toString(); + if (!query.isEmpty()) + query += " "; + query += context_menu_items_[0]->data(Role_AlbumName).toString(); + + QImage image = cover_searcher_->Exec(query); + if (image.isNull()) + return; + + foreach (QListWidgetItem* item, context_menu_items_) { + SaveAndSetCover(item, image); + } +} diff --git a/src/ui/albumcovermanager.h b/src/ui/albumcovermanager.h index 1f099f479..d799d0ccd 100644 --- a/src/ui/albumcovermanager.h +++ b/src/ui/albumcovermanager.h @@ -29,6 +29,7 @@ class LibraryBackend; class AlbumCoverFetcher; +class AlbumCoverSearcher; class NetworkAccessManager; class Ui_CoverManager; @@ -46,6 +47,7 @@ class AlbumCoverManager : public QMainWindow { static const char* kSettingsGroup; LibraryBackend* backend() const { return backend_; } + QIcon no_cover_icon() const { return no_cover_icon_; } void Reset(); void Init(); @@ -77,6 +79,7 @@ class AlbumCoverManager : public QMainWindow { // On the context menu void ShowFullsize(); void FetchSingleCover(); + void SearchManual(); void ChooseManualCover(); void UnsetCover(); @@ -109,6 +112,7 @@ class AlbumCoverManager : public QMainWindow { void UpdateStatusText(); bool ShouldHide(const QListWidgetItem& item, const QString& filter, HideCovers hide) const; + void SaveAndSetCover(QListWidgetItem* item, const QImage& image); private: bool constructed_; @@ -127,6 +131,8 @@ class AlbumCoverManager : public QMainWindow { AlbumCoverFetcher* cover_fetcher_; QMap cover_fetching_tasks_; + AlbumCoverSearcher* cover_searcher_; + QIcon artist_icon_; QIcon all_artists_icon_; QIcon no_cover_icon_; diff --git a/src/ui/albumcovermanager.ui b/src/ui/albumcovermanager.ui index c82b27f71..bc4ea6af4 100644 --- a/src/ui/albumcovermanager.ui +++ b/src/ui/albumcovermanager.ui @@ -176,7 +176,7 @@ - Choose manual cover... + Load cover from disk... @@ -194,6 +194,11 @@ Add to playlist + + + Search for album covers... + + diff --git a/src/ui/albumcoversearcher.cpp b/src/ui/albumcoversearcher.cpp new file mode 100644 index 000000000..1fa8e574c --- /dev/null +++ b/src/ui/albumcoversearcher.cpp @@ -0,0 +1,134 @@ +/* This file is part of Clementine. + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#include "albumcovermanager.h" +#include "albumcoversearcher.h" +#include "ui_albumcoversearcher.h" +#include "core/albumcoverfetcher.h" +#include "core/albumcoverloader.h" + +#include +#include + +AlbumCoverSearcher::AlbumCoverSearcher(AlbumCoverManager* parent) + : QDialog(parent), + ui_(new Ui_AlbumCoverSearcher), + manager_(parent), + fetcher_(NULL), + id_(0) +{ + ui_->setupUi(this); + ui_->busy->hide(); + + connect(ui_->search, SIGNAL(clicked()), SLOT(Search())); + connect(ui_->covers, SIGNAL(doubleClicked(QModelIndex)), SLOT(CoverDoubleClicked(QModelIndex))); +} + +AlbumCoverSearcher::~AlbumCoverSearcher() { + delete ui_; +} + +void AlbumCoverSearcher::Init(boost::shared_ptr loader, + AlbumCoverFetcher *fetcher) { + loader_ = loader; + fetcher_ = fetcher; + + connect(fetcher_, SIGNAL(SearchFinished(quint64,AlbumCoverFetcher::SearchResults)), SLOT(SearchFinished(quint64,AlbumCoverFetcher::SearchResults))); + connect(loader_.get(), SIGNAL(ImageLoaded(quint64,QImage)), SLOT(ImageLoaded(quint64,QImage))); +} + +QImage AlbumCoverSearcher::Exec(const QString &query) { + ui_->query->setText(query); + ui_->query->setFocus(); + Search(); + + if (exec() == QDialog::Rejected) + return QImage(); + if (!ui_->covers->currentItem()) + return QImage(); + + QIcon icon = ui_->covers->currentItem()->icon(); + if (icon.cacheKey() == manager_->no_cover_icon().cacheKey()) + return QImage(); + + return icon.pixmap(icon.availableSizes()[0]).toImage(); +} + +void AlbumCoverSearcher::Search() { + ui_->busy->show(); + ui_->search->setEnabled(false); + ui_->query->setEnabled(false); + ui_->covers->setEnabled(false); + + id_ = fetcher_->SearchForCovers(ui_->query->text()); +} + +void AlbumCoverSearcher::SearchFinished(quint64 id, const AlbumCoverFetcher::SearchResults &results) { + if (id != id_) + return; + + ui_->search->setEnabled(true); + ui_->query->setEnabled(true); + ui_->covers->setEnabled(true); + id_ = 0; + + ui_->covers->clear(); + cover_loading_tasks_.clear(); + foreach (const AlbumCoverFetcher::SearchResult& result, results) { + if (result.image_url.isEmpty()) + continue; + + quint64 id = loader_->LoadImageAsync(result.image_url, QString()); + + QListWidgetItem* item = new QListWidgetItem(ui_->covers); + item->setIcon(manager_->no_cover_icon()); + item->setText(result.artist + " - " + result.album); + item->setData(Role_ImageURL, result.image_url); + item->setData(Role_ImageRequestId, id); + item->setData(Qt::TextAlignmentRole, QVariant(Qt::AlignTop | Qt::AlignHCenter)); + + cover_loading_tasks_[id] = item; + } + + if (cover_loading_tasks_.isEmpty()) + ui_->busy->hide(); +} + +void AlbumCoverSearcher::ImageLoaded(quint64 id, const QImage &image) { + if (!cover_loading_tasks_.contains(id)) + return; + + QListWidgetItem* item = cover_loading_tasks_.take(id); + item->setIcon(QIcon(QPixmap::fromImage(image))); + + if (cover_loading_tasks_.isEmpty()) + ui_->busy->hide(); +} + +void AlbumCoverSearcher::keyPressEvent(QKeyEvent* e) { + if (e->key() == Qt::Key_Enter || + e->key() == Qt::Key_Return) { + e->ignore(); + return; + } + + QDialog::keyPressEvent(e); +} + +void AlbumCoverSearcher::CoverDoubleClicked(const QModelIndex &index) { + if (index.isValid()) + accept(); +} diff --git a/src/ui/albumcoversearcher.h b/src/ui/albumcoversearcher.h new file mode 100644 index 000000000..63a6f1227 --- /dev/null +++ b/src/ui/albumcoversearcher.h @@ -0,0 +1,71 @@ +/* This file is part of Clementine. + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#ifndef ALBUMCOVERSEARCHER_H +#define ALBUMCOVERSEARCHER_H + +#include "core/albumcoverfetcher.h" + +#include + +#include + +class AlbumCoverLoader; +class AlbumCoverManager; +class Ui_AlbumCoverSearcher; + +class QListWidgetItem; +class QModelIndex; + +class AlbumCoverSearcher : public QDialog { + Q_OBJECT + +public: + AlbumCoverSearcher(AlbumCoverManager* parent); + ~AlbumCoverSearcher(); + + enum Role { + Role_ImageURL = Qt::UserRole + 1, + Role_ImageRequestId, + }; + + void Init(boost::shared_ptr loader, + AlbumCoverFetcher* fetcher); + + QImage Exec(const QString& query); + +protected: + void keyPressEvent(QKeyEvent *); + +private slots: + void Search(); + void SearchFinished(quint64 id, const AlbumCoverFetcher::SearchResults& results); + void ImageLoaded(quint64 id, const QImage& image); + + void CoverDoubleClicked(const QModelIndex& index); + +private: + Ui_AlbumCoverSearcher* ui_; + + AlbumCoverManager* manager_; + boost::shared_ptr loader_; + AlbumCoverFetcher* fetcher_; + + quint64 id_; + QMap cover_loading_tasks_; +}; + +#endif // ALBUMCOVERSEARCHER_H diff --git a/src/ui/albumcoversearcher.ui b/src/ui/albumcoversearcher.ui new file mode 100644 index 000000000..3ca9d9ac5 --- /dev/null +++ b/src/ui/albumcoversearcher.ui @@ -0,0 +1,150 @@ + + + AlbumCoverSearcher + + + + 0 + 0 + 624 + 330 + + + + Cover Manager + + + + + + + + Enter search terms here + + + + + + + Search + + + + + + + + + + + + Qt::ScrollBarAlwaysOff + + + + 120 + 120 + + + + QListView::Static + + + QListView::TopToBottom + + + QListView::Adjust + + + 2 + + + QListView::IconMode + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + LineEdit + QLineEdit +
widgets/lineedit.h
+
+ + BusyIndicator + QLabel +
widgets/busyindicator.h
+
+
+ + query + search + covers + buttonBox + + + + + buttonBox + accepted() + AlbumCoverSearcher + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AlbumCoverSearcher + reject() + + + 316 + 260 + + + 286 + 274 + + + + + query + returnPressed() + search + click() + + + 347 + 50 + + + 575 + 50 + + + + +
diff --git a/src/widgets/lineedit.h b/src/widgets/lineedit.h index 665491480..810f42f14 100644 --- a/src/widgets/lineedit.h +++ b/src/widgets/lineedit.h @@ -19,6 +19,7 @@ #include +// Remove in Qt 4.7: QLineEdit has placeholderText class LineEdit : public QLineEdit { Q_OBJECT Q_PROPERTY(QString hint READ GetHint WRITE SetHint);