From 1b445934a8446257eecda6d68dfb5989311d785b Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 8 Apr 2012 20:05:20 -0400 Subject: [PATCH] Work on the tomahawk side of spotify syncing. bugfixes and new UI indicators --- src/accounts/spotify/SpotifyAccount.cpp | 44 ++++++++++++---- src/accounts/spotify/SpotifyAccount.h | 4 +- .../spotify/SpotifyPlaylistUpdater.cpp | 41 ++++++++++++++- src/accounts/spotify/SpotifyPlaylistUpdater.h | 7 +++ src/libtomahawk/playlist.cpp | 15 +++++- src/libtomahawk/playlist.h | 2 +- .../playlist/PlaylistUpdaterInterface.cpp | 4 +- .../playlist/PlaylistUpdaterInterface.h | 15 +++++- src/sourcetree/items/playlistitems.cpp | 52 ++++++++++++++++++- src/sourcetree/items/playlistitems.h | 5 +- 10 files changed, 169 insertions(+), 20 deletions(-) diff --git a/src/accounts/spotify/SpotifyAccount.cpp b/src/accounts/spotify/SpotifyAccount.cpp index c4cae8a3a..78159f693 100644 --- a/src/accounts/spotify/SpotifyAccount.cpp +++ b/src/accounts/spotify/SpotifyAccount.cpp @@ -368,10 +368,14 @@ void SpotifyAccount::sendMessage( const QVariantMap &m, QObject* obj, const QString& slot ) { QVariantMap msg = m; - const QString qid = QUuid::createUuid().toString().replace( "{", "" ).replace( "}", "" ); - m_qidToSlotMap[ qid ] = qMakePair( obj, slot ); - msg[ "qid" ] = qid; + if ( obj ) + { + const QString qid = QUuid::createUuid().toString().replace( "{", "" ).replace( "}", "" ); + + m_qidToSlotMap[ qid ] = qMakePair( obj, slot ); + msg[ "qid" ] = qid; + } m_spotifyResolver.data()->sendMessage( msg ); } @@ -413,16 +417,23 @@ SpotifyAccount::stopPlaylistSync( SpotifyPlaylistInfo* playlist ) m_spotifyResolver.data()->sendMessage( msg ); - if ( deleteOnUnsync() && m_updaters.contains( playlist->plid ) ) + if ( m_updaters.contains( playlist->plid ) ) { - SpotifyPlaylistUpdater* updater = m_updaters.take( playlist->plid ); - playlist_ptr tomahawkPl = updater->playlist(); + SpotifyPlaylistUpdater* updater = m_updaters[ playlist->plid ]; + updater->setSync( false ); - if ( !tomahawkPl.isNull() ) - Playlist::remove( tomahawkPl ); + if ( deleteOnUnsync() ) + { + playlist_ptr tomahawkPl = updater->playlist(); - updater->deleteLater(); + if ( !tomahawkPl.isNull() ) + Playlist::remove( tomahawkPl ); + updater->deleteLater(); + + } + + updater->save(); } } @@ -436,3 +447,18 @@ SpotifyAccount::loadPlaylists() msg[ "_msgtype" ] = "getAllPlaylists"; sendMessage( msg, this, "allPlaylistsLoaded" ); } + + +void +SpotifyAccount::setSyncForPlaylist( const QString& spotifyPlaylistId, bool sync ) +{ + foreach ( SpotifyPlaylistInfo* info, m_allSpotifyPlaylists ) + { + if( info->plid == spotifyPlaylistId ) + info->sync = sync; + } + + if ( !m_configWidget.isNull() ) + m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists ); +} + diff --git a/src/accounts/spotify/SpotifyAccount.h b/src/accounts/spotify/SpotifyAccount.h index 4a71b1a29..34c2520ae 100644 --- a/src/accounts/spotify/SpotifyAccount.h +++ b/src/accounts/spotify/SpotifyAccount.h @@ -85,7 +85,7 @@ public: virtual InfoSystem::InfoPlugin* infoPlugin() { return 0; } virtual SipPlugin* sipPlugin() { return 0; } - void sendMessage( const QVariantMap& msg, QObject* receiver, const QString& slot ); + void sendMessage( const QVariantMap& msg, QObject* receiver = 0, const QString& slot = QString() ); void registerUpdaterForPlaylist( const QString& plId, SpotifyPlaylistUpdater* updater ); void unregisterUpdater( const QString& plid ); @@ -105,6 +105,7 @@ private: void stopPlaylistSync( SpotifyPlaylistInfo* playlist ); void fetchFullPlaylist( SpotifyPlaylistInfo* playlist ); + void setSyncForPlaylist( const QString& spotifyPlaylistId, bool sync ); QWeakPointer m_configWidget; QWeakPointer m_spotifyResolver; @@ -115,6 +116,7 @@ private: QList< SpotifyPlaylistInfo* > m_allSpotifyPlaylists; QHash< QString, SpotifyPlaylistUpdater* > m_updaters; + friend class ::SpotifyPlaylistUpdater; }; } diff --git a/src/accounts/spotify/SpotifyPlaylistUpdater.cpp b/src/accounts/spotify/SpotifyPlaylistUpdater.cpp index a30b64c69..675cb6f07 100644 --- a/src/accounts/spotify/SpotifyPlaylistUpdater.cpp +++ b/src/accounts/spotify/SpotifyPlaylistUpdater.cpp @@ -20,10 +20,15 @@ #include "accounts/AccountManager.h" #include "SpotifyAccount.h" +#include "utils/tomahawkutils.h" using namespace Tomahawk; using namespace Accounts; +#ifndef ENABLE_HEADLESS +QPixmap* SpotifyPlaylistUpdater::s_typePixmap = 0; +#endif + Tomahawk::PlaylistUpdaterInterface* SpotifyUpdaterFactory::create( const Tomahawk::playlist_ptr& pl, const QString &key ) { @@ -49,7 +54,7 @@ SpotifyUpdaterFactory::create( const Tomahawk::playlist_ptr& pl, const QString & // Register the updater with the account const QString spotifyId = TomahawkSettings::instance()->value( QString( "%1/spotifyId" ).arg( key ) ).toString(); const QString latestRev = TomahawkSettings::instance()->value( QString( "%1/latestrev" ).arg( key ) ).toString(); - const bool sync = TomahawkSettings::instance()->value( QString( "%1/sync" ).arg( key ) ).toBool(); + const bool sync = TomahawkSettings::instance()->value( QString( "%1/sync" ).arg( key ) ).toBool(); Q_ASSERT( !spotifyId.isEmpty() ); SpotifyPlaylistUpdater* updater = new SpotifyPlaylistUpdater( m_account.data(), latestRev, spotifyId, pl ); @@ -87,6 +92,17 @@ SpotifyPlaylistUpdater::~SpotifyPlaylistUpdater() { if ( !m_spotify.isNull() ) { + if ( m_sync ) + { + QVariantMap msg; + msg[ "_msgtype" ] = "removeFromSyncList"; + msg[ "playlistid" ] = m_spotifyId; + + m_spotify.data()->sendMessage( msg ); + + m_spotify.data()->setSyncForPlaylist( m_spotifyId, false ); + } + m_spotify.data()->unregisterUpdater( m_spotifyId ); } } @@ -117,10 +133,33 @@ SpotifyPlaylistUpdater::type() const } +#ifndef ENABLE_HEADLESS +QPixmap +SpotifyPlaylistUpdater::typeIcon() const +{ + if ( !s_typePixmap ) + { + QPixmap pm( RESPATH "images/spotify-logo.png" ); + s_typePixmap = new QPixmap( pm.scaled( 32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation ) ); + } + + if ( !m_sync ) + return QPixmap(); + + return *s_typePixmap; +} +#endif + + void SpotifyPlaylistUpdater::setSync( bool sync ) { + if ( m_sync == sync ) + return; + m_sync = sync; + + emit changed(); } diff --git a/src/accounts/spotify/SpotifyPlaylistUpdater.h b/src/accounts/spotify/SpotifyPlaylistUpdater.h index e41dbe5d9..aef09e8d9 100644 --- a/src/accounts/spotify/SpotifyPlaylistUpdater.h +++ b/src/accounts/spotify/SpotifyPlaylistUpdater.h @@ -20,6 +20,7 @@ #define SPOTIFYPLAYLISTUPDATER_H #include "playlist/PlaylistUpdaterInterface.h" + #include namespace Tomahawk { @@ -43,6 +44,8 @@ public: #ifndef ENABLE_HEADLESS virtual QWidget* configurationWidget() const { return 0; } + + virtual QPixmap typeIcon() const; #endif bool sync() const; @@ -78,6 +81,10 @@ private: bool m_blockUpdatesForNextRevision; bool m_sync; + +#ifndef ENABLE_HEADLESS + static QPixmap* s_typePixmap; +#endif }; diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp index 7da6bc4d5..fa72c9f20 100644 --- a/src/libtomahawk/playlist.cpp +++ b/src/libtomahawk/playlist.cpp @@ -255,7 +255,7 @@ Playlist::setTitle( const QString& title ) return; const QString oldTitle = m_title; - m_title = title; +// m_title = title; emit changed(); emit renamed( m_title, oldTitle ); @@ -282,6 +282,19 @@ Playlist::reportDeleted( const Tomahawk::playlist_ptr& self ) emit deleted( self ); } +void +Playlist::setUpdater( PlaylistUpdaterInterface* pluinterface ) +{ + if ( m_updater ) + disconnect( m_updater, SIGNAL( changed() ), this, SIGNAL( changed() ) ); + + m_updater = pluinterface; + + connect( m_updater, SIGNAL( changed() ), this, SIGNAL( changed() ), Qt::UniqueConnection ); + + emit changed(); +} + void Playlist::loadRevision( const QString& rev ) diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index 7e8bafbf5..67ae033a9 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -188,7 +188,7 @@ public: QList entriesFromQueries( const QList& queries, bool clearFirst = false ); - void setUpdater( PlaylistUpdaterInterface* pluinterface ) { m_updater = pluinterface; } + void setUpdater( PlaylistUpdaterInterface* pluinterface ); PlaylistUpdaterInterface* updater() const { return m_updater; } Tomahawk::playlistinterface_ptr playlistInterface(); diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.cpp b/src/libtomahawk/playlist/PlaylistUpdaterInterface.cpp index 34cc32673..a3a6728cb 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.cpp +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.cpp @@ -65,12 +65,12 @@ PlaylistUpdaterInterface::PlaylistUpdaterInterface( const playlist_ptr& pl ) m_playlist->setUpdater( this ); - QTimer::singleShot( 0, this, SLOT( doSave() ) ); + QTimer::singleShot( 0, this, SLOT( save() ) ); } void -PlaylistUpdaterInterface::doSave() +PlaylistUpdaterInterface::save() { TomahawkSettings* s = TomahawkSettings::instance(); const QString key = QString( "playlistupdaters/%1" ).arg( m_playlist->guid() ); diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index 3fb2ed2ac..06a052c3e 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -26,6 +26,10 @@ #include #include +#ifndef ENABLE_HEADLESS +#include +#endif + namespace Tomahawk { /** @@ -50,6 +54,10 @@ public: #ifndef ENABLE_HEADLESS // Small widget to show in playlist header that configures the updater virtual QWidget* configurationWidget() const = 0; + + // Small overlay over playlist icon in the sidebar to indicate that it has this updater type + // Should be around 16x16 or something + virtual QPixmap typeIcon() const { return QPixmap(); } #endif void remove(); @@ -61,11 +69,14 @@ public: static PlaylistUpdaterInterface* loadForPlaylist( const playlist_ptr& pl ); static void registerUpdaterFactory( PlaylistUpdaterFactory* f ); + +signals: + void changed(); + public slots: virtual void updateNow() {} -private slots: - void doSave(); + void save(); protected: virtual void saveToSettings( const QString& group ) const = 0; diff --git a/src/sourcetree/items/playlistitems.cpp b/src/sourcetree/items/playlistitems.cpp index 3f0cb4b2e..9305ec63d 100644 --- a/src/sourcetree/items/playlistitems.cpp +++ b/src/sourcetree/items/playlistitems.cpp @@ -20,6 +20,7 @@ #include "playlistitems.h" #include +#include #include "query.h" #include "viewmanager.h" @@ -44,12 +45,15 @@ PlaylistItem::PlaylistItem( SourcesModel* mdl, SourceTreeItem* parent, const pla connect( pl.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), SLOT( onPlaylistLoaded( Tomahawk::PlaylistRevision ) ), Qt::QueuedConnection ); connect( pl.data(), SIGNAL( changed() ), - SIGNAL( updated() ), Qt::QueuedConnection ); + SLOT( onUpdated() ), Qt::QueuedConnection ); m_icon = QIcon( RESPATH "images/playlist-icon.png" ); if( ViewManager::instance()->pageForPlaylist( pl ) ) model()->linkSourceItemToPage( this, ViewManager::instance()->pageForPlaylist( pl ) ); + + if ( m_playlist->updater() && !m_playlist->updater()->typeIcon().isNull() ) + createOverlay(); } @@ -244,10 +248,54 @@ PlaylistItem::parsedDroppedTracks( const QList< query_ptr >& tracks ) } +void +PlaylistItem::onUpdated() +{ + if ( m_playlist->updater() && !m_playlist->updater()->typeIcon().isNull() && + m_overlaidIcon.isNull() ) // create overlay + { + createOverlay(); + } + else if ( !m_playlist->updater() || m_playlist->updater()->typeIcon().isNull() && + !m_overlaidIcon.isNull() ) + { + // No longer an updater with an icon + m_overlaidIcon = QIcon(); + } + + emit updated(); +} + + +void +PlaylistItem::createOverlay() +{ + Q_ASSERT( !m_playlist.isNull() ); + Q_ASSERT( m_playlist->updater() ); + Q_ASSERT( !m_playlist->updater()->typeIcon().isNull() ); + + m_overlaidIcon = QIcon(); + + QPixmap base = m_icon.pixmap( 48, 48 ); + const QPixmap overlay = m_playlist->updater()->typeIcon(); + + QPainter p( &base ); + const int w = base.width() / 2; + const QRect overlayRect( base.rect().right() - w, base.rect().height() - w, w, w ); + p.drawPixmap( overlayRect, overlay ); + p.end(); + + m_overlaidIcon.addPixmap( base ); +} + + QIcon PlaylistItem::icon() const { - return m_icon; + if ( !m_overlaidIcon.isNull() ) + return m_overlaidIcon; + else + return m_icon; } diff --git a/src/sourcetree/items/playlistitems.h b/src/sourcetree/items/playlistitems.h index 860eeffe7..3360e00c1 100644 --- a/src/sourcetree/items/playlistitems.h +++ b/src/sourcetree/items/playlistitems.h @@ -54,10 +54,13 @@ private slots: void onPlaylistChanged(); void parsedDroppedTracks( const QList& tracks ); + void onUpdated(); private: + void createOverlay(); + bool m_loaded; Tomahawk::playlist_ptr m_playlist; - QIcon m_icon; + QIcon m_icon, m_overlaidIcon; }; Q_DECLARE_OPERATORS_FOR_FLAGS(PlaylistItem::DropTypes)