1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-09 07:36:48 +02:00

Updated checkFinished

This commit is contained in:
hugolm84
2011-09-04 22:29:38 +02:00
committed by Leo Franchi
parent 8f6cc7846a
commit c2d9baa9d9
8 changed files with 405 additions and 51 deletions

View File

@@ -36,7 +36,7 @@ ContextMenu::ContextMenu( QWidget* parent )
m_sigmap = new QSignalMapper( this ); m_sigmap = new QSignalMapper( this );
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) ); connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) );
m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink; m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink | ActionAddToPlaylist | ActionAddTrackToPl;
} }
ContextMenu::~ContextMenu() ContextMenu::~ContextMenu()
@@ -50,6 +50,7 @@ ContextMenu::clear()
m_queries.clear(); m_queries.clear();
m_albums.clear(); m_albums.clear();
m_artists.clear(); m_artists.clear();
} }
unsigned int unsigned int
@@ -61,9 +62,11 @@ ContextMenu::itemCount() const
void void
ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries ) ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
{ {
if ( queries.isEmpty() ) if ( queries.isEmpty() )
return; return;
QMenu::clear(); QMenu::clear();
m_queries.clear(); m_queries.clear();
m_queries << queries; m_queries << queries;
@@ -74,7 +77,24 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
if ( m_supportedActions & ActionQueue ) if ( m_supportedActions & ActionQueue )
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue ); m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
//m_sigmap->setMapping( addAction( tr( "&Add to Playlist" ) ), ActionAddToPlaylist );
if ( m_supportedActions & ActionAddToPlaylist ){
QList<playlist_ptr> p = SourceList::instance()->getLocal()->collection()->playlists();
QMenu *addTo = new QMenu("Add to");
for(int i = 0; i< p.count(); i++){
m_sigmap->setMapping( addTo->addAction( p[i]->title() ), p[i]->guid() );
m_sigmap->setMapping( addMenu( addTo ), ActionAddToPlaylist );
}
foreach ( QAction* action, addTo->actions() )
connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) );
connect(m_sigmap, SIGNAL(mapped(QString)),
this, SLOT(onAction(QString)));
}
addSeparator(); addSeparator();
@@ -86,8 +106,11 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
if ( m_supportedActions & ActionDelete ) if ( m_supportedActions & ActionDelete )
m_sigmap->setMapping( addAction( queries.count() > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) ), ActionDelete ); m_sigmap->setMapping( addAction( queries.count() > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) ), ActionDelete );
foreach ( QAction* action, actions() ) foreach ( QAction* action, actions() )
{ {
connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) ); connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) );
} }
} }
@@ -96,12 +119,14 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
void void
ContextMenu::setQuery( const Tomahawk::query_ptr& query ) ContextMenu::setQuery( const Tomahawk::query_ptr& query )
{ {
QList<query_ptr> queries; QList<query_ptr> queries;
queries << query; queries << query;
setQueries( queries ); setQueries( queries );
} }
void void
ContextMenu::setAlbums( const QList<Tomahawk::album_ptr>& albums ) ContextMenu::setAlbums( const QList<Tomahawk::album_ptr>& albums )
{ {
@@ -180,6 +205,21 @@ ContextMenu::setArtist( const Tomahawk::artist_ptr& artist )
} }
void
ContextMenu::onClicked( int action )
{
qDebug() << Q_FUNC_INFO << "Action:" << action;
}
void
ContextMenu::onAction( const QString& what )
{
playlist_ptr p = SourceList::instance()->getLocal()->collection()->playlist( what );
p->addEntries( m_queries, p->currentrevision());
qDebug() << Q_FUNC_INFO << "Adding track to guid" << what << "With title" << p->title();
}
void void
ContextMenu::onTriggered( int action ) ContextMenu::onTriggered( int action )
{ {
@@ -199,6 +239,7 @@ ContextMenu::onTriggered( int action )
} }
void ContextMenu::addToQueue() void ContextMenu::addToQueue()
{ {
foreach ( const query_ptr& query, m_queries ) foreach ( const query_ptr& query, m_queries )
@@ -221,6 +262,7 @@ void ContextMenu::addToQueue()
void void
ContextMenu::copyLink() ContextMenu::copyLink()
{ {
qDebug() << Q_FUNC_INFO;
if ( m_queries.count() ) if ( m_queries.count() )
{ {
GlobalActionManager::instance()->copyToClipboard( m_queries.first() ); GlobalActionManager::instance()->copyToClipboard( m_queries.first() );

View File

@@ -34,7 +34,14 @@ Q_OBJECT
public: public:
enum MenuActions enum MenuActions
{ ActionPlay = 1, ActionQueue = 2, ActionDelete = 4, ActionCopyLink = 8 }; {
ActionPlay = 1,
ActionQueue = 2,
ActionDelete = 4,
ActionCopyLink = 8,
ActionAddToPlaylist = 9,
ActionAddTrackToPl = 5
};
explicit ContextMenu( QWidget* parent = 0 ); explicit ContextMenu( QWidget* parent = 0 );
virtual ~ContextMenu(); virtual ~ContextMenu();
@@ -57,19 +64,21 @@ public:
signals: signals:
void triggered( int action ); void triggered( int action );
void clicked( int action );
private slots: private slots:
void onTriggered( int action ); void onTriggered( int action );
void onClicked( int action );
void copyLink(); void copyLink();
void addToQueue(); void addToQueue();
void onAction(const QString& what);
private: private:
QSignalMapper* m_sigmap; QSignalMapper* m_sigmap;
int m_supportedActions; int m_supportedActions;
QList<Tomahawk::query_ptr> m_queries; QList<Tomahawk::query_ptr> m_queries;
QList<Tomahawk::artist_ptr> m_artists; QList<Tomahawk::artist_ptr> m_artists;
playlist_ptr m_playlist;
QList<Tomahawk::album_ptr> m_albums; QList<Tomahawk::album_ptr> m_albums;
}; };

View File

@@ -29,7 +29,7 @@
#include "utils/logger.h" #include "utils/logger.h"
#include "globalactionmanager.h" #include "globalactionmanager.h"
#include "infosystem/infosystem.h" #include "infosystem/infosystem.h"
#include "utils/xspfloader.h"
using namespace Tomahawk; using namespace Tomahawk;
DropJob::DropJob( QObject *parent ) DropJob::DropJob( QObject *parent )
@@ -60,10 +60,40 @@ DropJob::mimeTypes()
return mimeTypes; return mimeTypes;
} }
bool
DropJob::DropAction()
{
if ( dropAction() == DropJob::Create )
return true;
return false;
}
bool bool
DropJob::acceptsMimeData( const QMimeData* data, bool tracksOnly ) DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType, DropJob::DropActions acceptedAction)
{ {
if (acceptedType.testFlag(DropJob::None))
qDebug() << Q_FUNC_INFO << "AcceptedType is None";
if (acceptedType.testFlag(DropJob::All))
qDebug() << Q_FUNC_INFO << "AcceptedType is All";
if (acceptedType.testFlag(DropJob::Playlist))
qDebug() << Q_FUNC_INFO << "AcceptedType is Playlist";
if (acceptedType.testFlag(DropJob::Track))
qDebug() << Q_FUNC_INFO << "AcceptedType is Track";
if (acceptedAction.testFlag(DropJob::Append))
qDebug() << Q_FUNC_INFO << "AcceptedAction is Append";
if (acceptedAction.testFlag(DropJob::Create))
qDebug() << Q_FUNC_INFO << "AcceptedAction is Create";
if ( data->hasFormat( "application/tomahawk.query.list" ) if ( data->hasFormat( "application/tomahawk.query.list" )
|| data->hasFormat( "application/tomahawk.plentry.list" ) || data->hasFormat( "application/tomahawk.plentry.list" )
|| data->hasFormat( "application/tomahawk.result.list" ) || data->hasFormat( "application/tomahawk.result.list" )
@@ -75,22 +105,42 @@ DropJob::acceptsMimeData( const QMimeData* data, bool tracksOnly )
return true; return true;
} }
if( data->hasFormat( "text/plain" )
&& data->data( "text/plain" ).contains( "xspf" )
&& ( acceptedType.testFlag(DropJob::Playlist) || acceptedType.testFlag(DropJob::All) )
&& acceptedAction.testFlag(DropJob::Create)
)
return true;
// crude check for spotify tracks // crude check for spotify tracks
if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "spotify" ) && if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "spotify" )
( tracksOnly ? data->data( "text/plain" ).contains( "track" ) : true ) ) && data->data( "text/plain" ).contains( "playlist" )
&& ( acceptedType.testFlag(DropJob::Playlist) || acceptedType.testFlag(DropJob::All) )
)
return true;
// crude check for spotify tracks
if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "spotify" )
&& data->data( "text/plain" ).contains( "track" )
&& ( acceptedType.testFlag(DropJob::Track) || acceptedType.testFlag(DropJob::All) )
)
return true; return true;
// crude check for rdio tracks // crude check for rdio tracks
if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "rdio.com" ) && if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "rdio.com" )
( tracksOnly ? data->data( "text/plain" ).contains( "track" ) : true ) ) && data->data( "text/plain" ).contains( "track" )
&& ( acceptedType.testFlag(DropJob::Track) || acceptedType.testFlag(DropJob::All) )
)
return true; return true;
// We whitelist t.co and bit.ly (and j.mp) since they do some link checking. Often playable (e.g. spotify..) links hide behind them, // We whitelist t.co and bit.ly (and j.mp) since they do some link checking. Often playable (e.g. spotify..) links hide behind them,
// so we do an extra level of lookup // so we do an extra level of lookup
if ( ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "bit.ly" ) ) || if ( ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "bit.ly" ) ) ||
( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "j.mp" ) ) || ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "j.mp" ) ) ||
( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "t.co" ) ) || ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "t.co" ) ) ||
( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "rd.io" ) ) ) ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "rd.io" ) )
&& ( acceptedType.testFlag(DropJob::Track) || acceptedType.testFlag(DropJob::All) ) )
return true; return true;
return false; return false;
@@ -134,6 +184,26 @@ DropJob::tracksFromMimeData( const QMimeData* data, bool allowDuplicates, bool o
void void
DropJob::parseMimeData( const QMimeData *data ) DropJob::parseMimeData( const QMimeData *data )
{ {
if(dropTypes() & DropJob::Playlist)
qDebug() << Q_FUNC_INFO << "DropType is Playlist";
if(dropTypes() & DropJob::All)
qDebug() << Q_FUNC_INFO << "DropType is All";
if(dropTypes() & DropJob::Track)
qDebug() << Q_FUNC_INFO << "DropType is Track";
if(dropTypes() & DropJob::Artist)
qDebug() << Q_FUNC_INFO << "DropType is Artist";
if(DropTypes() & DropJob::None)
qDebug() << Q_FUNC_INFO << "DropType is None";
else qDebug() << "DropType is I DONT KNOW!";
if(dropAction() == DropJob::Append)
qDebug() << Q_FUNC_INFO << "DropAction is Append";
if(dropAction() == DropJob::Create)
qDebug() << Q_FUNC_INFO << "DropAction is Create";
QList< query_ptr > results; QList< query_ptr > results;
if ( data->hasFormat( "application/tomahawk.query.list" ) ) if ( data->hasFormat( "application/tomahawk.query.list" ) )
results = tracksFromQueryList( data ); results = tracksFromQueryList( data );
@@ -148,8 +218,14 @@ DropJob::parseMimeData( const QMimeData *data )
else if ( data->hasFormat( "text/plain" ) ) else if ( data->hasFormat( "text/plain" ) )
{ {
QString plainData = QString::fromUtf8( data->data( "text/plain" ).constData() ); QString plainData = QString::fromUtf8( data->data( "text/plain" ).constData() );
tDebug() << "Got text/plain mime data:" << data->data( "text/plain" ) << "decoded to:" << plainData; qDebug() << Q_FUNC_INFO << "Got text/plain mime data:" << data->data( "text/plain" ) << "decoded to:" << plainData.trimmed();
handleTrackUrls ( plainData );
if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "xspf" ) )
handleXspf( data->data( "text/plain" ).trimmed(), DropAction() );
else if ( plainData.contains( "spotify" ) && plainData.contains( "playlist" ) )
handleSpPlaylist( plainData, DropAction() );
else
handleTrackUrls ( plainData );
} }
m_resultList.append( results ); m_resultList.append( results );
@@ -331,13 +407,72 @@ DropJob::tracksFromMixedData( const QMimeData *data )
return queries; return queries;
} }
void
DropJob::handleXspf( const QString& fileUrl, bool createNewPlaylist )
{
qDebug() << Q_FUNC_INFO << "Got xspf playlist!!" << fileUrl;
// Doing like so on *nix, dont know really how files are
// passed on others.
qDebug() << "Got xspf playlist!!";
QString newFile = fileUrl;
newFile.replace("file://", "");
QFile xspfFile(newFile);
XSPFLoader* l = new XSPFLoader( createNewPlaylist, this );
tDebug( LOGINFO ) << "Loading local xspf:" << newFile;
l->load( xspfFile );
}
void
DropJob::handleSpPlaylist( const QString& url, bool createNewPlaylist)
{
qDebug() << "Got spotify playlist!!" << url;
if ( url.contains( "open.spotify.com/user") ||
url.contains( "spotify:user" ) )
{
// Lets create a valid playlist uri
QString playlistUri = url;
QString validUri;
if(url.contains( "open.spotify.com/user")){
playlistUri.replace("http://open.spotify.com/", "");
QStringList playlist = playlistUri.split( "/" );
validUri = "spotify:" + playlist.join(":");
}else validUri = playlistUri;
tDebug() << "Got a spotify playlist in dropjob!" << validUri;
SpotifyParser* spot = new SpotifyParser( validUri, this, createNewPlaylist);
//This currently supports draging and dropping a spotify playlist
if(createNewPlaylist){
qDebug() << Q_FUNC_INFO << "Got spotify playlist!! Create new" << url;
}else{
qDebug() << Q_FUNC_INFO << "Got spotify playlist!!" << url;
connect( spot, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ) );
}
m_queryCount++;
}
}
void void
DropJob::handleTrackUrls( const QString& urls ) DropJob::handleTrackUrls( const QString& urls )
{ {
if ( urls.contains( "open.spotify.com/track") || qDebug() << Q_FUNC_INFO << urls;
if ( urls.contains( "open.spotify.com/user") ||
urls.contains( "spotify:user" ) )
handleSpPlaylist( urls, dropAction() );
else if ( urls.contains( "open.spotify.com/track") ||
urls.contains( "spotify:track" ) ) urls.contains( "spotify:track" ) )
{ {
QStringList tracks = urls.split( "\n" ); QStringList tracks = urls.split(QRegExp("\\s+"), QString::SkipEmptyParts);
tDebug() << "Got a list of spotify urls!" << tracks; tDebug() << "Got a list of spotify urls!" << tracks;
SpotifyParser* spot = new SpotifyParser( tracks, this ); SpotifyParser* spot = new SpotifyParser( tracks, this );
@@ -367,7 +502,6 @@ DropJob::handleTrackUrls( const QString& urls )
} }
} }
void void
DropJob::expandedUrls( QStringList urls ) DropJob::expandedUrls( QStringList urls )
{ {

View File

@@ -43,12 +43,41 @@ public:
* *
* Connect to tracks( QList< query_ptr> ); for the extracted tracks. * Connect to tracks( QList< query_ptr> ); for the extracted tracks.
*/ */
static bool acceptsMimeData( const QMimeData* data, bool tracksOnly = true );
enum DropType {
None = 0x00,
Playlist = 0x01,
Track = 0x02,
Album = 0x04,
Artist = 0x08,
All = 0x10
};
Q_DECLARE_FLAGS(DropTypes, DropType)
enum DropAction {
Append = 0x0,
Create = 0x1
};
Q_DECLARE_FLAGS(DropActions, DropAction)
static bool acceptsMimeData( const QMimeData* data, DropJob::DropTypes type = All, DropJob::DropActions action = Append );
static QStringList mimeTypes(); static QStringList mimeTypes();
virtual void setDropTypes( DropTypes types ) { m_dropTypes = types; }
virtual void setDropAction( DropAction action ) { m_dropAction = action; }
virtual DropTypes dropTypes() const { return m_dropTypes; }
virtual DropAction dropAction() const { return m_dropAction; }
void parseMimeData( const QMimeData* data );
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, bool createNewPlaylist = false );
void handleSpPlaylist( const QString& url, bool createNewPlaylist = false );
signals: signals:
/// QMimeData parsing results /// QMimeData parsing results
@@ -63,7 +92,7 @@ private slots:
private: private:
/// handle parsing mime data /// handle parsing mime data
void parseMimeData( const QMimeData* data );
void handleTrackUrls( const QString& urls ); void handleTrackUrls( const QString& urls );
QList< Tomahawk::query_ptr > tracksFromQueryList( const QMimeData* d ); QList< Tomahawk::query_ptr > tracksFromQueryList( const QMimeData* d );
@@ -86,8 +115,11 @@ private:
bool m_getWholeArtists; bool m_getWholeArtists;
bool m_getWholeAlbums; bool m_getWholeAlbums;
bool m_top10; bool m_top10;
DropTypes m_dropTypes;
DropAction m_dropAction;
bool DropAction();
QList< Tomahawk::query_ptr > m_resultList; QList< Tomahawk::query_ptr > m_resultList;
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS(DropJob::DropTypes)
#endif // DROPJOB_H #endif // DROPJOB_H

View File

@@ -21,7 +21,7 @@
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/tomahawkutils.h" #include "utils/tomahawkutils.h"
#include "query.h" #include "query.h"
#include "sourcelist.h"
#include <qjson/parser.h> #include <qjson/parser.h>
#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkAccessManager>
@@ -29,19 +29,22 @@
using namespace Tomahawk; using namespace Tomahawk;
SpotifyParser::SpotifyParser( const QStringList& trackUrls, QObject* parent ) SpotifyParser::SpotifyParser( const QStringList& Urls, QObject* parent, bool createNewPlaylist)
: QObject ( parent ) : QObject ( parent )
, m_single( false ) , m_single( false )
{ {
foreach ( const QString& url, trackUrls ) m_createNewPlaylist = createNewPlaylist;
lookupTrack( url ); foreach ( const QString& url, Urls )
lookupUrl( url );
} }
SpotifyParser::SpotifyParser( const QString& trackUrl, QObject* parent ) SpotifyParser::SpotifyParser( const QString& Url, QObject* parent, bool createNewPlaylist )
: QObject ( parent ) : QObject ( parent )
, m_single( true ) , m_single( true )
{ {
lookupTrack( trackUrl ); m_createNewPlaylist = createNewPlaylist;
lookupUrl( Url );
} }
SpotifyParser::~SpotifyParser() SpotifyParser::~SpotifyParser()
@@ -49,10 +52,43 @@ SpotifyParser::~SpotifyParser()
} }
void
SpotifyParser::lookupUrl( const QString& link )
{
if( link.contains( "track" ) )
lookupTrack(link);
else if( link.contains( "playlist" ) )
lookupPlaylist( link );
else return; // We only support tracks and playlists
}
void
SpotifyParser::lookupPlaylist( const QString& link )
{
if ( !link.contains( "spotify:user:" ) ) // we only support playlist here
return;
QString uri = link;
tLog() << "Parsing Spotify Playlist URI:" << uri;
QUrl url = QUrl( QString( "http://www.trushuffle.com:5512/playlist/%1" ).arg( uri ) );
tDebug() << "Looking up URL..." << url.toString();
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
connect( reply, SIGNAL( finished() ), this, SLOT( spotifyPlaylistLookupFinished() ) );
m_queries.insert( reply );
}
void void
SpotifyParser::lookupTrack( const QString& link ) SpotifyParser::lookupTrack( const QString& link )
{ {
if ( !link.contains( "track" ) ) // we only support track links atm
tDebug() << "Got a QString " << link;
if ( !link.contains( "track" )) // we only support track links atm
return; return;
// we need Spotify URIs such as spotify:track:XXXXXX, so if we by chance get a http://open.spotify.com url, convert it // we need Spotify URIs such as spotify:track:XXXXXX, so if we by chance get a http://open.spotify.com url, convert it
@@ -76,6 +112,60 @@ SpotifyParser::lookupTrack( const QString& link )
} }
void
SpotifyParser::spotifyPlaylistLookupFinished()
{
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
Q_ASSERT( r );
m_queries.remove( r );
r->deleteLater();
if ( r->error() == QNetworkReply::NoError )
{
QJson::Parser p;
bool ok;
QVariantMap res = p.parse( r, &ok ).toMap();
if ( !ok )
{
tLog() << "Failed to parse json from Spotify playlist lookup:" << p.errorString() << "On line" << p.errorLine();
checkTrackFinished();
return;
} else if ( !res.contains( "tracks" ) )
{
tLog() << "No 'tracks' item in the spotify playlist lookup result... not doing anything";
checkTrackFinished();
return;
}
QVariantList trackResponse = res.value( "tracks" ).toList();
if(!trackResponse.isEmpty()){
m_title = res.value( "title" ).toString();
m_creator = res.value( "creator" ).toString();
qDebug() << "playlist owner: " << m_creator;
}
foreach(QVariant track, trackResponse){
QString title, artist, album;
title = track.toMap().value( "title" ).toString();
artist = track.toMap().value( "artists" ).toList().first().toString();
album = track.toMap().value( "album" ).toString();
Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album, uuid(), true );
m_tracks << q;
}
} else
{
tLog() << "Error in network request to Spotify for track decoding:" << r->errorString();
}
checkPlaylistFinished();
}
void void
SpotifyParser::spotifyTrackLookupFinished() SpotifyParser::spotifyTrackLookupFinished()
{ {
@@ -93,12 +183,12 @@ SpotifyParser::spotifyTrackLookupFinished()
if ( !ok ) if ( !ok )
{ {
tLog() << "Failed to parse json from Spotify track lookup:" << p.errorString() << "On line" << p.errorLine(); tLog() << "Failed to parse json from Spotify track lookup:" << p.errorString() << "On line" << p.errorLine();
checkFinished(); checkTrackFinished();
return; return;
} else if ( !res.contains( "track" ) ) } else if ( !res.contains( "track" ) )
{ {
tLog() << "No 'track' item in the spotify track lookup result... not doing anything"; tLog() << "No 'track' item in the spotify track lookup result... not doing anything";
checkFinished(); checkTrackFinished();
return; return;
} }
@@ -128,11 +218,33 @@ SpotifyParser::spotifyTrackLookupFinished()
tLog() << "Error in network request to Spotify for track decoding:" << r->errorString(); tLog() << "Error in network request to Spotify for track decoding:" << r->errorString();
} }
checkFinished(); checkTrackFinished();
} }
void void
SpotifyParser::checkFinished() SpotifyParser::checkPlaylistFinished()
{
if ( m_queries.isEmpty() ) // we're done
{
if(m_createNewPlaylist)
m_playlist = Playlist::create( SourceList::instance()->getLocal(),
uuid(),
m_title,
m_info,
m_creator,
false,
m_tracks );
else if ( !m_tracks.isEmpty() && !m_createNewPlaylist)
emit tracks( m_tracks );
deleteLater();
}
}
void
SpotifyParser::checkTrackFinished()
{ {
if ( m_queries.isEmpty() ) // we're done if ( m_queries.isEmpty() ) // we're done
{ {

View File

@@ -40,24 +40,31 @@ class DLLEXPORT SpotifyParser : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit SpotifyParser( const QString& trackUrl, QObject* parent = 0 ); explicit SpotifyParser( const QString& trackUrl, QObject* parent = 0, bool createNewPl = false );
explicit SpotifyParser( const QStringList& trackUrls, QObject* parent = 0 ); explicit SpotifyParser( const QStringList& trackUrls, QObject* parent = 0, bool createNewPl = false);
virtual ~SpotifyParser(); virtual ~SpotifyParser();
signals: signals:
void track( const Tomahawk::query_ptr& track ); void track( const Tomahawk::query_ptr& track );
void tracks( const QList< Tomahawk::query_ptr > tracks ); void tracks( const QList< Tomahawk::query_ptr > tracks );
void playlist( const Tomahawk::query_ptr& playlist );
private slots: private slots:
void spotifyTrackLookupFinished(); void spotifyTrackLookupFinished();
void spotifyPlaylistLookupFinished();
private: private:
void lookupUrl( const QString& url );
void lookupTrack( const QString& track ); void lookupTrack( const QString& track );
void checkFinished(); void lookupPlaylist( const QString& playlist );
void checkTrackFinished();
void checkPlaylistFinished();
bool m_single; bool m_single;
bool m_createNewPlaylist;
QList< query_ptr > m_tracks; QList< query_ptr > m_tracks;
QSet< QNetworkReply* > m_queries; QSet< QNetworkReply* > m_queries;
QString m_title, m_info, m_creator;
Tomahawk::playlist_ptr m_playlist;
}; };
} }

