Start auto tagging support (using MusicBrainz)

This commit is contained in:
Arnaud Bienner 2011-01-15 20:00:39 +00:00
parent ddd3f119d3
commit d53e74a91f
53 changed files with 663 additions and 4 deletions

View File

@ -69,6 +69,9 @@ endif (WIN32)
find_library(LASTFM_LIBRARIES lastfm) find_library(LASTFM_LIBRARIES lastfm)
find_path(LASTFM_INCLUDE_DIRS lastfm/ws.h) find_path(LASTFM_INCLUDE_DIRS lastfm/ws.h)
find_library(TUNEPIMP_LIBRARIES tunepimp)
find_path(TUNEPIMP_INCLUDE_DIRS tunepimp-0.5/tunepimp.h)
if (APPLE) if (APPLE)
find_library(GROWL Growl) find_library(GROWL Growl)
option(ENABLE_SPARKLE "Sparkle updating" ON) option(ENABLE_SPARKLE "Sparkle updating" ON)
@ -141,6 +144,7 @@ option(ENABLE_VISUALISATIONS "Use libprojectm visualisations" ON)
option(BUNDLE_PROJECTM_PRESETS "Install Clementine's own copies of libprojectm presets - disable this if you want to use a system package instead" ON) option(BUNDLE_PROJECTM_PRESETS "Install Clementine's own copies of libprojectm presets - disable this if you want to use a system package instead" ON)
option(ENABLE_SOUNDMENU "Add Clementine to the Gnome sound menu" ON) option(ENABLE_SOUNDMENU "Add Clementine to the Gnome sound menu" ON)
option(ENABLE_LIBLASTFM "Use liblastfm for fetching song info, scrobbling and radio streams" ON) option(ENABLE_LIBLASTFM "Use liblastfm for fetching song info, scrobbling and radio streams" ON)
option(ENABLE_LIBTUNEPIMP "Use libtunepimp for generating fingerprinting for musicbrainz, for auto tagging" ON)
option(ENABLE_SCRIPTING_PYTHON "Enable python scripting" ON) option(ENABLE_SCRIPTING_PYTHON "Enable python scripting" ON)
option(ENABLE_REMOTE "Enable support for using remote controls with Clementine" ON) option(ENABLE_REMOTE "Enable support for using remote controls with Clementine" ON)
@ -168,6 +172,10 @@ if(ENABLE_LIBLASTFM AND LASTFM_LIBRARIES AND LASTFM_INCLUDE_DIRS)
set(HAVE_LIBLASTFM ON) set(HAVE_LIBLASTFM ON)
endif(ENABLE_LIBLASTFM AND LASTFM_LIBRARIES AND LASTFM_INCLUDE_DIRS) endif(ENABLE_LIBLASTFM AND LASTFM_LIBRARIES AND LASTFM_INCLUDE_DIRS)
if(ENABLE_LIBTUNEPIMP AND TUNEPIMP_LIBRARIES AND TUNEPIMP_INCLUDE_DIRS)
set(HAVE_LIBTUNEPIMP ON)
endif(ENABLE_LIBTUNEPIMP AND TUNEPIMP_LIBRARIES AND TUNEPIMP_INCLUDE_DIRS)
if(ENABLE_SCRIPTING_PYTHON AND PYTHONLIBS_FOUND AND PYQT_SIP_DIR) if(ENABLE_SCRIPTING_PYTHON AND PYTHONLIBS_FOUND AND PYQT_SIP_DIR)
set(HAVE_SCRIPTING_PYTHON ON) set(HAVE_SCRIPTING_PYTHON ON)
endif(ENABLE_SCRIPTING_PYTHON AND PYTHONLIBS_FOUND AND PYQT_SIP_DIR) endif(ENABLE_SCRIPTING_PYTHON AND PYTHONLIBS_FOUND AND PYQT_SIP_DIR)
@ -293,5 +301,6 @@ summary_add("Visualisations" ENABLE_VISUALISATIONS)
summary_add("Last.fm support" HAVE_LIBLASTFM) summary_add("Last.fm support" HAVE_LIBLASTFM)
summary_add("Scripting support: Python" HAVE_SCRIPTING_PYTHON) summary_add("Scripting support: Python" HAVE_SCRIPTING_PYTHON)
summary_add("(Mac OS X) Sparkle integration" HAVE_SPARKLE) summary_add("(Mac OS X) Sparkle integration" HAVE_SPARKLE)
summary_add("MusicBrainz support" HAVE_LIBTUNEPIMP)
summary_add("Remote control support" HAVE_REMOTE) summary_add("Remote control support" HAVE_REMOTE)
summary_show() summary_show()

View File

