diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8fb41dad9..a95e6b622 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index eae4c4dac..4cf92d3de 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -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 ) diff --git a/src/libtomahawk/dropjob.cpp b/src/libtomahawk/dropjob.cpp index f65656a6d..c285723ec 100644 --- a/src/libtomahawk/dropjob.cpp +++ b/src/libtomahawk/dropjob.cpp @@ -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 diff --git a/src/libtomahawk/dropjob.h b/src/libtomahawk/dropjob.h index e45b0ff17..4bc81a2bd 100644 --- a/src/libtomahawk/dropjob.h +++ b/src/libtomahawk/dropjob.h @@ -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 ); diff --git a/src/jobview/JobStatusDelegate.cpp b/src/libtomahawk/jobview/JobStatusDelegate.cpp similarity index 100% rename from src/jobview/JobStatusDelegate.cpp rename to src/libtomahawk/jobview/JobStatusDelegate.cpp diff --git a/src/jobview/JobStatusDelegate.h b/src/libtomahawk/jobview/JobStatusDelegate.h similarity index 100% rename from src/jobview/JobStatusDelegate.h rename to src/libtomahawk/jobview/JobStatusDelegate.h diff --git a/src/jobview/JobStatusItem.h b/src/libtomahawk/jobview/JobStatusItem.h similarity index 100% rename from src/jobview/JobStatusItem.h rename to src/libtomahawk/jobview/JobStatusItem.h diff --git a/src/jobview/JobStatusModel.cpp b/src/libtomahawk/jobview/JobStatusModel.cpp similarity index 72% rename from src/jobview/JobStatusModel.cpp rename to src/libtomahawk/jobview/JobStatusModel.cpp index 9d9966be2..fdaf8bc2e 100644 --- a/src/jobview/JobStatusModel.cpp +++ b/src/libtomahawk/jobview/JobStatusModel.cpp @@ -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; } diff --git a/src/jobview/JobStatusModel.h b/src/libtomahawk/jobview/JobStatusModel.h similarity index 95% rename from src/jobview/JobStatusModel.h rename to src/libtomahawk/jobview/JobStatusModel.h index 7204d26d6..c3611cfd3 100644 --- a/src/jobview/JobStatusModel.h +++ b/src/libtomahawk/jobview/JobStatusModel.h @@ -19,10 +19,12 @@ #ifndef JOBSTATUSMODEL_H #define JOBSTATUSMODEL_H +#include "dllmacro.h" + #include class JobStatusItem; -class JobStatusModel : public QAbstractListModel +class DLLEXPORT JobStatusModel : public QAbstractListModel { Q_OBJECT public: diff --git a/src/jobview/JobStatusView.cpp b/src/libtomahawk/jobview/JobStatusView.cpp similarity index 94% rename from src/jobview/JobStatusView.cpp rename to src/libtomahawk/jobview/JobStatusView.cpp index 7a799f1c2..732875377 100644 --- a/src/jobview/JobStatusView.cpp +++ b/src/libtomahawk/jobview/JobStatusView.cpp @@ -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() ); + } diff --git a/src/jobview/JobStatusView.h b/src/libtomahawk/jobview/JobStatusView.h similarity index 81% rename from src/jobview/JobStatusView.h rename to src/libtomahawk/jobview/JobStatusView.h index bc6ac3462..1cbc5a7c2 100644 --- a/src/jobview/JobStatusView.h +++ b/src/libtomahawk/jobview/JobStatusView.h @@ -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 diff --git a/src/jobview/PipelineStatusItem.cpp b/src/libtomahawk/jobview/PipelineStatusItem.cpp similarity index 96% rename from src/jobview/PipelineStatusItem.cpp rename to src/libtomahawk/jobview/PipelineStatusItem.cpp index 2e47ae876..283ef509e 100644 --- a/src/jobview/PipelineStatusItem.cpp +++ b/src/libtomahawk/jobview/PipelineStatusItem.cpp @@ -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() ); } } diff --git a/src/jobview/PipelineStatusItem.h b/src/libtomahawk/jobview/PipelineStatusItem.h similarity index 100% rename from src/jobview/PipelineStatusItem.h rename to src/libtomahawk/jobview/PipelineStatusItem.h diff --git a/src/libtomahawk/utils/spotifyparser.cpp b/src/libtomahawk/utils/spotifyparser.cpp index 4851e8edb..6d1971eb2 100644 --- a/src/libtomahawk/utils/spotifyparser.cpp +++ b/src/libtomahawk/utils/spotifyparser.cpp @@ -22,6 +22,9 @@ #include "utils/tomahawkutils.h" #include "query.h" #include "sourcelist.h" +#include "jobview/JobStatusView.h" +#include "jobview/JobStatusModel.h" + #include #include @@ -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; +} diff --git a/src/libtomahawk/utils/spotifyparser.h b/src/libtomahawk/utils/spotifyparser.h index ea629545c..654258962 100644 --- a/src/libtomahawk/utils/spotifyparser.h +++ b/src/libtomahawk/utils/spotifyparser.h @@ -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; }; } diff --git a/src/tomahawkwindow.h b/src/tomahawkwindow.h index 4d490ffd1..ee62cb161 100644 --- a/src/tomahawkwindow.h +++ b/src/tomahawkwindow.h @@ -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 );