File indexing completed on 2024-05-19 04:49:13

0001 /****************************************************************************************
0002  * Copyright (c) 2009 Alejandro Wainzinger <aikawarazuni@gmail.com>                     *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #include "MediaDeviceMeta.h"
0018 
0019 #include "SvgHandler.h"
0020 #include "core/capabilities/ActionsCapability.h"
0021 #include "core/support/Debug.h"
0022 #include "core-impl/capabilities/AlbumActionsCapability.h"
0023 #include "core-impl/collections/mediadevicecollection/MediaDeviceCollection.h"
0024 #include "core-impl/collections/mediadevicecollection/MediaDeviceTrackEditor.h"
0025 #include "core-impl/collections/mediadevicecollection/handler/capabilities/ArtworkCapability.h"
0026 #include "covermanager/CoverCache.h"
0027 #include "covermanager/CoverFetchingActions.h"
0028 
0029 #include <QIcon>
0030 #include <QUrl>
0031 
0032 #include <QAction>
0033 
0034 using namespace Meta;
0035 
0036 MediaDeviceTrack::MediaDeviceTrack( Collections::MediaDeviceCollection *collection )
0037     : Meta::Track()
0038     , m_collection( collection )
0039     , m_artist( nullptr )
0040     , m_album( nullptr )
0041     , m_genre( nullptr )
0042     , m_composer( nullptr )
0043     , m_year( nullptr )
0044     , m_image()
0045     , m_comment()
0046     , m_name()
0047     , m_type()
0048     , m_bitrate( 0 )
0049     , m_filesize( 0 )
0050     , m_length( 0 )
0051     , m_discNumber( 0 )
0052     , m_samplerate( 0 )
0053     , m_trackNumber( 0 )
0054     , m_playCount( 0 )
0055     , m_rating( 0 )
0056     , m_bpm( 0 )
0057     , m_playableUrl()
0058 {
0059 }
0060 
0061 MediaDeviceTrack::~MediaDeviceTrack()
0062 {
0063     //nothing to do
0064 }
0065 
0066 QString
0067 MediaDeviceTrack::name() const
0068 {
0069     return m_name;
0070 }
0071 
0072 QUrl
0073 MediaDeviceTrack::playableUrl() const
0074 {
0075     return m_playableUrl;
0076 }
0077 
0078 QString
0079 MediaDeviceTrack::uidUrl() const
0080 {
0081     return m_playableUrl.isLocalFile() ? m_playableUrl.toLocalFile() : m_playableUrl.url();
0082 }
0083 
0084 QString
0085 MediaDeviceTrack::prettyUrl() const
0086 {
0087     if( m_playableUrl.isLocalFile() )
0088         return m_playableUrl.toLocalFile();
0089 
0090     QString collName = m_collection ? m_collection->prettyName() : i18n( "Unknown Collection" );
0091     QString artistName = artist()? artist()->prettyName() : i18n( "Unknown Artist" );
0092     // Check name() to prevent infinite recursion
0093     QString trackName = !name().isEmpty()? prettyName() : i18n( "Unknown track" );
0094 
0095     return  QStringLiteral( "%1: %2 - %3" ).arg( collName, artistName, trackName );
0096 }
0097 
0098 QString
0099 MediaDeviceTrack::notPlayableReason() const
0100 {
0101     return localFileNotPlayableReason( playableUrl().toLocalFile() );
0102 }
0103 
0104 bool
0105 MediaDeviceTrack::isEditable() const
0106 {
0107     if( m_collection )
0108         return m_collection->isWritable();
0109     return false;
0110 }
0111 
0112 AlbumPtr
0113 MediaDeviceTrack::album() const
0114 {
0115     return AlbumPtr::staticCast( m_album );
0116 }
0117 
0118 ArtistPtr
0119 MediaDeviceTrack::artist() const
0120 {
0121     return ArtistPtr::staticCast( m_artist );
0122 }
0123 
0124 GenrePtr
0125 MediaDeviceTrack::genre() const
0126 {
0127     return GenrePtr::staticCast( m_genre );
0128 }
0129 
0130 ComposerPtr
0131 MediaDeviceTrack::composer() const
0132 {
0133     return ComposerPtr::staticCast( m_composer );
0134 }
0135 
0136 YearPtr
0137 MediaDeviceTrack::year() const
0138 {
0139     return YearPtr::staticCast( m_year );
0140 }
0141 
0142 QString
0143 MediaDeviceTrack::comment() const
0144 {
0145     return m_comment;
0146 }
0147 
0148 void
0149 MediaDeviceTrack::setComment( const QString &newComment )
0150 {
0151     m_comment = newComment;
0152 }
0153 
0154 double
0155 MediaDeviceTrack::score() const
0156 {
0157     return 0.0;
0158 }
0159 
0160 void
0161 MediaDeviceTrack::setScore( double newScore )
0162 {
0163     Q_UNUSED( newScore )
0164 }
0165 
0166 int
0167 MediaDeviceTrack::rating() const
0168 {
0169     return m_rating;
0170 }
0171 
0172 void
0173 MediaDeviceTrack::setRating( int newRating )
0174 {
0175     if( newRating == m_rating )
0176         return;
0177     m_rating = newRating;
0178     // this method is _not_ called though TrackEditor, notify observers manually
0179     notifyObservers();
0180 }
0181 
0182 qint64
0183 MediaDeviceTrack::length() const
0184 {
0185     return m_length;
0186 }
0187 
0188 void
0189 MediaDeviceTrack::setFileSize( int newFileSize )
0190 {
0191     m_filesize = newFileSize;
0192 }
0193 
0194 int
0195 MediaDeviceTrack::filesize() const
0196 {
0197     return m_filesize;
0198 }
0199 
0200 int
0201 MediaDeviceTrack::bitrate() const
0202 {
0203     return m_bitrate;
0204 }
0205 
0206 void
0207 MediaDeviceTrack::setBitrate( int newBitrate )
0208 {
0209     m_bitrate = newBitrate;
0210 }
0211 
0212 int
0213 MediaDeviceTrack::sampleRate() const
0214 {
0215     return m_samplerate;
0216 }
0217 
0218 void
0219 MediaDeviceTrack::setSamplerate( int newSamplerate )
0220 {
0221     m_samplerate = newSamplerate;
0222 }
0223 
0224 qreal
0225 MediaDeviceTrack::bpm() const
0226 {
0227     return m_bpm;
0228 }
0229 void
0230 MediaDeviceTrack::setBpm( const qreal newBpm )
0231 {
0232     m_bpm = newBpm;
0233 }
0234 
0235 int
0236 MediaDeviceTrack::trackNumber() const
0237 {
0238     return m_trackNumber;
0239 }
0240 
0241 void
0242 MediaDeviceTrack::setTrackNumber( int newTrackNumber )
0243 {
0244     m_trackNumber = newTrackNumber;
0245 }
0246 
0247 int
0248 MediaDeviceTrack::discNumber() const
0249 {
0250     return m_discNumber;
0251 }
0252 
0253 void
0254 MediaDeviceTrack::setDiscNumber( int newDiscNumber )
0255 {
0256     m_discNumber = newDiscNumber;
0257 }
0258 
0259 int
0260 MediaDeviceTrack::playCount() const
0261 {
0262     return m_playCount;
0263 }
0264 
0265 void
0266 MediaDeviceTrack::setPlayCount( const int newCount )
0267 {
0268     m_playCount = newCount;
0269 }
0270 
0271 QDateTime
0272 MediaDeviceTrack::lastPlayed() const
0273 {
0274     return m_lastPlayed;
0275 }
0276 
0277 void
0278 MediaDeviceTrack::setLastPlayed( const QDateTime &newTime )
0279 {
0280     m_lastPlayed = newTime;
0281 }
0282 
0283 qreal
0284 MediaDeviceTrack::replayGain( ReplayGainTag mode ) const
0285 {
0286     /* no known non-UMS portable media player is able to differentiante between different
0287      * replay gain modes (track & album), so store only one value */
0288     switch( mode ) {
0289         case Meta::ReplayGain_Track_Gain:
0290         case Meta::ReplayGain_Album_Gain:
0291             return m_replayGain;
0292         case Meta::ReplayGain_Track_Peak:
0293         case Meta::ReplayGain_Album_Peak:
0294             // no default label so that compiler emits a warning when new enum value is added
0295             break;
0296     }
0297     return 0.0;
0298 }
0299 
0300 void
0301 MediaDeviceTrack::setReplayGain( qreal newReplayGain )
0302 {
0303     m_replayGain = newReplayGain;
0304 }
0305 
0306 QString
0307 MediaDeviceTrack::type() const
0308 {
0309     if( m_type.isEmpty() && !m_playableUrl.path().isEmpty() )
0310     {
0311         QString path = m_playableUrl.path();
0312         return path.mid( path.lastIndexOf( QLatin1Char('.') ) + 1 );
0313     }
0314     return m_type;
0315 }
0316 
0317 void
0318 MediaDeviceTrack::setType( const QString & type )
0319 {
0320     m_type = type;
0321 }
0322 
0323 void
0324 MediaDeviceTrack::prepareToPlay()
0325 {
0326     Meta::MediaDeviceTrackPtr ptr = Meta::MediaDeviceTrackPtr( this );
0327 
0328     if( m_collection && m_collection->handler() )
0329         m_collection->handler()->prepareToPlay( ptr );
0330 }
0331 
0332 // TODO: employ observers (e.g. Handler) to take care of updated
0333 // data
0334 /*
0335 void
0336 MediaDeviceTrack::subscribe( Observer *observer )
0337 {
0338     Q_UNUSED( observer )    //read only
0339 }
0340 
0341 void
0342 MediaDeviceTrack::unsubscribe( Observer *observer )
0343 {
0344     Q_UNUSED( observer )    //read only
0345 }
0346 */
0347 // TODO: implement this for MediaDeviceCollectionLocation
0348 bool
0349 MediaDeviceTrack::inCollection() const
0350 {
0351     return m_collection;  // true is m_collection is not null pointer, false otherwise
0352 }
0353 
0354 Collections::Collection*
0355 MediaDeviceTrack::collection() const
0356 {
0357     return m_collection.data();
0358 }
0359 
0360 TrackEditorPtr
0361 MediaDeviceTrack::editor()
0362 {
0363     return TrackEditorPtr( isEditable() ? new MediaDeviceTrackEditor( this ) : nullptr );
0364 }
0365 
0366 StatisticsPtr
0367 MediaDeviceTrack::statistics()
0368 {
0369     return StatisticsPtr( this );
0370 }
0371 
0372 void
0373 MediaDeviceTrack::setAlbum( const QString &newAlbum )
0374 {
0375     if( !m_collection )
0376         return;
0377 
0378     MediaDeviceAlbumPtr albumPtr;
0379     MediaDeviceTrackPtr track( this );
0380     AlbumMap albumMap = m_collection->memoryCollection()->albumMap();
0381 
0382     // do cleanup of soon to be previous album
0383 
0384     MediaDeviceArtistPtr albumArtist;
0385     QString albumArtistName;
0386     albumPtr = m_album;
0387     if ( !albumPtr.isNull() )
0388     {
0389         albumArtist = MediaDeviceArtistPtr::staticCast( albumPtr->albumArtist() );
0390         if( albumArtist )
0391             albumArtistName = albumArtist->name();
0392         // remove track from previous album's tracklist
0393         albumPtr->remTrack( track );
0394         // if album's tracklist is empty, remove album from albummap
0395         if( albumPtr->tracks().isEmpty() )
0396             albumMap.remove( AlbumPtr::staticCast( albumPtr ) );
0397     }
0398 
0399     // change to a new album
0400 
0401     // check for the existence of the album to be set to,
0402     // if album exists, reuse, else create
0403 
0404     if ( albumMap.contains( newAlbum, albumArtistName ) )
0405     {
0406         albumPtr = MediaDeviceAlbumPtr::staticCast( albumMap.value( newAlbum, albumArtistName ) );
0407     }
0408     else
0409     {
0410         albumPtr = MediaDeviceAlbumPtr( new MediaDeviceAlbum( m_collection.data(), newAlbum ) );
0411         albumPtr->setAlbumArtist( albumArtist );
0412         albumMap.insert( AlbumPtr::staticCast( albumPtr ) );
0413     }
0414 
0415     // add track to album's tracklist
0416     albumPtr->addTrack( track );
0417     // set track's album to the new album
0418     setAlbum( albumPtr );
0419 
0420     m_collection->memoryCollection()->acquireWriteLock();
0421     m_collection->memoryCollection()->setAlbumMap( albumMap );
0422     m_collection->memoryCollection()->releaseLock();
0423 }
0424 
0425 void
0426 MediaDeviceTrack::setAlbumArtist( const QString &newAlbumArtist )
0427 {
0428     if( !m_collection )
0429         return;
0430 
0431     if( m_album.isNull() || newAlbumArtist.isEmpty() )
0432         return;
0433 
0434     MediaDeviceArtistPtr artistPtr;
0435     ArtistMap artistMap = m_collection->memoryCollection()->artistMap();
0436 
0437     if( artistMap.contains( newAlbumArtist ) )
0438         artistPtr = MediaDeviceArtistPtr::staticCast( artistMap.value( newAlbumArtist ) );
0439     else
0440     {
0441         artistPtr = MediaDeviceArtistPtr( new MediaDeviceArtist( newAlbumArtist ) );
0442         artistMap.insert( newAlbumArtist, ArtistPtr::staticCast( artistPtr ) );
0443     }
0444 
0445     m_album->setAlbumArtist( artistPtr );
0446 
0447     m_collection->memoryCollection()->acquireWriteLock();
0448     m_collection->memoryCollection()->setArtistMap( artistMap );
0449     m_collection->memoryCollection()->releaseLock();
0450 }
0451 
0452 void
0453 MediaDeviceTrack::setArtist( const QString &newArtist )
0454 {
0455     if( !m_collection )
0456         return;
0457 
0458     MediaDeviceArtistPtr artistPtr;
0459     MediaDeviceTrackPtr track( this );
0460     ArtistMap artistMap = m_collection->memoryCollection()->artistMap();
0461 
0462     // do cleanup of soon to be previous artist
0463 
0464     artistPtr = m_artist;
0465     // remove track from previous artist's tracklist
0466     if ( !artistPtr.isNull() )
0467     {
0468         artistPtr->remTrack( track );
0469         // if artist's tracklist is empty, remove artist from artistmap
0470         if( artistPtr->tracks().isEmpty() )
0471             artistMap.remove( artistPtr->name() );
0472     }
0473 
0474     // change to a new artist
0475 
0476     // check for the existence of the artist to be set to,
0477     // if artist exists, reuse, else create
0478 
0479     if ( artistMap.contains( newArtist ) )
0480     {
0481         artistPtr = MediaDeviceArtistPtr::staticCast( artistMap.value( newArtist ) );
0482     }
0483     else
0484     {
0485         artistPtr = MediaDeviceArtistPtr( new MediaDeviceArtist( newArtist ) );
0486         artistMap.insert( newArtist, ArtistPtr::staticCast( artistPtr ) );
0487     }
0488 
0489     // add track to artist's tracklist
0490     artistPtr->addTrack( track );
0491     // set track's artist to the new artist
0492     setArtist( artistPtr );
0493 
0494     m_collection->memoryCollection()->acquireWriteLock();
0495     m_collection->memoryCollection()->setArtistMap( artistMap );
0496     m_collection->memoryCollection()->releaseLock();
0497 }
0498 
0499 void
0500 MediaDeviceTrack::setGenre( const QString &newGenre )
0501 {
0502     if( !m_collection )
0503         return;
0504 
0505     MediaDeviceGenrePtr genrePtr;
0506     MediaDeviceTrackPtr track( this );
0507     GenreMap genreMap = m_collection->memoryCollection()->genreMap();
0508 
0509     // do cleanup of soon to be previous genre
0510 
0511     genrePtr = m_genre;
0512     if ( !genrePtr.isNull() )
0513     {
0514         // remove track from previous genre's tracklist
0515         genrePtr->remTrack( track );
0516         // if genre's tracklist is empty, remove genre from genremap
0517         if( genrePtr->tracks().isEmpty() )
0518             genreMap.remove( genrePtr->name() );
0519     }
0520 
0521     // change to a new genre
0522 
0523     // check for the existence of the genre to be set to,
0524     // if genre exists, reuse, else create
0525 
0526     if ( genreMap.contains( newGenre ) )
0527     {
0528         genrePtr = MediaDeviceGenrePtr::staticCast( genreMap.value( newGenre ) );
0529     }
0530     else
0531     {
0532         genrePtr = MediaDeviceGenrePtr( new MediaDeviceGenre( newGenre ) );
0533         genreMap.insert( newGenre, GenrePtr::staticCast( genrePtr ) );
0534     }
0535 
0536     // add track to genre's tracklist
0537     genrePtr->addTrack( track );
0538     // set track's genre to the new genre
0539     setGenre( genrePtr );
0540 
0541     m_collection->memoryCollection()->acquireWriteLock();
0542     m_collection->memoryCollection()->setGenreMap( genreMap );
0543     m_collection->memoryCollection()->releaseLock();
0544 }
0545 
0546 void
0547 MediaDeviceTrack::setComposer( const QString &newComposer )
0548 {
0549     if( !m_collection )
0550         return;
0551 
0552     MediaDeviceComposerPtr composerPtr;
0553     MediaDeviceTrackPtr track( this );
0554     ComposerMap composerMap = m_collection->memoryCollection()->composerMap();
0555 
0556     // do cleanup of soon to be previous composer
0557 
0558     composerPtr = m_composer;
0559     if ( !composerPtr.isNull() )
0560     {
0561         // remove track from previous composer's tracklist
0562         composerPtr->remTrack( track );
0563         // if composer's tracklist is empty, remove composer from composermap
0564         if( composerPtr->tracks().isEmpty() )
0565             composerMap.remove( composerPtr->name() );
0566     }
0567 
0568     // change to a new composer
0569 
0570     // check for the existence of the composer to be set to,
0571     // if composer exists, reuse, else create
0572 
0573     if ( composerMap.contains( newComposer ) )
0574     {
0575         composerPtr = MediaDeviceComposerPtr::staticCast( composerMap.value( newComposer ) );
0576     }
0577     else
0578     {
0579         composerPtr = MediaDeviceComposerPtr( new MediaDeviceComposer( newComposer ) );
0580         composerMap.insert( newComposer, ComposerPtr::staticCast( composerPtr ) );
0581     }
0582 
0583     // add track to composer's tracklist
0584     composerPtr->addTrack( track );
0585     // set track's composer to the new composer
0586     setComposer( composerPtr );
0587 
0588     m_collection->memoryCollection()->acquireWriteLock();
0589     m_collection->memoryCollection()->setComposerMap( composerMap );
0590     m_collection->memoryCollection()->releaseLock();
0591 }
0592 
0593 void
0594 MediaDeviceTrack::setYear( int newYear )
0595 {
0596     if( !m_collection )
0597         return;
0598 
0599     MediaDeviceYearPtr yearPtr;
0600     MediaDeviceTrackPtr track( this );
0601     YearMap yearMap = m_collection->memoryCollection()->yearMap();
0602 
0603     // do cleanup of soon to be previous year
0604 
0605     yearPtr = m_year;
0606     if ( !yearPtr.isNull() )
0607     {
0608         // remove track from previous year's tracklist
0609         yearPtr->remTrack( track );
0610         // if year's tracklist is empty, remove year from yearmap
0611         if( yearPtr->tracks().isEmpty() )
0612             yearMap.remove( yearPtr->year() );
0613     }
0614 
0615     // change to a new year
0616 
0617     // check for the existence of the year to be set to,
0618     // if year exists, reuse, else create
0619 
0620     if ( yearMap.contains( newYear ) )
0621     {
0622         yearPtr = MediaDeviceYearPtr::staticCast( yearMap.value( newYear ) );
0623     }
0624     else
0625     {
0626         yearPtr = MediaDeviceYearPtr( new MediaDeviceYear( QString::number(newYear) ) );
0627         yearMap.insert( newYear, YearPtr::staticCast( yearPtr ) );
0628     }
0629 
0630     // add track to year's tracklist
0631     yearPtr->addTrack( track );
0632     // set track's year to the new year
0633     setYear( yearPtr );
0634 
0635     m_collection->memoryCollection()->acquireWriteLock();
0636     m_collection->memoryCollection()->setYearMap( yearMap );
0637     m_collection->memoryCollection()->releaseLock();
0638 }
0639 
0640 void
0641 MediaDeviceTrack::setAlbum( MediaDeviceAlbumPtr album )
0642 {
0643     m_album = album;
0644 }
0645 
0646 void
0647 MediaDeviceTrack::setArtist( MediaDeviceArtistPtr artist )
0648 {
0649     m_artist = artist;
0650 }
0651 
0652 void
0653 MediaDeviceTrack::setGenre( MediaDeviceGenrePtr genre )
0654 {
0655     m_genre = genre;
0656 }
0657 
0658 void
0659 MediaDeviceTrack::setComposer( MediaDeviceComposerPtr composer )
0660 {
0661     m_composer = composer;
0662 }
0663 
0664 void
0665 MediaDeviceTrack::setYear( MediaDeviceYearPtr year )
0666 {
0667     m_year = year;
0668 }
0669 
0670 QString
0671 MediaDeviceTrack::title() const
0672 {
0673     return m_name;
0674 }
0675 
0676 void
0677 MediaDeviceTrack::setTitle( const QString &title )
0678 {
0679     m_name = title;
0680 }
0681 
0682 void
0683 MediaDeviceTrack::setLength( qint64 length )
0684 {
0685     m_length = length;
0686 }
0687 
0688 void
0689 MediaDeviceTrack::commitChanges()
0690 {
0691     notifyObservers();
0692 }
0693 
0694 //MediaDeviceArtist
0695 
0696 MediaDeviceArtist::MediaDeviceArtist( const QString &name )
0697     : Meta::Artist()
0698     , m_name( name )
0699     , m_tracks()
0700 {
0701     //nothing to do
0702 }
0703 
0704 MediaDeviceArtist::~MediaDeviceArtist()
0705 {
0706     //nothing to do
0707 }
0708 
0709 QString
0710 MediaDeviceArtist::name() const
0711 {
0712     return m_name;
0713 }
0714 
0715 TrackList
0716 MediaDeviceArtist::tracks()
0717 {
0718     return m_tracks;
0719 }
0720 
0721 void
0722 MediaDeviceArtist::addTrack( MediaDeviceTrackPtr track )
0723 {
0724     m_tracks.append( TrackPtr::staticCast( track ) );
0725 }
0726 
0727 void
0728 MediaDeviceArtist::remTrack( MediaDeviceTrackPtr track )
0729 {
0730     m_tracks.removeOne( TrackPtr::staticCast( track ) );
0731 }
0732 
0733 //---------------MediaDeviceAlbum-----------------------------------
0734 
0735 MediaDeviceAlbum::MediaDeviceAlbum( Collections::MediaDeviceCollection *collection, const QString &name )
0736     : Meta::Album()
0737     , m_collection( collection )
0738     , m_artworkCapability()
0739     , m_name( name )
0740     , m_tracks()
0741     , m_isCompilation( false )
0742     , m_hasImagePossibility( true ) // assume it has a cover until proven otherwise
0743     , m_hasImageChecked( false )
0744     , m_image( QImage() )
0745     , m_albumArtist( nullptr )
0746 {
0747     MediaDeviceHandler *handler = m_collection->handler();
0748     if( handler && handler->hasCapabilityInterface( Handler::Capability::Artwork ) )
0749         m_artworkCapability = handler->create<Handler::ArtworkCapability>();
0750 }
0751 
0752 MediaDeviceAlbum::~MediaDeviceAlbum()
0753 {
0754     if( m_artworkCapability )
0755         m_artworkCapability->deleteLater();
0756     CoverCache::invalidateAlbum( this );
0757 }
0758 
0759 QString
0760 MediaDeviceAlbum::name() const
0761 {
0762     return m_name;
0763 }
0764 
0765 bool
0766 MediaDeviceAlbum::isCompilation() const
0767 {
0768     return m_isCompilation;
0769 }
0770 
0771 void
0772 MediaDeviceAlbum::setIsCompilation( bool compilation )
0773 {
0774     m_isCompilation = compilation;
0775 }
0776 
0777 bool
0778 MediaDeviceAlbum::hasAlbumArtist() const
0779 {
0780     return !m_albumArtist.isNull();
0781 }
0782 
0783 ArtistPtr
0784 MediaDeviceAlbum::albumArtist() const
0785 {
0786     return ArtistPtr::staticCast( m_albumArtist );
0787 }
0788 
0789 TrackList
0790 MediaDeviceAlbum::tracks()
0791 {
0792     return m_tracks;
0793 }
0794 
0795 bool
0796 MediaDeviceAlbum::hasImage( int size ) const
0797 {
0798     Q_UNUSED( size )
0799 
0800     if( !m_hasImageChecked )
0801         m_hasImagePossibility = ! const_cast<MediaDeviceAlbum*>( this )->image().isNull();
0802     return m_hasImagePossibility;
0803 }
0804 
0805 QImage
0806 MediaDeviceAlbum::image( int size ) const
0807 {
0808     if( m_name.isEmpty() || !m_hasImagePossibility || m_tracks.isEmpty() )
0809         return Meta::Album::image( size );
0810 
0811     if( m_image.isNull() && m_artworkCapability )
0812     {
0813         MediaDeviceTrackPtr track = MediaDeviceTrackPtr::staticCast( m_tracks.first() );
0814         m_image = m_artworkCapability->getCover( track );
0815         m_hasImagePossibility = !m_image.isNull();
0816         m_hasImageChecked = true;
0817         CoverCache::invalidateAlbum( this );
0818     }
0819 
0820     if( !m_image.isNull() )
0821     {
0822         if( !size )
0823             return m_image;
0824         return m_image.scaled( QSize( size, size ), Qt::KeepAspectRatio );
0825     }
0826     return Meta::Album::image( size );
0827 }
0828 
0829 bool
0830 MediaDeviceAlbum::canUpdateImage() const
0831 {
0832     if( m_artworkCapability )
0833         return m_artworkCapability->canUpdateCover();
0834     return false;
0835 }
0836 
0837 void
0838 MediaDeviceAlbum::setImage( const QImage &image )
0839 {
0840     if( m_artworkCapability && m_artworkCapability->canUpdateCover() )
0841     {
0842         // reset to initial values, let next call to image() re-fetch it
0843         m_hasImagePossibility = true;
0844         m_hasImageChecked = false;
0845 
0846         m_artworkCapability->setCover( MediaDeviceAlbumPtr( this ), image );
0847         CoverCache::invalidateAlbum( this );
0848     }
0849 }
0850 
0851 void
0852 MediaDeviceAlbum::setImagePath( const QString &path )
0853 {
0854     if( m_artworkCapability && m_artworkCapability->canUpdateCover() )
0855     {
0856         // reset to initial values, let next call to image() re-fetch it
0857         m_hasImagePossibility = true;
0858         m_hasImageChecked = false;
0859 
0860         m_artworkCapability->setCoverPath( MediaDeviceAlbumPtr( this ), path );
0861         CoverCache::invalidateAlbum( this );
0862     }
0863 }
0864 
0865 bool
0866 MediaDeviceAlbum::hasCapabilityInterface( Capabilities::Capability::Type type ) const
0867 {
0868     switch( type )
0869     {
0870         case Capabilities::Capability::Actions:
0871             return true;
0872         default:
0873             return false;
0874     }
0875 }
0876 
0877 Capabilities::Capability*
0878 MediaDeviceAlbum::createCapabilityInterface( Capabilities::Capability::Type type )
0879 {
0880     switch( type )
0881     {
0882         case Capabilities::Capability::Actions:
0883             return new Capabilities::AlbumActionsCapability( Meta::AlbumPtr( this ) );
0884 
0885         default:
0886             return nullptr;
0887     }
0888 }
0889 
0890 void
0891 MediaDeviceAlbum::addTrack( MediaDeviceTrackPtr track )
0892 {
0893     m_tracks.append( TrackPtr::staticCast( track ) );
0894 }
0895 
0896 void
0897 MediaDeviceAlbum::remTrack( MediaDeviceTrackPtr track )
0898 {
0899     m_tracks.removeOne( TrackPtr::staticCast( track ) );
0900 }
0901 
0902 void
0903 MediaDeviceAlbum::setAlbumArtist( MediaDeviceArtistPtr artist )
0904 {
0905     m_albumArtist = artist;
0906 }
0907 
0908 //MediaDeviceComposer
0909 
0910 MediaDeviceComposer::MediaDeviceComposer( const QString &name )
0911     : Meta::Composer()
0912     , m_name( name )
0913     , m_tracks()
0914 {
0915     //nothing to do
0916 }
0917 
0918 MediaDeviceComposer::~MediaDeviceComposer()
0919 {
0920     //nothing to do
0921 }
0922 
0923 QString
0924 MediaDeviceComposer::name() const
0925 {
0926     return m_name;
0927 }
0928 
0929 TrackList
0930 MediaDeviceComposer::tracks()
0931 {
0932     return m_tracks;
0933 }
0934 
0935 void
0936 MediaDeviceComposer::addTrack( MediaDeviceTrackPtr track )
0937 {
0938     m_tracks.append( TrackPtr::staticCast( track ) );
0939 }
0940 
0941 void
0942 MediaDeviceComposer::remTrack( MediaDeviceTrackPtr track )
0943 {
0944     m_tracks.removeOne( TrackPtr::staticCast( track ) );
0945 }
0946 
0947 //---------------MediaDeviceGenre-----------------------------------
0948 
0949 MediaDeviceGenre::MediaDeviceGenre( const QString &name )
0950     : Meta::Genre()
0951     , m_name( name )
0952     , m_tracks()
0953 {
0954     //nothing to do
0955 }
0956 
0957 MediaDeviceGenre::~MediaDeviceGenre()
0958 {
0959     //nothing to do
0960 }
0961 
0962 QString
0963 MediaDeviceGenre::name() const
0964 {
0965     return m_name;
0966 }
0967 
0968 TrackList
0969 MediaDeviceGenre::tracks()
0970 {
0971     return m_tracks;
0972 }
0973 
0974 void
0975 MediaDeviceGenre::addTrack( MediaDeviceTrackPtr track )
0976 {
0977     m_tracks.append( TrackPtr::staticCast( track ) );
0978 }
0979 
0980 void
0981 MediaDeviceGenre::remTrack( MediaDeviceTrackPtr track )
0982 {
0983     m_tracks.removeOne( TrackPtr::staticCast( track ) );
0984 }
0985 
0986 
0987 //MediaDeviceYear
0988 
0989 MediaDeviceYear::MediaDeviceYear( const QString &name )
0990     : Meta::Year()
0991     , m_name( name )
0992     , m_tracks()
0993 {
0994     //nothing to do
0995 }
0996 
0997 MediaDeviceYear::~MediaDeviceYear()
0998 {
0999     //nothing to do
1000 }
1001 
1002 QString
1003 MediaDeviceYear::name() const
1004 {
1005     return m_name;
1006 }
1007 
1008 TrackList
1009 MediaDeviceYear::tracks()
1010 {
1011     return m_tracks;
1012 }
1013 
1014 void
1015 MediaDeviceYear::addTrack( MediaDeviceTrackPtr track )
1016 {
1017     m_tracks.append( TrackPtr::staticCast( track ) );
1018 }
1019 
1020 void
1021 MediaDeviceYear::remTrack( MediaDeviceTrackPtr track )
1022 {
1023     m_tracks.removeOne( TrackPtr::staticCast( track ) );
1024 }