Remove cover provider factories and refactor everything else to use cover providers directly instead.
This commit is contained in:
parent
c6e2981860
commit
62bd3694ec
@ -14,22 +14,6 @@ import xml.etree.ElementTree
|
||||
LOGGER = logging.getLogger("amazon_covers")
|
||||
|
||||
|
||||
class AmazonCoversScript():
|
||||
def __init__(self):
|
||||
# create and register our factory
|
||||
self.factory = AmazonCoverProviderFactory()
|
||||
|
||||
|
||||
class AmazonCoverProviderFactory(clementine.CoverProviderFactory):
|
||||
def __init__(self):
|
||||
clementine.CoverProviderFactory.__init__(self)
|
||||
# register in the repository of factories
|
||||
clementine.cover_providers.AddProviderFactory(self)
|
||||
|
||||
def CreateCoverProvider(self, parent):
|
||||
return AmazonCoverProvider(parent)
|
||||
|
||||
|
||||
class AmazonCoverProvider(clementine.CoverProvider):
|
||||
"""
|
||||
Most of the Amazon API related code here comes from a plugin (which I wrote) for
|
||||
@ -40,7 +24,7 @@ class AmazonCoverProvider(clementine.CoverProvider):
|
||||
AWS_ACCESS_KEY = 'AKIAJ4QO3GQTSM3A43BQ'
|
||||
AWS_SECRET_ACCESS_KEY = 'KBlHVSNEvJrebNB/BBmGIh4a38z4cedfFvlDJ5fE'
|
||||
|
||||
def __init__(self, parent):
|
||||
def __init__(self, parent=None):
|
||||
clementine.CoverProvider.__init__(self, "Amazon", parent)
|
||||
|
||||
# basic API's arguments (search in all categories)
|
||||
@ -52,13 +36,22 @@ class AmazonCoverProvider(clementine.CoverProvider):
|
||||
'ResponseGroup' : 'Images',
|
||||
'AWSAccessKeyId': self.AWS_ACCESS_KEY
|
||||
}
|
||||
self.network = clementine.NetworkAccessManager(self)
|
||||
|
||||
def SendRequest(self, query):
|
||||
self.network = clementine.NetworkAccessManager()
|
||||
|
||||
def StartSearch(self, query, id):
|
||||
url = QUrl.fromEncoded(self.API_URL.format(self.PrepareAmazonRESTUrl(query)))
|
||||
LOGGER.info("Sending request to '%s'", url)
|
||||
LOGGER.debug("ID %d: Sending request to '%s'" % (id, url))
|
||||
|
||||
return self.network.get(QNetworkRequest(url))
|
||||
reply = self.network.get(QNetworkRequest(url))
|
||||
|
||||
def QueryFinished():
|
||||
LOGGER.debug("ID %d: Finished" % id)
|
||||
|
||||
self.SearchFinished(id, self.ParseReply(reply))
|
||||
|
||||
reply.connect("finished()", QueryFinished)
|
||||
return True
|
||||
|
||||
def ParseReply(self, reply):
|
||||
parsed = []
|
||||
@ -154,4 +147,5 @@ class AmazonCoverProvider(clementine.CoverProvider):
|
||||
return query_string + '&Signature=' + signature
|
||||
|
||||
|
||||
amazon_script = AmazonCoversScript()
|
||||
provider = AmazonCoverProvider()
|
||||
clementine.cover_providers.AddProvider(provider)
|
||||
|
@ -10,26 +10,10 @@ import urllib
|
||||
LOGGER = logging.getLogger("google_images")
|
||||
|
||||
|
||||
class GoogleImagesCoversScript():
|
||||
def __init__(self):
|
||||
# create and register our factory
|
||||
self.factory = GoogleImagesCoverProviderFactory()
|
||||
|
||||
|
||||
class GoogleImagesCoverProviderFactory(clementine.CoverProviderFactory):
|
||||
def __init__(self):
|
||||
clementine.CoverProviderFactory.__init__(self)
|
||||
# register in the repository of factories
|
||||
clementine.cover_providers.AddProviderFactory(self)
|
||||
|
||||
def CreateCoverProvider(self, parent):
|
||||
return GoogleImagesCoverProvider(parent)
|
||||
|
||||
|
||||
class GoogleImagesCoverProvider(clementine.CoverProvider):
|
||||
API_URL = 'https://ajax.googleapis.com/ajax/services/search/images?{0}'
|
||||
|
||||
def __init__(self, parent):
|
||||
def __init__(self, parent=None):
|
||||
clementine.CoverProvider.__init__(self, "Google Images", parent)
|
||||
|
||||
self.api_args = {
|
||||
@ -39,19 +23,23 @@ class GoogleImagesCoverProvider(clementine.CoverProvider):
|
||||
# only larger sizes
|
||||
'imgsz' : 'large|xlarge'
|
||||
}
|
||||
self.network = clementine.NetworkAccessManager(self)
|
||||
self.queries = {}
|
||||
self.network = clementine.NetworkAccessManager()
|
||||
|
||||
def SendRequest(self, query):
|
||||
def StartSearch(self, query, id):
|
||||
url = self.GetQueryURL(query)
|
||||
LOGGER.info("Sending request to '%s'", url)
|
||||
LOGGER.info("Id %d - sending request to '%s'" % (id, url))
|
||||
|
||||
reply = self.network.get(QNetworkRequest(url))
|
||||
self.queries[reply] = query
|
||||
|
||||
return reply
|
||||
def QueryFinished():
|
||||
LOGGER.debug("Id %d - finished" % id)
|
||||
|
||||
def ParseReply(self, reply):
|
||||
self.SearchFinished(id, self.ParseReply(query, reply))
|
||||
|
||||
reply.connect("finished()", QueryFinished)
|
||||
return True
|
||||
|
||||
def ParseReply(self, query, reply):
|
||||
results = json.loads(str(reply.readAll()))
|
||||
|
||||
parsed = []
|
||||
@ -60,7 +48,6 @@ class GoogleImagesCoverProvider(clementine.CoverProvider):
|
||||
LOGGER.warning("Error parsing reply: %s", results["responseDetails"])
|
||||
return parsed
|
||||
|
||||
query = self.queries[reply]
|
||||
LOGGER.info("Parsing reply for query '%s'", query)
|
||||
for result in results['responseData']['results']:
|
||||
current = clementine.CoverSearchResult()
|
||||
@ -79,4 +66,5 @@ class GoogleImagesCoverProvider(clementine.CoverProvider):
|
||||
return QUrl(self.API_URL.format(urllib.urlencode(current_args)))
|
||||
|
||||
|
||||
script = GoogleImagesCoversScript()
|
||||
provider = GoogleImagesCoverProvider()
|
||||
clementine.cover_providers.AddProvider(provider)
|
||||
|
@ -99,7 +99,6 @@ set(SOURCES
|
||||
covers/albumcoverloader.cpp
|
||||
covers/artloader.cpp
|
||||
covers/coverprovider.cpp
|
||||
covers/coverproviderfactory.cpp
|
||||
covers/coverproviders.cpp
|
||||
covers/kittenloader.cpp
|
||||
|
||||
@ -329,7 +328,6 @@ set(HEADERS
|
||||
covers/albumcoverloader.h
|
||||
covers/artloader.h
|
||||
covers/coverprovider.h
|
||||
covers/coverproviderfactory.h
|
||||
covers/coverproviders.h
|
||||
covers/kittenloader.h
|
||||
|
||||
@ -618,7 +616,6 @@ endif(ENABLE_VISUALISATIONS)
|
||||
if(HAVE_LIBLASTFM)
|
||||
list(APPEND SOURCES
|
||||
covers/lastfmcoverprovider.cpp
|
||||
covers/lastfmcoverproviderfactory.cpp
|
||||
radio/fixlastfm.cpp
|
||||
radio/lastfmconfig.cpp
|
||||
radio/lastfmservice.cpp
|
||||
@ -631,7 +628,6 @@ if(HAVE_LIBLASTFM)
|
||||
)
|
||||
list(APPEND HEADERS
|
||||
covers/lastfmcoverprovider.h
|
||||
covers/lastfmcoverproviderfactory.h
|
||||
radio/lastfmconfig.h
|
||||
radio/lastfmservice.h
|
||||
radio/lastfmstationdialog.h
|
||||
|
@ -45,9 +45,8 @@ void AlbumCoverFetcherSearch::Timeout() {
|
||||
}
|
||||
|
||||
void AlbumCoverFetcherSearch::TerminateSearch() {
|
||||
foreach (QNetworkReply* reply, pending_requests_.keys()) {
|
||||
disconnect(reply, SIGNAL(finished()), this, SLOT(ProviderSearchFinished()));
|
||||
reply->abort();
|
||||
foreach (int id, pending_requests_.keys()) {
|
||||
pending_requests_.take(id)->CancelSearch(id);
|
||||
}
|
||||
|
||||
if(request_.search) {
|
||||
@ -59,13 +58,17 @@ void AlbumCoverFetcherSearch::TerminateSearch() {
|
||||
}
|
||||
|
||||
void AlbumCoverFetcherSearch::Start() {
|
||||
// end this search before it even began if there are no providers...
|
||||
foreach(CoverProvider* provider, CoverProviders::instance().List(this)) {
|
||||
QNetworkReply* reply = provider->SendRequest(request_.query);
|
||||
CoverProviders* providers = &CoverProviders::instance();
|
||||
|
||||
if (reply) {
|
||||
connect(reply, SIGNAL(finished()), SLOT(ProviderSearchFinished()));
|
||||
pending_requests_.insert(reply, provider);
|
||||
// end this search before it even began if there are no providers...
|
||||
foreach(CoverProvider* provider, providers->List()) {
|
||||
connect(provider, SIGNAL(SearchFinished(int,QList<CoverSearchResult>)),
|
||||
SLOT(ProviderSearchFinished(int,QList<CoverSearchResult>)));
|
||||
const int id = providers->NextId();
|
||||
const bool success = provider->StartSearch(request_.query, id);
|
||||
|
||||
if (success) {
|
||||
pending_requests_[id] = provider;
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,33 +77,24 @@ void AlbumCoverFetcherSearch::Start() {
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumCoverFetcherSearch::ProviderSearchFinished() {
|
||||
// Note: we don't delete the reply here. It's parented to the provider's
|
||||
// network access manager which is deleted when it is deleted.
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
void AlbumCoverFetcherSearch::ProviderSearchFinished(
|
||||
int id, const QList<CoverSearchResult>& results) {
|
||||
if (!pending_requests_.contains(id))
|
||||
return;
|
||||
|
||||
CoverProvider* provider = pending_requests_.take(reply);
|
||||
CoverProvider* provider = pending_requests_.take(id);
|
||||
|
||||
if(reply->error() == QNetworkReply::NoError) {
|
||||
CoverSearchResults partial_results = provider->ParseReply(reply);
|
||||
|
||||
// Add categories to the results if the provider didn't specify them
|
||||
for (int i=0 ; i<partial_results.count() ; ++i) {
|
||||
if (partial_results[i].category.isEmpty()) {
|
||||
partial_results[i].category = provider->name();
|
||||
}
|
||||
CoverSearchResults results_copy(results);
|
||||
// Add categories to the results if the provider didn't specify them
|
||||
for (int i=0 ; i<results_copy.count() ; ++i) {
|
||||
if (results_copy[i].category.isEmpty()) {
|
||||
results_copy[i].category = provider->name();
|
||||
}
|
||||
|
||||
// add results from the current provider to our pool
|
||||
results_.append(partial_results);
|
||||
} else {
|
||||
QString contents(reply->readAll());
|
||||
qLog(Debug) << "CoverProvider's request error - summary:";
|
||||
qLog(Debug) << reply->errorString();
|
||||
qLog(Debug) << "CoverProvider's request error - contents:";
|
||||
qLog(Debug) << contents;
|
||||
}
|
||||
|
||||
// Add results from the current provider to our pool
|
||||
results_.append(results_copy);
|
||||
|
||||
// do we have more providers left?
|
||||
if(!pending_requests_.isEmpty()) {
|
||||
return;
|
||||
|
@ -27,10 +27,10 @@ class CoverProvider;
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
|
||||
// This class encapsulates a single search for covers initiated by an AlbumCoverFetcher.
|
||||
// The search engages all of the known cover providers. AlbumCoverFetcherSearch signals
|
||||
// search results to an interested AlbumCoverFetcher when all of the providers have done
|
||||
// their part.
|
||||
// This class encapsulates a single search for covers initiated by an
|
||||
// AlbumCoverFetcher. The search engages all of the known cover providers.
|
||||
// AlbumCoverFetcherSearch signals search results to an interested
|
||||
// AlbumCoverFetcher when all of the providers have done their part.
|
||||
class AlbumCoverFetcherSearch : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
@ -38,9 +38,8 @@ class AlbumCoverFetcherSearch : public QObject {
|
||||
// A timeout (in miliseconds) for every search.
|
||||
static const int kSearchTimeout;
|
||||
|
||||
AlbumCoverFetcherSearch(const CoverSearchRequest& request, QNetworkAccessManager* network,
|
||||
QObject* parent);
|
||||
virtual ~AlbumCoverFetcherSearch() {}
|
||||
AlbumCoverFetcherSearch(const CoverSearchRequest& request,
|
||||
QNetworkAccessManager* network, QObject* parent);
|
||||
|
||||
// Starts the search. This is the moment when we count cover providers available
|
||||
// in the application.
|
||||
@ -53,7 +52,7 @@ signals:
|
||||
void AlbumCoverFetched(quint64, const QImage& cover);
|
||||
|
||||
private slots:
|
||||
void ProviderSearchFinished();
|
||||
void ProviderSearchFinished(int id, const QList<CoverSearchResult>& results);
|
||||
void ProviderCoverFetchFinished();
|
||||
void Timeout();
|
||||
|
||||
@ -66,7 +65,7 @@ private:
|
||||
// Complete results (from all of the available providers).
|
||||
CoverSearchResults results_;
|
||||
|
||||
QMap<QNetworkReply*, CoverProvider*> pending_requests_;
|
||||
QMap<int, CoverProvider*> pending_requests_;
|
||||
|
||||
QNetworkAccessManager* network_;
|
||||
};
|
||||
|
@ -32,25 +32,20 @@ class CoverProvider : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CoverProvider(const QString& name, QObject* parent = &CoverProviders::instance());
|
||||
virtual ~CoverProvider() {}
|
||||
CoverProvider(const QString& name, QObject* parent);
|
||||
|
||||
// A name (very short description) of this provider, like "last.fm".
|
||||
QString name() const { return name_; }
|
||||
|
||||
// Given a search request from Clementine, provider has to create and invoke
|
||||
// a NetworkRequest. It then has to return a corresponding NetworkReply,
|
||||
// without connecting to its finished() signal!
|
||||
// Responsibilities of provider:
|
||||
// - maps the given query to a NetworkRequest that a service this provider
|
||||
// uses will understand
|
||||
// - makes the prepared request and returns the resulting reply
|
||||
virtual QNetworkReply* SendRequest(const QString& query) = 0;
|
||||
// Starts searching for covers matching the given query text. Returns true
|
||||
// if the query has been started, or false if an error occurred. The provider
|
||||
// should remember the ID and emit it along with the result when it finishes.
|
||||
virtual bool StartSearch(const QString& query, int id) = 0;
|
||||
|
||||
// Provider parses a reply which is now filled with data obtained from a service
|
||||
// this provider communicates with. The result is a QList of CoverSearchResult
|
||||
// objects.
|
||||
virtual CoverSearchResults ParseReply(QNetworkReply* reply) = 0;
|
||||
virtual void CancelSearch(int id) {}
|
||||
|
||||
signals:
|
||||
void SearchFinished(int id, const QList<CoverSearchResult>& results);
|
||||
|
||||
private:
|
||||
QString name_;
|
||||
|
@ -1,21 +0,0 @@
|
||||
/* 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 "coverproviderfactory.h"
|
||||
|
||||
CoverProviderFactory::CoverProviderFactory(QObject* parent)
|
||||
: QObject(parent) {}
|
@ -1,38 +0,0 @@
|
||||
/* 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 COVERPROVIDERFACTORY_H
|
||||
#define COVERPROVIDERFACTORY_H
|
||||
|
||||
#include "coverproviders.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class AlbumCoverFetcherSearch;
|
||||
class CoverProvider;
|
||||
|
||||
class CoverProviderFactory : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CoverProviderFactory(QObject* parent = &CoverProviders::instance());
|
||||
virtual ~CoverProviderFactory() {}
|
||||
|
||||
virtual CoverProvider* CreateCoverProvider(AlbumCoverFetcherSearch* parent) = 0;
|
||||
};
|
||||
|
||||
#endif // COVERPROVIDERFACTORY_H
|
@ -16,58 +16,42 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "coverproviderfactory.h"
|
||||
#include "coverprovider.h"
|
||||
#include "coverproviders.h"
|
||||
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
# include "lastfmcoverproviderfactory.h"
|
||||
#endif
|
||||
#include "core/logging.h"
|
||||
|
||||
CoverProviders::CoverProviders()
|
||||
{
|
||||
// registering built-in provider factories...
|
||||
|
||||
// every built-in provider factory needs an explicit parent; otherwise,
|
||||
// the default parent, namely CoverProviders::instance(), will
|
||||
// cause an infinite recursion here
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
cover_provider_factories_.append(new LastFmCoverProviderFactory(this));
|
||||
#endif
|
||||
: QObject(NULL) {
|
||||
}
|
||||
|
||||
void CoverProviders::AddProviderFactory(CoverProviderFactory* factory) {
|
||||
void CoverProviders::AddProvider(CoverProvider* provider) {
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
Q_UNUSED(locker);
|
||||
|
||||
cover_provider_factories_.append(factory);
|
||||
connect(factory, SIGNAL(destroyed()), SLOT(RemoveProviderFactory()));
|
||||
cover_providers_.append(provider);
|
||||
}
|
||||
|
||||
qLog(Debug) << "Registered cover provider" << provider->name();
|
||||
|
||||
connect(provider, SIGNAL(destroyed()), SLOT(ProviderDestroyed()));
|
||||
}
|
||||
|
||||
void CoverProviders::RemoveProviderFactory() {
|
||||
// qobject_cast doesn't work here with factories created by python
|
||||
CoverProviderFactory* factory = static_cast<CoverProviderFactory*>(sender());
|
||||
void CoverProviders::RemoveProvider(CoverProvider* provider) {
|
||||
if (!provider)
|
||||
return;
|
||||
|
||||
if (factory) {
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
Q_UNUSED(locker);
|
||||
qLog(Debug) << "Unregistered cover provider" << provider->name();
|
||||
|
||||
cover_provider_factories_.removeAll(factory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<CoverProvider*> CoverProviders::List(AlbumCoverFetcherSearch* parent) {
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
Q_UNUSED(locker);
|
||||
|
||||
QList<CoverProvider*> result;
|
||||
foreach(CoverProviderFactory* factory, cover_provider_factories_) {
|
||||
result.append(factory->CreateCoverProvider(parent));
|
||||
}
|
||||
return result;
|
||||
cover_providers_.removeAll(provider);
|
||||
}
|
||||
}
|
||||
|
||||
void CoverProviders::ProviderDestroyed() {
|
||||
CoverProvider* provider = static_cast<CoverProvider*>(sender());
|
||||
RemoveProvider(provider);
|
||||
}
|
||||
|
||||
int CoverProviders::NextId() {
|
||||
return next_id_.fetchAndAddRelaxed(1);
|
||||
}
|
||||
|
@ -23,11 +23,11 @@
|
||||
|
||||
class AlbumCoverFetcherSearch;
|
||||
class CoverProvider;
|
||||
class CoverProviderFactory;
|
||||
|
||||
// This is a singleton, a global repository for factories of cover providers. Each one of those has to register
|
||||
// with CoverProviders' instance by invoking "CoverProviders::instance().AddCoverProviderFactory(this)".
|
||||
// Factories are automatically unregistered from the repository when they are deleted.
|
||||
// This is a singleton, a global repository for cover providers.
|
||||
// Each one of those has to register with CoverProviders' instance by invoking
|
||||
// "CoverProviders::instance().AddCoverProvider(this)". Providers are
|
||||
// automatically unregistered from the repository when they are deleted.
|
||||
// The class is thread safe except for the initialization.
|
||||
class CoverProviders : public QObject {
|
||||
Q_OBJECT
|
||||
@ -35,31 +35,33 @@ class CoverProviders : public QObject {
|
||||
public:
|
||||
// This performs lazy initialization of the CoverProviders which is not thread-safe!
|
||||
static CoverProviders& instance() {
|
||||
static CoverProviders instance_;
|
||||
return instance_;
|
||||
static CoverProviders instance_;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
// Let's a cover provider factory to register itself in the repository.
|
||||
void AddProviderFactory(CoverProviderFactory* factory);
|
||||
// Lets a cover provider to register itself in the repository.
|
||||
void AddProvider(CoverProvider* provider);
|
||||
void RemoveProvider(CoverProvider* provider);
|
||||
|
||||
// Creates a list of cover providers, one for every registered factory. Providers that get created will
|
||||
// be children of the given AlbumCoverFetcherSearch's instance.
|
||||
QList<CoverProvider*> List(AlbumCoverFetcherSearch* parent);
|
||||
// Returns true if this repository has at least one registered provider factory.
|
||||
bool HasAnyProviderFactories() { return !cover_provider_factories_.isEmpty(); }
|
||||
// Returns a list of cover providers
|
||||
QList<CoverProvider*> List() const { return cover_providers_; }
|
||||
// Returns true if this repository has at least one registered provider.
|
||||
bool HasAnyProviders() const { return !cover_providers_.isEmpty(); }
|
||||
|
||||
~CoverProviders() {}
|
||||
int NextId();
|
||||
|
||||
private slots:
|
||||
void RemoveProviderFactory();
|
||||
void ProviderDestroyed();
|
||||
|
||||
private:
|
||||
CoverProviders();
|
||||
CoverProviders(CoverProviders const&);
|
||||
void operator=(CoverProviders const&);
|
||||
~CoverProviders() {}
|
||||
Q_DISABLE_COPY(CoverProviders);
|
||||
|
||||
QList<CoverProviderFactory*> cover_provider_factories_;
|
||||
QList<CoverProvider*> cover_providers_;
|
||||
QMutex mutex_;
|
||||
|
||||
QAtomicInt next_id_;
|
||||
};
|
||||
|
||||
#endif // COVERPROVIDERS_H
|
||||
|
@ -30,22 +30,34 @@ LastFmCoverProvider::LastFmCoverProvider(QObject* parent)
|
||||
{
|
||||
}
|
||||
|
||||
QNetworkReply* LastFmCoverProvider::SendRequest(const QString& query) {
|
||||
bool LastFmCoverProvider::StartSearch(const QString& query, int id) {
|
||||
QMap<QString, QString> params;
|
||||
params["method"] = "album.search";
|
||||
params["album"] = query;
|
||||
|
||||
return lastfm::ws::post(params);
|
||||
QNetworkReply* reply = lastfm::ws::post(params);
|
||||
connect(reply, SIGNAL(finished()), SLOT(QueryFinished()));
|
||||
pending_queries_[reply] = id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CoverSearchResults LastFmCoverProvider::ParseReply(QNetworkReply* reply) {
|
||||
void LastFmCoverProvider::QueryFinished() {
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
if (!reply || !pending_queries_.contains(reply))
|
||||
return;
|
||||
|
||||
int id = pending_queries_.take(reply);
|
||||
reply->deleteLater();
|
||||
|
||||
CoverSearchResults results;
|
||||
|
||||
try {
|
||||
lastfm::XmlQuery query(lastfm::ws::parse(reply));
|
||||
#ifdef Q_OS_WIN32
|
||||
if (lastfm::ws::last_parse_error != lastfm::ws::NoError)
|
||||
return results;
|
||||
if (lastfm::ws::last_parse_error != lastfm::ws::NoError) {
|
||||
throw std::runtime_error();
|
||||
}
|
||||
#endif
|
||||
|
||||
// parse the list of search results
|
||||
@ -57,10 +69,9 @@ CoverSearchResults LastFmCoverProvider::ParseReply(QNetworkReply* reply) {
|
||||
result.image_url = element["image size=extralarge"].text();
|
||||
results << result;
|
||||
}
|
||||
|
||||
return results;
|
||||
|
||||
} catch(std::runtime_error&) {
|
||||
return results;
|
||||
// Drop through and emit an empty list of results.
|
||||
}
|
||||
|
||||
emit SearchFinished(id, results);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "albumcoverfetcher.h"
|
||||
#include "coverprovider.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
|
||||
class QNetworkReply;
|
||||
@ -28,12 +29,17 @@ class QNetworkReply;
|
||||
// A built-in cover provider which fetches covers from last.fm.
|
||||
class LastFmCoverProvider : public CoverProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LastFmCoverProvider(QObject* parent);
|
||||
virtual ~LastFmCoverProvider() {}
|
||||
|
||||
QNetworkReply* SendRequest(const QString& query);
|
||||
CoverSearchResults ParseReply(QNetworkReply* reply);
|
||||
bool StartSearch(const QString& query, int id);
|
||||
|
||||
private slots:
|
||||
void QueryFinished();
|
||||
|
||||
private:
|
||||
QMap<QNetworkReply*, int> pending_queries_;
|
||||
};
|
||||
|
||||
#endif // LASTFMCOVERPROVIDER_H
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* 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 "albumcoverfetchersearch.h"
|
||||
#include "coverproviderfactory.h"
|
||||
#include "lastfmcoverprovider.h"
|
||||
#include "lastfmcoverproviderfactory.h"
|
||||
|
||||
LastFmCoverProviderFactory::LastFmCoverProviderFactory(QObject* parent)
|
||||
: CoverProviderFactory(parent) {}
|
||||
|
||||
CoverProvider* LastFmCoverProviderFactory::CreateCoverProvider(AlbumCoverFetcherSearch* parent) {
|
||||
return new LastFmCoverProvider(parent);
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/* 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 LASTFMCOVERPROVIDERFACTORY_H
|
||||
#define LASTFMCOVERPROVIDERFACTORY_H
|
||||
|
||||
#include "coverproviderfactory.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class AlbumCoverFetcherSearch;
|
||||
class CoverProvider;
|
||||
|
||||
class LastFmCoverProviderFactory : public CoverProviderFactory {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LastFmCoverProviderFactory(QObject* parent);
|
||||
~LastFmCoverProviderFactory() {}
|
||||
|
||||
CoverProvider* CreateCoverProvider(AlbumCoverFetcherSearch* parent);
|
||||
};
|
||||
|
||||
#endif // LASTFMCOVERPROVIDERFACTORY_H
|
@ -4,9 +4,7 @@
|
||||
#include <PythonQtSignalReceiver.h>
|
||||
#include <QVariant>
|
||||
#include <albumcoverfetcher.h>
|
||||
#include <albumcoverfetchersearch.h>
|
||||
#include <coverprovider.h>
|
||||
#include <coverproviderfactory.h>
|
||||
#include <coverproviders.h>
|
||||
#include <directory.h>
|
||||
#include <librarybackend.h>
|
||||
@ -56,118 +54,6 @@
|
||||
#include <taskmanager.h>
|
||||
#include <urlhandler.h>
|
||||
|
||||
void PythonQtShell_AlbumCoverFetcherSearch::childEvent(QChildEvent* arg__1)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "childEvent");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"" , "QChildEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
void* args[2] = {NULL, (void*)&arg__1};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
AlbumCoverFetcherSearch::childEvent(arg__1);
|
||||
}
|
||||
void PythonQtShell_AlbumCoverFetcherSearch::customEvent(QEvent* arg__1)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "customEvent");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"" , "QEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
void* args[2] = {NULL, (void*)&arg__1};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
AlbumCoverFetcherSearch::customEvent(arg__1);
|
||||
}
|
||||
bool PythonQtShell_AlbumCoverFetcherSearch::event(QEvent* arg__1)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "event");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"bool" , "QEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
bool returnValue = 0;
|
||||
void* args[2] = {NULL, (void*)&arg__1};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) {
|
||||
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
|
||||
if (args[0]!=&returnValue) {
|
||||
if (args[0]==NULL) {
|
||||
PythonQt::priv()->handleVirtualOverloadReturnError("event", methodInfo, result);
|
||||
} else {
|
||||
returnValue = *((bool*)args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return returnValue;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
return AlbumCoverFetcherSearch::event(arg__1);
|
||||
}
|
||||
bool PythonQtShell_AlbumCoverFetcherSearch::eventFilter(QObject* arg__1, QEvent* arg__2)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "eventFilter");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"bool" , "QObject*" , "QEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(3, argumentList);
|
||||
bool returnValue = 0;
|
||||
void* args[3] = {NULL, (void*)&arg__1, (void*)&arg__2};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) {
|
||||
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
|
||||
if (args[0]!=&returnValue) {
|
||||
if (args[0]==NULL) {
|
||||
PythonQt::priv()->handleVirtualOverloadReturnError("eventFilter", methodInfo, result);
|
||||
} else {
|
||||
returnValue = *((bool*)args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return returnValue;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
return AlbumCoverFetcherSearch::eventFilter(arg__1, arg__2);
|
||||
}
|
||||
void PythonQtShell_AlbumCoverFetcherSearch::timerEvent(QTimerEvent* arg__1)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "timerEvent");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"" , "QTimerEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
void* args[2] = {NULL, (void*)&arg__1};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
AlbumCoverFetcherSearch::timerEvent(arg__1);
|
||||
}
|
||||
void PythonQtWrapper_AlbumCoverFetcherSearch::Start(AlbumCoverFetcherSearch* theWrappedObject)
|
||||
{
|
||||
( theWrappedObject->Start());
|
||||
@ -175,24 +61,42 @@ void PythonQtWrapper_AlbumCoverFetcherSearch::Start(AlbumCoverFetcherSearch* the
|
||||
|
||||
|
||||
|
||||
QList<CoverSearchResult > PythonQtShell_CoverProvider::ParseReply(QNetworkReply* reply)
|
||||
void PythonQtShell_CoverProvider::CancelSearch(int id)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "ParseReply");
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "CancelSearch");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"QList<CoverSearchResult >" , "QNetworkReply*"};
|
||||
static const char* argumentList[] ={"" , "int"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
QList<CoverSearchResult > returnValue;
|
||||
void* args[2] = {NULL, (void*)&reply};
|
||||
void* args[2] = {NULL, (void*)&id};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
CoverProvider::CancelSearch(id);
|
||||
}
|
||||
bool PythonQtShell_CoverProvider::StartSearch(const QString& query, int id)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "StartSearch");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"bool" , "const QString&" , "int"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(3, argumentList);
|
||||
bool returnValue = 0;
|
||||
void* args[3] = {NULL, (void*)&query, (void*)&id};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) {
|
||||
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
|
||||
if (args[0]!=&returnValue) {
|
||||
if (args[0]==NULL) {
|
||||
PythonQt::priv()->handleVirtualOverloadReturnError("ParseReply", methodInfo, result);
|
||||
PythonQt::priv()->handleVirtualOverloadReturnError("StartSearch", methodInfo, result);
|
||||
} else {
|
||||
returnValue = *((QList<CoverSearchResult >*)args[0]);
|
||||
returnValue = *((bool*)args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,36 +106,7 @@ if (_wrapper) {
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
return QList<CoverSearchResult >();
|
||||
}
|
||||
QNetworkReply* PythonQtShell_CoverProvider::SendRequest(const QString& query)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "SendRequest");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"QNetworkReply*" , "const QString&"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
QNetworkReply* returnValue = 0;
|
||||
void* args[2] = {NULL, (void*)&query};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) {
|
||||
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
|
||||
if (args[0]!=&returnValue) {
|
||||
if (args[0]==NULL) {
|
||||
PythonQt::priv()->handleVirtualOverloadReturnError("SendRequest", methodInfo, result);
|
||||
} else {
|
||||
returnValue = *((QNetworkReply**)args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return returnValue;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
return 0;
|
||||
return bool();
|
||||
}
|
||||
void PythonQtShell_CoverProvider::childEvent(QChildEvent* arg__1)
|
||||
{
|
||||
@ -349,6 +224,11 @@ CoverProvider* PythonQtWrapper_CoverProvider::new_CoverProvider(const QString&
|
||||
{
|
||||
return new PythonQtShell_CoverProvider(name, parent); }
|
||||
|
||||
void PythonQtWrapper_CoverProvider::CancelSearch(CoverProvider* theWrappedObject, int id)
|
||||
{
|
||||
( ((PythonQtPublicPromoter_CoverProvider*)theWrappedObject)->promoted_CancelSearch(id));
|
||||
}
|
||||
|
||||
QString PythonQtWrapper_CoverProvider::name(CoverProvider* theWrappedObject) const
|
||||
{
|
||||
return ( theWrappedObject->name());
|
||||
@ -356,166 +236,29 @@ QString PythonQtWrapper_CoverProvider::name(CoverProvider* theWrappedObject) co
|
||||
|
||||
|
||||
|
||||
CoverProvider* PythonQtShell_CoverProviderFactory::CreateCoverProvider(AlbumCoverFetcherSearch* parent)
|
||||
void PythonQtWrapper_CoverProviders::AddProvider(CoverProviders* theWrappedObject, CoverProvider* provider)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "CreateCoverProvider");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"CoverProvider*" , "AlbumCoverFetcherSearch*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
CoverProvider* returnValue = 0;
|
||||
void* args[2] = {NULL, (void*)&parent};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) {
|
||||
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
|
||||
if (args[0]!=&returnValue) {
|
||||
if (args[0]==NULL) {
|
||||
PythonQt::priv()->handleVirtualOverloadReturnError("CreateCoverProvider", methodInfo, result);
|
||||
} else {
|
||||
returnValue = *((CoverProvider**)args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return returnValue;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void PythonQtShell_CoverProviderFactory::childEvent(QChildEvent* arg__1)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "childEvent");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"" , "QChildEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
void* args[2] = {NULL, (void*)&arg__1};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
CoverProviderFactory::childEvent(arg__1);
|
||||
}
|
||||
void PythonQtShell_CoverProviderFactory::customEvent(QEvent* arg__1)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "customEvent");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"" , "QEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
void* args[2] = {NULL, (void*)&arg__1};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
CoverProviderFactory::customEvent(arg__1);
|
||||
}
|
||||
bool PythonQtShell_CoverProviderFactory::event(QEvent* arg__1)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "event");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"bool" , "QEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
bool returnValue = 0;
|
||||
void* args[2] = {NULL, (void*)&arg__1};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) {
|
||||
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
|
||||
if (args[0]!=&returnValue) {
|
||||
if (args[0]==NULL) {
|
||||
PythonQt::priv()->handleVirtualOverloadReturnError("event", methodInfo, result);
|
||||
} else {
|
||||
returnValue = *((bool*)args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return returnValue;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
return CoverProviderFactory::event(arg__1);
|
||||
}
|
||||
bool PythonQtShell_CoverProviderFactory::eventFilter(QObject* arg__1, QEvent* arg__2)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "eventFilter");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"bool" , "QObject*" , "QEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(3, argumentList);
|
||||
bool returnValue = 0;
|
||||
void* args[3] = {NULL, (void*)&arg__1, (void*)&arg__2};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) {
|
||||
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
|
||||
if (args[0]!=&returnValue) {
|
||||
if (args[0]==NULL) {
|
||||
PythonQt::priv()->handleVirtualOverloadReturnError("eventFilter", methodInfo, result);
|
||||
} else {
|
||||
returnValue = *((bool*)args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return returnValue;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
return CoverProviderFactory::eventFilter(arg__1, arg__2);
|
||||
}
|
||||
void PythonQtShell_CoverProviderFactory::timerEvent(QTimerEvent* arg__1)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "timerEvent");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"" , "QTimerEvent*"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(2, argumentList);
|
||||
void* args[2] = {NULL, (void*)&arg__1};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) { Py_DECREF(result); }
|
||||
Py_DECREF(obj);
|
||||
return;
|
||||
}
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
CoverProviderFactory::timerEvent(arg__1);
|
||||
}
|
||||
CoverProviderFactory* PythonQtWrapper_CoverProviderFactory::new_CoverProviderFactory(QObject* parent)
|
||||
{
|
||||
return new PythonQtShell_CoverProviderFactory(parent); }
|
||||
|
||||
|
||||
|
||||
void PythonQtWrapper_CoverProviders::AddProviderFactory(CoverProviders* theWrappedObject, CoverProviderFactory* factory)
|
||||
{
|
||||
( theWrappedObject->AddProviderFactory(factory));
|
||||
( theWrappedObject->AddProvider(provider));
|
||||
}
|
||||
|
||||
bool PythonQtWrapper_CoverProviders::HasAnyProviderFactories(CoverProviders* theWrappedObject)
|
||||
bool PythonQtWrapper_CoverProviders::HasAnyProviders(CoverProviders* theWrappedObject) const
|
||||
{
|
||||
return ( theWrappedObject->HasAnyProviderFactories());
|
||||
return ( theWrappedObject->HasAnyProviders());
|
||||
}
|
||||
|
||||
QList<CoverProvider* > PythonQtWrapper_CoverProviders::List(CoverProviders* theWrappedObject, AlbumCoverFetcherSearch* parent)
|
||||
QList<CoverProvider* > PythonQtWrapper_CoverProviders::List(CoverProviders* theWrappedObject) const
|
||||
{
|
||||
return ( theWrappedObject->List(parent));
|
||||
return ( theWrappedObject->List());
|
||||
}
|
||||
|
||||
int PythonQtWrapper_CoverProviders::NextId(CoverProviders* theWrappedObject)
|
||||
{
|
||||
return ( theWrappedObject->NextId());
|
||||
}
|
||||
|
||||
void PythonQtWrapper_CoverProviders::RemoveProvider(CoverProviders* theWrappedObject, CoverProvider* provider)
|
||||
{
|
||||
( theWrappedObject->RemoveProvider(provider));
|
||||
}
|
||||
|
||||
CoverProviders* PythonQtWrapper_CoverProviders::static_CoverProviders_instance()
|
||||
@ -9782,3 +9525,9 @@ int PythonQtWrapper_TaskManager::StartTask(TaskManager* theWrappedObject, const
|
||||
}
|
||||
|
||||
|
||||
|
||||
TaskManager_Task* PythonQtWrapper_TaskManager_Task::new_TaskManager_Task()
|
||||
{
|
||||
return new PythonQtShell_TaskManager_Task(); }
|
||||
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include <albumcoverfetcher.h>
|
||||
#include <albumcoverfetchersearch.h>
|
||||
#include <coverprovider.h>
|
||||
#include <coverproviderfactory.h>
|
||||
#include <coverproviders.h>
|
||||
#include <directory.h>
|
||||
#include <librarybackend.h>
|
||||
@ -57,19 +56,6 @@
|
||||
|
||||
|
||||
|
||||
class PythonQtShell_AlbumCoverFetcherSearch : public AlbumCoverFetcherSearch
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void childEvent(QChildEvent* arg__1);
|
||||
virtual void customEvent(QEvent* arg__1);
|
||||
virtual bool event(QEvent* arg__1);
|
||||
virtual bool eventFilter(QObject* arg__1, QEvent* arg__2);
|
||||
virtual void timerEvent(QTimerEvent* arg__1);
|
||||
|
||||
PythonQtInstanceWrapper* _wrapper;
|
||||
};
|
||||
|
||||
class PythonQtWrapper_AlbumCoverFetcherSearch : public QObject
|
||||
{ Q_OBJECT
|
||||
public:
|
||||
@ -85,10 +71,10 @@ void delete_AlbumCoverFetcherSearch(AlbumCoverFetcherSearch* obj) { delete obj;
|
||||
class PythonQtShell_CoverProvider : public CoverProvider
|
||||
{
|
||||
public:
|
||||
PythonQtShell_CoverProvider(const QString& name, QObject* parent = &CoverProviders::instance()):CoverProvider(name, parent),_wrapper(NULL) {};
|
||||
PythonQtShell_CoverProvider(const QString& name, QObject* parent):CoverProvider(name, parent),_wrapper(NULL) {};
|
||||
|
||||
virtual QList<CoverSearchResult > ParseReply(QNetworkReply* reply);
|
||||
virtual QNetworkReply* SendRequest(const QString& query);
|
||||
virtual void CancelSearch(int id);
|
||||
virtual bool StartSearch(const QString& query, int id);
|
||||
virtual void childEvent(QChildEvent* arg__1);
|
||||
virtual void customEvent(QEvent* arg__1);
|
||||
virtual bool event(QEvent* arg__1);
|
||||
@ -98,12 +84,18 @@ virtual void timerEvent(QTimerEvent* arg__1);
|
||||
PythonQtInstanceWrapper* _wrapper;
|
||||
};
|
||||
|
||||
class PythonQtPublicPromoter_CoverProvider : public CoverProvider
|
||||
{ public:
|
||||
inline void promoted_CancelSearch(int id) { CoverProvider::CancelSearch(id); }
|
||||
};
|
||||
|
||||
class PythonQtWrapper_CoverProvider : public QObject
|
||||
{ Q_OBJECT
|
||||
public:
|
||||
public slots:
|
||||
CoverProvider* new_CoverProvider(const QString& name, QObject* parent = &CoverProviders::instance());
|
||||
CoverProvider* new_CoverProvider(const QString& name, QObject* parent);
|
||||
void delete_CoverProvider(CoverProvider* obj) { delete obj; }
|
||||
void CancelSearch(CoverProvider* theWrappedObject, int id);
|
||||
QString name(CoverProvider* theWrappedObject) const;
|
||||
};
|
||||
|
||||
@ -111,41 +103,15 @@ void delete_CoverProvider(CoverProvider* obj) { delete obj; }
|
||||
|
||||
|
||||
|
||||
class PythonQtShell_CoverProviderFactory : public CoverProviderFactory
|
||||
{
|
||||
public:
|
||||
PythonQtShell_CoverProviderFactory(QObject* parent = &CoverProviders::instance()):CoverProviderFactory(parent),_wrapper(NULL) {};
|
||||
|
||||
virtual CoverProvider* CreateCoverProvider(AlbumCoverFetcherSearch* parent);
|
||||
virtual void childEvent(QChildEvent* arg__1);
|
||||
virtual void customEvent(QEvent* arg__1);
|
||||
virtual bool event(QEvent* arg__1);
|
||||
virtual bool eventFilter(QObject* arg__1, QEvent* arg__2);
|
||||
virtual void timerEvent(QTimerEvent* arg__1);
|
||||
|
||||
PythonQtInstanceWrapper* _wrapper;
|
||||
};
|
||||
|
||||
class PythonQtWrapper_CoverProviderFactory : public QObject
|
||||
{ Q_OBJECT
|
||||
public:
|
||||
public slots:
|
||||
CoverProviderFactory* new_CoverProviderFactory(QObject* parent = &CoverProviders::instance());
|
||||
void delete_CoverProviderFactory(CoverProviderFactory* obj) { delete obj; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class PythonQtWrapper_CoverProviders : public QObject
|
||||
{ Q_OBJECT
|
||||
public:
|
||||
public slots:
|
||||
void delete_CoverProviders(CoverProviders* obj) { delete obj; }
|
||||
void AddProviderFactory(CoverProviders* theWrappedObject, CoverProviderFactory* factory);
|
||||
bool HasAnyProviderFactories(CoverProviders* theWrappedObject);
|
||||
QList<CoverProvider* > List(CoverProviders* theWrappedObject, AlbumCoverFetcherSearch* parent);
|
||||
void AddProvider(CoverProviders* theWrappedObject, CoverProvider* provider);
|
||||
bool HasAnyProviders(CoverProviders* theWrappedObject) const;
|
||||
QList<CoverProvider* > List(CoverProviders* theWrappedObject) const;
|
||||
int NextId(CoverProviders* theWrappedObject);
|
||||
void RemoveProvider(CoverProviders* theWrappedObject, CoverProvider* provider);
|
||||
CoverProviders* static_CoverProviders_instance();
|
||||
};
|
||||
|
||||
@ -1526,3 +1492,38 @@ void delete_TaskManager(TaskManager* obj) { delete obj; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class PythonQtShell_TaskManager_Task : public TaskManager_Task
|
||||
{
|
||||
public:
|
||||
PythonQtShell_TaskManager_Task():TaskManager_Task(),_wrapper(NULL) {};
|
||||
|
||||
|
||||
PythonQtInstanceWrapper* _wrapper;
|
||||
};
|
||||
|
||||
class PythonQtWrapper_TaskManager_Task : public QObject
|
||||
{ Q_OBJECT
|
||||
public:
|
||||
public slots:
|
||||
TaskManager_Task* new_TaskManager_Task();
|
||||
TaskManager_Task* new_TaskManager_Task(const TaskManager_Task& other) {
|
||||
PythonQtShell_TaskManager_Task* a = new PythonQtShell_TaskManager_Task();
|
||||
*((TaskManager_Task*)a) = other;
|
||||
return a; }
|
||||
void delete_TaskManager_Task(TaskManager_Task* obj) { delete obj; }
|
||||
void py_set_progress_max(TaskManager_Task* theWrappedObject, int progress_max){ theWrappedObject->progress_max = progress_max; }
|
||||
int py_get_progress_max(TaskManager_Task* theWrappedObject){ return theWrappedObject->progress_max; }
|
||||
void py_set_progress(TaskManager_Task* theWrappedObject, int progress){ theWrappedObject->progress = progress; }
|
||||
int py_get_progress(TaskManager_Task* theWrappedObject){ return theWrappedObject->progress; }
|
||||
void py_set_id(TaskManager_Task* theWrappedObject, int id){ theWrappedObject->id = id; }
|
||||
int py_get_id(TaskManager_Task* theWrappedObject){ return theWrappedObject->id; }
|
||||
void py_set_name(TaskManager_Task* theWrappedObject, QString name){ theWrappedObject->name = name; }
|
||||
QString py_get_name(TaskManager_Task* theWrappedObject){ return theWrappedObject->name; }
|
||||
void py_set_blocks_library_scans(TaskManager_Task* theWrappedObject, bool blocks_library_scans){ theWrappedObject->blocks_library_scans = blocks_library_scans; }
|
||||
bool py_get_blocks_library_scans(TaskManager_Task* theWrappedObject){ return theWrappedObject->blocks_library_scans; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,12 +12,6 @@
|
||||
#include <qurl.h>
|
||||
#include <urlhandler.h>
|
||||
|
||||
TaskManager_Task* PythonQtWrapper_TaskManager_Task::new_TaskManager_Task()
|
||||
{
|
||||
return new PythonQtShell_TaskManager_Task(); }
|
||||
|
||||
|
||||
|
||||
qint64 PythonQtShell_ThreadSafeNetworkDiskCache::cacheSize() const
|
||||
{
|
||||
if (_wrapper) {
|
||||
|
@ -9,46 +9,10 @@
|
||||
#include <qlist.h>
|
||||
#include <qobject.h>
|
||||
#include <qurl.h>
|
||||
#include <taskmanager.h>
|
||||
#include <urlhandler.h>
|
||||
|
||||
|
||||
|
||||
class PythonQtShell_TaskManager_Task : public TaskManager_Task
|
||||
{
|
||||
public:
|
||||
PythonQtShell_TaskManager_Task():TaskManager_Task(),_wrapper(NULL) {};
|
||||
|
||||
|
||||
PythonQtInstanceWrapper* _wrapper;
|
||||
};
|
||||
|
||||
class PythonQtWrapper_TaskManager_Task : public QObject
|
||||
{ Q_OBJECT
|
||||
public:
|
||||
public slots:
|
||||
TaskManager_Task* new_TaskManager_Task();
|
||||
TaskManager_Task* new_TaskManager_Task(const TaskManager_Task& other) {
|
||||
PythonQtShell_TaskManager_Task* a = new PythonQtShell_TaskManager_Task();
|
||||
*((TaskManager_Task*)a) = other;
|
||||
return a; }
|
||||
void delete_TaskManager_Task(TaskManager_Task* obj) { delete obj; }
|
||||
void py_set_progress_max(TaskManager_Task* theWrappedObject, int progress_max){ theWrappedObject->progress_max = progress_max; }
|
||||
int py_get_progress_max(TaskManager_Task* theWrappedObject){ return theWrappedObject->progress_max; }
|
||||
void py_set_progress(TaskManager_Task* theWrappedObject, int progress){ theWrappedObject->progress = progress; }
|
||||
int py_get_progress(TaskManager_Task* theWrappedObject){ return theWrappedObject->progress; }
|
||||
void py_set_id(TaskManager_Task* theWrappedObject, int id){ theWrappedObject->id = id; }
|
||||
int py_get_id(TaskManager_Task* theWrappedObject){ return theWrappedObject->id; }
|
||||
void py_set_name(TaskManager_Task* theWrappedObject, QString name){ theWrappedObject->name = name; }
|
||||
QString py_get_name(TaskManager_Task* theWrappedObject){ return theWrappedObject->name; }
|
||||
void py_set_blocks_library_scans(TaskManager_Task* theWrappedObject, bool blocks_library_scans){ theWrappedObject->blocks_library_scans = blocks_library_scans; }
|
||||
bool py_get_blocks_library_scans(TaskManager_Task* theWrappedObject){ return theWrappedObject->blocks_library_scans; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class PythonQtShell_ThreadSafeNetworkDiskCache : public ThreadSafeNetworkDiskCache
|
||||
{
|
||||
public:
|
||||
|
@ -4,9 +4,8 @@
|
||||
|
||||
|
||||
void PythonQt_init_Clementine(PyObject* module) {
|
||||
PythonQt::priv()->registerClass(&AlbumCoverFetcherSearch::staticMetaObject, "Clementine", PythonQtCreateObject<PythonQtWrapper_AlbumCoverFetcherSearch>, PythonQtSetInstanceWrapperOnShell<PythonQtShell_AlbumCoverFetcherSearch>, module, 0);
|
||||
PythonQt::priv()->registerClass(&AlbumCoverFetcherSearch::staticMetaObject, "Clementine", PythonQtCreateObject<PythonQtWrapper_AlbumCoverFetcherSearch>, NULL, module, 0);
|
||||
PythonQt::priv()->registerClass(&CoverProvider::staticMetaObject, "Clementine", PythonQtCreateObject<PythonQtWrapper_CoverProvider>, PythonQtSetInstanceWrapperOnShell<PythonQtShell_CoverProvider>, module, 0);
|
||||
PythonQt::priv()->registerClass(&CoverProviderFactory::staticMetaObject, "Clementine", PythonQtCreateObject<PythonQtWrapper_CoverProviderFactory>, PythonQtSetInstanceWrapperOnShell<PythonQtShell_CoverProviderFactory>, module, 0);
|
||||
PythonQt::priv()->registerClass(&CoverProviders::staticMetaObject, "Clementine", PythonQtCreateObject<PythonQtWrapper_CoverProviders>, NULL, module, 0);
|
||||
PythonQt::priv()->registerCPPClass("CoverSearchResult", "", "Clementine", PythonQtCreateObject<PythonQtWrapper_CoverSearchResult>, PythonQtSetInstanceWrapperOnShell<PythonQtShell_CoverSearchResult>, module, 0);
|
||||
PythonQt::priv()->registerCPPClass("Directory", "", "Clementine", PythonQtCreateObject<PythonQtWrapper_Directory>, PythonQtSetInstanceWrapperOnShell<PythonQtShell_Directory>, module, 0);
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "core/player.h"
|
||||
#include "core/song.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "covers/coverproviders.h"
|
||||
#include "covers/lastfmcoverprovider.h"
|
||||
#include "ui/iconloader.h"
|
||||
#include "ui/settingsdialog.h"
|
||||
|
||||
@ -105,6 +107,7 @@ LastFMService::LastFMService(RadioModel* parent)
|
||||
add_custom_action_->setEnabled(false);
|
||||
|
||||
model()->player()->RegisterUrlHandler(url_handler_);
|
||||
CoverProviders::instance().AddProvider(new LastFmCoverProvider(this));
|
||||
}
|
||||
|
||||
LastFMService::~LastFMService() {
|
||||
|
@ -78,15 +78,23 @@ PythonEngine::~PythonEngine() {
|
||||
template <typename T>
|
||||
static void RegisterListConverter(const char* other_class_name) {
|
||||
typedef QList<T> L;
|
||||
PythonQtConv::registerMetaTypeToPythonConverter(qMetaTypeId<L>(),
|
||||
PythonQtConvertListOfValueTypeToPythonList<L, T>);
|
||||
PythonQtConv::registerMetaTypeToPythonConverter(QMetaType::type(other_class_name),
|
||||
PythonQtConvertListOfValueTypeToPythonList<L, T>);
|
||||
const int primary_id = qMetaTypeId<L>();
|
||||
const int secondary_id = QMetaType::type(other_class_name);
|
||||
|
||||
PythonQtConv::registerPythonToMetaTypeConverter(qMetaTypeId<L>(),
|
||||
PythonQtConvertPythonListToListOfValueType<L, T>);
|
||||
PythonQtConv::registerPythonToMetaTypeConverter(QMetaType::type(other_class_name),
|
||||
PythonQtConvertPythonListToListOfValueType<L, T>);
|
||||
PythonQtConvertMetaTypeToPythonCB* metatype_to_python =
|
||||
PythonQtConvertListOfValueTypeToPythonList<L, T>;
|
||||
PythonQtConvertPythonToMetaTypeCB* python_to_metatype =
|
||||
PythonQtConvertPythonListToListOfValueType<L, T>;
|
||||
|
||||
qLog(Debug) << "Registering list converters for" <<
|
||||
primary_id << QMetaType::typeName(primary_id) << "," <<
|
||||
secondary_id << other_class_name;
|
||||
|
||||
PythonQtConv::registerMetaTypeToPythonConverter(primary_id, metatype_to_python);
|
||||
PythonQtConv::registerMetaTypeToPythonConverter(secondary_id, metatype_to_python);
|
||||
|
||||
PythonQtConv::registerPythonToMetaTypeConverter(primary_id, python_to_metatype);
|
||||
PythonQtConv::registerPythonToMetaTypeConverter(secondary_id, python_to_metatype);
|
||||
}
|
||||
|
||||
bool PythonEngine::EnsureInitialised() {
|
||||
|
@ -258,7 +258,7 @@ void AlbumCoverManager::Reset() {
|
||||
}
|
||||
|
||||
void AlbumCoverManager::ResetFetchCoversButton() {
|
||||
ui_->fetch->setEnabled(CoverProviders::instance().HasAnyProviderFactories());
|
||||
ui_->fetch->setEnabled(CoverProviders::instance().HasAnyProviders());
|
||||
}
|
||||
|
||||
void AlbumCoverManager::ArtistChanged(QListWidgetItem* current) {
|
||||
@ -454,7 +454,7 @@ bool AlbumCoverManager::eventFilter(QObject *obj, QEvent *event) {
|
||||
album_cover_choice_controller_->cover_from_url_action()->setEnabled(context_menu_items_.size() == 1);
|
||||
album_cover_choice_controller_->show_cover_action()->setEnabled(some_with_covers && context_menu_items_.size() == 1);
|
||||
album_cover_choice_controller_->unset_cover_action()->setEnabled(some_with_covers);
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(CoverProviders::instance().HasAnyProviderFactories());
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(CoverProviders::instance().HasAnyProviders());
|
||||
|
||||
QContextMenuEvent* e = static_cast<QContextMenuEvent*>(event);
|
||||
context_menu_->popup(e->globalPos());
|
||||
|
@ -430,7 +430,7 @@ void EditTagDialog::UpdateSummaryTab(const Song& song) {
|
||||
else
|
||||
ui_->filename->setText(song.url().toString());
|
||||
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(CoverProviders::instance().HasAnyProviderFactories());
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(CoverProviders::instance().HasAnyProviders());
|
||||
}
|
||||
|
||||
void EditTagDialog::UpdateStatisticsTab(const Song& song) {
|
||||
|
@ -379,7 +379,7 @@ void NowPlayingWidget::contextMenuEvent(QContextMenuEvent* e) {
|
||||
// initial 'enabled' values depending on the kitty mode
|
||||
album_cover_choice_controller_->cover_from_file_action()->setEnabled(!aww_);
|
||||
album_cover_choice_controller_->cover_from_url_action()->setEnabled(!aww_);
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(!aww_ && CoverProviders::instance().HasAnyProviderFactories());
|
||||
album_cover_choice_controller_->search_for_cover_action()->setEnabled(!aww_ && CoverProviders::instance().HasAnyProviders());
|
||||
album_cover_choice_controller_->unset_cover_action()->setEnabled(!aww_);
|
||||
album_cover_choice_controller_->show_cover_action()->setEnabled(!aww_);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user