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

* Speed up cover loading in TreeView.

This commit is contained in:
Christian Muehlhaeuser 2012-02-23 03:21:21 +01:00
parent 165276912f
commit 79d8b081d7
17 changed files with 165 additions and 56 deletions

View File

@ -264,11 +264,11 @@ AudioControls::onAlbumCoverUpdated()
void
AudioControls::setAlbumCover()
{
if ( !m_currentTrack->album()->cover().isNull() )
if ( !m_currentTrack->album()->cover( ui->coverImage->size() ).isNull() )
{
QPixmap cover;
cover.loadFromData( m_currentTrack->album()->cover() );
ui->coverImage->setPixmap( cover.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
cover = m_currentTrack->album()->cover( ui->coverImage->size() );
ui->coverImage->setPixmap( cover );
}
else
ui->coverImage->setPixmap( m_defaultCover );

View File

@ -32,6 +32,7 @@ using namespace Tomahawk;
Album::~Album()
{
delete m_cover;
}
@ -71,6 +72,7 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr&
, m_id( id )
, m_name( name )
, m_artist( artist )
, m_cover( 0 )
, m_infoLoaded( false )
{
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
@ -97,11 +99,14 @@ Album::artist() const
}
QByteArray
Album::cover() const
#ifndef ENABLE_HEADLESS
QPixmap
Album::cover( const QSize& size, bool forceLoad ) const
{
if ( !m_infoLoaded )
{
if ( !forceLoad )
return QPixmap();
m_uuid = uuid();
Tomahawk::InfoSystem::InfoStringHash trackInfo;
@ -117,8 +122,31 @@ Album::cover() const
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
return m_cover;
if ( !m_cover )
m_cover = new QPixmap();
if ( m_cover->isNull() && !m_coverBuffer.isEmpty() )
{
m_cover->loadFromData( m_coverBuffer );
}
if ( !m_cover->isNull() && !size.isEmpty() )
{
if ( m_coverCache.contains( size.width() ) )
{
return m_coverCache.value( size.width() );
}
else
{
QPixmap scaledCover;
scaledCover = m_cover->scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_coverCache.insert( size.width(), scaledCover );
}
}
return *m_cover;
}
#endif
void
@ -137,7 +165,7 @@ Album::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVaria
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
m_cover = ba;
m_coverBuffer = ba;
}
}

View File

@ -19,8 +19,13 @@
#ifndef TOMAHAWKALBUM_H
#define TOMAHAWKALBUM_H
#include "config.h"
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#ifndef ENABLE_HEADLESS
#include <QtGui/QPixmap>
#endif
#include "typedefs.h"
#include "playlistinterface.h"
@ -44,7 +49,9 @@ public:
unsigned int id() const { return m_id; }
QString name() const { return m_name; }
artist_ptr artist() const;
QByteArray cover() const;
#ifndef ENABLE_HEADLESS
QPixmap cover( const QSize& size, bool forceLoad = true ) const;
#endif
bool infoLoaded() const { return m_infoLoaded; }
Tomahawk::playlistinterface_ptr playlistInterface();
@ -64,10 +71,13 @@ private:
unsigned int m_id;
QString m_name;
artist_ptr m_artist;
QByteArray m_cover;
QByteArray m_coverBuffer;
mutable QPixmap* m_cover;
bool m_infoLoaded;
mutable QString m_uuid;
mutable QHash< int, QPixmap > m_coverCache;
Tomahawk::playlistinterface_ptr m_playlistInterface;
};

View File

@ -31,6 +31,7 @@ using namespace Tomahawk;
Artist::~Artist()
{
delete m_cover;
}
@ -69,6 +70,7 @@ Artist::Artist( unsigned int id, const QString& name )
: QObject()
, m_id( id )
, m_name( name )
, m_cover( 0 )
, m_infoLoaded( false )
{
m_sortname = DatabaseImpl::sortname( name, true );
@ -89,11 +91,14 @@ Artist::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
}
QByteArray
Artist::cover() const
#ifndef ENABLE_HEADLESS
QPixmap
Artist::cover( const QSize& size, bool forceLoad ) const
{
if ( !m_infoLoaded )
{
if ( !forceLoad )
return QPixmap();
m_uuid = uuid();
Tomahawk::InfoSystem::InfoStringHash trackInfo;
@ -108,8 +113,31 @@ Artist::cover() const
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
return m_cover;
if ( !m_cover )
m_cover = new QPixmap();
if ( m_cover->isNull() && !m_coverBuffer.isEmpty() )
{
m_cover->loadFromData( m_coverBuffer );
}
if ( !m_cover->isNull() && !size.isEmpty() )
{
if ( m_coverCache.contains( size.width() ) )
{
return m_coverCache.value( size.width() );
}
else
{
QPixmap scaledCover;
scaledCover = m_cover->scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_coverCache.insert( size.width(), scaledCover );
}
}
return *m_cover;
}
#endif
void
@ -128,7 +156,7 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
m_cover = ba;
m_coverBuffer = ba;
}
}