@ -26,6 +26,10 @@ if(HAVE_LIBLASTFM)
include_directories(${LASTFM_INCLUDE_DIRS}) include_directories(${LASTFM_INCLUDE_DIRS})
endif(HAVE_LIBLASTFM) endif(HAVE_LIBLASTFM)
if(HAVE_LIBTUNEPIMP)
include_directories(${TUNEPIMP_INCLUDE_DIRS})
endif(HAVE_LIBTUNEPIMP)
if(HAVE_SCRIPTING_PYTHON) if(HAVE_SCRIPTING_PYTHON)
include_directories(${PYTHON_INCLUDE_DIRS}) include_directories(${PYTHON_INCLUDE_DIRS})
endif(HAVE_SCRIPTING_PYTHON) endif(HAVE_SCRIPTING_PYTHON)
@ -73,6 +77,7 @@ set(SOURCES
core/stylesheetloader.cpp core/stylesheetloader.cpp
core/taskmanager.cpp core/taskmanager.cpp
core/utilities.cpp core/utilities.cpp
core/tagfetcher.cpp
devices/connecteddevice.cpp devices/connecteddevice.cpp
devices/devicedatabasebackend.cpp devices/devicedatabasebackend.cpp
@ -257,6 +262,7 @@ set(HEADERS
core/player.h core/player.h
core/songloader.h core/songloader.h
core/taskmanager.h core/taskmanager.h
core/tagfetcher.h
devices/connecteddevice.h devices/connecteddevice.h
devices/devicedatabasebackend.h devices/devicedatabasebackend.h
@ -874,6 +880,10 @@ if(HAVE_LIBLASTFM)
target_link_libraries(clementine_lib ${LASTFM_LIBRARIES}) target_link_libraries(clementine_lib ${LASTFM_LIBRARIES})
endif(HAVE_LIBLASTFM) endif(HAVE_LIBLASTFM)
if(HAVE_LIBTUNEPIMP)
target_link_libraries(clementine_lib ${TUNEPIMP_LIBRARIES})
endif(HAVE_LIBTUNEPIMP)
if(HAVE_LIBGPOD) if(HAVE_LIBGPOD)
target_link_libraries(clementine_lib ${LIBGPOD_LIBRARIES}) target_link_libraries(clementine_lib ${LIBGPOD_LIBRARIES})
endif(HAVE_LIBGPOD) endif(HAVE_LIBGPOD)

View File

@ -38,6 +38,7 @@
#cmakedefine HAVE_LIBGPOD #cmakedefine HAVE_LIBGPOD
#cmakedefine HAVE_LIBINDICATE #cmakedefine HAVE_LIBINDICATE
#cmakedefine HAVE_LIBLASTFM #cmakedefine HAVE_LIBLASTFM
#cmakedefine HAVE_LIBTUNEPIMP
#cmakedefine HAVE_LIBMTP #cmakedefine HAVE_LIBMTP
#cmakedefine HAVE_SCRIPTING_PYTHON #cmakedefine HAVE_SCRIPTING_PYTHON

210
src/core/tagfetcher.cpp Normal file
View File

@ -0,0 +1,210 @@
/* This file is part of Clementine.
Copyright 2010, David Sansome <me@davidsansome.com>
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 <http://www.gnu.org/licenses/>.
*/
#include "tagfetcher.h"
#include <QtDebug>
#include <QFile>
#include <QStringList>
#include <QNetworkReply>
#ifdef HAVE_LIBTUNEPIMP
static void NotifyCallback(tunepimp_t /*pimp*/, void */*data*/, TPCallbackEnum type, int fileId, TPFileStatus status);
const char* kMusicBrainzLookupUrl = "http://musicbrainz.org/ws/1/track/?type=xml&puid=%1";
TagFetcher::TagFetcher(QObject *parent)
: QObject(parent),
network_(new NetworkAccessManager(this)),
pimp_(NULL)
{
//active_fetchers_ = new QMap<int, TagFetcherItem*>;
pimp_ = tp_New("FETCHTAG", "0.1");
tp_SetDebug(pimp_, true);
tp_SetAutoSaveThreshold(pimp_, -1);
tp_SetMoveFiles(pimp_, false);
tp_SetRenameFiles(pimp_, false);
tp_SetFileNameEncoding(pimp_, "UTF-8");
tp_SetNotifyCallback(pimp_, NotifyCallback, this);
tp_SetMusicDNSClientId(pimp_, "0c6019606b1d8a54d0985e448f3603ca");
}
TagFetcher::~TagFetcher() {
delete network_;
tp_Delete(pimp_);
}
void TagFetcher::FetchFromFile(const QString& path) {
int id = tp_AddFile(pimp_, QFile::encodeName(path), 0);
TagFetcherItem* tagFetcherItem = new TagFetcherItem(path, id, pimp_, network_);
connect(tagFetcherItem, SIGNAL(PuidGeneratedSignal()), tagFetcherItem, SLOT(PuidGeneratedSlot()), Qt::QueuedConnection);
active_fetchers_.insert(id, tagFetcherItem);
connect(tagFetcherItem, SIGNAL(FetchFinishedSignal(int)), SLOT(FetchFinishedSlot(int)));
}
static void NotifyCallback(tunepimp_t pimp, void *data, TPCallbackEnum type, int fileId, TPFileStatus status)
{
TagFetcher *tagFetcher = (TagFetcher*)data;
tagFetcher->CallReturned(fileId, status);
if(type != tpFileChanged)
return;
}
void TagFetcher::CallReturned(int fileId, TPFileStatus status)
{
/*for(QMap<int, TagFetcherItem*>::Iterator it = active_fetchers_.begin();
it != active_fetchers_.end(); ++it) {
qDebug() << it.key();
active_fetchers_.insert(it.key(), it.value());
}*/
TagFetcherItem *tagFetcherItem = active_fetchers_.value(fileId);
switch(status) {
case eRecognized:
// TODO
break;
case eUnrecognized:
tagFetcherItem->Unrecognized();
break;
case ePUIDLookup:
case ePUIDCollision:
case eFileLookup:
//TODO
tagFetcherItem->PuidGenerated();
break;
case eUserSelection:
// TODO
break;
case eError:
//TODO
break;
default:
break;
}
}
void TagFetcher::FetchFinishedSlot(int id) {
TagFetcherItem *tagFetcherItem = active_fetchers_.value(id);
tp_Remove(pimp_, id);
active_fetchers_.erase(active_fetchers_.find(id));
emit FetchFinished(tagFetcherItem->getFilename(), tagFetcherItem->getSongsFetched());
delete tagFetcherItem;
}
TagFetcherItem::TagFetcherItem() { }
TagFetcherItem::TagFetcherItem(const QString& _filename, int _fileId, tunepimp_t _pimp, NetworkAccessManager *_network)
: filename_(_filename),
fileId_(_fileId),
pimp_(_pimp),
network_(_network)
{ }
TagFetcherItem::~TagFetcherItem()
{ }
void TagFetcherItem::Unrecognized() {
char trm[255];
bool finish = false;
trm[0] = 0;
track_t track = tp_GetTrack(pimp_, fileId_);
tr_Lock(track);
tr_GetPUID(track, trm, 255);
if ( !trm[0] ) {
tr_SetStatus(track, ePending);
tp_Wake(pimp_, track);
}
else {
finish = true;
}
tr_Unlock(track);
tp_ReleaseTrack(pimp_, track);
if ( !finish )
return;
//TODO clear
}
void TagFetcherItem::PuidGenerated() {
// Get PUID
track_t track = tp_GetTrack(pimp_, fileId_);
tr_Lock(track);
tr_GetPUID(track, puid_, 255);
tr_Unlock(track);
tp_ReleaseTrack(pimp_, track);
// Now we have PUID, let's download song's info from musicbrainz's Web Service
emit PuidGeneratedSignal();
}
void TagFetcherItem::PuidGeneratedSlot() {
QString reqString(QString(kMusicBrainzLookupUrl).arg(QString(puid_)));
QNetworkRequest req = QNetworkRequest(QUrl(reqString));
req.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
QNetworkRequest::AlwaysNetwork);
QNetworkReply* reply = network_->get(req);
connect(reply, SIGNAL(finished()), SLOT(DownloadInfoFinished()));
}
void TagFetcherItem::DownloadInfoFinished() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
Q_ASSERT(reply);
QXmlStreamReader reader(reply);
while(!reader.atEnd()) {
reader.readNext();
if(reader.tokenType() == QXmlStreamReader::StartElement &&
reader.name() == "track") {
songs_fetched_ << ReadTrack(&reader);
}
}
emit FetchFinishedSignal(fileId_);
}
SongList TagFetcherItem::ReadTrack(QXmlStreamReader *reader) {
QString currentArtist;
QString currentTitle;
SongList songs;
while(!reader->atEnd()) {
reader->readNext();
if(reader->tokenType() == QXmlStreamReader::StartElement) {
if(reader->name() == "title") { // track's title
currentTitle = reader->readElementText();
} else if(reader->name() == "artist") {
reader->readNext();
if(reader->name() == "name") {
currentArtist = reader->readElementText();
}
} else if(reader->name() == "release-list") {
while(!reader->atEnd()) {
reader->readNext();
if(reader->name() == "title") { // album (release) title
QString albumTitle = reader->readElementText();
Song newSongMatch;
newSongMatch.Init(currentTitle, currentArtist, albumTitle, 0); // Using 0 as length. We could have used <duration> field but it is not usefull, so don't wasting our time and keeping 0
songs << newSongMatch;
} else if(reader->tokenType() == QXmlStreamReader::EndElement &&
reader->name() == "release-list") {
break;
}
}
}
}
}
return songs;
}
#endif // HAVE_LIBTUNEPIMP

