diff --git a/src/accounts/spotify/SpotifyAccount.cpp b/src/accounts/spotify/SpotifyAccount.cpp index 2f0b1e820..cf2de46d5 100644 --- a/src/accounts/spotify/SpotifyAccount.cpp +++ b/src/accounts/spotify/SpotifyAccount.cpp @@ -80,6 +80,8 @@ SpotifyAccount::SpotifyAccount( const QString& accountId, const QString& path ) void SpotifyAccount::init() { + qRegisterMetaType< Tomahawk::Accounts::SpotifyPlaylist* >( "Tomahawk::Accounts::SpotifyPlaylist*" ); + m_spotifyResolver = dynamic_cast< ScriptResolver* >( m_resolver.data() ); connect( m_spotifyResolver.data(), SIGNAL( customMessage( QString,QVariantMap ) ), this, SLOT( resolverMessage( QString, QVariantMap ) ) ); @@ -92,6 +94,9 @@ SpotifyAccount::init() msg[ "_msgtype" ] = "getCredentials"; m_spotifyResolver.data()->sendMessage( msg ); } + + // TODO add caching + loadPlaylists(); } @@ -111,6 +116,63 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg config[ "hasMigrated" ] = true; setConfiguration( config ); sync(); + + return; + } + + + const QString qid = msg.value( "qid" ).toString(); + if ( m_qidToSlotMap.contains( qid ) ) + { + const QString& slot = m_qidToSlotMap[ qid ]; + m_qidToSlotMap.remove( qid ); + + QMetaObject::invokeMethod( this, slot.toLatin1(), Q_ARG( QString, msgType ), Q_ARG( QVariantMap, msg ) ); + } + else if ( msgType == "allPlaylists" ) + { + const QVariantList playlists = msg.value( "playlists" ).toList(); + qDeleteAll( m_allSpotifyPlaylists ); + m_allSpotifyPlaylists.clear(); + + foreach ( const QVariant& playlist, playlists ) + { + const QVariantMap plMap = playlist.toMap(); + const QString name = plMap.value( "name" ).toString(); + const QString plid = plMap.value( "id" ).toString(); + const QString revid = plMap.value( "revid" ).toString(); + const bool sync = plMap.value( "map" ).toBool(); + + if ( name.isNull() || plid.isNull() || revid.isNull() ) + { + qDebug() << "Did not get name and plid and revid for spotify playlist:" << name << plid << revid << plMap; + continue; + } + m_allSpotifyPlaylists << new SpotifyPlaylist( name, plid, revid, sync ); + } + + if ( !m_configWidget.isNull() ) + { + m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists ); + } + } + else if ( msgType == "playlists" ) + { +// QList< Tomahawk::query_ptr > tracks; +// const QString qid = m.value( "qid" ).toString(); +// const QString title = m.value( "identifier" ).toString(); +// const QVariantList reslist = m.value( "playlist" ).toList(); + +// if( !reslist.isEmpty() ) +// { +// foreach( const QVariant& rv, reslist ) +// { +// QVariantMap m = rv.toMap(); +// qDebug() << "Found playlist result:" << m; +// Tomahawk::query_ptr q = Tomahawk::Query::get( m.value( "artist" ).toString() , m.value( "track" ).toString() , QString(), uuid(), false ); +// tracks << q; +// } +// } } } @@ -144,14 +206,26 @@ SpotifyAccount::saveConfig() if ( m_configWidget.isNull() ) return; - // Send the result to the resolver - QVariantMap msg; - msg[ "_msgtype" ] = "saveSettings"; - msg[ "username" ] = m_configWidget.data()->username(); - msg[ "password" ] = m_configWidget.data()->password(); - msg[ "highQuality" ] = m_configWidget.data()->highQuality(); + QVariantHash creds = credentials(); + if ( creds.value( "username" ).toString() != m_configWidget.data()->username() || + creds.value( "password" ).toString() != m_configWidget.data()->password() || + creds.value( "highQuality" ).toBool() != m_configWidget.data()->highQuality() ) + { + creds[ "username" ] = m_configWidget.data()->username(); + creds[ "password" ] = m_configWidget.data()->password(); + creds[ "highQuality" ] = m_configWidget.data()->highQuality(); + setCredentials( creds ); + sync(); - m_spotifyResolver.data()->sendMessage( msg ); + // Send the result to the resolver + QVariantMap msg; + msg[ "_msgtype" ] = "saveSettings"; + msg[ "username" ] = m_configWidget.data()->username(); + msg[ "password" ] = m_configWidget.data()->password(); + msg[ "highQuality" ] = m_configWidget.data()->highQuality(); + + m_spotifyResolver.data()->sendMessage( msg ); + } } @@ -208,6 +282,29 @@ SpotifyAccount::addPlaylist( const QString &qid, const QString& title, QList< To } +void +SpotifyAccount::sendMessage( const QVariantMap &m, const QString& slot ) +{ + QVariantMap msg = m; + const QString qid = QUuid::createUuid().toString().replace( "{", "" ).replace( "}", "" ); + + m_qidToSlotMap[ qid ] = slot; + msg[ "qid" ] = qid; + + m_spotifyResolver.data()->sendMessage( msg ); +} + + +void +SpotifyAccount::loadPlaylists() +{ + // TODO cache this and only get changed? + QVariantMap msg; + msg[ "_msgtype" ] = "getAllPlaylists"; + sendMessage( msg, "allPlaylistsLoaded" ); +} + + bool operator==( Accounts::SpotifyAccount::Sync one, Accounts::SpotifyAccount::Sync two ) { diff --git a/src/accounts/spotify/SpotifyAccount.h b/src/accounts/spotify/SpotifyAccount.h index 4a54da19b..5725337e9 100644 --- a/src/accounts/spotify/SpotifyAccount.h +++ b/src/accounts/spotify/SpotifyAccount.h @@ -34,6 +34,16 @@ namespace Accounts { class SpotifyAccountConfig; +struct SpotifyPlaylist { + QString name, plid, revid; + bool sync; + + SpotifyPlaylist( const QString& nname, const QString& pid, const QString& rrevid, bool ssync ) + : name( nname ), plid( pid ), revid( rrevid ), sync( ssync ) {} + + SpotifyPlaylist() : sync( false ) {} +}; + class SpotifyAccountFactory : public AccountFactory { Q_OBJECT @@ -82,15 +92,25 @@ public: private slots: void resolverMessage( const QString& msgType, const QVariantMap& msg ); + // SpotifyResolver message handlers, all take msgtype, msg as argument + // void ( const QString& msgType, const QVariantMap& msg ); private: void init(); + void loadPlaylists(); + void sendMessage( const QVariantMap& msg, const QString& slot ); QList m_syncPlaylists; QWeakPointer m_configWidget; QWeakPointer m_spotifyResolver; + + QMap m_qidToSlotMap; + + QList< SpotifyPlaylist* > m_allSpotifyPlaylists; }; } } +Q_DECLARE_METATYPE( Tomahawk::Accounts::SpotifyPlaylist* ); + #endif // SpotifyAccount_H diff --git a/src/accounts/spotify/SpotifyAccountConfig.cpp b/src/accounts/spotify/SpotifyAccountConfig.cpp index c39eac08e..1afed75b0 100644 --- a/src/accounts/spotify/SpotifyAccountConfig.cpp +++ b/src/accounts/spotify/SpotifyAccountConfig.cpp @@ -3,6 +3,9 @@ #include "SpotifyAccount.h" #include "ui_SpotifyAccountConfig.h" +#include +#include + using namespace Tomahawk; using namespace Accounts; @@ -25,6 +28,17 @@ SpotifyAccountConfig::loadFromConfig() m_ui->streamingCheckbox->setChecked( m_account->credentials().value( "highQuality" ).toBool() ); } +void +SpotifyAccountConfig::saveSettings() +{ + for( int i = 0; i < m_ui->playlistList->count(); i++ ) + { + const QListWidgetItem* item = m_ui->playlistList->itemAt( i, 0 ); + SpotifyPlaylist* pl = item->data( Qt::UserRole ).value< SpotifyPlaylist* >(); + pl->sync = ( item->checkState() == Qt::Checked ); + } +} + QString SpotifyAccountConfig::username() const @@ -43,3 +57,17 @@ SpotifyAccountConfig::highQuality() const { return m_ui->streamingCheckbox->isChecked(); } + + +void +SpotifyAccountConfig::setPlaylists( const QList& playlists ) +{ + m_ui->playlistList->clear(); + foreach ( SpotifyPlaylist* pl, playlists ) + { + QListWidgetItem* item = new QListWidgetItem( pl->name, m_ui->playlistList ); + item->setData( Qt::UserRole, QVariant::fromValue< SpotifyPlaylist* >( pl ) ); + item->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled ); + item->setCheckState( pl->sync ? Qt::Checked : Qt::Unchecked ); + } +} diff --git a/src/accounts/spotify/SpotifyAccountConfig.h b/src/accounts/spotify/SpotifyAccountConfig.h index da1f4ae60..5ecf04c41 100644 --- a/src/accounts/spotify/SpotifyAccountConfig.h +++ b/src/accounts/spotify/SpotifyAccountConfig.h @@ -14,6 +14,7 @@ namespace Accounts { class SpotifyAccount; +struct SpotifyPlaylist; class SpotifyAccountConfig : public QWidget { @@ -25,9 +26,10 @@ public: QString password() const; bool highQuality() const; - QStringList playlistsToSync() const; + void setPlaylists( const QList< SpotifyPlaylist* >& playlists ); void loadFromConfig(); + void saveSettings(); private: Ui::SpotifyConfig* m_ui; diff --git a/src/accounts/spotify/SpotifyAccountConfig.ui b/src/accounts/spotify/SpotifyAccountConfig.ui index d2c377e9e..33f546604 100644 --- a/src/accounts/spotify/SpotifyAccountConfig.ui +++ b/src/accounts/spotify/SpotifyAccountConfig.ui @@ -158,7 +158,7 @@ - + diff --git a/src/libtomahawk/resolvers/scriptresolver.cpp b/src/libtomahawk/resolvers/scriptresolver.cpp index be4b90b04..8392346bd 100644 --- a/src/libtomahawk/resolvers/scriptresolver.cpp +++ b/src/libtomahawk/resolvers/scriptresolver.cpp @@ -273,25 +273,6 @@ ScriptResolver::handleMsg( const QByteArray& msg ) Tomahawk::Pipeline::instance()->reportResults( qid, results ); } - else if ( msgtype == "playlist" ) - { - - QList< Tomahawk::query_ptr > tracks; - const QString qid = m.value( "qid" ).toString(); - const QString title = m.value( "identifier" ).toString(); - const QVariantList reslist = m.value( "playlist" ).toList(); - - if( !reslist.isEmpty() ) - { - foreach( const QVariant& rv, reslist ) - { - QVariantMap m = rv.toMap(); - qDebug() << "Found playlist result:" << m; - Tomahawk::query_ptr q = Tomahawk::Query::get( m.value( "artist" ).toString() , m.value( "track" ).toString() , QString(), uuid(), false ); - tracks << q; - } - } - } else { // Unknown message, give up for custom implementations