View File

@ -19,8 +19,13 @@
#ifndef TOMAHAWKARTIST_H
#define TOMAHAWKARTIST_H
#include "config.h"
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#ifndef ENABLE_HEADLESS
#include <QtGui/QPixmap>
#endif
#include "typedefs.h"
#include "dllmacro.h"
@ -43,7 +48,9 @@ public:
unsigned int id() const { return m_id; }
QString name() const { return m_name; }
QString sortname() const { return m_sortname; }
QByteArray cover() const;
#ifndef ENABLE_HEADLESS
QPixmap cover( const QSize& size, bool forceLoad = true ) const;
#endif
bool infoLoaded() const { return m_infoLoaded; }
Tomahawk::playlistinterface_ptr playlistInterface();
@ -63,10 +70,13 @@ private:
unsigned int m_id;
QString m_name;
QString m_sortname;
QByteArray m_cover;
QByteArray m_coverBuffer;
mutable QPixmap* m_cover;
bool m_infoLoaded;
mutable QString m_uuid;
mutable QHash< int, QPixmap > m_coverCache;
Tomahawk::playlistinterface_ptr m_playlistInterface;
};

View File

@ -333,7 +333,7 @@ AudioEngine::sendNowPlayingNotification()
else
{
connect( m_currentTrack->album().data(), SIGNAL( updated() ), SLOT( onNowPlayingInfoReady() ), Qt::UniqueConnection );
m_currentTrack->album()->cover();
m_currentTrack->album()->cover( QSize( 0, 0 ) );
}
}
@ -358,7 +358,7 @@ AudioEngine::onNowPlayingInfoReady()
if ( !m_currentTrack->album().isNull() )
{
QImage cover;
cover.loadFromData( m_currentTrack->album()->cover() );
cover = m_currentTrack->album()->cover( QSize( 0, 0 ) ).toImage();
playInfo["image"] = QVariant( cover );
}

View File

@ -89,21 +89,20 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
painter->drawLine( shadowRect.bottomLeft() + QPoint( 0, 4 ), shadowRect.bottomRight() + QPoint( 0, 4 ) );
}
QRect r = option.rect.adjusted( 6, 5, -6, -41 );
QPixmap cover;
if ( !item->album().isNull() )
{
cover.loadFromData( item->album()->cover() );
cover = item->album()->cover( r.size() );
}
else if ( !item->artist().isNull() )
{
cover.loadFromData( item->artist()->cover() );
cover = item->artist()->cover( r.size() );
}
if ( cover.isNull() )
cover = m_defaultCover;
QRect r = option.rect.adjusted( 6, 5, -6, -41 );
if ( option.state & QStyle::State_Selected )
{
#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
@ -123,17 +122,7 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
#endif
}
QPixmap scover;
if ( m_cache.contains( cover.cacheKey() ) )
{
scover = m_cache.value( cover.cacheKey() );
}
else
{
scover = cover.scaled( r.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_cache.insert( cover.cacheKey(), scover );
}
painter->drawPixmap( r, scover );
painter->drawPixmap( r, cover );
painter->setPen( opt.palette.color( QPalette::Text ) );
QTextOption to;

View File

@ -49,7 +49,6 @@ private:
QAbstractItemView* m_view;
AlbumProxyModel* m_model;
mutable QHash< qint64, QPixmap > m_cache;
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
QPersistentModelIndex m_hoveringOver;

View File

@ -80,6 +80,11 @@ ArtistView::ArtistView( QWidget* parent )
setFont( f );
#endif
m_timer.setInterval( SCROLL_TIMEOUT );
connect( verticalScrollBar(), SIGNAL( rangeChanged( int, int ) ), SLOT( onViewChanged() ) );
connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), SLOT( onViewChanged() ) );
connect( &m_timer, SIGNAL( timeout() ), SLOT( onScrollTimeout() ) );
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
connect( m_contextMenu, SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) );
@ -129,6 +134,7 @@ ArtistView::setTreeModel( TreeModel* model )
connect( m_model, SIGNAL( itemCountChanged( unsigned int ) ), SLOT( onItemCountChanged( unsigned int ) ) );
connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
connect( m_proxyModel, SIGNAL( rowsInserted( QModelIndex, int, int ) ), SLOT( onViewChanged() ) );
guid(); // this will set the guid on the header
@ -145,6 +151,43 @@ ArtistView::setTreeModel( TreeModel* model )
}
void
ArtistView::onViewChanged()
{
if ( m_timer.isActive() )
m_timer.stop();
m_timer.start();
}
void
ArtistView::onScrollTimeout()
{
if ( m_timer.isActive() )
m_timer.stop();
QModelIndex left = indexAt( viewport()->rect().topLeft() );
while ( left.isValid() && left.parent().isValid() )
left = left.parent();
QModelIndex right = indexAt( viewport()->rect().bottomLeft() );
while ( right.isValid() && right.parent().isValid() )
right = right.parent();
int max = m_proxyModel->playlistInterface()->trackCount();
if ( right.isValid() )
max = right.row() + 1;
if ( !max )
return;
for ( int i = left.row(); i < max; i++ )
{
m_model->getCover( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) );
}
}
void
ArtistView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
{

View File

@ -95,6 +95,8 @@ private slots:
void onItemCountChanged( unsigned int items );
void onFilterChanged( const QString& filter );
void onFilteringStarted();
void onViewChanged();
void onScrollTimeout();
void onCustomContextMenu( const QPoint& pos );
void onMenuTriggered( int action );
@ -113,6 +115,7 @@ private:
Tomahawk::ContextMenu* m_contextMenu;
bool m_showModes;
QTimer m_timer;
mutable QString m_guid;
};