95
src/core/tagfetcher.h Normal file
View File

@ -0,0 +1,95 @@
/* This file is part of Clementine.
Copyright 2010, David Sansome <me@davidsansome.com>
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 <http://www.gnu.org/licenses/>.
*/
#ifndef TAGFETCHER_H
#define TAGFETCHER_H
#include "config.h"
#include "core/network.h"
#include "core/song.h"
#include <QtDebug>
#include <QMap>
#include <QXmlStreamReader>
#include <tunepimp-0.5/tp_c.h>
class TagFetcherItem;
class TagFetcher : public QObject {
Q_OBJECT
#ifdef HAVE_LIBTUNEPIMP
public:
TagFetcher(QObject *parent = 0);
~TagFetcher();
void FetchFromFile(const QString& path);
void CallReturned(int fileId, TPFileStatus status);
signals:
void FetchFinished(QString filename, SongList songs_guessed);
private slots:
void FetchFinishedSlot(int id);
private:
NetworkAccessManager *network_;
tunepimp_t pimp_;
QMap<int, TagFetcherItem*> active_fetchers_;
#endif // HAVE_LIBTUNEPIMP
};
class TagFetcherItem : public QObject {
Q_OBJECT
#ifdef HAVE_LIBTUNEPIMP
public:
TagFetcherItem();
TagFetcherItem(const QString& filename, int filedId, tunepimp_t pimp, NetworkAccessManager *network);
~TagFetcherItem();
void setFileId(int _fileId) { fileId_ = _fileId; };
int getFileId() { return fileId_; };
void setFilename(const QString& _filename) { filename_ = _filename; };
QString getFilename() { return filename_; }
SongList getSongsFetched() { return songs_fetched_; }
void Unrecognized();
void PuidGenerated();
signals:
void PuidGeneratedSignal();
void FetchFinishedSignal(int id);
private slots:
void PuidGeneratedSlot();
void DownloadInfoFinished();
private:
SongList ReadTrack(QXmlStreamReader *reader);
private:
QString filename_;
int fileId_; // tunepimp generated id
tunepimp_t pimp_;
NetworkAccessManager *network_;
char puid_[255];
SongList songs_fetched_;
#endif // HAVE_LIBTUNEPIMP
};
#endif // TAGFETCHER_H

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "الملحّن" msgstr "الملحّن"
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "النوع" msgstr "النوع"

