diff --git a/data/images/lastfm-icon.png b/data/images/lastfm-icon.png new file mode 100644 index 000000000..ff605dae4 Binary files /dev/null and b/data/images/lastfm-icon.png differ diff --git a/resources.qrc b/resources.qrc index 9b9010880..134cccd5d 100644 --- a/resources.qrc +++ b/resources.qrc @@ -133,6 +133,7 @@ data/images/headphones-bigger.png data/images/no-album-no-case.png data/images/rdio.png + data/images/lastfm-icon.png data/sql/dbmigrate-27_to_28.sql diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index ba8342302..6fdb22e0f 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -75,10 +75,10 @@ AccountDelegate::AccountDelegate( QObject* parent ) QSize -AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +AccountDelegate::sizeHint( const QStyleOptionViewItem&, const QModelIndex& index ) const { AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); - if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::UniqueFactory ) + if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::UniqueFactory || rowType == AccountModel::CustomAccount ) return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT ); else if ( rowType == AccountModel::TopLevelFactory ) { @@ -204,7 +204,6 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, rightEdge = drawAccountList( painter, opt, accts, rightEdge ); painter->restore(); - int centeredUnderAccounts = oldRightEdge - (oldRightEdge - rightEdge)/2 - (btnWidth/2); btnRect = QRect( opt.rect.right() - PADDING - btnWidth, opt.rect.bottom() - installMetrics.height() - 3*PADDING, btnWidth, installMetrics.height() + 2*PADDING ); } @@ -303,7 +302,6 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, { // rating stars const int rating = index.data( AccountModel::RatingRole ).toInt(); - const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); // int runningEdge = opt.rect.right() - 2*PADDING - ratingWidth; int runningEdge = textRect.left(); @@ -414,7 +412,8 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS m_configPressed = index; const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); - if ( rowType == AccountModel::TopLevelAccount ) + if ( rowType == AccountModel::TopLevelAccount || + rowType == AccountModel::CustomAccount ) { Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() ); Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account! @@ -445,8 +444,6 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS m_configPressed = QModelIndex(); - const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); - if ( checkRectForIndex( option, index ).contains( me->pos() ) ) { // Check box for this row diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index f443458ef..3ddce4215 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -308,6 +308,8 @@ set( libSources accounts/AccountModel.cpp accounts/AccountModelFilterProxy.cpp accounts/ResolverAccount.cpp + accounts/LastFmAccount.cpp + accounts/LastFmConfig.cpp sip/SipPlugin.cpp sip/SipHandler.cpp @@ -450,6 +452,8 @@ set( libHeaders accounts/AccountModel.h accounts/AccountModelFilterProxy.h accounts/ResolverAccount.h + accounts/LastFmAccount.h + accounts/LastFmConfig.h EchonestCatalogSynchronizer.h @@ -582,6 +586,7 @@ set( libUI ${libUI} playlist/queueview.ui context/ContextWidget.ui infobar/infobar.ui + accounts/LastFmConfig.ui ) include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.. .. diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index 36a22ebef..6fdaf8315 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -35,6 +35,7 @@ accountTypeToString( AccountType type ) case ResolverType: return QObject::tr( "Music Finders" ); case InfoType: + case StatusPushType: return QObject::tr( "Status Updaters" ); } @@ -174,6 +175,8 @@ Account::setTypes( AccountTypes types ) m_types << "SipType"; if ( types & ResolverType ) m_types << "ResolverType"; + if ( types & StatusPushType ) + m_types << "StatusPushType"; syncConfig(); } @@ -189,6 +192,8 @@ Account::types() const types |= SipType; if ( m_types.contains( "ResolverType" ) ) types |= ResolverType; + if ( m_types.contains( "StatusPushTypeType" ) ) + types |= StatusPushType; return types; } diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index addc02184..d02bdceab 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -50,7 +50,8 @@ enum AccountType InfoType = 0x01, SipType = 0x02, - ResolverType = 0x04 + ResolverType = 0x04, + StatusPushType = 0x08 }; DLLEXPORT QString accountTypeToString( AccountType type ); @@ -88,7 +89,7 @@ public: virtual QWidget* configurationWidget() = 0; virtual void saveConfig() {} // called when the widget has been edited. save values from config widget, call sync() to write to disk account generic settings - QVariantHash credentials() { QMutexLocker locker( &m_mutex ); return m_credentials; } + QVariantHash credentials() const { QMutexLocker locker( &m_mutex ); return m_credentials; } QVariantMap acl() const { QMutexLocker locker( &m_mutex ); return m_acl; } virtual QWidget* aclWidget() = 0; diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index c20cb0cfa..6c5715113 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -21,6 +21,7 @@ #include "config.h" #include "sourcelist.h" #include "ResolverAccount.h" +#include "LastFmAccount.h" #include #include @@ -58,6 +59,9 @@ AccountManager::AccountManager( QObject *parent ) // We include the resolver factory manually, not in a plugin ResolverAccountFactory* f = new ResolverAccountFactory(); m_accountFactories[ f->factoryId() ] = f; + + LastFmAccountFactory* l = new LastFmAccountFactory(); + m_accountFactories[ l->factoryId() ] = l; } @@ -291,16 +295,14 @@ AccountManager::addAccount( Account* account ) if ( account->types() & Accounts::SipType ) m_accountsByAccountType[ Accounts::SipType ].append( account ); if ( account->types() & Accounts::InfoType ) - { m_accountsByAccountType[ Accounts::InfoType ].append( account ); - - if ( account->infoPlugin() ) - { - InfoSystem::InfoSystem::instance()->addInfoPlugin( account->infoPlugin() ); - } - } if ( account->types() & Accounts::ResolverType ) m_accountsByAccountType[ Accounts::ResolverType ].append( account ); + if ( account->types() & Accounts::StatusPushType ) + m_accountsByAccountType[ Accounts::StatusPushType ].append( account ); + + if ( account->infoPlugin() ) + InfoSystem::InfoSystem::instance()->addInfoPlugin( account->infoPlugin() ); emit added( account ); } diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 662bbd071..6457c8837 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -59,6 +59,13 @@ AccountModel::loadData() qDebug() << "Creating factory node:" << fac->prettyName(); m_accounts << new AccountModelNode( fac ); + + // remove the accounts we are dealing with + foreach ( Account* acct, allAccounts ) + { + if ( AccountManager::instance()->factoryForAccount( acct ) == fac ) + allAccounts.removeAll( acct ); + } } // add all attica resolvers (installed or uninstalled) @@ -67,15 +74,26 @@ AccountModel::loadData() { qDebug() << "Loading ATTICA ACCOUNT with content:" << content.id() << content.name(); m_accounts << new AccountModelNode( content ); + + foreach ( Account* acct, AccountManager::instance()->accounts( Accounts::ResolverType ) ) + { + if ( AtticaResolverAccount* resolver = qobject_cast< AtticaResolverAccount* >( acct ) ) + { + if ( resolver->atticaId() == content.id() ) + { + allAccounts.removeAll( acct ); + } + } + } } - // Add all non-attica manually installed resolvers + // All other accounts we haven't dealt with yet foreach ( Account* acct, allAccounts ) { if ( qobject_cast< ResolverAccount* >( acct ) && !qobject_cast< AtticaResolverAccount* >( acct ) ) - { m_accounts << new AccountModelNode( qobject_cast< ResolverAccount* >( acct ) ); - } + else + m_accounts << new AccountModelNode( acct ); } endResetModel(); @@ -280,6 +298,41 @@ AccountModel::data( const QModelIndex& index, int role ) const } } } + case AccountModelNode::CustomAccountType: + { + Q_ASSERT( node->customAccount ); + Q_ASSERT( node->factory ); + + Account* account = node->customAccount; + switch ( role ) + { + case Qt::DisplayRole: + return account->accountFriendlyName(); + case Qt::DecorationRole: + return account->icon(); + case StateRole: + return ShippedWithTomahawk; + case Qt::ToolTipRole: + case DescriptionRole: + return node->factory->description(); + case CanRateRole: + return false; + case RowTypeRole: + return CustomAccount; + case AccountData: + return QVariant::fromValue< QObject* >( account ); + case HasConfig: + return account->configurationWidget() != 0; + case AccountTypeRole: + return QVariant::fromValue< AccountTypes >( account->types() ); + case Qt::CheckStateRole: + return account->enabled(); + case ConnectionStateRole: + return account->connectionState(); + default: + return QVariant(); + } + } } return QVariant(); @@ -345,6 +398,9 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role case AccountModelNode::ManualResolverType: acct = node->resolverAccount; break; + case AccountModelNode::CustomAccountType: + acct = node->customAccount; + break; default: ; }; diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index d06d0a147..4396dcd7a 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -70,7 +70,8 @@ public: enum RowType { TopLevelFactory, TopLevelAccount, - UniqueFactory + UniqueFactory, + CustomAccount }; enum ItemState { diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 6b333a3b8..795e17b6f 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -36,13 +36,14 @@ namespace Accounts { * 1) AccountFactory* for all factories that have child accounts. Also a list of children * 2) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers) * 3) ResolverAccount* for manually added resolvers (from file). + * 4) Account* for custom accounts. These may be hybrid infosystem/resolver/sip plugins or other special accounts * * These are the top-level items in tree. * * Top level nodes all look the same to the user. The only difference is that services that have login (and thus * can have multiple logins at once) allow a user to create multiple children with specific login information. * All other top level accounts (Account*, Attica::Content, ResolverAccount*) behave the same to the user, they can - * simply click "Install" or toggle on/off. + * simply toggle on/off. * */ @@ -51,7 +52,8 @@ struct AccountModelNode { FactoryType, UniqueFactoryType, AtticaType, - ManualResolverType + ManualResolverType, + CustomAccountType }; AccountModelNode* parent; NodeType type; @@ -67,6 +69,9 @@ struct AccountModelNode { /// 3. ResolverAccount* resolverAccount; + /// 4. + Account* customAccount; + // Construct in one of four ways. Then access the corresponding members explicit AccountModelNode( AccountFactory* fac ) : type( FactoryType ) { @@ -114,11 +119,19 @@ struct AccountModelNode { resolverAccount = ra; } + explicit AccountModelNode( Account* account ) : type( CustomAccountType ) + { + init(); + customAccount = account; + factory = AccountManager::instance()->factoryForAccount( account ); + } + void init() { factory = 0; atticaAccount = 0; resolverAccount = 0; + customAccount = 0; } }; diff --git a/src/libtomahawk/accounts/LastFmAccount.cpp b/src/libtomahawk/accounts/LastFmAccount.cpp new file mode 100644 index 000000000..4e97fcb95 --- /dev/null +++ b/src/libtomahawk/accounts/LastFmAccount.cpp @@ -0,0 +1,194 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Leo Franchi + * + * Tomahawk 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. + * + * Tomahawk 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 Tomahawk. If not, see . + */ + +#include "LastFmAccount.h" +#include "LastFmConfig.h" + +#include "infosystem/infosystem.h" +#include "infosystem/infoplugins/generic/lastfmplugin.h" +#include "utils/tomahawkutils.h" +#include "resolvers/qtscriptresolver.h" + +using namespace Tomahawk; +using namespace InfoSystem; +using namespace Accounts; + +LastFmAccountFactory::LastFmAccountFactory() +{ + m_icon.load( RESPATH "images/lastfm-icon.png" ); +} + + +Account* +LastFmAccountFactory::createAccount( const QString& accountId ) +{ + return new LastFmAccount( accountId.isEmpty() ? generateId( factoryId() ) : accountId ); +} + + +QPixmap +LastFmAccountFactory::icon() const +{ + return m_icon; +} + + +LastFmAccount::LastFmAccount( const QString& accountId ) + : Account( accountId ) +{ + m_infoPlugin = new LastFmPlugin( this ); + + setAccountFriendlyName( "Last.Fm" ); + m_icon.load( RESPATH "images/lastfm-icon.png" ); +} + + +LastFmAccount::~LastFmAccount() +{ + delete m_infoPlugin; + delete m_resolver.data(); +} + + +void +LastFmAccount::authenticate() +{ + +} + + +void +LastFmAccount::deauthenticate() +{ + +} + + +QWidget* +LastFmAccount::configurationWidget() +{ + if ( m_configWidget.isNull() ) + m_configWidget = QWeakPointer( new LastFmConfig( this ) ); + + return m_configWidget.data(); +} + + +Account::ConnectionState +LastFmAccount::connectionState() const +{ + return m_authenticated ? Account::Connected : Account::Disconnected; +} + + +QPixmap +LastFmAccount::icon() const +{ + return m_icon; +} + + +InfoPlugin* +LastFmAccount::infoPlugin() +{ + return m_infoPlugin; +} + +bool +LastFmAccount::isAuthenticated() const +{ + return m_authenticated; +} + + +void +LastFmAccount::saveConfig() +{ + if ( !m_configWidget.isNull() ) + { + setUsername( m_configWidget.data()->username() ); + setPassword( m_configWidget.data()->password() ); + setScrobble( m_configWidget.data()->scrobble() ); + } + + m_infoPlugin->settingsChanged(); +} + + +QString +LastFmAccount::password() const +{ + return credentials().value( "password" ).toString(); +} + + +void +LastFmAccount::setPassword( const QString& password ) +{ + QVariantHash creds; + creds[ "password" ] = password; + setCredentials( creds ); +} + +QString +LastFmAccount::sessionKey() const +{ + return credentials().value( "sessionkey" ).toString(); +} + + +void +LastFmAccount::setSessionKey( const QString& sessionkey ) +{ + QVariantHash creds; + creds[ "sessionkey" ] = sessionkey; + setCredentials( creds ); +} + + +QString +LastFmAccount::username() const +{ + return credentials().value( "username" ).toString(); +} + + +void +LastFmAccount::setUsername( const QString& username ) +{ + QVariantHash creds; + creds[ "username" ] = username; + setCredentials( creds ); +} + + +bool +LastFmAccount::scrobble() const +{ + return configuration().value( "scrobble" ).toBool(); +} + + +void +LastFmAccount::setScrobble( bool scrobble ) +{ + QVariantHash conf; + conf[ "scrobble" ] = scrobble; + setConfiguration( conf ); +} + diff --git a/src/libtomahawk/accounts/LastFmAccount.h b/src/libtomahawk/accounts/LastFmAccount.h new file mode 100644 index 000000000..1ab607be4 --- /dev/null +++ b/src/libtomahawk/accounts/LastFmAccount.h @@ -0,0 +1,103 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Leo Franchi + * + * Tomahawk 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. + * + * Tomahawk 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 Tomahawk. If not, see . + */ + +#ifndef LASTFMACCOUNT_H +#define LASTFMACCOUNT_H + +#include "accounts/Account.h" + +#include + +class QtScriptResolver; + +namespace Tomahawk { +namespace InfoSystem { + class LastFmPlugin; +} + +namespace Accounts { + +class LastFmConfig; + +class LastFmAccountFactory : public AccountFactory +{ + Q_OBJECT +public: + LastFmAccountFactory(); + + virtual Account* createAccount(const QString& accountId = QString()); + virtual QString description() const { return tr( "Scrobble your tracks to last.fm, and find freely downloadable tracks to play" ); } + virtual QString factoryId() const { return "lastfmaccount"; } + virtual QString prettyName() const { return "Last.fm"; } + virtual AccountTypes types() const { return AccountTypes( InfoType | StatusPushType ); } + virtual bool allowUserCreation() const { return false; } + virtual QPixmap icon() const; + virtual bool isUnique() const { return true; } + +private: + QPixmap m_icon; +}; + +/** + * 3.Last.Fm account is special. It is both an attica resolver *and* a InfoPlugin. We always want the infoplugin, + * but the user can install the attica resolver on-demand. So we take care of both there. + * + */ +class LastFmAccount : public Account +{ + Q_OBJECT +public: + explicit LastFmAccount( const QString& accountId ); + ~LastFmAccount(); + + virtual void deauthenticate(); + virtual void authenticate(); + + virtual SipPlugin* sipPlugin() { return 0; } + virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin(); + + virtual bool isAuthenticated() const; + + virtual ConnectionState connectionState() const; + virtual QPixmap icon() const; + virtual QWidget* aclWidget() { return 0; } + virtual QWidget* configurationWidget(); + virtual void saveConfig(); + + QString username() const; + void setUsername( const QString& ); + QString password() const; + void setPassword( const QString& ); + QString sessionKey() const; + void setSessionKey( const QString& ); + bool scrobble() const; + void setScrobble( bool scrobble ); + +private: + bool m_authenticated; + QWeakPointer m_resolver; + Tomahawk::InfoSystem::LastFmPlugin* m_infoPlugin; + QWeakPointer m_configWidget; + QPixmap m_icon; +}; + + +} +} + +#endif // LASTFMACCOUNT_H diff --git a/src/libtomahawk/accounts/LastFmConfig.cpp b/src/libtomahawk/accounts/LastFmConfig.cpp new file mode 100644 index 000000000..70648d305 --- /dev/null +++ b/src/libtomahawk/accounts/LastFmConfig.cpp @@ -0,0 +1,134 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * Tomahawk 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. + * + * Tomahawk 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 Tomahawk. If not, see . + */ + +#include "LastFmConfig.h" + +#include "LastFmAccount.h" +#include +#include "ui_LastFmConfig.h" +#include "lastfm/ws.h" +#include "lastfm/XmlQuery" + +using namespace Tomahawk::Accounts; + +LastFmConfig::LastFmConfig( LastFmAccount* account ) + : QWidget( 0 ) + , m_account( account ) +{ + m_ui = new Ui_LastFmConfig; + m_ui->setupUi( this ); + + m_ui->username->setText( m_account->username() ); + m_ui->password->setText( m_account->password() ); + m_ui->enable->setChecked( m_account->scrobble() ); + + connect( m_ui->testLogin, SIGNAL( clicked( bool ) ), this, SLOT( testLogin( bool ) ) ); + +// #ifdef Q_WS_MAC // FIXME +// m_ui->testLogin->setVisible( false ); +// #endif +} + + +QString +LastFmConfig::password() const +{ + return m_ui->password->text(); +} + + +bool +LastFmConfig::scrobble() const +{ + return m_ui->enable->isChecked(); +} + + +QString +LastFmConfig::username() const +{ + return m_ui->username->text().trimmed(); +} + + +void +LastFmConfig::testLogin(bool ) +{ + m_ui->testLogin->setEnabled( false ); + m_ui->testLogin->setText( "Testing..." ); + + QString authToken = TomahawkUtils::md5( ( m_ui->username->text().toLower() + TomahawkUtils::md5( m_ui->password->text().toUtf8() ) ).toUtf8() ); + + // now authenticate w/ last.fm and get our session key + QMap query; + query[ "method" ] = "auth.getMobileSession"; + query[ "username" ] = m_ui->username->text().toLower(); + query[ "authToken" ] = authToken; + + // ensure they have up-to-date settings + lastfm::setNetworkAccessManager( TomahawkUtils::nam() ); + + QNetworkReply* authJob = lastfm::ws::post( query ); + + connect( authJob, SIGNAL( finished() ), SLOT( onLastFmFinished() ) ); +} + + +void +LastFmConfig::onLastFmFinished() +{ + QNetworkReply* authJob = dynamic_cast( sender() ); + if( !authJob ) + { + qDebug() << Q_FUNC_INFO << "No auth job returned!"; + return; + } + if( authJob->error() == QNetworkReply::NoError ) + { + lastfm::XmlQuery lfm = lastfm::XmlQuery( authJob->readAll() ); + + if( lfm.children( "error" ).size() > 0 ) + { + qDebug() << "ERROR from last.fm:" << lfm.text(); + m_ui->testLogin->setText( tr( "Failed" ) ); + m_ui->testLogin->setEnabled( true ); + } + else + { + m_ui->testLogin->setText( tr( "Success" ) ); + m_ui->testLogin->setEnabled( false ); + } + } + else + { + switch( authJob->error() ) + { + case QNetworkReply::ContentOperationNotPermittedError: + case QNetworkReply::AuthenticationRequiredError: + m_ui->testLogin->setText( tr( "Failed" ) ); + m_ui->testLogin->setEnabled( true ); + break; + + default: + qDebug() << "Couldn't get last.fm auth result"; + m_ui->testLogin->setText( tr( "Could not contact server" ) ); + m_ui->testLogin->setEnabled( true ); + return; + } + } +} diff --git a/src/libtomahawk/accounts/LastFmConfig.h b/src/libtomahawk/accounts/LastFmConfig.h new file mode 100644 index 000000000..a86d73f0e --- /dev/null +++ b/src/libtomahawk/accounts/LastFmConfig.h @@ -0,0 +1,53 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * Tomahawk 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. + * + * Tomahawk 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 Tomahawk. If not, see . + */ + +#ifndef LASTFMCONFIG_H +#define LASTFMCONFIG_H + +#include + +class Ui_LastFmConfig; + +namespace Tomahawk { +namespace Accounts { + +class LastFmAccount; + +class LastFmConfig : public QWidget +{ + Q_OBJECT +public: + explicit LastFmConfig( LastFmAccount* account ); + + QString username() const; + QString password() const; + bool scrobble() const; + +public slots: + void testLogin( bool ); + void onLastFmFinished(); + +private: + LastFmAccount* m_account; + Ui_LastFmConfig* m_ui; +}; + +} +} + +#endif // LASTFMCONFIG_H diff --git a/src/libtomahawk/accounts/LastFmConfig.ui b/src/libtomahawk/accounts/LastFmConfig.ui new file mode 100644 index 000000000..c0a0ece12 --- /dev/null +++ b/src/libtomahawk/accounts/LastFmConfig.ui @@ -0,0 +1,85 @@ + + + LastFmConfig + + + + 0 + 0 + 400 + 178 + + + + Form + + + + + + + + + :/data/images/lastfm-icon.png + + + Qt::AlignCenter + + + + + + + + + Qt::LeftToRight + + + Scrobble tracks to Last.fm + + + + + + + + + Username: + + + + + + + + + + Password: + + + + + + + QLineEdit::Password + + + + + + + + + Test Login + + + + + + + + + + + + diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index 99f58d815..b2d5b7a32 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -26,34 +26,37 @@ #include "album.h" #include "typedefs.h" #include "audio/audioengine.h" -#include "tomahawksettings.h" #include "utils/tomahawkutils.h" #include "utils/logger.h" +#include "accounts/LastFmAccount.h" #include #include #include +using namespace Tomahawk::Accounts; using namespace Tomahawk::InfoSystem; -LastFmPlugin::LastFmPlugin() +LastFmPlugin::LastFmPlugin( LastFmAccount* account ) : InfoPlugin() + , m_account( account ) , m_scrobbler( 0 ) { m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages << InfoArtistSimilars << InfoArtistSongs << InfoChart << InfoChartCapabilities; m_supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying << InfoLove << InfoUnLove; // Flush session key cache - TomahawkSettings::instance()->setLastFmSessionKey( QByteArray() ); + // TODO WHY FLUSH +// m_account->setSessionKey( QByteArray() ); lastfm::ws::ApiKey = "7194b85b6d1f424fe1668173a78c0c4a"; lastfm::ws::SharedSecret = "ba80f1df6d27ae63e9cb1d33ccf2052f"; - lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername(); + lastfm::ws::Username = m_account->username(); lastfm::setNetworkAccessManager( TomahawkUtils::nam() ); - m_pw = TomahawkSettings::instance()->lastFmPassword(); + m_pw = m_account->password(); //HACK work around a bug in liblastfm---it doesn't create its config dir, so when it // tries to write the track cache, it fails silently. until we have a fixed version, do this @@ -69,9 +72,6 @@ LastFmPlugin::LastFmPlugin() m_badUrls << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage" ); - connect( TomahawkSettings::instance(), SIGNAL( changed() ), - SLOT( settingsChanged() ), Qt::QueuedConnection ); - QTimer::singleShot( 0, this, SLOT( settingsChanged() ) ); } @@ -693,23 +693,23 @@ LastFmPlugin::artistImagesReturned() void LastFmPlugin::settingsChanged() { - if ( !m_scrobbler && TomahawkSettings::instance()->scrobblingEnabled() ) + if ( !m_scrobbler && m_account->enabled() ) { // can simply create the scrobbler - lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername(); - m_pw = TomahawkSettings::instance()->lastFmPassword(); + lastfm::ws::Username = m_account->username(); + m_pw = m_account->password(); createScrobbler(); } - else if ( m_scrobbler && !TomahawkSettings::instance()->scrobblingEnabled() ) + else if ( m_scrobbler && !m_account->enabled() ) { delete m_scrobbler; m_scrobbler = 0; } - else if ( TomahawkSettings::instance()->lastFmUsername() != lastfm::ws::Username || - TomahawkSettings::instance()->lastFmPassword() != m_pw ) + else if ( m_account->username() != lastfm::ws::Username || + m_account->password() != m_pw ) { - lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername(); - m_pw = TomahawkSettings::instance()->lastFmPassword(); + lastfm::ws::Username = m_account->username(); + m_pw = m_account->password(); // credentials have changed, have to re-create scrobbler for them to take effect if ( m_scrobbler ) { @@ -739,16 +739,16 @@ LastFmPlugin::onAuthenticated() if ( lfm.children( "error" ).size() > 0 ) { tLog() << "Error from authenticating with Last.fm service:" << lfm.text(); - TomahawkSettings::instance()->setLastFmSessionKey( QByteArray() ); + m_account->setSessionKey( QByteArray() ); } else { lastfm::ws::SessionKey = lfm[ "session" ][ "key" ].text(); - TomahawkSettings::instance()->setLastFmSessionKey( lastfm::ws::SessionKey.toLatin1() ); + m_account->setSessionKey( lastfm::ws::SessionKey.toLatin1() ); // qDebug() << "Got session key from last.fm"; - if ( TomahawkSettings::instance()->scrobblingEnabled() ) + if ( m_account->enabled() ) m_scrobbler = new lastfm::Audioscrobbler( "thk" ); } } @@ -764,7 +764,7 @@ LastFmPlugin::onAuthenticated() void LastFmPlugin::createScrobbler() { - if ( TomahawkSettings::instance()->lastFmSessionKey().isEmpty() ) // no session key, so get one + if ( m_account->sessionKey().isEmpty() ) // no session key, so get one { qDebug() << "LastFmPlugin::createScrobbler Session key is empty"; QString authToken = TomahawkUtils::md5( ( lastfm::ws::Username.toLower() + TomahawkUtils::md5( m_pw.toUtf8() ) ).toUtf8() ); @@ -780,7 +780,7 @@ LastFmPlugin::createScrobbler() else { qDebug() << "LastFmPlugin::createScrobbler Already have session key"; - lastfm::ws::SessionKey = TomahawkSettings::instance()->lastFmSessionKey(); + lastfm::ws::SessionKey = m_account->sessionKey(); m_scrobbler = new lastfm::Audioscrobbler( "thk" ); } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h index 4850fb44c..00b133a58 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h @@ -32,6 +32,11 @@ class QNetworkReply; namespace Tomahawk { +namespace Accounts +{ + class LastFmAccount; +} + namespace InfoSystem { @@ -40,7 +45,7 @@ class LastFmPlugin : public InfoPlugin Q_OBJECT public: - LastFmPlugin(); + LastFmPlugin( Accounts::LastFmAccount* account ); virtual ~LastFmPlugin(); public slots: @@ -74,6 +79,7 @@ private: void dataError( Tomahawk::InfoSystem::InfoRequestData requestData ); + Accounts::LastFmAccount* m_account; QList parseTrackList( QNetworkReply * reply ); lastfm::MutableTrack m_track; @@ -88,3 +94,5 @@ private: } #endif // LASTFMPLUGIN_H + +class A; diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index a16e28ecc..877a3b345 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -46,6 +46,9 @@ InfoSystem* InfoSystem::s_instance = 0; InfoSystem* InfoSystem::instance() { + if ( !s_instance ) + s_instance = new InfoSystem( 0 ); + return s_instance; } @@ -101,6 +104,9 @@ void InfoSystem::init() { tDebug() << Q_FUNC_INFO; + if ( m_inited ) + return; + if ( !m_infoSystemCacheThreadController->cache() || !m_infoSystemWorkerThreadController->worker() ) { QTimer::singleShot( 0, this, SLOT( init() ) ); @@ -199,6 +205,12 @@ InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) void InfoSystem::addInfoPlugin( InfoPlugin* plugin ) { + // Init is not complete (waiting for worker th read to start and create worker object) so keep trying till then + if ( !m_inited || !m_infoSystemWorkerThreadController->worker() ) + { + QMetaObject::invokeMethod( this, "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPlugin*, plugin ) ); + return; + } QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPlugin*, plugin ) ); } diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 1b9b5f988..a8f0fda66 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -242,8 +242,9 @@ public: bool pushInfo( const QString &caller, const InfoType type, const QVariant &input ); bool pushInfo( const QString &caller, const InfoTypeMap &input ); +public slots: // InfoSystem takes ownership of InfoPlugins - void addInfoPlugin( InfoPlugin* plugin ); + void addInfoPlugin( Tomahawk::InfoSystem::InfoPlugin* plugin ); signals: void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index bf530114f..12c4d1ae8 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -62,7 +62,8 @@ public slots: void infoSlot( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); - void addInfoPlugin( InfoPlugin* plugin ); + void addInfoPlugin( Tomahawk::InfoSystem::InfoPlugin* plugin ); + private slots: void checkTimeoutsTimerFired(); diff --git a/src/libtomahawk/pipeline.cpp b/src/libtomahawk/pipeline.cpp index 0fdc9c563..2b25caa14 100644 --- a/src/libtomahawk/pipeline.cpp +++ b/src/libtomahawk/pipeline.cpp @@ -164,6 +164,9 @@ Pipeline::removeScriptResolver( const QString& scriptPath ) QWeakPointer< ExternalResolver > r; foreach ( QWeakPointer< ExternalResolver > res, m_scriptResolvers ) { + if ( res.isNull() ) + continue; + if ( res.data()->filePath() == scriptPath ) r = res; } diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 6991b0fbc..21ca03c00 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -296,6 +296,28 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) } + // Add a Last.Fm account since we now moved the infoplugin into the account + const QString accountKey = QString( "lastfmaccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) ); + accounts << accountKey; + const QString lfmUsername = value( "lastfm/username" ).toString(); + const QString lfmPassword = value( "lastfm/password" ).toString(); + const bool scrobble = value( "lastfm/enablescrobbling", false ).toBool(); + beginGroup( "accounts/" + accountKey ); +// setValue( "enabled", false ); + setValue( "autoconnect", true ); + setValue( "types", QStringList() << "ResolverType" << "StatusPushType" ); + QVariantHash credentials; + credentials[ "username" ] = lfmUsername; + credentials[ "password" ] = lfmPassword; + credentials[ "session" ] = value( "lastfm/session" ).toString(); + setValue( "credentials", credentials ); + QVariantHash configuration; + configuration[ "scrobble" ] = scrobble; + setValue( "configuration", configuration ); + endGroup(); + + remove( "lastfm" ); + remove( "script/resolvers" ); remove( "script/loadedresolvers" ); @@ -892,62 +914,6 @@ TomahawkSettings::setExternalPort(int externalPort) } -QString -TomahawkSettings::lastFmPassword() const -{ - return value( "lastfm/password" ).toString(); -} - - -void -TomahawkSettings::setLastFmPassword( const QString& password ) -{ - setValue( "lastfm/password", password ); -} - - -QByteArray -TomahawkSettings::lastFmSessionKey() const -{ - return value( "lastfm/session" ).toByteArray(); -} - - -void -TomahawkSettings::setLastFmSessionKey( const QByteArray& key ) -{ - setValue( "lastfm/session", key ); -} - - -QString -TomahawkSettings::lastFmUsername() const -{ - return value( "lastfm/username" ).toString(); -} - - -void -TomahawkSettings::setLastFmUsername( const QString& username ) -{ - setValue( "lastfm/username", username ); -} - - -bool -TomahawkSettings::scrobblingEnabled() const -{ - return value( "lastfm/enablescrobbling", false ).toBool(); -} - - -void -TomahawkSettings::setScrobblingEnabled( bool enable ) -{ - setValue( "lastfm/enablescrobbling", enable ); -} - - QString TomahawkSettings::xmppBotServer() const { diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index e52c2b80f..52788b15c 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -165,19 +165,6 @@ public: QStringList aclEntries() const; void setAclEntries( const QStringList &entries ); - /// Last.fm settings - bool scrobblingEnabled() const; /// false by default - void setScrobblingEnabled( bool enable ); - - QString lastFmUsername() const; - void setLastFmUsername( const QString& username ); - - QString lastFmPassword() const; - void setLastFmPassword( const QString& password ); - - QByteArray lastFmSessionKey() const; - void setLastFmSessionKey( const QByteArray& key ); - /// XMPP Component Settings QString xmppBotServer() const; void setXmppBotServer( const QString &server ); diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h index 91b673a6a..42adc2efe 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h @@ -87,11 +87,6 @@ public slots: } signals: - void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode ); - void shuffleModeChanged( bool enabled ); - - void trackCountChanged( unsigned int tracks ); - void sourceTrackCountChanged( unsigned int tracks ); void nextTrackReady(); private slots: diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index f784f34ae..bcd2c997b 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -30,11 +30,6 @@ #include #include -#ifdef LIBLASTFM_FOUND -#include -#include -#endif - #include "AtticaManager.h" #include "tomahawkapp.h" #include "tomahawksettings.h" @@ -168,21 +163,11 @@ SettingsDialog::SettingsDialog( QWidget *parent ) } // NOW PLAYING -#ifdef Q_WS_MAC - ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() ); -#else - ui->checkBoxEnableAdium->hide(); -#endif - - // LAST FM - ui->checkBoxEnableLastfm->setChecked( s->scrobblingEnabled() ); - ui->lineEditLastfmUsername->setText( s->lastFmUsername() ); - ui->lineEditLastfmPassword->setText(s->lastFmPassword() ); - connect( ui->pushButtonTestLastfmLogin, SIGNAL( clicked( bool) ), SLOT( testLastFmLogin() ) ); - -#ifdef Q_WS_MAC // FIXME - ui->pushButtonTestLastfmLogin->setVisible( false ); -#endif +// #ifdef Q_WS_MAC +// ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() ); +// #else +// ui->checkBoxEnableAdium->hide(); +// #endif connect( ui->proxyButton, SIGNAL( clicked() ), SLOT( showProxySettings() ) ); connect( ui->checkBoxStaticPreferred, SIGNAL( toggled(bool) ), SLOT( toggleUpnp(bool) ) ); @@ -217,11 +202,7 @@ SettingsDialog::~SettingsDialog() s->setScannerTime( ui->scannerTimeSpinBox->value() ); s->setEnableEchonestCatalogs( ui->enableEchonestCatalog->isChecked() ); - s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() ); - - s->setScrobblingEnabled( ui->checkBoxEnableLastfm->isChecked() ); - s->setLastFmUsername( ui->lineEditLastfmUsername->text() ); - s->setLastFmPassword( ui->lineEditLastfmPassword->text() ); +// s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() ); s->applyChanges(); s->sync(); @@ -265,13 +246,6 @@ SettingsDialog::createIcons() musicButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); maxlen = qMax( fm.width( musicButton->text() ), maxlen ); - QListWidgetItem *lastfmButton = new QListWidgetItem( ui->listWidget ); - lastfmButton->setIcon( QIcon( RESPATH "images/lastfm-settings.png" ) ); - lastfmButton->setText( tr( "Last.fm" ) ); - lastfmButton->setTextAlignment( Qt::AlignHCenter ); - lastfmButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - maxlen = qMax( fm.width( lastfmButton->text() ), maxlen ); - QListWidgetItem *advancedButton = new QListWidgetItem( ui->listWidget ); advancedButton->setIcon( QIcon( RESPATH "images/advanced-settings.png" ) ); advancedButton->setText( tr( "Advanced" ) ); @@ -282,7 +256,6 @@ SettingsDialog::createIcons() maxlen += 15; // padding accountsButton->setSizeHint( QSize( maxlen, 60 ) ); musicButton->setSizeHint( QSize( maxlen, 60 ) ); - lastfmButton->setSizeHint( QSize( maxlen, 60 ) ); advancedButton->setSizeHint( QSize( maxlen, 60 ) ); #ifndef Q_WS_MAC @@ -362,78 +335,6 @@ SettingsDialog::updateScanOptionsView() } -void -SettingsDialog::testLastFmLogin() -{ -#ifdef LIBLASTFM_FOUND - ui->pushButtonTestLastfmLogin->setEnabled( false ); - ui->pushButtonTestLastfmLogin->setText( "Testing..." ); - - QString authToken = TomahawkUtils::md5( ( ui->lineEditLastfmUsername->text().toLower() + TomahawkUtils::md5( ui->lineEditLastfmPassword->text().toUtf8() ) ).toUtf8() ); - - // now authenticate w/ last.fm and get our session key - QMap query; - query[ "method" ] = "auth.getMobileSession"; - query[ "username" ] = ui->lineEditLastfmUsername->text().toLower(); - query[ "authToken" ] = authToken; - - // ensure they have up-to-date settings - lastfm::setNetworkAccessManager( TomahawkUtils::nam() ); - - QNetworkReply* authJob = lastfm::ws::post( query ); - - connect( authJob, SIGNAL( finished() ), SLOT( onLastFmFinished() ) ); -#endif -} - - -void -SettingsDialog::onLastFmFinished() -{ -#ifdef LIBLASTFM_FOUND - QNetworkReply* authJob = dynamic_cast( sender() ); - if( !authJob ) - { - qDebug() << Q_FUNC_INFO << "No auth job returned!"; - return; - } - if( authJob->error() == QNetworkReply::NoError ) - { - lastfm::XmlQuery lfm = lastfm::XmlQuery( authJob->readAll() ); - - if( lfm.children( "error" ).size() > 0 ) - { - qDebug() << "ERROR from last.fm:" << lfm.text(); - ui->pushButtonTestLastfmLogin->setText( tr( "Failed" ) ); - ui->pushButtonTestLastfmLogin->setEnabled( true ); - } - else - { - ui->pushButtonTestLastfmLogin->setText( tr( "Success" ) ); - ui->pushButtonTestLastfmLogin->setEnabled( false ); - } - } - else - { - switch( authJob->error() ) - { - case QNetworkReply::ContentOperationNotPermittedError: - case QNetworkReply::AuthenticationRequiredError: - ui->pushButtonTestLastfmLogin->setText( tr( "Failed" ) ); - ui->pushButtonTestLastfmLogin->setEnabled( true ); - break; - - default: - qDebug() << "Couldn't get last.fm auth result"; - ui->pushButtonTestLastfmLogin->setText( tr( "Could not contact server" ) ); - ui->pushButtonTestLastfmLogin->setEnabled( true ); - return; - } - } -#endif -} - - void SettingsDialog::accountsFilterChanged( int ) { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index dc61925d7..ca146efb3 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -86,9 +86,6 @@ private slots: void toggleUpnp( bool preferStaticEnabled ); void showProxySettings(); - void testLastFmLogin(); - void onLastFmFinished(); - void accountsFilterChanged( int ); void createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ); diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index 78c36c9f5..ab707c2b5 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -85,7 +85,7 @@ - 0 + 2 @@ -98,6 +98,9 @@ Internet Sources + + 2 + @@ -221,119 +224,6 @@ - - - - 0 - - - - - Now Playing Information - - - - - - Applications to update with currently playing track: - - - - - - - - - - - Adium - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Qt::LeftToRight - - - Scrobble tracks to Last.fm - - - - - - - - - Username: - - - - - - - - - - Password: - - - - - - - QLineEdit::Password - - - - - - - - - Test Login - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - @@ -582,4 +472,4 @@ - + \ No newline at end of file diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index aa59a8cb1..192256915 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -219,13 +219,13 @@ TomahawkApp::init() connect( m_shortcutHandler.data(), SIGNAL( mute() ), m_audioEngine.data(), SLOT( mute() ) ); } + tDebug() << "Init InfoSystem."; + m_infoSystem = QWeakPointer( Tomahawk::InfoSystem::InfoSystem::instance() ); + tDebug() << "Init AccountManager."; m_accountManager = QWeakPointer< Tomahawk::Accounts::AccountManager >( new Tomahawk::Accounts::AccountManager( this ) ); Tomahawk::Accounts::AccountManager::instance()->loadFromConfig(); - tDebug() << "Init InfoSystem."; - m_infoSystem = QWeakPointer( new Tomahawk::InfoSystem::InfoSystem( this ) ); - Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() ); #ifndef ENABLE_HEADLESS EchonestGenerator::setupCatalogs(); @@ -422,6 +422,7 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoRequestData >( "Tomahawk::InfoSystem::InfoRequestData" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoSystemCache* >( "Tomahawk::InfoSystem::InfoSystemCache*" ); + qRegisterMetaType< Tomahawk::InfoSystem::InfoPlugin* >( "Tomahawk::InfoSystem::InfoPlugin*" ); qRegisterMetaType< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > "); qRegisterMetaTypeStreamOperators< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > ");