mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-21 13:21:52 +02:00
Merge branch 'master' of github.com:tomahawk-player/tomahawk
This commit is contained in:
@@ -538,6 +538,7 @@ AudioControls::dropEvent( QDropEvent* e )
|
|||||||
if ( DropJob::acceptsMimeData( e->mimeData() ) )
|
if ( DropJob::acceptsMimeData( e->mimeData() ) )
|
||||||
{
|
{
|
||||||
DropJob *dj = new DropJob();
|
DropJob *dj = new DropJob();
|
||||||
|
dj->setDropAction( DropJob::Append );
|
||||||
connect( dj, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( droppedTracks( QList<Tomahawk::query_ptr> ) ) );
|
connect( dj, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( droppedTracks( QList<Tomahawk::query_ptr> ) ) );
|
||||||
dj->tracksFromMimeData( e->mimeData() );
|
dj->tracksFromMimeData( e->mimeData() );
|
||||||
|
|
||||||
@@ -551,8 +552,8 @@ AudioControls::droppedTracks( QList< query_ptr > tracks )
|
|||||||
{
|
{
|
||||||
if ( !tracks.isEmpty() )
|
if ( !tracks.isEmpty() )
|
||||||
{
|
{
|
||||||
// queue and play the first if nothign is playing
|
// queue and play the first no matter what
|
||||||
GlobalActionManager::instance()->handleOpenTrack( tracks.first() );
|
GlobalActionManager::instance()->handlePlayTrack( tracks.first() );
|
||||||
|
|
||||||
// just queue the rest
|
// just queue the rest
|
||||||
for ( int i = 1; i < tracks.size(); i++ )
|
for ( int i = 1; i < tracks.size(); i++ )
|
||||||
|
@@ -371,54 +371,50 @@ DropJob::tracksFromMixedData( const QMimeData *data )
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DropJob::handleXspf( const QString& fileUrl )
|
DropJob::handleXspfs( const QString& fileUrls )
|
||||||
{
|
{
|
||||||
tDebug() << Q_FUNC_INFO << "Got xspf playlist!!" << fileUrl;
|
tDebug() << Q_FUNC_INFO << "Got xspf playlist!!" << fileUrls;
|
||||||
|
|
||||||
|
QStringList urls = fileUrls.split( QRegExp( "\\s+" ), QString::SkipEmptyParts );
|
||||||
|
|
||||||
if ( dropAction() == Default )
|
if ( dropAction() == Default )
|
||||||
setDropAction( Create );
|
setDropAction( Create );
|
||||||
|
|
||||||
QFile xspfFile( QUrl::fromUserInput( fileUrl ).toLocalFile() );
|
foreach ( const QString& url, urls )
|
||||||
|
|
||||||
if ( xspfFile.exists() )
|
|
||||||
{
|
{
|
||||||
XSPFLoader* l = new XSPFLoader( true, this );
|
QFile xspfFile( QUrl::fromUserInput( url ).toLocalFile() );
|
||||||
tDebug( LOGINFO ) << "Loading local xspf " << xspfFile.fileName();
|
|
||||||
l->load( xspfFile );
|
if ( xspfFile.exists() )
|
||||||
|
{
|
||||||
|
XSPFLoader* l = new XSPFLoader( true, this );
|
||||||
|
tDebug( LOGINFO ) << "Loading local xspf " << xspfFile.fileName();
|
||||||
|
l->load( xspfFile );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tLog( LOGINFO ) << "Error Loading local xspf " << xspfFile.fileName();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
tLog( LOGINFO ) << "Error Loading local xspf " << xspfFile.fileName();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DropJob::handleSpotifyUrl( const QString& url )
|
DropJob::handleSpotifyUrls( const QString& urlsRaw )
|
||||||
{
|
{
|
||||||
qDebug() << "Got spotify browse uri!!" << url;
|
QStringList urls = urlsRaw.split( QRegExp( "\\s+" ), QString::SkipEmptyParts );
|
||||||
|
qDebug() << "Got spotify browse uris!!" << urls;
|
||||||
|
|
||||||
/// Lets allow parsing all spotify uris here, if parse server is not available
|
/// Lets allow parsing all spotify uris here, if parse server is not available
|
||||||
/// fallback to spotify metadata for tracks /hugo
|
/// fallback to spotify metadata for tracks /hugo
|
||||||
QString browseUri = url;
|
|
||||||
if ( url.contains( "open.spotify.com/" ) ) // convert to a URI
|
|
||||||
{
|
|
||||||
browseUri.replace( "http://open.spotify.com/", "" );
|
|
||||||
browseUri.replace( "/", ":" );
|
|
||||||
browseUri = "spotify:" + browseUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( dropAction() == Default )
|
if ( dropAction() == Default )
|
||||||
setDropAction( Create );
|
setDropAction( Create );
|
||||||
|
|
||||||
tDebug() << "Got a spotify browse uri in dropjob!" << browseUri;
|
tDebug() << "Got a spotify browse uri in dropjob!" << urls;
|
||||||
SpotifyParser* spot = new SpotifyParser( browseUri, dropAction() == Create, this );
|
SpotifyParser* spot = new SpotifyParser( urls, dropAction() == Create, this );
|
||||||
spot->setSingleMode( false );
|
spot->setSingleMode( false );
|
||||||
|
|
||||||
/// This currently supports draging and dropping a spotify playlist and artist
|
/// This currently supports draging and dropping a spotify playlist and artist
|
||||||
if ( dropAction() == Append )
|
if ( dropAction() == Append )
|
||||||
{
|
{
|
||||||
tDebug() << Q_FUNC_INFO << "Asking for spotify browse contents from" << browseUri;
|
tDebug() << Q_FUNC_INFO << "Asking for spotify browse contents from" << urls;
|
||||||
connect( spot, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ) );
|
connect( spot, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,11 +425,11 @@ void
|
|||||||
DropJob::handleAllUrls( const QString& urls )
|
DropJob::handleAllUrls( const QString& urls )
|
||||||
{
|
{
|
||||||
if ( urls.contains( "xspf" ) )
|
if ( urls.contains( "xspf" ) )
|
||||||
handleXspf( urls );
|
handleXspfs( urls );
|
||||||
else if ( urls.contains( "spotify" ) /// Handle all the spotify uris on internal server, if not avail. fallback to spotify
|
else if ( urls.contains( "spotify" ) /// Handle all the spotify uris on internal server, if not avail. fallback to spotify
|
||||||
&& ( urls.contains( "playlist" ) || urls.contains( "artist" ) || urls.contains( "album" ) || urls.contains( "track" ) )
|
&& ( urls.contains( "playlist" ) || urls.contains( "artist" ) || urls.contains( "album" ) || urls.contains( "track" ) )
|
||||||
&& s_canParseSpotifyPlaylists )
|
&& s_canParseSpotifyPlaylists )
|
||||||
handleSpotifyUrl( urls );
|
handleSpotifyUrls( urls );
|
||||||
else
|
else
|
||||||
handleTrackUrls ( urls );
|
handleTrackUrls ( urls );
|
||||||
}
|
}
|
||||||
|
@@ -89,8 +89,8 @@ public:
|
|||||||
void setGetWholeArtists( bool getWholeArtists );
|
void setGetWholeArtists( bool getWholeArtists );
|
||||||
void setGetWholeAlbums( bool getWholeAlbums );
|
void setGetWholeAlbums( bool getWholeAlbums );
|
||||||
void tracksFromMimeData( const QMimeData* data, bool allowDuplicates = false, bool onlyLocal = false, bool top10 = false );
|
void tracksFromMimeData( const QMimeData* data, bool allowDuplicates = false, bool onlyLocal = false, bool top10 = false );
|
||||||
void handleXspf( const QString& file );
|
void handleXspfs( const QString& files );
|
||||||
void handleSpotifyUrl( const QString& url );
|
void handleSpotifyUrls( const QString& urls );
|
||||||
|
|
||||||
static bool canParseSpotifyPlaylists() { return s_canParseSpotifyPlaylists; }
|
static bool canParseSpotifyPlaylists() { return s_canParseSpotifyPlaylists; }
|
||||||
static void setCanParseSpotifyPlaylists( bool parseable ) { s_canParseSpotifyPlaylists = parseable; }
|
static void setCanParseSpotifyPlaylists( bool parseable ) { s_canParseSpotifyPlaylists = parseable; }
|
||||||
|
@@ -363,6 +363,13 @@ GlobalActionManager::handleOpenTrack ( const query_ptr& q )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GlobalActionManager::handlePlayTrack( const query_ptr& qry )
|
||||||
|
{
|
||||||
|
playNow( qry );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GlobalActionManager::handleQueueCommand( const QUrl& url )
|
GlobalActionManager::handleQueueCommand( const QUrl& url )
|
||||||
@@ -697,11 +704,8 @@ GlobalActionManager::handlePlayCommand( const QUrl& url )
|
|||||||
query_ptr q = Query::get( artist, title, album );
|
query_ptr q = Query::get( artist, title, album );
|
||||||
if( !urlStr.isEmpty() )
|
if( !urlStr.isEmpty() )
|
||||||
q->setResultHint( urlStr );
|
q->setResultHint( urlStr );
|
||||||
Pipeline::instance()->resolve( q, true );
|
|
||||||
|
|
||||||
m_waitingToPlay = q;
|
|
||||||
connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) );
|
|
||||||
|
|
||||||
|
playNow( q );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,14 +721,25 @@ GlobalActionManager::playSpotify( const QUrl& url )
|
|||||||
|
|
||||||
QString spotifyUrl = url.hasQueryItem( "spotifyURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "spotifyURL" );
|
QString spotifyUrl = url.hasQueryItem( "spotifyURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "spotifyURL" );
|
||||||
SpotifyParser* p = new SpotifyParser( spotifyUrl, this );
|
SpotifyParser* p = new SpotifyParser( spotifyUrl, this );
|
||||||
connect( p, SIGNAL( track( Tomahawk::query_ptr ) ), this, SLOT( playNow( Tomahawk::query_ptr ) ) );
|
connect( p, SIGNAL( track( Tomahawk::query_ptr ) ), this, SLOT( playOrQueueNow( Tomahawk::query_ptr ) ) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GlobalActionManager::playNow( const query_ptr& q )
|
GlobalActionManager::playNow( const query_ptr& q )
|
||||||
|
{
|
||||||
|
|
||||||
|
Pipeline::instance()->resolve( q, true );
|
||||||
|
|
||||||
|
m_waitingToPlay = q;
|
||||||
|
q->setProperty( "playNow", true );
|
||||||
|
connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
GlobalActionManager::playOrQueueNow( const query_ptr& q )
|
||||||
{
|
{
|
||||||
Pipeline::instance()->resolve( q, true );
|
Pipeline::instance()->resolve( q, true );
|
||||||
|
|
||||||
@@ -743,7 +758,7 @@ GlobalActionManager::playRdio( const QUrl& url )
|
|||||||
QString rdioUrl = url.hasQueryItem( "rdioURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "rdioURL" );
|
QString rdioUrl = url.hasQueryItem( "rdioURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "rdioURL" );
|
||||||
RdioParser* p = new RdioParser( this );
|
RdioParser* p = new RdioParser( this );
|
||||||
p->parse( rdioUrl );
|
p->parse( rdioUrl );
|
||||||
connect( p, SIGNAL( track( Tomahawk::query_ptr ) ), this, SLOT( playNow( Tomahawk::query_ptr ) ) );
|
connect( p, SIGNAL( track( Tomahawk::query_ptr ) ), this, SLOT( playOrQueueNow( Tomahawk::query_ptr ) ) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -921,7 +936,17 @@ GlobalActionManager::waitingForResolved( bool /* success */ )
|
|||||||
{
|
{
|
||||||
// play it!
|
// play it!
|
||||||
// AudioEngine::instance()->playItem( AudioEngine::instance()->playlist(), m_waitingToPlay->results().first() );
|
// AudioEngine::instance()->playItem( AudioEngine::instance()->playlist(), m_waitingToPlay->results().first() );
|
||||||
AudioEngine::instance()->play();
|
if ( sender() && sender()->property( "playNow" ).toBool() )
|
||||||
|
{
|
||||||
|
if ( AudioEngine::instance()->playlist() )
|
||||||
|
AudioEngine::instance()->playItem( AudioEngine::instance()->playlist(), m_waitingToPlay->results().first() );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ViewManager::instance()->queue()->model()->append( m_waitingToPlay );
|
||||||
|
AudioEngine::instance()->play();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
AudioEngine::instance()->play();
|
||||||
|
|
||||||
m_waitingToPlay.clear();
|
m_waitingToPlay.clear();
|
||||||
}
|
}
|
||||||
|
@@ -64,6 +64,7 @@ public slots:
|
|||||||
Tomahawk::dynplaylist_ptr loadDynamicPlaylist( const QUrl& url, bool station );
|
Tomahawk::dynplaylist_ptr loadDynamicPlaylist( const QUrl& url, bool station );
|
||||||
|
|
||||||
void handleOpenTrack( const Tomahawk::query_ptr& qry );
|
void handleOpenTrack( const Tomahawk::query_ptr& qry );
|
||||||
|
void handlePlayTrack( const Tomahawk::query_ptr& qry );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void shortLinkReady( QUrl longUrl, QUrl shortUrl ) const;
|
void shortLinkReady( QUrl longUrl, QUrl shortUrl ) const;
|
||||||
@@ -77,6 +78,7 @@ private slots:
|
|||||||
|
|
||||||
void xspfCreated( const QByteArray& xspf );
|
void xspfCreated( const QByteArray& xspf );
|
||||||
|
|
||||||
|
void playOrQueueNow( const Tomahawk::query_ptr& );
|
||||||
void playNow( const Tomahawk::query_ptr& );
|
void playNow( const Tomahawk::query_ptr& );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -44,7 +44,7 @@ JobStatusModel::addJob( JobStatusItem* item )
|
|||||||
if ( m_collapseCount.contains( item->type() ) )
|
if ( m_collapseCount.contains( item->type() ) )
|
||||||
{
|
{
|
||||||
m_collapseCount[ item->type() ].append( item );
|
m_collapseCount[ item->type() ].append( item );
|
||||||
qDebug() << "Adding item:" << item << "TO COLLAPSE ONLY";
|
// qDebug() << "Adding item:" << item << "TO COLLAPSE ONLY";
|
||||||
return; // we're done, no new rows
|
return; // we're done, no new rows
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -118,26 +118,26 @@ JobStatusModel::itemFinished()
|
|||||||
if ( !m_items.contains( item ) && !m_collapseCount.contains( item->type() ) )
|
if ( !m_items.contains( item ) && !m_collapseCount.contains( item->type() ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach( JobStatusItem* item, m_items )
|
// foreach( JobStatusItem* item, m_items )
|
||||||
{
|
// {
|
||||||
qDebug() << "ITEM #:" << item;
|
// qDebug() << "ITEM #:" << item;
|
||||||
}
|
// }
|
||||||
foreach( const QString& str, m_collapseCount.keys() )
|
// foreach( const QString& str, m_collapseCount.keys() )
|
||||||
{
|
// {
|
||||||
tDebug() << "\t" << str;
|
// tDebug() << "\t" << str;
|
||||||
foreach( JobStatusItem* chain, m_collapseCount[ str ] )
|
// foreach( JobStatusItem* chain, m_collapseCount[ str ] )
|
||||||
qDebug() << "\t\t" << chain;
|
// qDebug() << "\t\t" << chain;
|
||||||
}
|
// }
|
||||||
if ( m_collapseCount.contains( item->type() ) )
|
if ( m_collapseCount.contains( item->type() ) )
|
||||||
{
|
{
|
||||||
const int indexOf = m_items.indexOf( m_collapseCount[ item->type() ].first() );
|
const int indexOf = m_items.indexOf( m_collapseCount[ item->type() ].first() );
|
||||||
tDebug() << "index in main list of collapsed irst item:" << indexOf;
|
// tDebug() << "index in main list of collapsed irst item:" << indexOf;
|
||||||
if ( m_collapseCount[ item->type() ].first() == item &&
|
if ( m_collapseCount[ item->type() ].first() == item &&
|
||||||
m_items.contains( m_collapseCount[ item->type() ].first() ) && m_collapseCount[ item->type() ].size() > 1 )
|
m_items.contains( m_collapseCount[ item->type() ].first() ) && m_collapseCount[ item->type() ].size() > 1 )
|
||||||
{
|
{
|
||||||
// the placeholder we use that links m_items and m_collapsecount is done, so choose another one
|
// the placeholder we use that links m_items and m_collapsecount is done, so choose another one
|
||||||
m_items.replace( m_items.indexOf( m_collapseCount[ item->type() ].first() ), m_collapseCount[ item->type() ][ 1 ] );
|
m_items.replace( m_items.indexOf( m_collapseCount[ item->type() ].first() ), m_collapseCount[ item->type() ][ 1 ] );
|
||||||
qDebug() << "Replaced" << m_collapseCount[ item->type() ].first() << "with:" << m_collapseCount[ item->type() ][ 1 ] << m_items;
|
// qDebug() << "Replaced" << m_collapseCount[ item->type() ].first() << "with:" << m_collapseCount[ item->type() ][ 1 ] << m_items;
|
||||||
}
|
}
|
||||||
m_collapseCount[ item->type() ].removeAll( item );
|
m_collapseCount[ item->type() ].removeAll( item );
|
||||||
tDebug() << "New collapse count list:" << m_collapseCount[ item->type() ];
|
tDebug() << "New collapse count list:" << m_collapseCount[ item->type() ];
|
||||||
@@ -154,7 +154,7 @@ JobStatusModel::itemFinished()
|
|||||||
|
|
||||||
// Remove row completely
|
// Remove row completely
|
||||||
const int idx = m_items.indexOf( item );
|
const int idx = m_items.indexOf( item );
|
||||||
tDebug() << "Got index of item:" << idx;
|
// tDebug() << "Got index of item:" << idx;
|
||||||
Q_ASSERT( idx >= 0 );
|
Q_ASSERT( idx >= 0 );
|
||||||
|
|
||||||
beginRemoveRows( QModelIndex(), idx, idx );
|
beginRemoveRows( QModelIndex(), idx, idx );
|
||||||
|
@@ -147,6 +147,7 @@ void
|
|||||||
Playlist::init()
|
Playlist::init()
|
||||||
{
|
{
|
||||||
m_busy = false;
|
m_busy = false;
|
||||||
|
m_deleted = false;
|
||||||
m_locallyChanged = false;
|
m_locallyChanged = false;
|
||||||
connect( Pipeline::instance(), SIGNAL( idle() ), SLOT( onResolvingFinished() ) );
|
connect( Pipeline::instance(), SIGNAL( idle() ), SLOT( onResolvingFinished() ) );
|
||||||
}
|
}
|
||||||
@@ -248,6 +249,7 @@ void
|
|||||||
Playlist::reportDeleted( const Tomahawk::playlist_ptr& self )
|
Playlist::reportDeleted( const Tomahawk::playlist_ptr& self )
|
||||||
{
|
{
|
||||||
Q_ASSERT( self.data() == this );
|
Q_ASSERT( self.data() == this );
|
||||||
|
m_deleted = true;
|
||||||
m_source->collection()->deletePlaylist( self );
|
m_source->collection()->deletePlaylist( self );
|
||||||
|
|
||||||
emit deleted( self );
|
emit deleted( self );
|
||||||
@@ -480,7 +482,7 @@ Playlist::onResultsFound( const QList<Tomahawk::result_ptr>& results )
|
|||||||
void
|
void
|
||||||
Playlist::onResolvingFinished()
|
Playlist::onResolvingFinished()
|
||||||
{
|
{
|
||||||
if ( m_locallyChanged )
|
if ( m_locallyChanged && !m_deleted )
|
||||||
{
|
{
|
||||||
m_locallyChanged = false;
|
m_locallyChanged = false;
|
||||||
createNewRevision( currentrevision(), currentrevision(), m_entries );
|
createNewRevision( currentrevision(), currentrevision(), m_entries );
|
||||||
|
@@ -295,6 +295,7 @@ private:
|
|||||||
QQueue<RevisionQueueItem> m_revisionQueue;
|
QQueue<RevisionQueueItem> m_revisionQueue;
|
||||||
|
|
||||||
bool m_locallyChanged;
|
bool m_locallyChanged;
|
||||||
|
bool m_deleted;
|
||||||
bool m_busy;
|
bool m_busy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -368,6 +368,12 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r
|
|||||||
|
|
||||||
DropJob* dj = new DropJob();
|
DropJob* dj = new DropJob();
|
||||||
|
|
||||||
|
if ( !DropJob::acceptsMimeData( data, DropJob::Track | DropJob::Playlist | DropJob::Album | DropJob::Artist ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
dj->setDropTypes( DropJob::Track | DropJob::Playlist | DropJob::Artist | DropJob::Album );
|
||||||
|
dj->setDropAction( DropJob::Append );
|
||||||
|
|
||||||
// On mac, drags from outside the app are still Qt::MoveActions instead of Qt::CopyAction by default
|
// On mac, drags from outside the app are still Qt::MoveActions instead of Qt::CopyAction by default
|
||||||
// so check if the drag originated in this playlist to determine whether or not to copy
|
// so check if the drag originated in this playlist to determine whether or not to copy
|
||||||
#ifdef Q_WS_MAC
|
#ifdef Q_WS_MAC
|
||||||
|
@@ -88,10 +88,19 @@ SpotifyParser::lookupUrl( const QString& link )
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SpotifyParser::lookupSpotifyBrowse( const QString& link )
|
SpotifyParser::lookupSpotifyBrowse( const QString& linkRaw )
|
||||||
{
|
{
|
||||||
tLog() << "Parsing Spotify Browse URI:" << link;
|
tLog() << "Parsing Spotify Browse URI:" << linkRaw;
|
||||||
QUrl url = QUrl( QString( SPOTIFY_PLAYLIST_API_URL "/browse/%1" ).arg( link ) );
|
QString browseUri = linkRaw;
|
||||||
|
if ( browseUri.contains( "open.spotify.com/" ) ) // convert to a URI
|
||||||
|
{
|
||||||
|
browseUri.replace( "http://open.spotify.com/", "" );
|
||||||
|
browseUri.replace( "/", ":" );
|
||||||
|
browseUri = "spotify:" + browseUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QUrl url = QUrl( QString( SPOTIFY_PLAYLIST_API_URL "/browse/%1" ).arg( browseUri ) );
|
||||||
tDebug() << "Looking up URL..." << url.toString();
|
tDebug() << "Looking up URL..." << url.toString();
|
||||||
|
|
||||||
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
||||||
@@ -99,13 +108,13 @@ SpotifyParser::lookupSpotifyBrowse( const QString& link )
|
|||||||
|
|
||||||
DropJob::DropType type;
|
DropJob::DropType type;
|
||||||
|
|
||||||
if ( link.contains( "spotify:user" ) )
|
if ( browseUri.contains( "spotify:user" ) )
|
||||||
type = DropJob::Playlist;
|
type = DropJob::Playlist;
|
||||||
if ( link.contains( "spotify:artist" ) )
|
if ( browseUri.contains( "spotify:artist" ) )
|
||||||
type = DropJob::Artist;
|
type = DropJob::Artist;
|
||||||
if ( link.contains( "spotify:album" ) )
|
if ( browseUri.contains( "spotify:album" ) )
|
||||||
type = DropJob::Album;
|
type = DropJob::Album;
|
||||||
if ( link.contains( "spotify:track" ) )
|
if ( browseUri.contains( "spotify:track" ) )
|
||||||
type = DropJob::Track;
|
type = DropJob::Track;
|
||||||
|
|
||||||
m_browseJob = new DropJobNotifier( pixmap(), "Spotify", type, reply );
|
m_browseJob = new DropJobNotifier( pixmap(), "Spotify", type, reply );
|
||||||
|
@@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
|
||||||
ResolversModel::ResolversModel( QObject* parent )
|
ResolversModel::ResolversModel( QObject* parent )
|
||||||
: QAbstractListModel( parent )
|
: QAbstractListModel( parent )
|
||||||
{
|
{
|
||||||
@@ -135,6 +134,11 @@ ResolversModel::addResolver( const QString& resolver, bool enable )
|
|||||||
Tomahawk::ExternalResolver* res = Tomahawk::Pipeline::instance()->addScriptResolver( resolver, enable );
|
Tomahawk::ExternalResolver* res = Tomahawk::Pipeline::instance()->addScriptResolver( resolver, enable );
|
||||||
connect( res, SIGNAL( changed() ), this, SLOT( resolverChanged() ) );
|
connect( res, SIGNAL( changed() ), this, SLOT( resolverChanged() ) );
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
|
||||||
|
if ( res->configUI() )
|
||||||
|
emit openConfig( res->filePath() );
|
||||||
|
else
|
||||||
|
m_waitingForLoad << resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -177,6 +181,12 @@ ResolversModel::resolverChanged()
|
|||||||
qDebug() << "Got resolverChanged signal, does it have a config UI yet?" << res->configUI();
|
qDebug() << "Got resolverChanged signal, does it have a config UI yet?" << res->configUI();
|
||||||
const QModelIndex idx = index( Tomahawk::Pipeline::instance()->scriptResolvers().indexOf( res ), 0, QModelIndex() );
|
const QModelIndex idx = index( Tomahawk::Pipeline::instance()->scriptResolvers().indexOf( res ), 0, QModelIndex() );
|
||||||
emit dataChanged( idx, idx );
|
emit dataChanged( idx, idx );
|
||||||
|
|
||||||
|
if ( m_waitingForLoad.contains( res->filePath() ) )
|
||||||
|
{
|
||||||
|
m_waitingForLoad.remove( res->filePath() );
|
||||||
|
emit openConfig( res->filePath() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
class ResolversModel : public QAbstractListModel
|
class ResolversModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
@@ -49,11 +49,16 @@ public:
|
|||||||
void removeResolver( const QString& resolver );
|
void removeResolver( const QString& resolver );
|
||||||
|
|
||||||
void saveScriptResolvers();
|
void saveScriptResolvers();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void openConfig( const QString& filePath );
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void resolverChanged();
|
void resolverChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addInstalledResolvers();
|
void addInstalledResolvers();
|
||||||
|
QSet<QString> m_waitingForLoad;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RESOLVERSMODEL_H
|
#endif // RESOLVERSMODEL_H
|
||||||
|
@@ -200,6 +200,7 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
|||||||
m_resolversModel = new ResolversModel( this );
|
m_resolversModel = new ResolversModel( this );
|
||||||
ui->scriptList->setModel( m_resolversModel );
|
ui->scriptList->setModel( m_resolversModel );
|
||||||
ui->scriptList->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
|
ui->scriptList->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
|
||||||
|
connect( m_resolversModel, SIGNAL( openConfig( QString ) ), SLOT( openResolverConfig( QString ) ) );
|
||||||
|
|
||||||
#ifdef LIBATTICA_FOUND
|
#ifdef LIBATTICA_FOUND
|
||||||
connect( ui->getMoreResolvers, SIGNAL( clicked() ), this, SLOT( getMoreResolvers() ) );
|
connect( ui->getMoreResolvers, SIGNAL( clicked() ), this, SLOT( getMoreResolvers() ) );
|
||||||
|
@@ -183,6 +183,7 @@ PlaylistItem::dropMimeData( const QMimeData* data, Qt::DropAction action )
|
|||||||
|
|
||||||
DropJob *dj = new DropJob();
|
DropJob *dj = new DropJob();
|
||||||
dj->setDropTypes( DropJob::Track );
|
dj->setDropTypes( DropJob::Track );
|
||||||
|
dj->setDropAction( DropJob::Append );
|
||||||
|
|
||||||
connect( dj, SIGNAL( tracks( QList< Tomahawk::query_ptr > ) ), this, SLOT( parsedDroppedTracks( QList< Tomahawk::query_ptr > ) ) );
|
connect( dj, SIGNAL( tracks( QList< Tomahawk::query_ptr > ) ), this, SLOT( parsedDroppedTracks( QList< Tomahawk::query_ptr > ) ) );
|
||||||
|
|
||||||
|
@@ -417,7 +417,7 @@ SourceTreeView::dragEnterEvent( QDragEnterEvent* event )
|
|||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
QTreeView::dragEnterEvent( event );
|
QTreeView::dragEnterEvent( event );
|
||||||
|
|
||||||
if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Track | DropJob::Playlist, DropJob::Create ) )
|
if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Track | DropJob::Artist | DropJob::Album | DropJob::Playlist, DropJob::Create ) )
|
||||||
{
|
{
|
||||||
m_dragging = true;
|
m_dragging = true;
|
||||||
m_dropRect = QRect();
|
m_dropRect = QRect();
|
||||||
@@ -491,7 +491,7 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
|
|||||||
event->ignore();
|
event->ignore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Playlist, DropJob::Create ) )
|
else if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Playlist | DropJob::Artist | DropJob::Album, DropJob::Create ) )
|
||||||
{
|
{
|
||||||
event->setDropAction( Qt::CopyAction );
|
event->setDropAction( Qt::CopyAction );
|
||||||
event->accept();
|
event->accept();
|
||||||
|
Reference in New Issue
Block a user