View File

@ -535,6 +535,9 @@ msgstr "Колер"
msgid "Comment" msgid "Comment"
msgstr "Каментар" msgstr "Каментар"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Кампазітар" msgstr "Кампазітар"
@ -1048,6 +1051,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -527,6 +527,9 @@ msgstr "Цвят"
msgid "Comment" msgid "Comment"
msgstr "Коментар" msgstr "Коментар"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1036,6 +1039,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "Общи настройки" msgstr "Общи настройки"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Жанр" msgstr "Жанр"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -548,6 +548,9 @@ msgstr "Color"
msgid "Comment" msgid "Comment"
msgstr "Comentari" msgstr "Comentari"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Compositor" msgstr "Compositor"
@ -1065,6 +1068,9 @@ msgstr "Motor d'audio GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Arranjaments generals" msgstr "Arranjaments generals"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Gènere" msgstr "Gènere"

View File

@ -543,6 +543,9 @@ msgstr "Barva"
msgid "Comment" msgid "Comment"
msgstr "Poznámka" msgstr "Poznámka"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Skladatel" msgstr "Skladatel"
@ -1061,6 +1064,9 @@ msgstr "Zvukový stroj GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Obecná nastavení" msgstr "Obecná nastavení"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Žánr" msgstr "Žánr"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -528,6 +528,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "Kommentar" msgstr "Kommentar"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Komponist" msgstr "Komponist"
@ -1037,6 +1040,9 @@ msgstr "GStreamer lydmotor"
msgid "General settings" msgid "General settings"
msgstr "Generelle indstillinger" msgstr "Generelle indstillinger"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"

View File

@ -547,6 +547,9 @@ msgstr "Farbe"
msgid "Comment" msgid "Comment"
msgstr "Kommentar" msgstr "Kommentar"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Komponist" msgstr "Komponist"
@ -1064,6 +1067,9 @@ msgstr "GStreamer Audio Engine"
msgid "General settings" msgid "General settings"
msgstr "Allgemeine Einstellungen" msgstr "Allgemeine Einstellungen"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"

View File

@ -550,6 +550,9 @@ msgstr "Χρώμα"
msgid "Comment" msgid "Comment"
msgstr "Σχόλια" msgstr "Σχόλια"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Συνθέτης" msgstr "Συνθέτης"
@ -1071,6 +1074,9 @@ msgstr "GStreamer, μηχανή ήχου"
msgid "General settings" msgid "General settings"
msgstr "Γενικές ρυθμίσεις" msgstr "Γενικές ρυθμίσεις"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Είδος" msgstr "Είδος"

View File

