diff --git a/src/libtomahawk/album.cpp b/src/libtomahawk/album.cpp index 425183174..f8ebc9853 100644 --- a/src/libtomahawk/album.cpp +++ b/src/libtomahawk/album.cpp @@ -52,6 +52,7 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& , m_id( id ) , m_name( name ) , m_artist( artist ) + , m_currentItem( 0 ) , m_currentTrack( 0 ) { } @@ -80,7 +81,20 @@ Album::siblingItem( int itemsAway ) return Tomahawk::result_ptr(); m_currentTrack = p; - return m_queries.at( p )->results().first(); + m_currentItem = m_queries.at( p )->results().first(); + return m_currentItem; +} + + +bool +Album::hasNextItem() +{ + int p = m_currentTrack; + p++; + if ( p < 0 || p >= m_queries.count() ) + return false; + + return true; } diff --git a/src/libtomahawk/album.h b/src/libtomahawk/album.h index a1497f490..96b901b0e 100644 --- a/src/libtomahawk/album.h +++ b/src/libtomahawk/album.h @@ -52,6 +52,9 @@ public: virtual Tomahawk::result_ptr siblingItem( int itemsAway ); + virtual bool hasNextItem(); + virtual Tomahawk::result_ptr currentItem() const { return m_currentItem; } + virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } virtual bool shuffled() const { return false; } @@ -77,7 +80,7 @@ private: artist_ptr m_artist; QList m_queries; - + result_ptr m_currentItem; unsigned int m_currentTrack; }; diff --git a/src/libtomahawk/artist.cpp b/src/libtomahawk/artist.cpp index 0d24772a4..b801c38a6 100644 --- a/src/libtomahawk/artist.cpp +++ b/src/libtomahawk/artist.cpp @@ -54,6 +54,7 @@ Artist::Artist( unsigned int id, const QString& name ) : PlaylistInterface( this ) , m_id( id ) , m_name( name ) + , m_currentItem( 0 ) , m_currentTrack( 0 ) { } @@ -82,7 +83,20 @@ Artist::siblingItem( int itemsAway ) return Tomahawk::result_ptr(); m_currentTrack = p; - return m_queries.at( p )->results().first(); + m_currentItem = m_queries.at( p )->results().first(); + return m_currentItem; +} + + +bool +Artist::hasNextItem() +{ + int p = m_currentTrack; + p++; + if ( p < 0 || p >= m_queries.count() ) + return false; + + return true; } diff --git a/src/libtomahawk/artist.h b/src/libtomahawk/artist.h index 200e29c48..f1b631d81 100644 --- a/src/libtomahawk/artist.h +++ b/src/libtomahawk/artist.h @@ -52,6 +52,9 @@ public: virtual Tomahawk::result_ptr siblingItem( int itemsAway ); + virtual bool hasNextItem(); + virtual Tomahawk::result_ptr currentItem() const { return m_currentItem; } + virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } virtual bool shuffled() const { return false; } @@ -76,6 +79,7 @@ private: QString m_name; QList m_queries; + result_ptr m_currentItem; unsigned int m_currentTrack; }; diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index 38333189a..6fce7bf11 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -181,17 +181,12 @@ AudioEngine::next() m_playlist->skipRestrictions() == PlaylistInterface::NoSkipForwards ) return; - if ( dynamic_cast< SourcePlaylistInterface* >( m_playlist ) ) + if ( !m_currentTrack.isNull() && !m_playlist->hasNextItem() && + m_currentTrack->id() == m_playlist->currentItem()->id() ) { - SourcePlaylistInterface* sourcepi = dynamic_cast< SourcePlaylistInterface* >( m_playlist ); - if ( !sourcepi->source().isNull() ) - { - //it's a catch-up -- if they're trying to catch-up in the same track, don't do anything - //so that you don't repeat the track and/or cause the retry timer to fire - if ( !m_currentTrack.isNull() && !sourcepi->hasNextSong() && - m_currentTrack->id() == sourcepi->currentItem()->id() ) - return; - } + //For instance, when doing a catch-up while listening along, but the person + //you're following hasn't started a new track yet...don't do anything + return; } loadNextTrack(); diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp index df3792064..f72bb91be 100644 --- a/src/libtomahawk/playlist.cpp +++ b/src/libtomahawk/playlist.cpp @@ -114,6 +114,7 @@ Playlist::Playlist( const source_ptr& src, , m_lastmodified( lastmod ) , m_createdOn( createdOn ) , m_shared( shared ) + , m_currentItem( 0 ) , m_busy( false ) { // qDebug() << Q_FUNC_INFO << "1"; @@ -137,6 +138,7 @@ Playlist::Playlist( const source_ptr& author, , m_lastmodified( 0 ) , m_createdOn( 0 ) // will be set by db command , m_shared( shared ) + , m_currentItem ( 0 ) , m_initEntries( entries ) , m_busy( false ) { diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index dfbccb8e8..76bab9b74 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -170,6 +170,9 @@ public: virtual int unfilteredTrackCount() const { return m_entries.count(); } virtual int trackCount() const { return m_entries.count(); } + virtual bool hasNextItem() { return false; } + virtual Tomahawk::result_ptr currentItem() const { return m_currentItem; } + virtual Tomahawk::result_ptr siblingItem( int /*itemsAway*/ ) { return result_ptr(); } virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } @@ -268,6 +271,8 @@ private: unsigned int m_createdOn; bool m_shared; + result_ptr m_currentItem; + QList< plentry_ptr > m_initEntries; QList< plentry_ptr > m_entries; diff --git a/src/libtomahawk/playlist/albumproxymodel.h b/src/libtomahawk/playlist/albumproxymodel.h index f9cb482a9..8b9d5e1f6 100644 --- a/src/libtomahawk/playlist/albumproxymodel.h +++ b/src/libtomahawk/playlist/albumproxymodel.h @@ -46,6 +46,8 @@ public: virtual void removeIndex( const QModelIndex& index ); virtual void removeIndexes( const QList& indexes ); + virtual bool hasNextItem() { return true; } + virtual Tomahawk::result_ptr currentItem() const { return Tomahawk::result_ptr(); } virtual Tomahawk::result_ptr siblingItem( int direction ); virtual void setFilter( const QString& pattern ); diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index faf31731f..bcfeeb9d1 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -250,6 +250,6 @@ ArtistView::onScrollTimeout() bool ArtistView::jumpToCurrentTrack() { - scrollTo( m_proxyModel->currentItem(), QAbstractItemView::PositionAtCenter ); + scrollTo( m_proxyModel->currentIndex(), QAbstractItemView::PositionAtCenter ); return true; } diff --git a/src/libtomahawk/playlist/collectionview.cpp b/src/libtomahawk/playlist/collectionview.cpp index 8d3895389..55ff115b3 100644 --- a/src/libtomahawk/playlist/collectionview.cpp +++ b/src/libtomahawk/playlist/collectionview.cpp @@ -132,6 +132,6 @@ CollectionView::onTrackCountChanged( unsigned int tracks ) bool CollectionView::jumpToCurrentTrack() { - scrollTo( proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); + scrollTo( proxyModel()->currentIndex(), QAbstractItemView::PositionAtCenter ); return true; } diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp index aa4ec336d..b0e4048f4 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp @@ -410,7 +410,7 @@ DynamicWidget::paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qre bool DynamicWidget::jumpToCurrentTrack() { - m_view->scrollTo( m_view->proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); + m_view->scrollTo( m_view->proxyModel()->currentIndex(), QAbstractItemView::PositionAtCenter ); return true; } diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index dddbc1693..210558a4b 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -168,7 +168,7 @@ PlaylistView::onTrackCountChanged( unsigned int tracks ) bool PlaylistView::jumpToCurrentTrack() { - scrollTo( proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); + scrollTo( proxyModel()->currentIndex(), QAbstractItemView::PositionAtCenter ); return true; } diff --git a/src/libtomahawk/playlist/queueproxymodel.cpp b/src/libtomahawk/playlist/queueproxymodel.cpp index 28bb5a203..c52fb2c88 100644 --- a/src/libtomahawk/playlist/queueproxymodel.cpp +++ b/src/libtomahawk/playlist/queueproxymodel.cpp @@ -44,12 +44,12 @@ QueueProxyModel::siblingItem( int itemsAway ) { qDebug() << Q_FUNC_INFO << rowCount( QModelIndex() ); - setCurrentItem( QModelIndex() ); + setCurrentIndex( QModelIndex() ); Tomahawk::result_ptr res = PlaylistProxyModel::siblingItem( itemsAway ); qDebug() << "new rowcount:" << rowCount( QModelIndex() ); - removeIndex( currentItem() ); + removeIndex( currentIndex() ); return res; } diff --git a/src/libtomahawk/playlist/trackproxymodel.cpp b/src/libtomahawk/playlist/trackproxymodel.cpp index 07b1d9e48..c1e1c34a2 100644 --- a/src/libtomahawk/playlist/trackproxymodel.cpp +++ b/src/libtomahawk/playlist/trackproxymodel.cpp @@ -94,6 +94,20 @@ TrackProxyModel::tracks() Tomahawk::result_ptr TrackProxyModel::siblingItem( int itemsAway ) +{ + return siblingItem( itemsAway, false ); +} + + +bool +TrackProxyModel::hasNextItem() +{ + return !( siblingItem( 1, true ).isNull() ); +} + + +Tomahawk::result_ptr +TrackProxyModel::siblingItem( int itemsAway, bool readOnly ) { qDebug() << Q_FUNC_INFO; @@ -106,9 +120,9 @@ TrackProxyModel::siblingItem( int itemsAway ) // TODO come up with a clever random logic, that keeps track of previously played items idx = index( qrand() % rowCount(), 0 ); } - else if ( currentItem().isValid() ) + else if ( currentIndex().isValid() ) { - idx = currentItem(); + idx = currentIndex(); // random mode is disabled if ( m_repeatMode == PlaylistInterface::RepeatOne ) @@ -146,7 +160,8 @@ TrackProxyModel::siblingItem( int itemsAway ) if ( item && item->query()->playable() ) { qDebug() << "Next PlaylistItem found:" << item->query()->toString() << item->query()->results().at( 0 )->url(); - setCurrentItem( idx ); + if ( !readOnly ) + setCurrentIndex( idx ); return item->query()->results().at( 0 ); } @@ -154,11 +169,21 @@ TrackProxyModel::siblingItem( int itemsAway ) } while ( idx.isValid() ); - setCurrentItem( QModelIndex() ); + if ( !readOnly ) + setCurrentIndex( QModelIndex() ); return Tomahawk::result_ptr(); } +Tomahawk::result_ptr +TrackProxyModel::currentItem() const +{ + TrackModelItem* item = itemFromIndex( mapToSource( currentIndex() ) ); + if ( item && item->query()->playable() ) + return item->query()->results().at( 0 ); + return Tomahawk::result_ptr(); +} + bool TrackProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const { diff --git a/src/libtomahawk/playlist/trackproxymodel.h b/src/libtomahawk/playlist/trackproxymodel.h index f861b7bbc..3ddb35779 100644 --- a/src/libtomahawk/playlist/trackproxymodel.h +++ b/src/libtomahawk/playlist/trackproxymodel.h @@ -37,8 +37,8 @@ public: virtual void setSourceTrackModel( TrackModel* sourceModel ); virtual void setSourceModel( QAbstractItemModel* model ); - virtual QPersistentModelIndex currentItem() const { return mapFromSource( m_model->currentItem() ); } - virtual void setCurrentItem( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); } + virtual QPersistentModelIndex currentIndex() const { return mapFromSource( m_model->currentItem() ); } + virtual void setCurrentIndex( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); } virtual QList tracks(); @@ -49,7 +49,10 @@ public: virtual void removeIndexes( const QModelIndexList& indexes ); virtual void removeIndexes( const QList& indexes ); + virtual Tomahawk::result_ptr currentItem() const; virtual Tomahawk::result_ptr siblingItem( int itemsAway ); + virtual Tomahawk::result_ptr siblingItem( int itemsAway, bool readOnly ); + virtual bool hasNextItem(); virtual QString filter() const { return filterRegExp().pattern(); } virtual void setFilter( const QString& pattern ); diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index 2b0981b11..65f655ff8 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -156,7 +156,7 @@ TrackView::onItemActivated( const QModelIndex& index ) if ( item && item->query()->numResults() ) { qDebug() << "Result activated:" << item->query()->toString() << item->query()->results().first()->url(); - m_proxyModel->setCurrentItem( index ); + m_proxyModel->setCurrentIndex( index ); AudioEngine::instance()->playItem( m_proxyModel, item->query()->results().first() ); } } diff --git a/src/libtomahawk/playlist/treeproxymodel.cpp b/src/libtomahawk/playlist/treeproxymodel.cpp index 0d20e9d4b..2f04dcb84 100644 --- a/src/libtomahawk/playlist/treeproxymodel.cpp +++ b/src/libtomahawk/playlist/treeproxymodel.cpp @@ -137,12 +137,26 @@ TreeProxyModel::removeIndexes( const QList& indexes ) } +bool +TreeProxyModel::hasNextItem() +{ + return !( siblingItem( 1, true ).isNull() ); +} + + Tomahawk::result_ptr TreeProxyModel::siblingItem( int itemsAway ) +{ + return siblingItem( itemsAway, false ); +} + + +Tomahawk::result_ptr +TreeProxyModel::siblingItem( int itemsAway, bool readOnly ) { qDebug() << Q_FUNC_INFO; - QModelIndex idx = currentItem(); + QModelIndex idx = currentIndex(); // Try to find the next available PlaylistItem (with results) if ( idx.isValid() ) do @@ -155,13 +169,25 @@ TreeProxyModel::siblingItem( int itemsAway ) if ( item && item->result()->isOnline() ) { qDebug() << "Next PlaylistItem found:" << item->result()->url(); - setCurrentItem( idx ); + if ( !readOnly ) + setCurrentIndex( idx ); return item->result(); } } while ( idx.isValid() ); - setCurrentItem( QModelIndex() ); + if ( !readOnly ) + setCurrentIndex( QModelIndex() ); + return Tomahawk::result_ptr(); +} + + +Tomahawk::result_ptr +TreeProxyModel::currentItem() const +{ + TreeModelItem* item = itemFromIndex( mapToSource( currentIndex() ) ); + if ( item && item->result()->isOnline() ) + return item->result(); return Tomahawk::result_ptr(); } diff --git a/src/libtomahawk/playlist/treeproxymodel.h b/src/libtomahawk/playlist/treeproxymodel.h index 0caa76819..66efc7668 100644 --- a/src/libtomahawk/playlist/treeproxymodel.h +++ b/src/libtomahawk/playlist/treeproxymodel.h @@ -36,8 +36,8 @@ public: virtual TreeModel* sourceModel() const { return m_model; } virtual void setSourceModel( TreeModel* sourceModel ); - virtual QPersistentModelIndex currentItem() const { return mapFromSource( m_model->currentItem() ); } - virtual void setCurrentItem( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); } + virtual QPersistentModelIndex currentIndex() const { return mapFromSource( m_model->currentItem() ); } + virtual void setCurrentIndex( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); } virtual QList tracks() { Q_ASSERT( FALSE ); QList queries; return queries; } @@ -48,7 +48,10 @@ public: virtual void removeIndex( const QModelIndex& index ); virtual void removeIndexes( const QList& indexes ); + virtual bool hasNextItem(); + virtual Tomahawk::result_ptr currentItem() const; virtual Tomahawk::result_ptr siblingItem( int direction ); + virtual Tomahawk::result_ptr siblingItem( int direction, bool readOnly ); virtual void setFilter( const QString& pattern ); diff --git a/src/libtomahawk/playlistinterface.h b/src/libtomahawk/playlistinterface.h index ce425f581..2679aa09f 100644 --- a/src/libtomahawk/playlistinterface.h +++ b/src/libtomahawk/playlistinterface.h @@ -47,7 +47,9 @@ public: virtual int unfilteredTrackCount() const = 0; virtual int trackCount() const = 0; + virtual Tomahawk::result_ptr currentItem() const = 0; virtual Tomahawk::result_ptr previousItem() { return siblingItem( -1 ); } + virtual bool hasNextItem() { return true; } virtual Tomahawk::result_ptr nextItem() { return siblingItem( 1 ); } virtual Tomahawk::result_ptr siblingItem( int itemsAway ) = 0; diff --git a/src/libtomahawk/sourceplaylistinterface.cpp b/src/libtomahawk/sourceplaylistinterface.cpp index 3c68a5047..c8023baf2 100644 --- a/src/libtomahawk/sourceplaylistinterface.cpp +++ b/src/libtomahawk/sourceplaylistinterface.cpp @@ -29,7 +29,7 @@ SourcePlaylistInterface::SourcePlaylistInterface( Tomahawk::source_ptr& source ) : PlaylistInterface( this ) , m_source( source ) , m_currentItem( 0 ) - , m_gotNextSong( false ) + , m_gotNextItem( false ) { connect( source.data(), SIGNAL( playbackStarted( const Tomahawk::query_ptr& ) ), SLOT( onSourcePlaybackStarted( const Tomahawk::query_ptr& ) ) ); } @@ -53,18 +53,28 @@ SourcePlaylistInterface::nextItem() m_currentItem = Tomahawk::result_ptr(); return m_currentItem; } - else if ( !m_gotNextSong ) + else if ( !m_gotNextItem ) { qDebug() << Q_FUNC_INFO << " This song was already fetched"; return Tomahawk::result_ptr(); } - m_gotNextSong = false; + m_gotNextItem = false; m_currentItem = m_source->currentTrack()->results().first(); return m_currentItem; } +bool +SourcePlaylistInterface::hasNextItem() +{ + if ( m_source.isNull() || m_source->currentTrack().isNull() || m_source->currentTrack()->results().isEmpty() ) + return false; + + return m_gotNextItem; +} + + QList SourcePlaylistInterface::tracks() { @@ -76,9 +86,9 @@ void SourcePlaylistInterface::reset() { if ( !m_currentItem.isNull() ) - m_gotNextSong = true; + m_gotNextItem = true; else - m_gotNextSong = false; + m_gotNextItem = false; } @@ -89,7 +99,7 @@ SourcePlaylistInterface::onSourcePlaybackStarted( const Tomahawk::query_ptr& que connect( query.data(), SIGNAL( resultsAdded( const QList& ) ), SLOT( resolveResultsAdded( const QList& ) ) ); connect( query.data(), SIGNAL( resolvingFinished( bool ) ), SLOT( resolvingFinished( bool ) ) ); Pipeline::instance()->resolve( query, true ); - m_gotNextSong = true; + m_gotNextItem = true; } diff --git a/src/libtomahawk/sourceplaylistinterface.h b/src/libtomahawk/sourceplaylistinterface.h index 43d2d37bb..56d8bebfa 100644 --- a/src/libtomahawk/sourceplaylistinterface.h +++ b/src/libtomahawk/sourceplaylistinterface.h @@ -44,8 +44,9 @@ public: virtual int unfilteredTrackCount() const { return 1; } virtual Tomahawk::result_ptr siblingItem( int itemsAway ); + virtual bool hasNextItem(); virtual Tomahawk::result_ptr nextItem(); - virtual Tomahawk::result_ptr currentItem() { return m_currentItem; } + virtual Tomahawk::result_ptr currentItem() const { return m_currentItem; } virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } virtual PlaylistInterface::SeekRestrictions seekRestrictions() const { return PlaylistInterface::NoSeek; } @@ -58,7 +59,6 @@ public: virtual Tomahawk::source_ptr source() const { return m_source; } - virtual bool hasNextSong() { return m_gotNextSong; } virtual void reset(); public slots: @@ -79,7 +79,7 @@ private slots: private: Tomahawk::source_ptr m_source; Tomahawk::result_ptr m_currentItem; - bool m_gotNextSong; + bool m_gotNextItem; }; }; // ns diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 09b9adbfc..43253b355 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -353,7 +353,7 @@ SourceTreeView::latchOn() { //it's a catch-up -- if they're trying to catch-up in the same track, don't do anything //so that you don't repeat the track and/or cause the retry timer to fire - if ( !AudioEngine::instance()->currentTrack().isNull() && !sourcepi->hasNextSong() && + if ( !AudioEngine::instance()->currentTrack().isNull() && !sourcepi->hasNextItem() && AudioEngine::instance()->currentTrack()->id() == sourcepi->currentItem()->id() ) return; }