View File

@ -155,14 +155,13 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
QPixmap cover;
if ( !item->album().isNull() )
{
cover.loadFromData( item->album()->cover() );
cover = item->album()->cover( r.size(), false );
}
else if ( !item->artist().isNull() )
{
cover.loadFromData( item->artist()->cover() );
cover = item->artist()->cover( r.size(), false );
}
QPixmap scover;
if ( cover.isNull() )
{
if ( !item->artist().isNull() )
@ -171,16 +170,7 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
cover = m_defaultAlbumCover;
}
if ( m_cache.contains( cover.cacheKey() ) )
{
scover = m_cache.value( cover.cacheKey() );
}
else
{
scover = cover.scaled( r.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_cache.insert( cover.cacheKey(), scover );
}
painter->drawPixmap( r, scover );
painter->drawPixmap( r, cover );
QTextOption to;
to.setAlignment( Qt::AlignVCenter );

View File

@ -43,8 +43,6 @@ private:
ArtistView* m_view;
TreeProxyModel* m_model;
mutable QHash< qint64, QPixmap > m_cache;
QPixmap m_nowPlayingIcon;
QPixmap m_defaultAlbumCover;
QPixmap m_defaultArtistImage;

View File

@ -87,6 +87,18 @@ TreeModel::collection() const
}
void
TreeModel::getCover( const QModelIndex& index )
{
TreeModelItem* item = itemFromIndex( index );
if ( !item->artist().isNull() && !item->artist()->infoLoaded() )
item->artist()->cover( QSize( 0, 0 ) );
else if ( !item->album().isNull() && !item->album()->infoLoaded() )
item->album()->cover( QSize( 0, 0 ) );
}
void
TreeModel::setCurrentItem( const QModelIndex& index )
{

View File

@ -98,6 +98,8 @@ public:
void addAlbums( const Tomahawk::artist_ptr& artist, const QModelIndex& parent, bool autoRefetch = false );
void addTracks( const Tomahawk::album_ptr& album, const QModelIndex& parent, bool autoRefetch = false );
void getCover( const QModelIndex& index );
ColumnStyle columnStyle() const { return m_columnStyle; }
void setColumnStyle( ColumnStyle style );

View File

@ -243,10 +243,10 @@ AlbumInfoWidget::loadAlbums( bool autoRefetch )
void
AlbumInfoWidget::onAlbumCoverUpdated()
{
if ( m_album->cover().isNull() )
if ( m_album->cover( QSize( 0, 0 ) ).isNull() )
return;
m_pixmap.loadFromData( m_album->cover() );
m_pixmap = m_album->cover( QSize( 0, 0 ) );
emit pixmapChanged( m_pixmap );
}

View File

@ -289,10 +289,10 @@ ArtistInfoWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestD
void
ArtistInfoWidget::onArtistImageUpdated()
{
if ( m_artist->cover().isNull() )
if ( m_artist->cover( QSize( 0, 0 ) ).isNull() )
return;
m_pixmap.loadFromData( m_artist->cover() );
m_pixmap = m_artist->cover( QSize( 0, 0 ) );
emit pixmapChanged( m_pixmap );
}

View File

@ -543,10 +543,7 @@ TomahawkApp::spotifyApiCheckFinished()
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
Q_ASSERT( reply );
if ( reply->error() )
DropJob::setCanParseSpotifyPlaylists( false );
else
DropJob::setCanParseSpotifyPlaylists( true );
DropJob::setCanParseSpotifyPlaylists( !reply->error() );
#endif
}