@ -516,6 +516,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1023,6 +1026,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "Comment" msgstr "Comment"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Composer" msgstr "Composer"
@ -1037,6 +1040,9 @@ msgstr "GStreamer audio engine"
msgid "General settings" msgid "General settings"
msgstr "General settings" msgstr "General settings"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "Comment" msgstr "Comment"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Composer" msgstr "Composer"
@ -1035,6 +1038,9 @@ msgstr "GStreamer audio engine"
msgid "General settings" msgid "General settings"
msgstr "General settings" msgstr "General settings"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -549,6 +549,9 @@ msgstr "Color"
msgid "Comment" msgid "Comment"
msgstr "Comentario" msgstr "Comentario"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Compositor" msgstr "Compositor"
@ -1069,6 +1072,9 @@ msgstr "Motor de audio GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Preferencias generales" msgstr "Preferencias generales"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Género" msgstr "Género"

View File

@ -527,6 +527,9 @@ msgstr "Värv"
msgid "Comment" msgid "Comment"
msgstr "Märkus" msgstr "Märkus"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Helilooja" msgstr "Helilooja"
@ -1035,6 +1038,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "Üldised seadistused" msgstr "Üldised seadistused"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Žanr" msgstr "Žanr"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "Kommentti" msgstr "Kommentti"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Säveltäjä" msgstr "Säveltäjä"
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "Yleiset asetukset" msgstr "Yleiset asetukset"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Tyylilaji" msgstr "Tyylilaji"

View File

@ -551,6 +551,9 @@ msgstr "Couleur"
msgid "Comment" msgid "Comment"
msgstr "Commentaire" msgstr "Commentaire"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Compositeur" msgstr "Compositeur"
@ -1073,6 +1076,9 @@ msgstr "Moteur audio GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Configuration générale" msgstr "Configuration générale"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"

View File

@ -531,6 +531,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Compositor" msgstr "Compositor"
@ -1038,6 +1041,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Xénero" msgstr "Xénero"

View File

@ -529,6 +529,9 @@ msgstr "צבע"
msgid "Comment" msgid "Comment"
msgstr "הערה" msgstr "הערה"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "מלחין" msgstr "מלחין"
@ -1038,6 +1041,9 @@ msgstr "מנוע האודיו של GStreamer"
msgid "General settings" msgid "General settings"
msgstr "הגדרות כלליות" msgstr "הגדרות כלליות"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "סגנון" msgstr "סגנון"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -533,6 +533,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1040,6 +1043,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -542,6 +542,9 @@ msgstr "Szín"
msgid "Comment" msgid "Comment"
msgstr "Megjegyzés" msgstr "Megjegyzés"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Zeneszerző" msgstr "Zeneszerző"
@ -1062,6 +1065,9 @@ msgstr "GStreamer audio meghajtó"
msgid "General settings" msgid "General settings"
msgstr "Általános beállítások" msgstr "Általános beállítások"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Műfaj" msgstr "Műfaj"

View File

@ -547,6 +547,9 @@ msgstr "Colore"
msgid "Comment" msgid "Comment"
msgstr "Commento" msgstr "Commento"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Compositore" msgstr "Compositore"
@ -1066,6 +1069,9 @@ msgstr "Motore audio GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Impostazioni generali" msgstr "Impostazioni generali"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Genere" msgstr "Genere"

View File

@ -537,6 +537,9 @@ msgstr "色"
msgid "Comment" msgid "Comment"
msgstr "コメント" msgstr "コメント"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "作曲者" msgstr "作曲者"
@ -1055,6 +1058,9 @@ msgstr "GStreamer オーディオ エンジン"
msgid "General settings" msgid "General settings"
msgstr "全般設定" msgstr "全般設定"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "ジャンル" msgstr "ジャンル"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Жанры" msgstr "Жанры"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -534,6 +534,9 @@ msgstr "Farge"
msgid "Comment" msgid "Comment"
msgstr "Kommentar" msgstr "Kommentar"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Komponist" msgstr "Komponist"
@ -1046,6 +1049,9 @@ msgstr "GStreamer lydmotor"
msgid "General settings" msgid "General settings"
msgstr "Generelle innstillinger" msgstr "Generelle innstillinger"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Sjanger" msgstr "Sjanger"

View File

@ -539,6 +539,9 @@ msgstr "Kleur"
msgid "Comment" msgid "Comment"
msgstr "Opmerking" msgstr "Opmerking"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Componist" msgstr "Componist"
@ -1057,6 +1060,9 @@ msgstr "GStreamer audio engine"
msgid "General settings" msgid "General settings"
msgstr "Algemene instellingen" msgstr "Algemene instellingen"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "Comentari" msgstr "Comentari"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Compositor" msgstr "Compositor"
@ -1034,6 +1037,9 @@ msgstr "Motor àudio GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Paramètres generals" msgstr "Paramètres generals"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"

View File

