diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index 6ea43c6e8..385891a0c 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -516,6 +516,16 @@ AudioEngine::loadNextTrack() Tomahawk::result_ptr result; + if ( !m_stopAfterTrack.isNull() && !m_currentTrack.isNull() ) + { + if ( m_stopAfterTrack.data() == m_currentTrack->toQuery().data() ) + { + m_stopAfterTrack.clear(); + stop(); + return; + } + } + if ( m_queue && m_queue->trackCount() ) { result = m_queue->nextItem(); @@ -555,7 +565,9 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk: m_currentTrackPlaylist = playlist; if ( !result.isNull() ) + { loadTrack( result ); + } else if ( !m_playlist.isNull() && m_playlist.data()->retryMode() == PlaylistInterface::Retry ) { m_waitingOnNewTrack = true; @@ -678,6 +690,9 @@ AudioEngine::timerTriggered( qint64 time ) void AudioEngine::setPlaylist( Tomahawk::playlistinterface_ptr playlist ) { + if ( m_playlist == playlist ) + return; + if ( !m_playlist.isNull() ) { if ( m_playlist.data() && m_playlist.data()->retryMode() == PlaylistInterface::Retry ) @@ -691,8 +706,9 @@ AudioEngine::setPlaylist( Tomahawk::playlistinterface_ptr playlist ) emit playlistChanged( playlist ); return; } - + m_playlist = playlist; + m_stopAfterTrack.clear(); if ( !m_playlist.isNull() && m_playlist.data() && m_playlist.data()->retryMode() == PlaylistInterface::Retry ) connect( m_playlist.data(), SIGNAL( nextTrackReady() ), SLOT( onPlaylistNextTrackReady() ) ); @@ -704,16 +720,16 @@ AudioEngine::setPlaylist( Tomahawk::playlistinterface_ptr playlist ) void AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result ) { - m_lastTrack = m_currentTrack; - if ( !m_lastTrack.isNull() ) + Tomahawk::result_ptr lastTrack = m_currentTrack; + if ( !lastTrack.isNull() ) { if ( TomahawkSettings::instance()->privateListeningMode() == TomahawkSettings::PublicListening ) { - DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_lastTrack, DatabaseCommand_LogPlayback::Finished, m_timeElapsed ); + DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( lastTrack, DatabaseCommand_LogPlayback::Finished, m_timeElapsed ); Database::instance()->enqueue( QSharedPointer(cmd) ); } - emit finished( m_lastTrack ); + emit finished( lastTrack ); } m_currentTrack = result; diff --git a/src/libtomahawk/audio/audioengine.h b/src/libtomahawk/audio/audioengine.h index 3c6400229..4928fd6c4 100644 --- a/src/libtomahawk/audio/audioengine.h +++ b/src/libtomahawk/audio/audioengine.h @@ -64,6 +64,8 @@ public: Tomahawk::playlistinterface_ptr playlist() const { return m_playlist; } Tomahawk::result_ptr currentTrack() const { return m_currentTrack; } + + Tomahawk::query_ptr stopAfterTrack() const { return m_stopAfterTrack; } qint64 currentTime() const { return m_mediaObject->currentTime(); } qint64 currentTrackTotalTime() const { return m_mediaObject->totalTime(); } @@ -91,6 +93,8 @@ public slots: void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result ); void setPlaylist( Tomahawk::playlistinterface_ptr playlist ); void setQueue( Tomahawk::playlistinterface_ptr queue ) { m_queue = queue; } + + void setStopAfterTrack( const Tomahawk::query_ptr& query ) { m_stopAfterTrack = query; } signals: void loading( const Tomahawk::result_ptr& track ); @@ -141,8 +145,8 @@ private: QSharedPointer m_input; + Tomahawk::query_ptr m_stopAfterTrack; Tomahawk::result_ptr m_currentTrack; - Tomahawk::result_ptr m_lastTrack; Tomahawk::playlistinterface_ptr m_playlist; Tomahawk::playlistinterface_ptr m_currentTrackPlaylist; Tomahawk::playlistinterface_ptr m_queue; diff --git a/src/libtomahawk/contextmenu.cpp b/src/libtomahawk/contextmenu.cpp index de5122a05..b64dca517 100644 --- a/src/libtomahawk/contextmenu.cpp +++ b/src/libtomahawk/contextmenu.cpp @@ -37,7 +37,7 @@ ContextMenu::ContextMenu( QWidget* parent ) m_sigmap = new QSignalMapper( this ); connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) ); - m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink | ActionLove; + m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink | ActionLove | ActionStopAfter; } @@ -80,6 +80,14 @@ ContextMenu::setQueries( const QList& queries ) if ( m_supportedActions & ActionQueue ) m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue ); + if ( m_supportedActions & ActionStopAfter && itemCount() == 1 ) + { + if ( AudioEngine::instance()->stopAfterTrack() == queries.first() ) + m_sigmap->setMapping( addAction( tr( "&Continue playback after this track" ) ), ActionStopAfter ); + else + m_sigmap->setMapping( addAction( tr( "&Stop playback after this track" ) ), ActionStopAfter ); + } + addSeparator(); if ( m_supportedActions & ActionLove && itemCount() == 1 ) @@ -110,7 +118,6 @@ ContextMenu::setQueries( const QList& queries ) void ContextMenu::setQuery( const Tomahawk::query_ptr& query ) { - QList queries; queries << query; setQueries( queries ); @@ -212,6 +219,13 @@ ContextMenu::onTriggered( int action ) m_queries.first()->setLoved( !m_queries.first()->loved() ); break; + case ActionStopAfter: + if ( AudioEngine::instance()->stopAfterTrack() == m_queries.first() ) + AudioEngine::instance()->setStopAfterTrack( query_ptr() ); + else + AudioEngine::instance()->setStopAfterTrack( m_queries.first() ); + break; + default: emit triggered( action ); } diff --git a/src/libtomahawk/contextmenu.h b/src/libtomahawk/contextmenu.h index 467faeeb2..f077a4f04 100644 --- a/src/libtomahawk/contextmenu.h +++ b/src/libtomahawk/contextmenu.h @@ -40,7 +40,8 @@ public: ActionQueue = 2, ActionDelete = 4, ActionCopyLink = 8, - ActionLove = 16 + ActionLove = 16, + ActionStopAfter = 32 }; explicit ContextMenu( QWidget* parent = 0 ); diff --git a/src/libtomahawk/playlist/trackmodelitem.cpp b/src/libtomahawk/playlist/trackmodelitem.cpp index 18f0c5126..4a02431cf 100644 --- a/src/libtomahawk/playlist/trackmodelitem.cpp +++ b/src/libtomahawk/playlist/trackmodelitem.cpp @@ -82,10 +82,7 @@ TrackModelItem::entry() const const Tomahawk::query_ptr& TrackModelItem::query() const { - if ( !m_entry.isNull() ) - return m_entry->query(); - else - return m_query; + return m_query; } diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index af79f853d..35ed48376 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -558,7 +558,12 @@ TrackView::onCustomContextMenu( const QPoint& pos ) TrackModelItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( index ) ); if ( item && !item->query().isNull() ) - queries << item->query(); + { + if ( item->query()->numResults() > 0 ) + queries << item->query()->results().first()->toQuery(); + else + queries << item->query(); + } } m_contextMenu->setQueries( queries ); diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index 7d7f41846..a381fc343 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -58,7 +58,6 @@ Query::get( const QString& artist, const QString& track, const QString& album, c query_ptr Query::get( const QString& query, const QID& qid ) { - query_ptr q = query_ptr( new Query( query, qid ), &QObject::deleteLater ); q->setWeakRef( q.toWeakRef() ); @@ -164,10 +163,12 @@ Query::addResults( const QList< Tomahawk::result_ptr >& newresults ) m_results << newresults; qStableSort( m_results.begin(), m_results.end(), Query::resultSorter ); + query_ptr q = m_ownRef.toStrongRef(); // hook up signals, and check solved status foreach( const result_ptr& rp, newresults ) { + rp->setQuery( q ); connect( rp.data(), SIGNAL( statusChanged() ), SLOT( onResultStatusChanged() ) ); } } @@ -538,7 +539,7 @@ Query::parseSocialActions() { Tomahawk::SocialAction socialAction; socialAction = it.next(); - if ( socialAction.timestamp.toUInt() > highestTimestamp && socialAction.source->id() == SourceList::instance()->getLocal()->id() ) + if ( socialAction.timestamp.toUInt() > highestTimestamp && socialAction.source->isLocal() ) { m_currentSocialActions[ socialAction.action.toString() ] = socialAction.value.toBool(); } @@ -568,7 +569,7 @@ Query::setLoved( bool loved ) query_ptr q = m_ownRef.toStrongRef(); if ( q ) { - m_currentSocialActions[ "Loved" ] = loved; + m_currentSocialActions[ "Love" ] = loved; Tomahawk::InfoSystem::InfoStringHash trackInfo; trackInfo["title"] = track(); @@ -581,6 +582,8 @@ Query::setLoved( bool loved ) DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( q, QString( "Love" ), loved ? QString( "true" ) : QString( "false" ) ); Database::instance()->enqueue( QSharedPointer(cmd) ); + + emit socialActionsLoaded(); } } diff --git a/src/libtomahawk/result.h b/src/libtomahawk/result.h index b15245342..7c8d3925a 100644 --- a/src/libtomahawk/result.h +++ b/src/libtomahawk/result.h @@ -85,6 +85,7 @@ public: int year() const { return m_year; } unsigned int discnumber() const { return m_discnumber; } + void setQuery( const Tomahawk::query_ptr& query ) { m_query = query; } void setScore( float score ) { m_score = score; } void setTrackId( unsigned int id ) { m_trackId = id; } void setFileId( unsigned int id ) { m_fileId = id; } diff --git a/src/libtomahawk/widgets/querylabel.cpp b/src/libtomahawk/widgets/querylabel.cpp index 131204e95..5271d0b89 100644 --- a/src/libtomahawk/widgets/querylabel.cpp +++ b/src/libtomahawk/widgets/querylabel.cpp @@ -80,7 +80,7 @@ void QueryLabel::init() { m_contextMenu = new ContextMenu( this ); - m_contextMenu->setSupportedActions( ContextMenu::ActionQueue | ContextMenu::ActionCopyLink ); + m_contextMenu->setSupportedActions( ContextMenu::ActionQueue | ContextMenu::ActionCopyLink | ContextMenu::ActionStopAfter | ContextMenu::ActionLove ); m_hoverType = None; setContentsMargins( 0, 0, 0, 0 );