diff --git a/src/libtomahawk/AlbumPlaylistInterface.cpp b/src/libtomahawk/AlbumPlaylistInterface.cpp index ab1b3d1fe..355409079 100644 --- a/src/libtomahawk/AlbumPlaylistInterface.cpp +++ b/src/libtomahawk/AlbumPlaylistInterface.cpp @@ -32,7 +32,6 @@ using namespace Tomahawk; -AlbumPlaylistInterface::AlbumPlaylistInterface() {} AlbumPlaylistInterface::AlbumPlaylistInterface( Tomahawk::Album* album, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ) : Tomahawk::PlaylistInterface() @@ -42,7 +41,6 @@ AlbumPlaylistInterface::AlbumPlaylistInterface( Tomahawk::Album* album, Tomahawk , m_databaseLoaded( false ) , m_mode( mode ) , m_collection( collection ) - , m_uuid( uuid() ) , m_album( QWeakPointer< Tomahawk::Album >( album ) ) { } @@ -106,7 +104,7 @@ AlbumPlaylistInterface::tracks() artistInfo["album"] = m_album.data()->name(); Tomahawk::InfoSystem::InfoRequestData requestData; - requestData.caller = m_uuid; + requestData.caller = id(); requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( artistInfo ); requestData.type = Tomahawk::InfoSystem::InfoAlbumSongs; requestData.timeoutMillis = 0; @@ -137,7 +135,7 @@ AlbumPlaylistInterface::tracks() void AlbumPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { - if ( requestData.caller != m_uuid ) + if ( requestData.caller != id() ) return; switch ( requestData.type ) @@ -164,7 +162,6 @@ AlbumPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData re query_ptr query = Query::get( inputInfo[ "artist" ], trackName, inputInfo[ "album" ] ); query->setAlbumPos( trackNo++ ); ql << query; - tDebug() << Q_FUNC_INFO << query->toString(); } Pipeline::instance()->resolve( ql ); @@ -216,40 +213,3 @@ AlbumPlaylistInterface::onTracksLoaded( const QList< query_ptr >& tracks ) emit tracksLoaded( m_mode, m_collection ); } - - -QList -AlbumPlaylistInterface::filterTracks( const QList& queries ) -{ - QList result; - - for ( int i = 0; i < queries.count(); i++ ) - { - bool picked = true; - const query_ptr q1 = queries.at( i ); - - for ( int j = 0; j < result.count(); j++ ) - { - if ( !picked ) - break; - - const query_ptr& q2 = result.at( j ); - - if ( q1->track() == q2->track() ) - { - picked = false; - } - } - - if ( picked ) - { - query_ptr q = Query::get( q1->artist(), q1->track(), q1->album(), uuid(), false ); - q->setAlbumPos( q1->results().first()->albumpos() ); - q->setDiscNumber( q1->discnumber() ); - result << q; - } - } - - Pipeline::instance()->resolve( result ); - return result; -} diff --git a/src/libtomahawk/AlbumPlaylistInterface.h b/src/libtomahawk/AlbumPlaylistInterface.h index de5c3d440..14d6efd19 100644 --- a/src/libtomahawk/AlbumPlaylistInterface.h +++ b/src/libtomahawk/AlbumPlaylistInterface.h @@ -59,14 +59,6 @@ public: virtual void setFilter( const QString& /*pattern*/ ) {} signals: - void repeatModeChanged( Tomahawk::PlaylistModes::RepeatMode mode ); - void shuffleModeChanged( bool enabled ); - - void trackCountChanged( unsigned int tracks ); - void sourceTrackCountChanged( unsigned int tracks ); - - void nextTrackReady(); - void tracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ); private slots: @@ -74,10 +66,6 @@ private slots: void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); private: - AlbumPlaylistInterface(); - - QList filterTracks( const QList& queries ); - QList< Tomahawk::query_ptr > m_queries; result_ptr m_currentItem; unsigned int m_currentTrack; @@ -87,7 +75,6 @@ private: Tomahawk::ModelMode m_mode; Tomahawk::collection_ptr m_collection; - QString m_uuid; QWeakPointer< Tomahawk::Album > m_album; }; diff --git a/src/libtomahawk/Artist.cpp b/src/libtomahawk/Artist.cpp index 6a413f3b8..c70aeb593 100644 --- a/src/libtomahawk/Artist.cpp +++ b/src/libtomahawk/Artist.cpp @@ -95,13 +95,9 @@ Artist::Artist( unsigned int id, const QString& name ) void -Artist::onTracksAdded( const QList& tracks ) +Artist::onTracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ) { - Tomahawk::ArtistPlaylistInterface* api = dynamic_cast< Tomahawk::ArtistPlaylistInterface* >( playlistInterface().data() ); - if ( api ) - api->addQueries( tracks ); - - emit tracksAdded( tracks ); + emit tracksAdded( playlistInterface( mode, collection )->tracks(), mode, collection ); } @@ -410,12 +406,25 @@ Artist::cover( const QSize& size, bool forceLoad ) const Tomahawk::playlistinterface_ptr -Artist::playlistInterface() +Artist::playlistInterface( ModelMode mode, const Tomahawk::collection_ptr& collection ) { - if ( m_playlistInterface.isNull() ) + playlistinterface_ptr pli = m_playlistInterface[ mode ][ collection ]; + + if ( pli.isNull() ) { - m_playlistInterface = Tomahawk::playlistinterface_ptr( new Tomahawk::ArtistPlaylistInterface( this ) ); + pli = Tomahawk::playlistinterface_ptr( new Tomahawk::ArtistPlaylistInterface( this, mode, collection ) ); + connect( pli.data(), SIGNAL( tracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ), + SLOT( onTracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) ); + + m_playlistInterface[ mode ][ collection ] = pli; } - return m_playlistInterface; + return pli; +} + + +QList +Artist::tracks( ModelMode mode, const Tomahawk::collection_ptr& collection ) +{ + return playlistInterface( mode, collection )->tracks(); } diff --git a/src/libtomahawk/Artist.h b/src/libtomahawk/Artist.h index a0a89dbb8..a19f5931b 100644 --- a/src/libtomahawk/Artist.h +++ b/src/libtomahawk/Artist.h @@ -54,6 +54,9 @@ public: QList albums( ModelMode mode = Mixed, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() ) const; QList similarArtists() const; + QList tracks( ModelMode mode = Mixed, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() ); + Tomahawk::playlistinterface_ptr playlistInterface( ModelMode mode, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() ); + void loadStats(); QList< Tomahawk::PlaybackLog > playbackHistory( const Tomahawk::source_ptr& source = Tomahawk::source_ptr() ) const; void setPlaybackHistory( const QList< Tomahawk::PlaybackLog >& playbackData ); @@ -69,7 +72,7 @@ public: void setWeakRef( QWeakPointer< Tomahawk::Artist > weakRef ) { m_ownRef = weakRef; } signals: - void tracksAdded( const QList& tracks ); + void tracksAdded( const QList& tracks, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ); void albumsAdded( const QList& albums, Tomahawk::ModelMode mode ); void updated(); @@ -78,7 +81,7 @@ signals: void statsLoaded(); private slots: - void onTracksAdded( const QList& tracks ); + void onTracksLoaded(Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ); void onAlbumsFound( const QList& albums, const QVariant& data ); void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); @@ -112,8 +115,8 @@ private: mutable QHash< int, QPixmap > m_coverCache; #endif - Tomahawk::playlistinterface_ptr m_playlistInterface; - + QHash< Tomahawk::ModelMode, QHash< Tomahawk::collection_ptr, Tomahawk::playlistinterface_ptr > > m_playlistInterface; + QWeakPointer< Tomahawk::Artist > m_ownRef; }; diff --git a/src/libtomahawk/ArtistPlaylistInterface.cpp b/src/libtomahawk/ArtistPlaylistInterface.cpp index e2055dc38..c3c5a1164 100644 --- a/src/libtomahawk/ArtistPlaylistInterface.cpp +++ b/src/libtomahawk/ArtistPlaylistInterface.cpp @@ -25,16 +25,21 @@ #include "database/Database.h" #include "database/DatabaseCommand_AllTracks.h" #include "Source.h" +#include "Pipeline.h" #include "utils/Logger.h" using namespace Tomahawk; -ArtistPlaylistInterface::ArtistPlaylistInterface( Tomahawk::Artist *artist ) +ArtistPlaylistInterface::ArtistPlaylistInterface( Tomahawk::Artist* artist, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ) : Tomahawk::PlaylistInterface() , m_currentItem( 0 ) , m_currentTrack( 0 ) + , m_infoSystemLoaded( false ) + , m_databaseLoaded( false ) + , m_mode( mode ) + , m_collection( collection ) , m_artist( QWeakPointer< Tomahawk::Artist >( artist ) ) { } @@ -58,6 +63,9 @@ ArtistPlaylistInterface::siblingItem( int itemsAway ) if ( p >= m_queries.count() ) return Tomahawk::result_ptr(); + if ( !m_queries.at( p )->numResults() ) + return siblingItem( itemsAway + 1 ); + m_currentTrack = p; m_currentItem = m_queries.at( p )->results().first(); return m_currentItem; @@ -88,14 +96,34 @@ ArtistPlaylistInterface::tracks() { if ( m_queries.isEmpty() && m_artist ) { - DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks(); - cmd->setArtist( m_artist ); - cmd->setSortOrder( DatabaseCommand_AllTracks::Album ); + if ( ( m_mode == Mixed || m_mode == InfoSystemMode ) && !m_infoSystemLoaded ) + { + Tomahawk::InfoSystem::InfoStringHash artistInfo; + artistInfo["artist"] = m_artist.data()->name(); - connect( cmd, SIGNAL( tracks( QList, QVariant ) ), - m_artist.data(), SLOT( onTracksAdded( QList ) ) ); + Tomahawk::InfoSystem::InfoRequestData requestData; + requestData.caller = id(); + requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( artistInfo ); + requestData.type = Tomahawk::InfoSystem::InfoArtistSongs; + requestData.timeoutMillis = 0; + requestData.allSources = true; + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); - Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) ); + connect( Tomahawk::InfoSystem::InfoSystem::instance(), + SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); + } + else if ( m_mode == DatabaseMode && !m_databaseLoaded ) + { + DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_collection ); + cmd->setArtist( m_artist ); + cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition ); + + connect( cmd, SIGNAL( tracks( QList, QVariant ) ), + SLOT( onTracksLoaded( QList ) ) ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); + } } return m_queries; @@ -103,7 +131,83 @@ ArtistPlaylistInterface::tracks() void -ArtistPlaylistInterface::addQueries( const QList< query_ptr >& tracks ) +ArtistPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { - m_queries << tracks; + if ( requestData.caller != id() ) + return; + + switch ( requestData.type ) + { + case Tomahawk::InfoSystem::InfoArtistSongs: + { + QVariantMap returnedData = output.value< QVariantMap >(); + if ( !returnedData.isEmpty() ) + { + Tomahawk::InfoSystem::InfoStringHash inputInfo; + inputInfo = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >(); + + QStringList tracks = returnedData[ "tracks" ].toStringList(); + QList ql; + + //TODO: Figure out how to do this with a multi-disk album without breaking the + // current behaviour. I just know too little about InfoSystem to deal with + // it right now, I've only taken the liberty of adding Query::setDiscNumber + // which should make this easier. --Teo 11/2011 + unsigned int trackNo = 1; + + foreach ( const QString& trackName, tracks ) + { + query_ptr query = Query::get( inputInfo[ "artist" ], trackName, inputInfo[ "album" ] ); + query->setAlbumPos( trackNo++ ); + ql << query; + } + Pipeline::instance()->resolve( ql ); + + m_queries << ql; + } + + break; + } + + default: + { + Q_ASSERT( false ); + break; + } + } + + m_infoSystemLoaded = true; + disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + this, SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); + + if ( m_queries.isEmpty() && m_mode == Mixed ) + { + DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_collection ); + cmd->setArtist( m_artist ); + //this takes discnumber into account as well + cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition ); + + connect( cmd, SIGNAL( tracks( QList, QVariant ) ), + SLOT( onTracksLoaded( QList ) ) ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); + } + else + { + emit tracksLoaded( m_mode, m_collection ); + } +} + + +void +ArtistPlaylistInterface::onTracksLoaded( const QList< query_ptr >& tracks ) +{ + m_databaseLoaded = true; + + if ( m_collection.isNull() ) + m_queries << filterTracks( tracks ); + else + m_queries << tracks; + + emit tracksLoaded( m_mode, m_collection ); } diff --git a/src/libtomahawk/ArtistPlaylistInterface.h b/src/libtomahawk/ArtistPlaylistInterface.h index d325f6abe..03b1b36bd 100644 --- a/src/libtomahawk/ArtistPlaylistInterface.h +++ b/src/libtomahawk/ArtistPlaylistInterface.h @@ -36,12 +36,12 @@ class DLLEXPORT ArtistPlaylistInterface : public Tomahawk::PlaylistInterface Q_OBJECT public: - ArtistPlaylistInterface( Tomahawk::Artist *artist ); + ArtistPlaylistInterface( Tomahawk::Artist* artist, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ); virtual ~ArtistPlaylistInterface(); virtual QList tracks(); - virtual int trackCount() const { return 0; } + virtual int trackCount() const { return m_queries.count(); } virtual int unfilteredTrackCount() const { return m_queries.count(); } virtual Tomahawk::result_ptr siblingItem( int itemsAway ); @@ -57,7 +57,12 @@ public: virtual void setFilter( const QString& /*pattern*/ ) {} - virtual void addQueries( const QList& tracks ); +signals: + void tracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ); + +private slots: + void onTracksLoaded( const QList< Tomahawk::query_ptr >& tracks ); + void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); private: Q_DISABLE_COPY( ArtistPlaylistInterface ) @@ -66,6 +71,12 @@ private: result_ptr m_currentItem; unsigned int m_currentTrack; + bool m_infoSystemLoaded; + bool m_databaseLoaded; + + Tomahawk::ModelMode m_mode; + Tomahawk::collection_ptr m_collection; + QWeakPointer< Tomahawk::Artist > m_artist; }; diff --git a/src/libtomahawk/DropJob.cpp b/src/libtomahawk/DropJob.cpp index eeb899346..029eb44cb 100644 --- a/src/libtomahawk/DropJob.cpp +++ b/src/libtomahawk/DropJob.cpp @@ -840,17 +840,18 @@ QList< query_ptr > DropJob::getArtist( const QString &artist ) { artist_ptr artistPtr = Artist::get( artist ); - if ( artistPtr->playlistInterface()->tracks().isEmpty() ) + if ( artistPtr->playlistInterface( Mixed )->tracks().isEmpty() ) { m_artistsToKeep.insert( artistPtr ); - connect( artistPtr.data(), SIGNAL( tracksAdded( QList ) ), + connect( artistPtr.data(), SIGNAL( tracksAdded( QList, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ), SLOT( tracksFromDB( QList ) ) ); + m_queryCount++; return QList< query_ptr >(); } else - return artistPtr->playlistInterface()->tracks(); + return artistPtr->playlistInterface( Mixed )->tracks(); } diff --git a/src/libtomahawk/PlaylistInterface.cpp b/src/libtomahawk/PlaylistInterface.cpp index 7dda7ff5c..4cfefcab9 100644 --- a/src/libtomahawk/PlaylistInterface.cpp +++ b/src/libtomahawk/PlaylistInterface.cpp @@ -20,9 +20,11 @@ #include "PlaylistInterface.h" #include "utils/Logger.h" #include "Result.h" +#include "Pipeline.h" using namespace Tomahawk; + PlaylistInterface::PlaylistInterface () : QObject() , m_latchMode( PlaylistModes::StayOnSong ) @@ -30,18 +32,58 @@ PlaylistInterface::PlaylistInterface () m_id = uuid(); } + PlaylistInterface::~PlaylistInterface() { } + result_ptr PlaylistInterface::previousItem() { return siblingItem( -1 ); } + result_ptr PlaylistInterface::nextItem() { return siblingItem( 1 ); } + + +QList +PlaylistInterface::filterTracks( const QList& queries ) +{ + QList result; + + for ( int i = 0; i < queries.count(); i++ ) + { + bool picked = true; + const query_ptr q1 = queries.at( i ); + + for ( int j = 0; j < result.count(); j++ ) + { + if ( !picked ) + break; + + const query_ptr& q2 = result.at( j ); + + if ( q1->track() == q2->track() ) + { + picked = false; + } + } + + if ( picked ) + { + query_ptr q = Query::get( q1->artist(), q1->track(), q1->album(), uuid(), false ); + q->setAlbumPos( q1->results().first()->albumpos() ); + q->setDiscNumber( q1->discnumber() ); + result << q; + } + } + + Pipeline::instance()->resolve( result ); + return result; +} diff --git a/src/libtomahawk/PlaylistInterface.h b/src/libtomahawk/PlaylistInterface.h index 0c88c2ef9..fa18a4de7 100644 --- a/src/libtomahawk/PlaylistInterface.h +++ b/src/libtomahawk/PlaylistInterface.h @@ -88,7 +88,12 @@ signals: void nextTrackReady(); protected: + virtual QList filterTracks( const QList& queries ); + PlaylistModes::LatchMode m_latchMode; + +private: + Q_DISABLE_COPY( PlaylistInterface ) private: QString m_id; diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 963789267..dc882e46b 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -594,8 +594,8 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk: } else { - _detail::Closure* closure = NewClosure( query.data(), SIGNAL( resolvingFinished( bool ) ), - const_cast(this), SLOT( playItem( Tomahawk::playlistinterface_ptr, Tomahawk::query_ptr ) ), playlist, query ); + NewClosure( query.data(), SIGNAL( resolvingFinished( bool ) ), + const_cast(this), SLOT( playItem( Tomahawk::playlistinterface_ptr, Tomahawk::query_ptr ) ), playlist, query ); } } @@ -603,14 +603,16 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk: void AudioEngine::playItem( const Tomahawk::artist_ptr& artist ) { - if ( artist->playlistInterface()->trackCount() ) + playlistinterface_ptr pli = artist->playlistInterface( Mixed ); + if ( pli->trackCount() ) { - playItem( artist->playlistInterface(), artist->playlistInterface()->tracks().first() ); + playItem( pli, pli->tracks().first() ); } else { - _detail::Closure* closure = NewClosure( artist.data(), SIGNAL( tracksAdded( QList ) ), const_cast(this), SLOT( playItem( Tomahawk::artist_ptr ) ), artist ); - artist->playlistInterface()->tracks(); + NewClosure( artist.data(), SIGNAL( tracksAdded( QList, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ), + const_cast(this), SLOT( playItem( Tomahawk::artist_ptr ) ), artist ); + pli->tracks(); } } @@ -625,8 +627,8 @@ AudioEngine::playItem( const Tomahawk::album_ptr& album ) } else { - _detail::Closure* closure = NewClosure( album.data(), SIGNAL( tracksAdded( QList, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ), - const_cast(this), SLOT( playItem( Tomahawk::album_ptr ) ), album ); + NewClosure( album.data(), SIGNAL( tracksAdded( QList, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ), + const_cast(this), SLOT( playItem( Tomahawk::album_ptr ) ), album ); pli->tracks(); } } diff --git a/src/libtomahawk/playlist/AlbumItemDelegate.cpp b/src/libtomahawk/playlist/AlbumItemDelegate.cpp index 5035a8ea0..1726d5e59 100644 --- a/src/libtomahawk/playlist/AlbumItemDelegate.cpp +++ b/src/libtomahawk/playlist/AlbumItemDelegate.cpp @@ -469,7 +469,7 @@ AlbumItemDelegate::onPlaylistChanged( const QPersistentModelIndex& index ) } else if ( !item->artist().isNull() ) { - if ( AudioEngine::instance()->currentTrackPlaylist() != item->artist()->playlistInterface() ) + if ( AudioEngine::instance()->currentTrackPlaylist() != item->artist()->playlistInterface( Tomahawk::Mixed ) ) finished = true; } diff --git a/src/libtomahawk/playlist/PlaylistModel.cpp b/src/libtomahawk/playlist/PlaylistModel.cpp index 8f7b2c077..a5aeef5b4 100644 --- a/src/libtomahawk/playlist/PlaylistModel.cpp +++ b/src/libtomahawk/playlist/PlaylistModel.cpp @@ -158,7 +158,7 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist ) if ( artist.isNull() ) return; - connect( artist.data(), SIGNAL( tracksAdded( QList ) ), + connect( artist.data(), SIGNAL( tracksAdded( QList, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ), SLOT( append( QList ) ) ); if ( rowCount( QModelIndex() ) == 0 ) @@ -168,7 +168,7 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist ) m_isTemporary = true; } - append( artist->playlistInterface()->tracks() ); + append( artist->playlistInterface( Mixed )->tracks() ); }