@ -545,6 +545,9 @@ msgstr "Kolor"
msgid "Comment" msgid "Comment"
msgstr "Komentarz" msgstr "Komentarz"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Kompozytor" msgstr "Kompozytor"
@ -1062,6 +1065,9 @@ msgstr "Silnik dźwiękowy GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Podstawowe ustawienia" msgstr "Podstawowe ustawienia"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Gatunek" msgstr "Gatunek"

View File

@ -547,6 +547,9 @@ msgstr "Cor"
msgid "Comment" msgid "Comment"
msgstr "Comentário" msgstr "Comentário"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Compositor" msgstr "Compositor"
@ -1066,6 +1069,9 @@ msgstr "Sistema de áudio GSTreamer"
msgid "General settings" msgid "General settings"
msgstr "Definições gerais" msgstr "Definições gerais"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Género" msgstr "Género"

View File

@ -540,6 +540,9 @@ msgstr "Cor"
msgid "Comment" msgid "Comment"
msgstr "Comentário" msgstr "Comentário"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Composto por" msgstr "Composto por"
@ -1059,6 +1062,9 @@ msgstr "Mecanismo de áudio GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Configurações gerais" msgstr "Configurações gerais"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Gênero" msgstr "Gênero"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "Comentariu" msgstr "Comentariu"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Compozitor" msgstr "Compozitor"
@ -1034,6 +1037,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "Setări generale" msgstr "Setări generale"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Gen" msgstr "Gen"

View File

@ -540,6 +540,9 @@ msgstr "Цвет"
msgid "Comment" msgid "Comment"
msgstr "Комментарий" msgstr "Комментарий"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Композитор" msgstr "Композитор"
@ -1057,6 +1060,9 @@ msgstr "Движок аудио GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Общие настройки" msgstr "Общие настройки"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Жанр" msgstr "Жанр"

View File

@ -539,6 +539,9 @@ msgstr "Farba"
msgid "Comment" msgid "Comment"
msgstr "Komentár" msgstr "Komentár"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Skladateľ" msgstr "Skladateľ"
@ -1056,6 +1059,9 @@ msgstr "GStreamer audio engine"
msgid "General settings" msgid "General settings"
msgstr "Všeobecné nastavenia" msgstr "Všeobecné nastavenia"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Žáner" msgstr "Žáner"

View File

@ -541,6 +541,9 @@ msgstr "Barva"
msgid "Comment" msgid "Comment"
msgstr "Opomba" msgstr "Opomba"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Skladatelj" msgstr "Skladatelj"
@ -1058,6 +1061,9 @@ msgstr "GStreamerjev zvočni pogon"
msgid "General settings" msgid "General settings"
msgstr "Splošne nastavitve" msgstr "Splošne nastavitve"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Zvrst" msgstr "Zvrst"

View File

@ -527,6 +527,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "Коментар" msgstr "Коментар"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Композитор" msgstr "Композитор"
@ -1037,6 +1040,9 @@ msgstr "Гстример звучни мотор"
msgid "General settings" msgid "General settings"
msgstr "Опште поставке" msgstr "Опште поставке"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Жанр" msgstr "Жанр"

View File

@ -545,6 +545,9 @@ msgstr "Färg"
msgid "Comment" msgid "Comment"
msgstr "Kommentar" msgstr "Kommentar"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Kompositör" msgstr "Kompositör"
@ -1062,6 +1065,9 @@ msgstr "GStreamer-ljudmotor"
msgid "General settings" msgid "General settings"
msgstr "Allmänna inställningar" msgstr "Allmänna inställningar"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"

View File

@ -538,6 +538,9 @@ msgstr "Renk"
msgid "Comment" msgid "Comment"
msgstr "Yorum" msgstr "Yorum"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Besteci" msgstr "Besteci"
@ -1055,6 +1058,9 @@ msgstr "GStreamer ses motoru"
msgid "General settings" msgid "General settings"
msgstr "Genel ayarlar" msgstr "Genel ayarlar"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Tür" msgstr "Tür"

View File

@ -517,6 +517,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "" msgstr ""
@ -1024,6 +1027,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "" msgstr ""
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""

View File

@ -542,6 +542,9 @@ msgstr "Колір"
msgid "Comment" msgid "Comment"
msgstr "Коментар" msgstr "Коментар"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "Композитор" msgstr "Композитор"
@ -1058,6 +1061,9 @@ msgstr "Аудіо-рушій GStreamer"
msgid "General settings" msgid "General settings"
msgstr "Загальні налаштування" msgstr "Загальні налаштування"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Жанр" msgstr "Жанр"

View File

@ -529,6 +529,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "备注" msgstr "备注"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "作曲家" msgstr "作曲家"
@ -1036,6 +1039,9 @@ msgstr ""
msgid "General settings" msgid "General settings"
msgstr "常规设置" msgstr "常规设置"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "流派" msgstr "流派"

View File

