1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-10 16:14:40 +02:00

* Implemented new PlaylistInterface for PlayableProxyModelPlaylistInterface.

This commit is contained in:
Christian Muehlhaeuser
2012-11-28 04:47:14 +01:00
parent ebeb50d84e
commit a03c295767
2 changed files with 117 additions and 63 deletions

View File

@@ -35,12 +35,18 @@ PlayableProxyModelPlaylistInterface::PlayableProxyModelPlaylistInterface( Playab
, m_proxyModel( proxyModel ) , m_proxyModel( proxyModel )
, m_repeatMode( PlaylistModes::NoRepeat ) , m_repeatMode( PlaylistModes::NoRepeat )
, m_shuffled( false ) , m_shuffled( false )
, m_prevAvail( false )
, m_nextAvail( false )
{ {
connect( proxyModel, SIGNAL( currentIndexChanged() ), SLOT( onModelChanged() ) );
connect( proxyModel, SIGNAL( indexPlayable( QModelIndex ) ), SLOT( onModelChanged() ) );
// connect( proxyModel, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onModelChanged() ) );
} }
PlayableProxyModelPlaylistInterface::~PlayableProxyModelPlaylistInterface() PlayableProxyModelPlaylistInterface::~PlayableProxyModelPlaylistInterface()
{ {
tDebug() << Q_FUNC_INFO;
m_proxyModel.clear(); m_proxyModel.clear();
} }
@@ -59,6 +65,51 @@ PlayableProxyModelPlaylistInterface::filter() const
} }
void
PlayableProxyModelPlaylistInterface::onModelChanged()
{
if ( QThread::currentThread() != thread() )
{
tDebug() << Q_FUNC_INFO << "Reinvoking in correct thread!";
QMetaObject::invokeMethod( this, "onModelChanged", Qt::QueuedConnection );
return;
}
Tomahawk::result_ptr prevResult = siblingResult( -1 );
Tomahawk::result_ptr nextResult = siblingResult( 1 );
if ( prevResult )
{
bool avail = prevResult->toQuery()->playable();
if ( avail != m_prevAvail )
{
m_prevAvail = avail;
emit previousTrackAvailable();
}
}
else if ( m_prevAvail )
{
m_prevAvail = false;
emit previousTrackAvailable();
}
if ( nextResult )
{
bool avail = nextResult->toQuery()->playable();
if ( avail != m_nextAvail )
{
m_nextAvail = avail;
emit nextTrackAvailable();
}
}
else if ( m_nextAvail )
{
m_nextAvail = false;
emit nextTrackAvailable();
}
}
QList< Tomahawk::query_ptr > QList< Tomahawk::query_ptr >
PlayableProxyModelPlaylistInterface::tracks() PlayableProxyModelPlaylistInterface::tracks()
{ {
@@ -79,20 +130,28 @@ PlayableProxyModelPlaylistInterface::tracks()
} }
bool void
PlayableProxyModelPlaylistInterface::hasNextItem() PlayableProxyModelPlaylistInterface::setCurrentIndex( qint64 index )
{ {
return !( siblingItem( 1, true ).isNull() ); PlayableItem* item = static_cast<PlayableItem*>( (void*)index );
if ( index < 0 || !item )
{
m_proxyModel.data()->setCurrentIndex( QModelIndex() );
}
else
{
m_proxyModel.data()->setCurrentIndex( m_proxyModel.data()->mapFromSource( item->index ) );
m_shuffleHistory << queryAt( index );
m_shuffleCache = QPersistentModelIndex();
}
} }
Tomahawk::result_ptr qint64
PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly ) PlayableProxyModelPlaylistInterface::siblingIndex( int itemsAway ) const
{ {
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << m_shuffled << itemsAway << readOnly;
if ( m_proxyModel.isNull() ) if ( m_proxyModel.isNull() )
return result_ptr(); return -1;
PlayableProxyModel* proxyModel = m_proxyModel.data(); PlayableProxyModel* proxyModel = m_proxyModel.data();
@@ -101,7 +160,7 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly )
m_shuffleHistory.removeFirst(); m_shuffleHistory.removeFirst();
} }
QModelIndex idx = proxyModel->index( 0, 0 ); QModelIndex idx = QModelIndex();
if ( proxyModel->rowCount() ) if ( proxyModel->rowCount() )
{ {
if ( m_shuffled ) if ( m_shuffled )
@@ -115,7 +174,7 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly )
idx = proxyModel->mapFromSource( proxyModel->itemFromQuery( m_shuffleHistory.takeLast() )->index ); idx = proxyModel->mapFromSource( proxyModel->itemFromQuery( m_shuffleHistory.takeLast() )->index );
} }
else else
return result_ptr(); return -1;
} }
else else
{ {
@@ -138,14 +197,11 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly )
( !item || !item->query()->playable() || m_shuffleHistory.contains( item->query() ) ) ); ( !item || !item->query()->playable() || m_shuffleHistory.contains( item->query() ) ) );
if ( item && item->query()->playable() ) if ( item && item->query()->playable() )
{
if ( readOnly )
{ {
m_shuffleCache = idx; m_shuffleCache = idx;
tDebug( LOGVERBOSE ) << "Next shuffled PlaylistItem cached:" << item->query()->toString() << item->query()->results().at( 0 )->url() tDebug( LOGVERBOSE ) << "Next shuffled PlaylistItem cached:" << item->query()->toString() << item->query()->results().at( 0 )->url()
<< "- after" << safetyCounter << "tries to find a track"; << "- after" << safetyCounter << "tries to find a track";
} }
}
else else
{ {
tDebug() << Q_FUNC_INFO << "Error finding next shuffled playable track"; tDebug() << Q_FUNC_INFO << "Error finding next shuffled playable track";
@@ -185,26 +241,15 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly )
while ( idx.isValid() ) while ( idx.isValid() )
{ {
PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( idx ) ); PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( idx ) );
if ( item && item->query()->playable() ) if ( item )
{ {
tDebug( LOGVERBOSE ) << "Next PlaylistItem found:" << item->query()->toString() << item->query()->results().at( 0 )->url(); return (qint64)( item->index.internalPointer() );
if ( !readOnly )
{
proxyModel->setCurrentIndex( idx );
m_shuffleHistory << item->query();
m_shuffleCache = QPersistentModelIndex();
}
return item->query()->results().at( 0 );
} }
idx = proxyModel->index( idx.row() + ( itemsAway > 0 ? 1 : -1 ), 0 ); idx = proxyModel->index( idx.row() + ( itemsAway > 0 ? 1 : -1 ), 0 );
} }
if ( !readOnly ) return -1;
proxyModel->setCurrentIndex( QModelIndex() );
return result_ptr();
} }
@@ -225,14 +270,12 @@ PlayableProxyModelPlaylistInterface::currentItem() const
Tomahawk::query_ptr Tomahawk::query_ptr
PlayableProxyModelPlaylistInterface::itemAt( unsigned int position ) const PlayableProxyModelPlaylistInterface::queryAt( qint64 index ) const
{ {
if ( m_proxyModel.isNull() ) if ( m_proxyModel.isNull() )
return query_ptr(); return query_ptr();
PlayableProxyModel* proxyModel = m_proxyModel.data(); PlayableItem* item = static_cast<PlayableItem*>( (void*)index );
PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->index( position, 0 ) ) );
if ( item && item->query() ) if ( item && item->query() )
return item->query(); return item->query();
@@ -240,43 +283,43 @@ PlayableProxyModelPlaylistInterface::itemAt( unsigned int position ) const
} }
int Tomahawk::result_ptr
PlayableProxyModelPlaylistInterface::resultAt( qint64 index ) const
{
if ( m_proxyModel.isNull() )
return result_ptr();
PlayableItem* item = static_cast<PlayableItem*>( (void*)index );
if ( item && item->result() )
return item->result();
return result_ptr();
}
qint64
PlayableProxyModelPlaylistInterface::indexOfResult( const Tomahawk::result_ptr& result ) const PlayableProxyModelPlaylistInterface::indexOfResult( const Tomahawk::result_ptr& result ) const
{ {
if ( m_proxyModel.isNull() ) if ( m_proxyModel.isNull() )
return -1; return -1;
PlayableProxyModel* proxyModel = m_proxyModel.data(); PlayableItem* item = m_proxyModel.data()->itemFromResult( result );
if ( item )
for ( int i = 0; i < proxyModel->rowCount( QModelIndex() ); i++ ) return (qint64)( item->index.internalPointer() );
{
PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->index( i, 0 ) ) );
if ( item && item->result() == result )
{
return i;
}
}
return -1; return -1;
} }
int qint64
PlayableProxyModelPlaylistInterface::indexOfQuery( const Tomahawk::query_ptr& query ) const PlayableProxyModelPlaylistInterface::indexOfQuery( const Tomahawk::query_ptr& query ) const
{ {
if ( m_proxyModel.isNull() ) if ( m_proxyModel.isNull() )
return -1; return -1;
PlayableProxyModel* proxyModel = m_proxyModel.data(); PlayableItem* item = m_proxyModel.data()->itemFromQuery( query );
if ( item )
for ( int i = 0; i < proxyModel->rowCount( QModelIndex() ); i++ ) return (qint64)( item->index.internalPointer() );
{
PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->index( i, 0 ) ) );
if ( item && item->query() == query )
{
return i;
}
}
return -1; return -1;
} }

