1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-23 09:19:41 +01:00

Add spotify support to jobsview

This commit is contained in:
Leo Franchi 2011-09-17 12:23:31 -04:00
parent d40ed14d80
commit b6c1d06165
16 changed files with 158 additions and 61 deletions

View File

@ -63,10 +63,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
sourcetree/items/genericpageitems.cpp
sourcetree/items/temporarypageitem.cpp
jobview/JobStatusView.cpp
jobview/JobStatusModel.cpp
jobview/JobStatusDelegate.cpp
jobview/PipelineStatusItem.cpp
# breakpad/BreakPad.cpp
transferview.cpp
@ -118,12 +114,6 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
sourcetree/items/genericpageitems.h
sourcetree/items/temporarypageitem.h
jobview/JobStatusView.h
jobview/JobStatusModel.h
jobview/JobStatusDelegate.h
jobview/JobStatusItem.h
jobview/PipelineStatusItem.h
transferview.h
tomahawktrayicon.h
audiocontrols.h

View File

@ -215,6 +215,11 @@ set( libSources
widgets/headerbreadcrumb.cpp
widgets/siblingcrumbbutton.cpp
jobview/JobStatusView.cpp
jobview/JobStatusModel.cpp
jobview/JobStatusDelegate.cpp
jobview/PipelineStatusItem.cpp
thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp
thirdparty/kdsingleapplicationguard/kdsharedmemorylocker.cpp
thirdparty/kdsingleapplicationguard/kdtoolsglobal.cpp
@ -421,6 +426,12 @@ set( libHeaders
widgets/headerbreadcrumb.h
widgets/siblingcrumbbutton.h
jobview/JobStatusView.h
jobview/JobStatusModel.h
jobview/JobStatusDelegate.h
jobview/JobStatusItem.h
jobview/PipelineStatusItem.h
thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.h
thirdparty/Qocoa/qsearchfield.h
)

View File

@ -178,13 +178,7 @@ DropJob::parseMimeData( const QMimeData *data )
else if ( data->hasFormat( "text/plain" ) )
{
const QString plainData = QString::fromUtf8( data->data( "text/plain" ) );
if ( plainData.contains( "xspf" ) )
handleXspf( data->data( "text/plain" ).trimmed() );
else if ( plainData.contains( "spotify" ) && plainData.contains( "playlist" ) && s_canParseSpotifyPlaylists )
handleSpPlaylist( plainData );
else
handleTrackUrls ( plainData );
handleAllUrls( plainData );
}
m_resultList.append( results );
@ -415,6 +409,18 @@ DropJob::handleSpPlaylist( const QString& url )
m_queryCount++;
}
void
DropJob::handleAllUrls( const QString& urls )
{
if ( urls.contains( "xspf" ) )
handleXspf( urls );
else if ( urls.contains( "spotify" ) && urls.contains( "playlist" ) && s_canParseSpotifyPlaylists )
handleSpPlaylist( urls );
else
handleTrackUrls ( urls );
}
void
DropJob::handleTrackUrls( const QString& urls )
{
@ -471,7 +477,7 @@ void
DropJob::expandedUrls( QStringList urls )
{
m_queryCount--;
handleTrackUrls( urls.join( "\n" ) );
handleAllUrls( urls.join( "\n" ) );
}
void

View File

@ -105,7 +105,7 @@ private slots:
private:
/// handle parsing mime data
void handleAllUrls( const QString& urls );
void handleTrackUrls( const QString& urls );
QList< Tomahawk::query_ptr > tracksFromQueryList( const QMimeData* d );
QList< Tomahawk::query_ptr > tracksFromResultList( const QMimeData* d );

View File

@ -17,7 +17,9 @@
*/
#include "JobStatusModel.h"
#include "JobStatusItem.h"
#include "utils/logger.h"
JobStatusModel::JobStatusModel( QObject* parent )
: QAbstractListModel ( parent )
@ -34,11 +36,15 @@ JobStatusModel::~JobStatusModel()
void
JobStatusModel::addJob( JobStatusItem* item )
{
connect( item, SIGNAL( statusChanged() ), this, SLOT( itemUpdated() ) );
connect( item, SIGNAL( finished() ), this, SLOT( itemFinished() ) );
if ( item->collapseItem() )
{
if ( m_collapseCount.contains( item->type() ) )
{
m_collapseCount[ item->type() ].append( item );
qDebug() << "Adding item:" << item << "TO COLLAPSE ONLY";
return; // we're done, no new rows
}
else
@ -47,9 +53,7 @@ JobStatusModel::addJob( JobStatusItem* item )
}
}
connect( item, SIGNAL( statusChanged() ), this, SLOT( itemUpdated() ) );
connect( item, SIGNAL( finished() ), this, SLOT( itemFinished() ) );
qDebug() << "Adding item:" << item;
beginInsertRows( QModelIndex(), 0, 0 );
m_items.prepend( item );
@ -108,15 +112,36 @@ JobStatusModel::itemFinished()
JobStatusItem* item = qobject_cast< JobStatusItem* >( sender() );
Q_ASSERT( item );
// tDebug() << "Got item finished:" << item->type() << item->mainText() << item;
// foreach( JobStatusItem* item, m_items )
// {
// qDebug() << "ITEM #:" << item;
// }
// foreach( const QString& str, m_collapseCount.keys() )
// {
// tDebug() << "\t" << str;
// foreach( JobStatusItem* chain, m_collapseCount[ str ] )
// qDebug() << "\t\t" << chain;
// }
if ( m_collapseCount.contains( item->type() ) )
{
const int indexOf = m_items.indexOf( m_collapseCount[ item->type() ].first() );
// tDebug() << "index in main list of collapsed irst item:" << indexOf;
if ( m_collapseCount[ item->type() ].first() == item &&
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
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;
}
m_collapseCount[ item->type() ].removeAll( item );
// tDebug() << "New collapse count list:" << m_collapseCount[ item->type() ];
if ( m_collapseCount[ item->type() ].isEmpty() )
m_collapseCount.remove( item->type() );
else
{
// One less to count, but item is still there
const QModelIndex idx = index( m_items.indexOf( m_collapseCount[ item->type() ].first() ), 0, QModelIndex() );
const QModelIndex idx = index( indexOf, 0, QModelIndex() );
emit dataChanged( idx, idx );
return;
}

View File

@ -19,10 +19,12 @@
#ifndef JOBSTATUSMODEL_H
#define JOBSTATUSMODEL_H
#include "dllmacro.h"
#include <QModelIndex>
class JobStatusItem;
class JobStatusModel : public QAbstractListModel
class DLLEXPORT JobStatusModel : public QAbstractListModel
{
Q_OBJECT
public:

View File

@ -34,11 +34,14 @@
using namespace Tomahawk;
JobStatusView* JobStatusView::s_instance = 0;
JobStatusView::JobStatusView( AnimatedSplitter* parent )
: AnimatedWidget( parent )
, m_parent( parent )
{
s_instance = this;
setHiddenSize( QSize( 0, 0 ) );
setLayout( new QVBoxLayout() );
m_view = new QListView( this );
@ -73,8 +76,9 @@ JobStatusView::JobStatusView( AnimatedSplitter* parent )
}
void
JobStatusView::setModel( QAbstractItemModel* m )
JobStatusView::setModel( JobStatusModel* m )
{
m_model = m;
m_view->setModel( m );
m_view->setItemDelegate( new JobStatusDelegate( m_view ) );
@ -90,6 +94,8 @@ JobStatusView::checkCount()
else if ( isHidden() && m_view->model()->rowCount() > 0 )
emit showWidget();
emit sizeChanged( sizeHint() );
}

View File

@ -22,17 +22,22 @@
#include "typedefs.h"
#include "widgets/animatedsplitter.h"
#include "dllmacro.h"
class QAbstractItemModel;
class QListView;
class JobStatusModel;
class StreamConnection;
class JobStatusView : public AnimatedWidget
class DLLEXPORT JobStatusView : public AnimatedWidget
{
Q_OBJECT
public:
static JobStatusView* instance() {
return s_instance;
}
explicit JobStatusView( AnimatedSplitter* parent );
virtual ~JobStatusView()
{
@ -40,14 +45,19 @@ public:
QSize sizeHint() const;
void setModel( QAbstractItemModel* model );
void setModel( JobStatusModel* model );
JobStatusModel* model() { return m_model; }
private slots:
void checkCount();
private:
QListView* m_view;
JobStatusModel* m_model;
AnimatedSplitter* m_parent;
static JobStatusView* s_instance;
};
#endif // JOBSTATUSVIEW_H

View File

@ -22,6 +22,7 @@
#include "pipeline.h"
#include "tomahawkapp.h"
#include "JobStatusModel.h"
#include "JobStatusView.h"
PipelineStatusItem::PipelineStatusItem()
: JobStatusItem()
@ -76,6 +77,6 @@ PipelineStatusManager::resolving( const Tomahawk::query_ptr& p )
{
// No current query item and we're resolving something, so show it
m_curItem = QWeakPointer< PipelineStatusItem >( new PipelineStatusItem );
APP->mainWindow()->jobsModel()->addJob( m_curItem.data() );
JobStatusView::instance()->model()->addJob( m_curItem.data() );
}
}

View File

@ -22,6 +22,9 @@
#include "utils/tomahawkutils.h"
#include "query.h"
#include "sourcelist.h"
#include "jobview/JobStatusView.h"
#include "jobview/JobStatusModel.h"
#include <qjson/parser.h>
#include <QtNetwork/QNetworkAccessManager>
@ -29,30 +32,51 @@
using namespace Tomahawk;
QPixmap SpotifyParser::s_pixmap = QPixmap();
QPixmap* SpotifyParser::s_pixmap = 0;
SpotifyJobNotifier::SpotifyJobNotifier( const QString &type, const QPixmap& pixmap )
SpotifyJobNotifier::SpotifyJobNotifier( QNetworkReply* job )
: JobStatusItem()
, m_type( type )
, m_icon( pixmap )
, m_type( "track" )
, m_job( job )
{
connect( job, SIGNAL( finished() ), this, SLOT( setFinished()) );
}
SpotifyJobNotifier::SpotifyJobNotifier()
: JobStatusItem()
, m_type( "playlist" )
, m_job( 0 )
{
}
SpotifyJobNotifier::~SpotifyJobNotifier()
{}
QString
SpotifyJobNotifier::rightColumnText() const
{
return QString();
}
QPixmap
SpotifyJobNotifier::icon() const
{
return SpotifyParser::pixmap();
}
QString
SpotifyJobNotifier::mainText() const
{
return tr( "Parsing Spotify %1" ).arg( m_type );
}
void
SpotifyJobNotifier::setFinished()
{
emit finished();
}
SpotifyParser::SpotifyParser( const QStringList& Urls, bool createNewPlaylist, QObject* parent )
@ -60,6 +84,7 @@ SpotifyParser::SpotifyParser( const QStringList& Urls, bool createNewPlaylist, Q
, m_single( false )
, m_trackMode( true )
, m_createNewPlaylist( createNewPlaylist )
, m_playlistJob( 0 )
{
foreach ( const QString& url, Urls )
@ -71,16 +96,13 @@ SpotifyParser::SpotifyParser( const QString& Url, bool createNewPlaylist, QObjec
, m_single( true )
, m_trackMode( true )
, m_createNewPlaylist( createNewPlaylist )
, m_playlistJob( 0 )
{
if ( s_pixmap.isNull() )
s_pixmap.load( RESPATH "images/spotify-logo.jpg" );
lookupUrl( Url );
}
SpotifyParser::~SpotifyParser()
{
}
@ -116,6 +138,9 @@ SpotifyParser::lookupPlaylist( const QString& link )
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
connect( reply, SIGNAL( finished() ), this, SLOT( spotifyPlaylistLookupFinished() ) );
m_playlistJob = new SpotifyJobNotifier();
JobStatusView::instance()->model()->addJob( m_playlistJob );
m_queries.insert( reply );
}
@ -142,6 +167,9 @@ SpotifyParser::lookupTrack( const QString& link )
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
connect( reply, SIGNAL( finished() ), this, SLOT( spotifyTrackLookupFinished() ) );
SpotifyJobNotifier* j = new SpotifyJobNotifier( reply );
JobStatusView::instance()->model()->addJob( j );
m_queries.insert( reply );
}
@ -262,6 +290,8 @@ SpotifyParser::checkPlaylistFinished()
tDebug() << "Checking for spotify batch playlist job finished" << m_queries.isEmpty() << m_createNewPlaylist;
if ( m_queries.isEmpty() ) // we're done
{
if ( m_playlistJob )
m_playlistJob->setFinished();
if( m_createNewPlaylist )
m_playlist = Playlist::create( SourceList::instance()->getLocal(),
uuid(),
@ -294,3 +324,12 @@ SpotifyParser::checkTrackFinished()
}
}
QPixmap
SpotifyParser::pixmap()
{
if ( !s_pixmap )
s_pixmap = new QPixmap( RESPATH "images/spotify-logo.jpg" );
return *s_pixmap;
}

View File

@ -34,6 +34,31 @@ class QNetworkReply;
namespace Tomahawk
{
class DLLEXPORT SpotifyJobNotifier : public JobStatusItem
{
Q_OBJECT
public:
// track
SpotifyJobNotifier( QNetworkReply* job );
// playlist
SpotifyJobNotifier();
virtual ~SpotifyJobNotifier();
virtual QString rightColumnText() const;
virtual QString mainText() const;
virtual QPixmap icon() const;
virtual QString type() const { return m_type; }
virtual bool collapseItem() const { return true; }
public slots:
void setFinished();
private:
QString m_type;
QNetworkReply* m_job;
};
/**
* Small class to parse spotify links into query_ptrs
*
@ -43,6 +68,7 @@ class DLLEXPORT SpotifyParser : public QObject
{
Q_OBJECT
public:
friend class SpotifyJobNotifier;
explicit SpotifyParser( const QString& trackUrl, bool createNewPlaylist = false, QObject* parent = 0 );
explicit SpotifyParser( const QStringList& trackUrls, bool createNewPlaylist = false, QObject* parent = 0 );
virtual ~SpotifyParser();
@ -57,6 +83,8 @@ private slots:
void spotifyPlaylistLookupFinished();
private:
static QPixmap pixmap();
void lookupUrl( const QString& url );
void lookupTrack( const QString& track );
void lookupPlaylist( const QString& playlist );
@ -70,29 +98,9 @@ private:
QSet< QNetworkReply* > m_queries;
QString m_title, m_info, m_creator;
Tomahawk::playlist_ptr m_playlist;
SpotifyJobNotifier* m_playlistJob;
static QPixmap s_pixmap;
};
class DLLEXPORT SpotifyJobNotifier : public JobStatusItem
{
Q_OBJECT
friend class SpotifyParser;
public:
SpotifyJobNotifier( const QString& type, const QPixmap& pixmap );
virtual ~SpotifyJobNotifier();
virtual QString rightColumnText() const;
virtual QString mainText() const;
virtual QPixmap icon() const { return m_icon; }
virtual QString type() const { return m_type; }
virtual bool collapseItem() const { return true; }
private:
void set
QPixmap m_icon;
QString m_type;
static QPixmap* s_pixmap;
};
}

View File

@ -57,7 +57,6 @@ public:
AudioControls* audioControls() { return m_audioControls; }
SourceTreeView* sourceTreeView() const { return m_sourcetree; }
JobStatusModel* jobsModel() const { return m_jobsModel; }
void setWindowTitle( const QString& title );