1
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
3
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
4
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
6
* Tomahawk is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* Tomahawk is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
23
#include "AlbumPlaylistInterface.h"
24
#include "database/Database.h"
25
#include "database/DatabaseImpl.h"
26
#include "database/IdThreadWorker.h"
30
#include "utils/TomahawkUtilsGui.h"
31
#include "utils/Logger.h"
33
#include <QReadWriteLock>
35
using namespace Tomahawk;
37
QHash< QString, album_ptr > Album::s_albumsByName = QHash< QString, album_ptr >();
38
QHash< unsigned int, album_ptr > Album::s_albumsById = QHash< unsigned int, album_ptr >();
40
static QMutex s_nameCacheMutex;
41
static QMutex s_idCacheMutex;
42
static QReadWriteLock s_idMutex;
48
#ifndef ENABLE_HEADLESS
54
albumCacheKey( const Tomahawk::artist_ptr& artist, const QString& albumName )
56
return QString( "%1\t\t%2" ).arg( artist->name().toLower() ).arg( albumName.toLower() );
61
Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCreate )
63
if ( !Database::instance() || !Database::instance()->impl() )
66
QMutexLocker l( &s_nameCacheMutex );
68
const QString key = albumCacheKey( artist, name );
69
if ( s_albumsByName.contains( key ) )
71
return s_albumsByName.value( key );
74
album_ptr album = album_ptr( new Album( name, artist ) );
75
album->setWeakRef( album.toWeakRef() );
76
album->loadId( autoCreate );
77
s_albumsByName.insert( key, album );
84
Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist )
86
static QHash< unsigned int, album_ptr > s_albums;
87
static QMutex s_mutex;
89
QMutexLocker lock( &s_idCacheMutex );
91
const QString key = albumCacheKey( artist, name );
92
if ( s_albumsByName.contains( key ) )
94
return s_albumsByName.value( key );
96
if ( s_albumsById.contains( id ) )
98
return s_albumsById.value( id );
101
album_ptr a = album_ptr( new Album( id, name, artist ), &QObject::deleteLater );
102
a->setWeakRef( a.toWeakRef() );
103
s_albumsByName.insert( key, a );
107
s_albumsById.insert( id, a );
114
Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist )
116
, m_waitingForId( false )
120
, m_coverLoaded( false )
121
, m_coverLoading( false )
122
#ifndef ENABLE_HEADLESS
126
m_sortname = DatabaseImpl::sortname( name );
130
Album::Album( const QString& name, const Tomahawk::artist_ptr& artist )
132
, m_waitingForId( true )
135
, m_coverLoaded( false )
136
, m_coverLoading( false )
137
#ifndef ENABLE_HEADLESS
141
m_sortname = DatabaseImpl::sortname( name );
145
Album::onTracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection )
147
emit tracksAdded( playlistInterface( mode, collection )->tracks(), mode, collection );
152
Album::artist() const
159
Album::loadId( bool autoCreate )
161
Q_ASSERT( m_waitingForId );
162
IdThreadWorker::getAlbumId( m_ownRef.toStrongRef(), autoCreate );
167
Album::setIdFuture( QFuture<unsigned int> future )
176
s_idMutex.lockForRead();
177
const bool waiting = m_waitingForId;
178
unsigned int finalId = m_id;
183
finalId = m_idFuture.result();
185
s_idMutex.lockForWrite();
187
m_waitingForId = false;
190
s_albumsById[ m_id ] = m_ownRef.toStrongRef();
199
#ifndef ENABLE_HEADLESS
201
Album::cover( const QSize& size, bool forceLoad ) const
203
if ( name().isEmpty() )
205
m_coverLoaded = true;
209
if ( !m_coverLoaded && !m_coverLoading )
214
Tomahawk::InfoSystem::InfoStringHash trackInfo;
215
trackInfo["artist"] = artist()->name();
216
trackInfo["album"] = name();
218
Tomahawk::InfoSystem::InfoRequestData requestData;
219
requestData.caller = infoid();
220
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
221
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
222
requestData.customData = QVariantMap();
224
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
225
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
226
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
228
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
229
SIGNAL( finished( QString ) ),
230
SLOT( infoSystemFinished( QString ) ) );
232
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
234
m_coverLoading = true;
237
if ( !m_cover && !m_coverBuffer.isEmpty() )
240
cover.loadFromData( m_coverBuffer );
241
m_coverBuffer.clear();
243
m_cover = new QPixmap( TomahawkUtils::squareCenterPixmap( cover ) );
246
if ( m_cover && !m_cover->isNull() && !size.isEmpty() )
248
if ( m_coverCache.contains( size.width() ) )
250
return m_coverCache.value( size.width() );
254
scaledCover = m_cover->scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
255
m_coverCache.insert( size.width(), scaledCover );
268
Album::infoSystemInfo( const Tomahawk::InfoSystem::InfoRequestData& requestData, const QVariant& output )
270
if ( requestData.caller != infoid() ||
271
requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
276
if ( output.isNull() )
278
m_coverLoaded = true;
280
else if ( output.isValid() )
282
QVariantMap returnedData = output.value< QVariantMap >();
283
const QByteArray ba = returnedData["imgbytes"].toByteArray();
289
m_coverLoaded = true;
296
Album::infoSystemFinished( const QString& target )
298
if ( target != infoid() )
301
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
302
this, SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
304
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ),
305
this, SLOT( infoSystemFinished( QString ) ) );
307
m_coverLoading = false;
312
Tomahawk::playlistinterface_ptr
313
Album::playlistInterface( ModelMode mode, const Tomahawk::collection_ptr& collection )
315
playlistinterface_ptr pli = m_playlistInterface[ mode ][ collection ];
319
pli = Tomahawk::playlistinterface_ptr( new Tomahawk::AlbumPlaylistInterface( this, mode, collection ) );
320
connect( pli.data(), SIGNAL( tracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
321
SLOT( onTracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) );
323
m_playlistInterface[ mode ][ collection ] = pli;
330
QList<Tomahawk::query_ptr>
331
Album::tracks( ModelMode mode, const Tomahawk::collection_ptr& collection )
333
return playlistInterface( mode, collection )->tracks();
338
Album::infoid() const
340
if ( m_uuid.isEmpty() )