View File

@@ -43,13 +43,14 @@ public:
virtual int trackCount() const; virtual int trackCount() const;
virtual Tomahawk::query_ptr itemAt( unsigned int position ) const; virtual void setCurrentIndex( qint64 index );
virtual int indexOfResult( const Tomahawk::result_ptr& result ) const; virtual Tomahawk::result_ptr resultAt( qint64 index ) const;
virtual int indexOfQuery( const Tomahawk::query_ptr& query ) const; virtual Tomahawk::query_ptr queryAt( qint64 index ) const;
virtual qint64 indexOfResult( const Tomahawk::result_ptr& result ) const;
virtual qint64 indexOfQuery( const Tomahawk::query_ptr& query ) const;
virtual Tomahawk::result_ptr currentItem() const; virtual Tomahawk::result_ptr currentItem() const;
virtual Tomahawk::result_ptr siblingItem( int itemsAway, bool readOnly ); virtual qint64 siblingIndex( int itemsAway ) const;
virtual bool hasNextItem();
virtual QString filter() const; virtual QString filter() const;
@@ -60,13 +61,23 @@ public slots:
virtual void setRepeatMode( Tomahawk::PlaylistModes::RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); } virtual void setRepeatMode( Tomahawk::PlaylistModes::RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); }
virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); } virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); }
signals:
void previousTrackAvailable();
void nextTrackAvailable();
private slots:
virtual void onModelChanged();
protected: protected:
QWeakPointer< PlayableProxyModel > m_proxyModel; QWeakPointer< PlayableProxyModel > m_proxyModel;
PlaylistModes::RepeatMode m_repeatMode; PlaylistModes::RepeatMode m_repeatMode;
bool m_shuffled; bool m_shuffled;
QList< Tomahawk::query_ptr > m_shuffleHistory; mutable QList< Tomahawk::query_ptr > m_shuffleHistory;
QPersistentModelIndex m_shuffleCache; mutable QPersistentModelIndex m_shuffleCache;
mutable bool m_prevAvail;
mutable bool m_nextAvail;
}; };
} //ns } //ns