1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-23 01:09:42 +01:00

* Implemented proper ArtistPlaylistInterface. Enables direct artist playback from the grid.

This commit is contained in:
Christian Muehlhaeuser 2012-05-20 08:17:51 +02:00
parent b052486e2e
commit 46f0ef9552
12 changed files with 219 additions and 95 deletions

View File

@ -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<Tomahawk::query_ptr>
AlbumPlaylistInterface::filterTracks( const QList<Tomahawk::query_ptr>& queries )
{
QList<Tomahawk::query_ptr> 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;
}

View File

@ -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<Tomahawk::query_ptr> filterTracks( const QList<Tomahawk::query_ptr>& 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;
};

View File

@ -95,13 +95,9 @@ Artist::Artist( unsigned int id, const QString& name )
void
Artist::onTracksAdded( const QList<Tomahawk::query_ptr>& 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<Tomahawk::query_ptr>
Artist::tracks( ModelMode mode, const Tomahawk::collection_ptr& collection )
{
return playlistInterface( mode, collection )->tracks();
}

View File

@ -54,6 +54,9 @@ public:
QList<Tomahawk::album_ptr> albums( ModelMode mode = Mixed, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() ) const;
QList<Tomahawk::artist_ptr> similarArtists() const;
QList<Tomahawk::query_ptr> 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<Tomahawk::query_ptr>& tracks );
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
void albumsAdded( const QList<Tomahawk::album_ptr>& albums, Tomahawk::ModelMode mode );
void updated();
@ -78,7 +81,7 @@ signals:
void statsLoaded();
private slots:
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void onTracksLoaded(Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
void onAlbumsFound( const QList<Tomahawk::album_ptr>& 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;
};

View File

@ -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<Tomahawk::query_ptr>, QVariant ) ),
m_artist.data(), SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
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<Tomahawk::query_ptr>, QVariant ) ),
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( 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<query_ptr> 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<Tomahawk::query_ptr>, QVariant ) ),
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( 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 );
}

View File

@ -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<Tomahawk::query_ptr> 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<Tomahawk::query_ptr>& 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;
};

View File

@ -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<Tomahawk::query_ptr> ) ),
connect( artistPtr.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
SLOT( tracksFromDB( QList<Tomahawk::query_ptr> ) ) );
m_queryCount++;
return QList< query_ptr >();
}
else
return artistPtr->playlistInterface()->tracks();
return artistPtr->playlistInterface( Mixed )->tracks();
}

View File

@ -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<Tomahawk::query_ptr>
PlaylistInterface::filterTracks( const QList<Tomahawk::query_ptr>& queries )
{
QList<Tomahawk::query_ptr> 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;
}

View File

@ -88,7 +88,12 @@ signals:
void nextTrackReady();
protected:
virtual QList<Tomahawk::query_ptr> filterTracks( const QList<Tomahawk::query_ptr>& queries );
PlaylistModes::LatchMode m_latchMode;
private:
Q_DISABLE_COPY( PlaylistInterface )
private:
QString m_id;

View File

@ -594,8 +594,8 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
}
else
{
_detail::Closure* closure = NewClosure( query.data(), SIGNAL( resolvingFinished( bool ) ),
const_cast<AudioEngine*>(this), SLOT( playItem( Tomahawk::playlistinterface_ptr, Tomahawk::query_ptr ) ), playlist, query );
NewClosure( query.data(), SIGNAL( resolvingFinished( bool ) ),
const_cast<AudioEngine*>(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<Tomahawk::query_ptr> ) ), const_cast<AudioEngine*>(this), SLOT( playItem( Tomahawk::artist_ptr ) ), artist );
artist->playlistInterface()->tracks();
NewClosure( artist.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
const_cast<AudioEngine*>(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::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
const_cast<AudioEngine*>(this), SLOT( playItem( Tomahawk::album_ptr ) ), album );
NewClosure( album.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
const_cast<AudioEngine*>(this), SLOT( playItem( Tomahawk::album_ptr ) ), album );
pli->tracks();
}
}

View File

@ -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;
}

View File

@ -158,7 +158,7 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist )
if ( artist.isNull() )
return;
connect( artist.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
connect( artist.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
SLOT( append( QList<Tomahawk::query_ptr> ) ) );
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() );
}