@ -531,6 +531,9 @@ msgstr ""
msgid "Comment" msgid "Comment"
msgstr "評論" msgstr "評論"
msgid "Complete automatically"
msgstr ""
msgid "Composer" msgid "Composer"
msgstr "作曲家" msgstr "作曲家"
@ -1038,6 +1041,9 @@ msgstr "GStreamer的音頻引擎"
msgid "General settings" msgid "General settings"
msgstr "一般設定" msgstr "一般設定"
msgid "Generating audio fingerprint and fetching results..."
msgstr ""
msgid "Genre" msgid "Genre"
msgstr "風格" msgstr "風格"

View File

@ -42,6 +42,8 @@
#include <QtDebug> #include <QtDebug>
const char* EditTagDialog::kHintText = QT_TR_NOOP("(different across multiple songs)"); const char* EditTagDialog::kHintText = QT_TR_NOOP("(different across multiple songs)");
const char* EditTagDialog::kTagFetchText = QT_TR_NOOP("Complete automatically");
const char* EditTagDialog::kTagFetchOnLoadText = QT_TR_NOOP("Generating audio fingerprint and fetching results...");
EditTagDialog::EditTagDialog(QWidget* parent) EditTagDialog::EditTagDialog(QWidget* parent)
: QDialog(parent), : QDialog(parent),
@ -49,6 +51,9 @@ EditTagDialog::EditTagDialog(QWidget* parent)
backend_(NULL), backend_(NULL),
loading_(false), loading_(false),
ignore_edits_(false), ignore_edits_(false),
#ifdef HAVE_LIBTUNEPIMP
tag_fetcher_(new TagFetcher()),
#endif
#ifdef HAVE_LIBLASTFM #ifdef HAVE_LIBLASTFM
cover_searcher_(new AlbumCoverSearcher(QIcon(":/nocover.png"), this)), cover_searcher_(new AlbumCoverSearcher(QIcon(":/nocover.png"), this)),
cover_fetcher_(new AlbumCoverFetcher(this)), cover_fetcher_(new AlbumCoverFetcher(this)),
@ -61,6 +66,9 @@ EditTagDialog::EditTagDialog(QWidget* parent)
cover_loader_->Worker()->SetDefaultOutputImage(QImage(":nocover.png")); cover_loader_->Worker()->SetDefaultOutputImage(QImage(":nocover.png"));
connect(cover_loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)), connect(cover_loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)),
SLOT(ArtLoaded(quint64,QImage))); SLOT(ArtLoaded(quint64,QImage)));
#ifdef HAVE_LIBTUNEPIMP
connect(tag_fetcher_, SIGNAL(FetchFinished(QString, SongList)), SLOT(FetchTagFinished(QString, SongList)));
#endif
#ifdef HAVE_LIBLASTFM #ifdef HAVE_LIBLASTFM
cover_searcher_->Init(cover_fetcher_); cover_searcher_->Init(cover_fetcher_);
@ -69,6 +77,11 @@ EditTagDialog::EditTagDialog(QWidget* parent)
ui_->setupUi(this); ui_->setupUi(this);
ui_->splitter->setSizes(QList<int>() << 200 << width() - 200); ui_->splitter->setSizes(QList<int>() << 200 << width() - 200);
ui_->loading_container->hide(); ui_->loading_container->hide();
#ifdef HAVE_LIBTUNEPIMP
ui_->fetch_tag->setText(kTagFetchText);
#else
ui_->fetch_tag->setVisible(false);
#endif
// An editable field is one that has a label as a buddy. The label is // An editable field is one that has a label as a buddy. The label is
// important because it gets turned bold when the field is changed. // important because it gets turned bold when the field is changed.
@ -118,6 +131,10 @@ EditTagDialog::EditTagDialog(QWidget* parent)
connect(ui_->rating, SIGNAL(RatingChanged(float)), connect(ui_->rating, SIGNAL(RatingChanged(float)),
SLOT(SongRated(float))); SLOT(SongRated(float)));
connect(ui_->playcount_reset, SIGNAL(clicked()), SLOT(ResetPlayCounts())); connect(ui_->playcount_reset, SIGNAL(clicked()), SLOT(ResetPlayCounts()));
#ifdef HAVE_LIBTUNEPIMP
connect(ui_->fetch_tag, SIGNAL(clicked()), SLOT(FetchTag()));
ui_->fetch_tag->setText(kTagFetchText);
#endif
// Set up the album cover menu // Set up the album cover menu
cover_menu_ = new QMenu(this); cover_menu_ = new QMenu(this);
@ -167,6 +184,7 @@ bool EditTagDialog::SetLoading(const QString& message) {
ui_->button_box->setEnabled(!loading); ui_->button_box->setEnabled(!loading);
ui_->tab_widget->setEnabled(!loading); ui_->tab_widget->setEnabled(!loading);
ui_->song_list->setEnabled(!loading); ui_->song_list->setEnabled(!loading);
ui_->fetch_tag->setEnabled(!loading);
ui_->loading_label->setText(message); ui_->loading_label->setText(message);
return true; return true;
} }
@ -231,6 +249,9 @@ void EditTagDialog::SetSongsFinished() {
previous_button_->setEnabled(multiple); previous_button_->setEnabled(multiple);
next_button_->setEnabled(multiple); next_button_->setEnabled(multiple);
// Display tag fetcher if there's only one song
ui_->fetch_tag->setVisible(!multiple);
ui_->tab_widget->setCurrentWidget(multiple ? ui_->tags_tab : ui_->summary_tab); ui_->tab_widget->setCurrentWidget(multiple ? ui_->tags_tab : ui_->summary_tab);
} }
@ -670,3 +691,31 @@ void EditTagDialog::ResetPlayCounts() {
backend_->ResetStatisticsAsync(song->id()); backend_->ResetStatisticsAsync(song->id());
UpdateStatisticsTab(*song); UpdateStatisticsTab(*song);
} }
void EditTagDialog::FetchTag() {
#ifdef HAVE_LIBTUNEPIMP
const QModelIndexList sel = ui_->song_list->selectionModel()->selectedIndexes();
if (sel.isEmpty())
return;
Song* song = &data_[sel.first().row()].original_;
if (!song->is_valid() || song->id() == -1)
return;
tag_fetcher_->FetchFromFile(song->filename());
ui_->fetch_tag->setDisabled(true); // disable button, will be re-enabled later
ui_->fetch_tag->setText(kTagFetchOnLoadText);
#endif
}
void EditTagDialog::FetchTagFinished(QString filename, SongList songs_guessed) {
#ifdef HAVE_LIBTUNEPIMP
ui_->fetch_tag->setDisabled(false);
ui_->fetch_tag->setText(kTagFetchText);
// TODO: pop-up a window with suggestions (songs_guessed) and complete tags
foreach(const Song& song, songs_guessed) {
qDebug() << "Song guessed:";
qDebug() << "Artist: " + song.artist();
qDebug() << "Album: " + song.album();
qDebug() << "Title: " + song.title();
}
#endif
}

