From a03c295767b0d8939b17c438ac9414a7db4ec580 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 28 Nov 2012 04:47:14 +0100 Subject: [PATCH] * Implemented new PlaylistInterface for PlayableProxyModelPlaylistInterface. --- .../PlayableProxyModelPlaylistInterface.cpp | 155 +++++++++++------- .../PlayableProxyModelPlaylistInterface.h | 25 ++- 2 files changed, 117 insertions(+), 63 deletions(-) diff --git a/src/libtomahawk/playlist/PlayableProxyModelPlaylistInterface.cpp b/src/libtomahawk/playlist/PlayableProxyModelPlaylistInterface.cpp index ead16362a..f08b51cdd 100644 --- a/src/libtomahawk/playlist/PlayableProxyModelPlaylistInterface.cpp +++ b/src/libtomahawk/playlist/PlayableProxyModelPlaylistInterface.cpp @@ -35,12 +35,18 @@ PlayableProxyModelPlaylistInterface::PlayableProxyModelPlaylistInterface( Playab , m_proxyModel( proxyModel ) , m_repeatMode( PlaylistModes::NoRepeat ) , 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() { + tDebug() << Q_FUNC_INFO; 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 > PlayableProxyModelPlaylistInterface::tracks() { @@ -79,20 +130,28 @@ PlayableProxyModelPlaylistInterface::tracks() } -bool -PlayableProxyModelPlaylistInterface::hasNextItem() +void +PlayableProxyModelPlaylistInterface::setCurrentIndex( qint64 index ) { - return !( siblingItem( 1, true ).isNull() ); + PlayableItem* item = static_cast( (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 -PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly ) +qint64 +PlayableProxyModelPlaylistInterface::siblingIndex( int itemsAway ) const { - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << m_shuffled << itemsAway << readOnly; - if ( m_proxyModel.isNull() ) - return result_ptr(); + return -1; PlayableProxyModel* proxyModel = m_proxyModel.data(); @@ -101,7 +160,7 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly ) m_shuffleHistory.removeFirst(); } - QModelIndex idx = proxyModel->index( 0, 0 ); + QModelIndex idx = QModelIndex(); if ( proxyModel->rowCount() ) { if ( m_shuffled ) @@ -115,7 +174,7 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly ) idx = proxyModel->mapFromSource( proxyModel->itemFromQuery( m_shuffleHistory.takeLast() )->index ); } else - return result_ptr(); + return -1; } else { @@ -139,12 +198,9 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly ) if ( item && item->query()->playable() ) { - if ( readOnly ) - { - m_shuffleCache = idx; - tDebug( LOGVERBOSE ) << "Next shuffled PlaylistItem cached:" << item->query()->toString() << item->query()->results().at( 0 )->url() - << "- after" << safetyCounter << "tries to find a track"; - } + m_shuffleCache = idx; + tDebug( LOGVERBOSE ) << "Next shuffled PlaylistItem cached:" << item->query()->toString() << item->query()->results().at( 0 )->url() + << "- after" << safetyCounter << "tries to find a track"; } else { @@ -185,26 +241,15 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly ) while ( idx.isValid() ) { 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(); - if ( !readOnly ) - { - proxyModel->setCurrentIndex( idx ); - m_shuffleHistory << item->query(); - m_shuffleCache = QPersistentModelIndex(); - } - - return item->query()->results().at( 0 ); + return (qint64)( item->index.internalPointer() ); } idx = proxyModel->index( idx.row() + ( itemsAway > 0 ? 1 : -1 ), 0 ); } - if ( !readOnly ) - proxyModel->setCurrentIndex( QModelIndex() ); - - return result_ptr(); + return -1; } @@ -225,14 +270,12 @@ PlayableProxyModelPlaylistInterface::currentItem() const Tomahawk::query_ptr -PlayableProxyModelPlaylistInterface::itemAt( unsigned int position ) const +PlayableProxyModelPlaylistInterface::queryAt( qint64 index ) const { if ( m_proxyModel.isNull() ) return query_ptr(); - PlayableProxyModel* proxyModel = m_proxyModel.data(); - - PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->index( position, 0 ) ) ); + PlayableItem* item = static_cast( (void*)index ); if ( item && 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( (void*)index ); + if ( item && item->result() ) + return item->result(); + + return result_ptr(); +} + + +qint64 PlayableProxyModelPlaylistInterface::indexOfResult( const Tomahawk::result_ptr& result ) const { if ( m_proxyModel.isNull() ) return -1; - PlayableProxyModel* proxyModel = m_proxyModel.data(); - - for ( int i = 0; i < proxyModel->rowCount( QModelIndex() ); i++ ) - { - PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->index( i, 0 ) ) ); - if ( item && item->result() == result ) - { - return i; - } - } + PlayableItem* item = m_proxyModel.data()->itemFromResult( result ); + if ( item ) + return (qint64)( item->index.internalPointer() ); return -1; } -int +qint64 PlayableProxyModelPlaylistInterface::indexOfQuery( const Tomahawk::query_ptr& query ) const { if ( m_proxyModel.isNull() ) return -1; - PlayableProxyModel* proxyModel = m_proxyModel.data(); - - for ( int i = 0; i < proxyModel->rowCount( QModelIndex() ); i++ ) - { - PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->index( i, 0 ) ) ); - if ( item && item->query() == query ) - { - return i; - } - } + PlayableItem* item = m_proxyModel.data()->itemFromQuery( query ); + if ( item ) + return (qint64)( item->index.internalPointer() ); return -1; } diff --git a/src/libtomahawk/playlist/PlayableProxyModelPlaylistInterface.h b/src/libtomahawk/playlist/PlayableProxyModelPlaylistInterface.h index c52c786db..a8a2b479d 100644 --- a/src/libtomahawk/playlist/PlayableProxyModelPlaylistInterface.h +++ b/src/libtomahawk/playlist/PlayableProxyModelPlaylistInterface.h @@ -43,13 +43,14 @@ public: virtual int trackCount() const; - virtual Tomahawk::query_ptr itemAt( unsigned int position ) const; - virtual int indexOfResult( const Tomahawk::result_ptr& result ) const; - virtual int indexOfQuery( const Tomahawk::query_ptr& query ) const; + virtual void setCurrentIndex( qint64 index ); + virtual Tomahawk::result_ptr resultAt( qint64 index ) 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 siblingItem( int itemsAway, bool readOnly ); - virtual bool hasNextItem(); + virtual qint64 siblingIndex( int itemsAway ) 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 setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); } +signals: + void previousTrackAvailable(); + void nextTrackAvailable(); + +private slots: + virtual void onModelChanged(); + protected: QWeakPointer< PlayableProxyModel > m_proxyModel; PlaylistModes::RepeatMode m_repeatMode; bool m_shuffled; - QList< Tomahawk::query_ptr > m_shuffleHistory; - QPersistentModelIndex m_shuffleCache; + mutable QList< Tomahawk::query_ptr > m_shuffleHistory; + mutable QPersistentModelIndex m_shuffleCache; + + mutable bool m_prevAvail; + mutable bool m_nextAvail; }; } //ns