View File

@@ -426,16 +426,16 @@ SourceTreeView::dragEnterEvent( QDragEnterEvent* event )
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
QTreeView::dragEnterEvent( event ); QTreeView::dragEnterEvent( event );
if ( DropJob::acceptsMimeData( event->mimeData() ) ) if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Track | DropJob::Playlist, DropJob::Create ) )
{ {
m_dragging = true; m_dragging = true;
m_dropRect = QRect(); m_dropRect = QRect();
m_dropIndex = QPersistentModelIndex(); m_dropIndex = QPersistentModelIndex();
qDebug() << "Accepting Drag Event"; qDebug() << Q_FUNC_INFO << "Accepting Drag Event";
event->setDropAction( Qt::CopyAction ); event->setDropAction( Qt::CopyAction );
event->accept(); event->acceptProposedAction();
} }
} }
@@ -459,7 +459,7 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
bool accept = false; bool accept = false;
QTreeView::dragMoveEvent( event ); QTreeView::dragMoveEvent( event );
if ( DropJob::acceptsMimeData( event->mimeData() ) ) if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Track, DropJob::Append ) )
{ {
setDirtyRegion( m_dropRect ); setDirtyRegion( m_dropRect );
const QPoint pos = event->pos(); const QPoint pos = event->pos();
@@ -475,6 +475,7 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
SourceTreeItem* item = itemFromIndex< SourceTreeItem >( index ); SourceTreeItem* item = itemFromIndex< SourceTreeItem >( index );
if( item->willAcceptDrag( event->mimeData() ) ) if( item->willAcceptDrag( event->mimeData() ) )
{ {
accept = true; accept = true;
m_delegate->hovered( index, event->mimeData() ); m_delegate->hovered( index, event->mimeData() );
dataChanged(index, index); dataChanged(index, index);
@@ -489,14 +490,24 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
if ( accept ) if ( accept )
{ {
//qDebug() << Q_FUNC_INFO << "Accepting";
event->setDropAction( Qt::CopyAction ); event->setDropAction( Qt::CopyAction );
event->accept(); event->accept();
} }
else else{
event->ignore();
setDirtyRegion( m_dropRect ); qDebug() << Q_FUNC_INFO << "Ignoring";
} event->ignore();
}
}else if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Playlist, DropJob::Create ) )
{
// Should maybe ignore, but we are just dropping
// a playlist in the container, not on a specific playlist
event->setDropAction( Qt::CopyAction );
event->accept();
}
setDirtyRegion( m_dropRect );
} }
@@ -513,18 +524,25 @@ SourceTreeView::dropEvent( QDropEvent* event )
Q_ASSERT( item ); Q_ASSERT( item );
item->setDropType( m_delegate->hoveredDropType() ); item->setDropType( m_delegate->hoveredDropType() );
qDebug() << "dropType is " << m_delegate->hoveredDropType(); qDebug() << Q_FUNC_INFO << "dropType is " << m_delegate->hoveredDropType();
} }
// Need to fake the dropevent because the treeview would reject it if it is outside the item (on the tree) // Need to fake the dropevent because the treeview would reject it if it is outside the item (on the tree)
if ( pos.x() < 100 ) if ( pos.x() < 100 )
{ {
qDebug() << Q_FUNC_INFO << "New Event";
QDropEvent* newEvent = new QDropEvent( pos + QPoint( 100, 0 ), event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers(), event->type() ); QDropEvent* newEvent = new QDropEvent( pos + QPoint( 100, 0 ), event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers(), event->type() );
QTreeView::dropEvent( newEvent ); QTreeView::dropEvent( newEvent );
delete newEvent; delete newEvent;
} }
else else
{ {
// In current event, parse sourceTreeView mime instead of playlistitems
qDebug() << Q_FUNC_INFO << "Current Event";
DropJob *dropThis = new DropJob;
dropThis->setDropTypes( DropJob::Playlist );
dropThis->setDropAction( DropJob::Create );
dropThis->parseMimeData( event->mimeData() );
QTreeView::dropEvent( event ); QTreeView::dropEvent( event );
} }

View File

@@ -34,7 +34,7 @@ Q_OBJECT
public: public:
explicit SourceTreeView( QWidget* parent = 0 ); explicit SourceTreeView( QWidget* parent = 0 );
//static bool acceptsMimeData( const QMimeData* data, bool playlistOnly = true );
public slots: public slots:
void showOfflineSources( bool offlineSourcesShown ); void showOfflineSources( bool offlineSourcesShown );
@@ -79,7 +79,7 @@ private:
template< typename T > template< typename T >
T* itemFromIndex( const QModelIndex& index ) const; T* itemFromIndex( const QModelIndex& index ) const;
//void parseMimeData( const QMimeData* data );
SourcesModel* m_model; SourcesModel* m_model;
SourcesProxyModel* m_proxyModel; SourcesProxyModel* m_proxyModel;
QModelIndex m_contextMenuIndex; QModelIndex m_contextMenuIndex;