diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index f6211ca06..95c079e0c 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -220,12 +220,12 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result ) { if ( !m_currentTrack.isNull() ) { - disconnect( m_currentTrack->album().data(), SIGNAL( updated() ), this, SLOT( onAlbumCoverUpdated() ) ); + disconnect( m_currentTrack->toQuery().data(), SIGNAL( updated() ), this, SLOT( onCoverUpdated() ) ); disconnect( m_currentTrack->toQuery().data(), SIGNAL( socialActionsLoaded() ), this, SLOT( onSocialActionsLoaded() ) ); } m_currentTrack = result; - connect( m_currentTrack->album().data(), SIGNAL( updated() ), SLOT( onAlbumCoverUpdated() ) ); + connect( m_currentTrack->toQuery().data(), SIGNAL( updated() ), SLOT( onCoverUpdated() ) ); connect( m_currentTrack->toQuery().data(), SIGNAL( socialActionsLoaded() ), SLOT( onSocialActionsLoaded() ) ); ui->artistTrackLabel->setResult( result ); @@ -243,29 +243,29 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result ) ui->loveButton->setEnabled( true ); ui->loveButton->setVisible( true ); - setAlbumCover(); + setCover(); setSocialActions(); } void -AudioControls::onAlbumCoverUpdated() +AudioControls::onCoverUpdated() { - Album* album = qobject_cast< Album* >( sender() ); - if ( !album || album != m_currentTrack->album().data() ) + Query* query = qobject_cast< Query* >( sender() ); + if ( !query || query != m_currentTrack->toQuery().data() ) return; - setAlbumCover(); + setCover(); } void -AudioControls::setAlbumCover() +AudioControls::setCover() { - if ( !m_currentTrack->album()->cover( ui->coverImage->size() ).isNull() ) + if ( !m_currentTrack->toQuery()->cover( ui->coverImage->size() ).isNull() ) { QPixmap cover; - cover = m_currentTrack->album()->cover( ui->coverImage->size() ); + cover = m_currentTrack->toQuery()->cover( ui->coverImage->size() ); ui->coverImage->setPixmap( cover ); } else @@ -277,16 +277,10 @@ void AudioControls::onSocialActionsLoaded() { Query* query = qobject_cast< Query* >( sender() ); - if ( !query ) + if ( !query || query != m_currentTrack->toQuery().data() ) return; - query_ptr currentQuery = m_currentTrack->toQuery(); - if ( query->artist() == currentQuery->artist() && - query->track() == currentQuery->track() && - query->album() == currentQuery->album() ) - { - setSocialActions(); - } + setSocialActions(); } diff --git a/src/audiocontrols.h b/src/audiocontrols.h index 651f1dbf8..593e383ee 100644 --- a/src/audiocontrols.h +++ b/src/audiocontrols.h @@ -79,14 +79,13 @@ private slots: void onTrackClicked(); void onLoveButtonClicked( bool ); - void onAlbumCoverUpdated(); - void droppedTracks( QList ); + void onCoverUpdated(); void onSocialActionsLoaded(); private: - void setAlbumCover(); + void setCover(); void setSocialActions(); Ui::AudioControls *ui; diff --git a/src/libtomahawk/album.cpp b/src/libtomahawk/album.cpp index fbf362427..10b7b32e5 100644 --- a/src/libtomahawk/album.cpp +++ b/src/libtomahawk/album.cpp @@ -80,6 +80,10 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); + + connect( Tomahawk::InfoSystem::InfoSystem::instance(), + SIGNAL( finished( QString ) ), + SLOT( infoSystemFinished( QString ) ) ); } @@ -109,6 +113,7 @@ Album::cover( const QSize& size, bool forceLoad ) const { if ( !forceLoad ) return QPixmap(); + m_uuid = uuid(); Tomahawk::InfoSystem::InfoStringHash trackInfo; @@ -160,7 +165,6 @@ Album::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVaria return; } - m_infoLoaded = true; if ( !output.isNull() && output.isValid() ) { QVariantMap returnedData = output.value< QVariantMap >(); @@ -170,7 +174,18 @@ Album::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVaria m_coverBuffer = ba; } } +} + +void +Album::infoSystemFinished( QString target ) +{ + Q_UNUSED( target ); + + if ( target != m_uuid ) + return; + + m_infoLoaded = true; emit updated(); } diff --git a/src/libtomahawk/album.h b/src/libtomahawk/album.h index 741c7d65a..1e886c47c 100644 --- a/src/libtomahawk/album.h +++ b/src/libtomahawk/album.h @@ -64,6 +64,7 @@ private slots: void onTracksAdded( const QList& tracks ); void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); + void infoSystemFinished( QString target ); private: Q_DISABLE_COPY( Album ) diff --git a/src/libtomahawk/artist.cpp b/src/libtomahawk/artist.cpp index cdefc2505..968aff242 100644 --- a/src/libtomahawk/artist.cpp +++ b/src/libtomahawk/artist.cpp @@ -81,6 +81,10 @@ Artist::Artist( unsigned int id, const QString& name ) connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); + + connect( Tomahawk::InfoSystem::InfoSystem::instance(), + SIGNAL( finished( QString ) ), + SLOT( infoSystemFinished( QString ) ) ); } @@ -152,7 +156,6 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari return; } - m_infoLoaded = true; if ( !output.isNull() && output.isValid() ) { QVariantMap returnedData = output.value< QVariantMap >(); @@ -162,7 +165,18 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari m_coverBuffer = ba; } } +} + +void +Artist::infoSystemFinished( QString target ) +{ + Q_UNUSED( target ); + + if ( target != m_uuid ) + return; + + m_infoLoaded = true; emit updated(); } diff --git a/src/libtomahawk/artist.h b/src/libtomahawk/artist.h index 05efe48eb..a9f9a5b7c 100644 --- a/src/libtomahawk/artist.h +++ b/src/libtomahawk/artist.h @@ -63,6 +63,7 @@ private slots: void onTracksAdded( const QList& tracks ); void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); + void infoSystemFinished( QString target ); private: Q_DISABLE_COPY( Artist ) diff --git a/src/libtomahawk/playlist/playlistitemdelegate.cpp b/src/libtomahawk/playlist/playlistitemdelegate.cpp index ba932a8c1..d0520cc20 100644 --- a/src/libtomahawk/playlist/playlistitemdelegate.cpp +++ b/src/libtomahawk/playlist/playlistitemdelegate.cpp @@ -36,9 +36,6 @@ #include "utils/tomahawkutilsgui.h" #include "utils/logger.h" -#define PLAYING_ICON QString( RESPATH "images/now-playing-speaker.png" ) -#define ARROW_ICON QString( RESPATH "images/info.png" ) - using namespace Tomahawk; @@ -47,16 +44,11 @@ PlaylistItemDelegate::PlaylistItemDelegate( TrackView* parent, TrackProxyModel* , m_view( parent ) , m_model( proxy ) { - m_nowPlayingIcon = QPixmap( PLAYING_ICON ); - m_arrowIcon = QPixmap( ARROW_ICON ); - m_topOption = QTextOption( Qt::AlignTop ); m_topOption.setWrapMode( QTextOption::NoWrap ); m_bottomOption = QTextOption( Qt::AlignBottom ); m_bottomOption.setWrapMode( QTextOption::NoWrap ); - - m_defaultAvatar = TomahawkUtils::createAvatarFrame( QPixmap( RESPATH "images/user-avatar.png" ) ); } @@ -140,6 +132,7 @@ PlaylistItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& opti break; case TrackModel::ShortWithAvatars: paintShort( painter, option, index, true ); + break; } } @@ -188,16 +181,8 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& lowerText = QString( tr( "played %1 by you" ) ).arg( playtime ); else lowerText = QString( tr( "played %1 by %2" ) ).arg( playtime ).arg( source->friendlyName() ); - - if ( useAvatars ) - pixmap = source->avatar( Source::FancyStyle ); } - if ( pixmap.isNull() && !useAvatars ) - pixmap = QPixmap( RESPATH "images/track-placeholder.png" ); - else if ( pixmap.isNull() && useAvatars ) - pixmap = m_defaultAvatar; - painter->save(); { QRect r = opt.rect.adjusted( 3, 6, 0, -6 ); @@ -205,27 +190,31 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& // Paint Now Playing Speaker Icon if ( item->isPlaying() ) { - r.adjust( 0, 0, 0, 0 ); - QRect npr = r.adjusted( 3, r.height() / 2 - m_nowPlayingIcon.height() / 2, 18 - r.width(), -r.height() / 2 + m_nowPlayingIcon.height() / 2 ); - painter->drawPixmap( npr, m_nowPlayingIcon ); + QPixmap nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker ); + QRect npr = r.adjusted( 3, r.height() / 2 - nowPlayingIcon.height() / 2, 18 - r.width(), -r.height() / 2 + nowPlayingIcon.height() / 2 ); + nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker, TomahawkUtils::Original, npr.size() ); + painter->drawPixmap( npr, nowPlayingIcon ); r.adjust( 22, 0, 0, 0 ); } painter->setPen( opt.palette.text().color() ); QRect ir = r.adjusted( 4, 0, -option.rect.width() + option.rect.height() - 8 + r.left(), 0 ); - - QPixmap scover; - if ( m_cache.contains( pixmap.cacheKey() ) ) - { - scover = m_cache.value( pixmap.cacheKey() ); - } + + if ( useAvatars ) + pixmap = source->avatar( Source::FancyStyle, ir.size() ); else + pixmap = item->query()->cover( ir.size() ); + + if ( pixmap.isNull() ) { - scover = pixmap.scaled( ir.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ); - m_cache.insert( pixmap.cacheKey(), scover ); + if ( !useAvatars ) + pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::ScaledCover, ir.size() ); + else + pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultSourceAvatar, TomahawkUtils::AvatarInFrame, ir.size() ); } - painter->drawPixmap( ir, scover ); + + painter->drawPixmap( ir, pixmap ); QFont boldFont = opt.font; boldFont.setBold( true ); @@ -263,9 +252,8 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt opt.rect.setWidth( opt.rect.width() - 16 ); QRect arrowRect( opt.rect.x() + opt.rect.width(), opt.rect.y() + 1, opt.rect.height() - 2, opt.rect.height() - 2 ); - if ( m_arrowIcon.height() != arrowRect.height() ) - m_arrowIcon = m_arrowIcon.scaled( arrowRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ); - painter->drawPixmap( arrowRect, m_arrowIcon ); + QPixmap infoIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::InfoIcon, TomahawkUtils::Original, arrowRect.size() ); + painter->drawPixmap( arrowRect, infoIcon ); } painter->save(); @@ -300,7 +288,7 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt if ( m_view->header()->visualIndex( index.column() ) == 0 ) { r.adjust( 0, 0, 0, -3 ); - painter->drawPixmap( r.adjusted( 3, 1, 18 - r.width(), 1 ), m_nowPlayingIcon ); + painter->drawPixmap( r.adjusted( 3, 1, 18 - r.width(), 1 ), TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker ) ); r.adjust( 25, 0, 0, 3 ); } diff --git a/src/libtomahawk/playlist/playlistitemdelegate.h b/src/libtomahawk/playlist/playlistitemdelegate.h index 905a9fe3a..00fc2c5d4 100644 --- a/src/libtomahawk/playlist/playlistitemdelegate.h +++ b/src/libtomahawk/playlist/playlistitemdelegate.h @@ -38,9 +38,6 @@ public: void updateRowSize( const QModelIndex& index ); -public slots: - void setRemovalProgress( unsigned int progress ) { m_removalProgress = progress; } - protected: void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; @@ -52,12 +49,6 @@ private: void paintDetailed( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; void paintShort( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, bool useAvatars = false ) const; - unsigned int m_removalProgress; - - mutable QHash< qint64, QPixmap > m_cache; - QPixmap m_nowPlayingIcon, m_defaultAvatar; - mutable QPixmap m_arrowIcon; - QTextOption m_topOption; QTextOption m_bottomOption; diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index 113ad7b8c..fb5285216 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -584,6 +584,35 @@ Query::setLoved( bool loved ) } +#ifndef ENABLE_HEADLESS +QPixmap +Query::cover( const QSize& size, bool forceLoad ) const +{ + if ( !forceLoad ) + return QPixmap(); + + if ( m_albumPtr.isNull() ) + { + m_artistPtr = Artist::get( artist(), false ); + m_albumPtr = Album::get( m_artistPtr, album(), false ); + connect( m_artistPtr.data(), SIGNAL( updated() ), SIGNAL( updated() ), Qt::UniqueConnection ); + connect( m_albumPtr.data(), SIGNAL( updated() ), SIGNAL( updated() ), Qt::UniqueConnection ); + } + + m_albumPtr->cover( size ); + if ( m_albumPtr->infoLoaded() ) + { + if ( !m_albumPtr->cover( size ).isNull() ) + return m_albumPtr->cover( size ); + + return m_artistPtr->cover( size ); + } + + return QPixmap(); +} +#endif + + int Query::levenshtein( const QString& source, const QString& target ) { diff --git a/src/libtomahawk/query.h b/src/libtomahawk/query.h index 8dfa3fd40..8f4b64194 100644 --- a/src/libtomahawk/query.h +++ b/src/libtomahawk/query.h @@ -103,6 +103,10 @@ public: unsigned int albumpos() const { return m_albumpos; } unsigned int discnumber() const { return m_discnumber; } +#ifndef ENABLE_HEADLESS + QPixmap cover( const QSize& size, bool forceLoad = true ) const; +#endif + void setResolveFinished( bool resolved ) { m_resolveFinished = resolved; } void setPlayedBy( const Tomahawk::source_ptr& source, unsigned int playtime ); @@ -130,6 +134,7 @@ signals: // emitted when social actions are loaded void socialActionsLoaded(); + void updated(); public slots: /// (indirectly) called by resolver plugins when results are found @@ -144,7 +149,7 @@ public slots: // resolve if not solved() void onResolverAdded(); void onResolverRemoved(); - + private slots: void onResultStatusChanged(); void refreshResults(); @@ -190,6 +195,9 @@ private: unsigned int m_discnumber; QString m_resultHint; + mutable Tomahawk::artist_ptr m_artistPtr; + mutable Tomahawk::album_ptr m_albumPtr; + QPair< Tomahawk::source_ptr, unsigned int > m_playedBy; QList< QWeakPointer< Tomahawk::Resolver > > m_resolvers; diff --git a/src/libtomahawk/source.cpp b/src/libtomahawk/source.cpp index ebf795a08..669685edc 100644 --- a/src/libtomahawk/source.cpp +++ b/src/libtomahawk/source.cpp @@ -128,17 +128,31 @@ Source::setAvatar( const QPixmap& avatar ) QPixmap -Source::avatar( AvatarStyle style ) const +Source::avatar( AvatarStyle style, const QSize& size ) const { if ( style == FancyStyle && m_avatar && !m_fancyAvatar ) m_fancyAvatar = new QPixmap( TomahawkUtils::createAvatarFrame( QPixmap( *m_avatar ) ) ); + QPixmap pixmap; if ( style == Original && m_avatar ) - return QPixmap( *m_avatar ); + pixmap = *m_avatar; else if ( style == FancyStyle && m_fancyAvatar ) - return QPixmap( *m_fancyAvatar ); - else - return QPixmap(); + pixmap = *m_fancyAvatar; + + if ( !pixmap.isNull() && !size.isEmpty() ) + { + if ( m_coverCache.contains( size.width() ) ) + { + return m_coverCache.value( size.width() ); + } + + QPixmap scaledCover; + scaledCover = pixmap.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_coverCache.insert( size.width(), scaledCover ); + return scaledCover; + } + + return pixmap; } #endif diff --git a/src/libtomahawk/source.h b/src/libtomahawk/source.h index 396094c0e..14e093822 100644 --- a/src/libtomahawk/source.h +++ b/src/libtomahawk/source.h @@ -65,7 +65,7 @@ public: #ifndef ENABLE_HEADLESS void setAvatar( const QPixmap& avatar ); - QPixmap avatar( AvatarStyle style = Original ) const; + QPixmap avatar( AvatarStyle style = Original, const QSize& size = QSize() ) const; #endif collection_ptr collection() const; @@ -158,6 +158,7 @@ private: QPixmap* m_avatar; mutable QPixmap* m_fancyAvatar; + mutable QHash< int, QPixmap > m_coverCache; Tomahawk::playlistinterface_ptr m_playlistInterface; }; diff --git a/src/libtomahawk/utils/tomahawkutils.h b/src/libtomahawk/utils/tomahawkutils.h index c5eb57ad4..3c89de986 100644 --- a/src/libtomahawk/utils/tomahawkutils.h +++ b/src/libtomahawk/utils/tomahawkutils.h @@ -46,12 +46,17 @@ namespace TomahawkUtils enum ImageType { DefaultAlbumCover, - DefaultArtistImage + DefaultArtistImage, + DefaultTrackImage, + DefaultSourceAvatar, + NowPlayingSpeaker, + InfoIcon }; enum ImageMode { - NoDefaultCover, + Original, CoverInCase, + AvatarInFrame, ScaledCover }; diff --git a/src/libtomahawk/utils/tomahawkutilsgui.cpp b/src/libtomahawk/utils/tomahawkutilsgui.cpp index 168e5915c..583b7de6c 100644 --- a/src/libtomahawk/utils/tomahawkutilsgui.cpp +++ b/src/libtomahawk/utils/tomahawkutilsgui.cpp @@ -341,6 +341,24 @@ defaultPixmap( ImageType type, ImageMode mode, const QSize& size ) pixmap = QPixmap( RESPATH "images/no-artist-image-placeholder.png" ); break; + case DefaultTrackImage: + pixmap = QPixmap( RESPATH "images/track-placeholder.png" ); + break; + + case DefaultSourceAvatar: + if ( mode == AvatarInFrame ) + pixmap = TomahawkUtils::createAvatarFrame( QPixmap( RESPATH "images/user-avatar.png" ) ); + else + pixmap = QPixmap( RESPATH "images/user-avatar.png" ); + break; + + case NowPlayingSpeaker: + pixmap = QPixmap( RESPATH "images/now-playing-speaker.png" ); + break; + + case InfoIcon: + pixmap = QPixmap( RESPATH "images/info.png" ); + default: break; } diff --git a/src/libtomahawk/utils/tomahawkutilsgui.h b/src/libtomahawk/utils/tomahawkutilsgui.h index 1790aeb9b..86e842014 100644 --- a/src/libtomahawk/utils/tomahawkutilsgui.h +++ b/src/libtomahawk/utils/tomahawkutilsgui.h @@ -50,7 +50,7 @@ namespace TomahawkUtils DLLEXPORT int headerHeight(); DLLEXPORT void setHeaderHeight( int height ); - DLLEXPORT QPixmap defaultPixmap( ImageType type, ImageMode mode, const QSize& size = QSize( 0, 0 ) ); + DLLEXPORT QPixmap defaultPixmap( ImageType type, ImageMode mode = TomahawkUtils::Original, const QSize& size = QSize( 0, 0 ) ); }