View File

@ -24,6 +24,9 @@
#include "config.h" #include "config.h"
#include "core/backgroundthread.h" #include "core/backgroundthread.h"
#include "core/song.h" #include "core/song.h"
#ifdef HAVE_LIBTUNEPIMP
# include "core/tagfetcher.h"
#endif
#include "playlist/playlistitem.h" #include "playlist/playlistitem.h"
#include "widgets/lineedit.h" #include "widgets/lineedit.h"
@ -49,6 +52,8 @@ public:
~EditTagDialog(); ~EditTagDialog();
static const char* kHintText; static const char* kHintText;
static const char* kTagFetchText;
static const char* kTagFetchOnLoadText;
void SetSongs(const SongList& songs, const PlaylistItemList& items = PlaylistItemList()); void SetSongs(const SongList& songs, const PlaylistItemList& items = PlaylistItemList());
void SetTagCompleter(LibraryBackend* backend); void SetTagCompleter(LibraryBackend* backend);
@ -74,6 +79,8 @@ private slots:
void ButtonClicked(QAbstractButton* button); void ButtonClicked(QAbstractButton* button);
void SongRated(float rating); void SongRated(float rating);
void ResetPlayCounts(); void ResetPlayCounts();
void FetchTag();
void FetchTagFinished(QString filename, SongList songs_guessed);
void ArtLoaded(quint64 id, const QImage& image); void ArtLoaded(quint64 id, const QImage& image);
@ -139,6 +146,10 @@ private:
bool ignore_edits_; bool ignore_edits_;
#ifdef HAVE_LIBTUNEPIMP
TagFetcher* tag_fetcher_;
#endif
#ifdef HAVE_LIBLASTFM #ifdef HAVE_LIBLASTFM
AlbumCoverSearcher* cover_searcher_; AlbumCoverSearcher* cover_searcher_;
AlbumCoverFetcher* cover_fetcher_; AlbumCoverFetcher* cover_fetcher_;

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>863</width> <width>863</width>
<height>571</height> <height>586</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -30,7 +30,7 @@
</widget> </widget>
<widget class="QTabWidget" name="tab_widget"> <widget class="QTabWidget" name="tab_widget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="summary_tab"> <widget class="QWidget" name="summary_tab">
<attribute name="title"> <attribute name="title">
@ -711,7 +711,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="7" column="0">
<widget class="QLabel" name="comment_label"> <widget class="QLabel" name="comment_label">
<property name="text"> <property name="text">
<string>Comment</string> <string>Comment</string>
@ -721,7 +721,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1" colspan="3"> <item row="7" column="1" colspan="3">
<widget class="TextEdit" name="comment"> <widget class="TextEdit" name="comment">
<property name="has_reset_button" stdset="0"> <property name="has_reset_button" stdset="0">
<bool>true</bool> <bool>true</bool>
@ -731,6 +731,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1">
<widget class="QPushButton" name="fetch_tag">
</widget>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>