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:
parent
165276912f
commit
79d8b081d7
@ -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 );
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user