MediaDeviceArtist::albums() is not used, do not maintain album list
[amarok:rengelss-amarok.git] / src / core-impl / collections / mediadevicecollection / MediaDeviceMeta.cpp
1 /****************************************************************************************
2  * Copyright (c) 2009 Alejandro Wainzinger <aikawarazuni@gmail.com>                     *
3  *                                                                                      *
4  * This program is free software; you can redistribute it and/or modify it under        *
5  * the terms of the GNU General Public License as published by the Free Software        *
6  * Foundation; either version 2 of the License, or (at your option) any later           *
7  * version.                                                                             *
8  *                                                                                      *
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
11  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
12  *                                                                                      *
13  * You should have received a copy of the GNU General Public License along with         *
14  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
15  ****************************************************************************************/
16
17 #include "MediaDeviceMeta.h"
18 #include "MediaDeviceCollection.h"
19 #include "MediaDeviceHandler.h"
20
21 #include "handler/capabilities/ArtworkCapability.h"
22 #include "covermanager/CoverCache.h"
23 #include "covermanager/CoverFetchingActions.h"
24 #include "core/support/Debug.h"
25 #include "SvgHandler.h"
26 #include "core/capabilities/ActionsCapability.h"
27 #include "core/capabilities/EditCapability.h"
28 #include "core/capabilities/UpdateCapability.h"
29
30 #include <KIcon>
31 #include <KUrl>
32
33 #include <QAction>
34
35 using namespace Meta;
36 // Currently complaining about some vtable issue
37
38 class EditCapabilityMediaDevice : public Capabilities::EditCapability
39 {
40     Q_OBJECT
41     public:
42         EditCapabilityMediaDevice( MediaDeviceTrack *track )
43             : Capabilities::EditCapability()
44             , m_track( track ) {}
45
46         virtual bool isEditable() const { return m_track->isEditable(); }
47         virtual void setAlbum( const QString &newAlbum ) { m_track->setAlbum( newAlbum ); }
48         virtual void setAlbumArtist( const QString &newAlbumArtist ) { m_track->setAlbumArtist( newAlbumArtist ); }
49         virtual void setArtist( const QString &newArtist ) { m_track->setArtist( newArtist ); }
50         virtual void setComposer( const QString &newComposer ) { m_track->setComposer( newComposer ); }
51         virtual void setGenre( const QString &newGenre ) { m_track->setGenre( newGenre ); }
52         virtual void setYear( int newYear ) { m_track->setYear( newYear ); }
53         virtual void setBpm( const qreal newBpm ) { m_track->setBpm( newBpm ); }
54         virtual void setTitle( const QString &newTitle ) { m_track->setTitle( newTitle ); }
55         virtual void setComment( const QString &newComment ) { m_track->setComment( newComment ); }
56         virtual void setTrackNumber( int newTrackNumber ) { m_track->setTrackNumber( newTrackNumber ); }
57         virtual void setDiscNumber( int newDiscNumber ) { m_track->setDiscNumber( newDiscNumber ); }
58         virtual void setUidUrl( const QString &newUidUrl ) { m_track->setUidUrl( newUidUrl ); }
59         virtual void beginMetaDataUpdate() { m_track->beginMetaDataUpdate(); }
60         virtual void endMetaDataUpdate() { m_track->endMetaDataUpdate(); }
61
62     private:
63         KSharedPtr<MediaDeviceTrack> m_track;
64 };
65
66 class UpdateCapabilityMediaDevice : public Capabilities::UpdateCapability
67 {
68     Q_OBJECT
69     public:
70         UpdateCapabilityMediaDevice( Collections::MediaDeviceCollection *coll )
71             : Capabilities::UpdateCapability()
72             , m_coll( coll )
73         {}
74
75         virtual void collectionUpdated() const
76         {
77             m_coll->collectionUpdated();
78             m_coll->writeDatabase();
79         }
80
81     private:
82         Collections::MediaDeviceCollection *m_coll;
83 };
84
85
86 MediaDeviceTrack::MediaDeviceTrack( Collections::MediaDeviceCollection *collection )
87     : Meta::Track()
88     , m_collection( collection )
89     , m_artist( 0 )
90     , m_album( 0 )
91     , m_genre( 0 )
92     , m_composer( 0 )
93     , m_year( 0 )
94     , m_image()
95     , m_comment()
96     , m_name()
97     , m_type()
98     , m_bitrate( 0 )
99     , m_filesize( 0 )
100     , m_length( 0 )
101     , m_discNumber( 0 )
102     , m_samplerate( 0 )
103     , m_trackNumber( 0 )
104     , m_playCount( 0 )
105     , m_rating( 0 )
106     , m_bpm( 0 )
107     , m_playableUrl()
108 {
109 }
110
111 MediaDeviceTrack::~MediaDeviceTrack()
112 {
113     //nothing to do
114 }
115
116 QString
117 MediaDeviceTrack::name() const
118 {
119     return m_name;
120 }
121
122 KUrl
123 MediaDeviceTrack::playableUrl() const
124 {
125     return m_playableUrl;
126 }
127
128 QString
129 MediaDeviceTrack::uidUrl() const
130 {
131     return m_playableUrl.isLocalFile() ? m_playableUrl.toLocalFile() : m_playableUrl.url();
132 }
133
134 void
135 MediaDeviceTrack::setUidUrl( const QString &newUidUrl ) const
136 {
137     Q_UNUSED( newUidUrl )
138 }
139
140 QString
141 MediaDeviceTrack::prettyUrl() const
142 {
143     if( m_playableUrl.isLocalFile() )
144         return m_playableUrl.toLocalFile();
145
146     QString collName = m_collection ? m_collection.data()->prettyName() : i18n( "Unknown Collection" );
147     QString artistName = artist()? artist()->prettyName() : i18n( "Unknown Artist" );
148     // Check name() to prevent infinite recursion
149     QString trackName = !name().isEmpty()? prettyName() : i18n( "Unknown track" );
150
151     return  QString( "%1: %2 - %3" ).arg( collName, artistName, trackName );
152 }
153
154 bool
155 MediaDeviceTrack::isPlayable() const
156 {
157     KUrl trackUrl = playableUrl();
158     QFileInfo trackFileInfo = QFileInfo( trackUrl.pathOrUrl() );
159     if( trackFileInfo.exists() && trackFileInfo.isFile() && trackFileInfo.isReadable() )
160         return true;
161
162     return false;
163 }
164
165 bool
166 MediaDeviceTrack::isEditable() const
167 {
168     if( m_collection )
169         return m_collection.data()->isWritable();
170     return false;
171 }
172
173 AlbumPtr
174 MediaDeviceTrack::album() const
175 {
176     return AlbumPtr::staticCast( m_album );
177 }
178
179 ArtistPtr
180 MediaDeviceTrack::artist() const
181 {
182     return ArtistPtr::staticCast( m_artist );
183 }
184
185 GenrePtr
186 MediaDeviceTrack::genre() const
187 {
188     return GenrePtr::staticCast( m_genre );
189 }
190
191 ComposerPtr
192 MediaDeviceTrack::composer() const
193 {
194     return ComposerPtr::staticCast( m_composer );
195 }
196
197 YearPtr
198 MediaDeviceTrack::year() const
199 {
200     return YearPtr::staticCast( m_year );
201 }
202
203 QString
204 MediaDeviceTrack::comment() const
205 {
206     return m_comment;
207 }
208
209 void
210 MediaDeviceTrack::setComment( const QString &newComment )
211 {
212     m_comment = newComment;
213 }
214
215 double
216 MediaDeviceTrack::score() const
217 {
218     return 0.0;
219 }
220
221 void
222 MediaDeviceTrack::setScore( double newScore )
223 {
224     Q_UNUSED( newScore )
225 }
226
227 int
228 MediaDeviceTrack::rating() const
229 {
230     return m_rating;
231 }
232
233 void
234 MediaDeviceTrack::setRating( int newRating )
235 {
236     m_rating = newRating;
237     notifyObservers();
238 }
239
240 qint64
241 MediaDeviceTrack::length() const
242 {
243     return m_length;
244 }
245
246 void
247 MediaDeviceTrack::setFileSize( int newFileSize )
248 {
249     m_filesize = newFileSize;
250 }
251
252 int
253 MediaDeviceTrack::filesize() const
254 {
255     return m_filesize;
256 }
257
258 int
259 MediaDeviceTrack::bitrate() const
260 {
261     return m_bitrate;
262 }
263
264 void
265 MediaDeviceTrack::setBitrate( int newBitrate )
266 {
267     m_bitrate = newBitrate;
268 }
269
270 int
271 MediaDeviceTrack::sampleRate() const
272 {
273     return m_samplerate;
274 }
275
276 void
277 MediaDeviceTrack::setSamplerate( int newSamplerate )
278 {
279     m_samplerate = newSamplerate;
280 }
281
282 qreal
283 MediaDeviceTrack::bpm() const
284 {
285     return m_bpm;
286 }
287 void
288 MediaDeviceTrack::setBpm( const qreal newBpm )
289 {
290     m_bpm = newBpm;
291 }
292
293 int
294 MediaDeviceTrack::trackNumber() const
295 {
296     return m_trackNumber;
297 }
298
299 void
300 MediaDeviceTrack::setTrackNumber( int newTrackNumber )
301 {
302     m_trackNumber = newTrackNumber;
303 }
304
305 int
306 MediaDeviceTrack::discNumber() const
307 {
308     return m_discNumber;
309 }
310
311 void
312 MediaDeviceTrack::setDiscNumber( int newDiscNumber )
313 {
314     m_discNumber = newDiscNumber;
315 }
316
317 int
318 MediaDeviceTrack::playCount() const
319 {
320     return m_playCount;
321 }
322
323 void
324 MediaDeviceTrack::setPlayCount( const int newCount )
325 {
326     m_playCount = newCount;
327 }
328
329 QDateTime
330 MediaDeviceTrack::lastPlayed() const
331 {
332     return m_lastPlayed;
333 }
334
335 void
336 MediaDeviceTrack::setLastPlayed( const QDateTime &newTime )
337 {
338     m_lastPlayed = newTime;
339 }
340
341 QString
342 MediaDeviceTrack::type() const
343 {
344     if( m_type.isEmpty() && !m_playableUrl.path().isEmpty() )
345     {
346         QString path = m_playableUrl.path();
347         return path.mid( path.lastIndexOf( '.' ) + 1 );
348     }
349     return m_type;
350 }
351
352 void
353 MediaDeviceTrack::setType( const QString & type )
354 {
355     m_type = type;
356 }
357
358 void
359 MediaDeviceTrack::prepareToPlay()
360 {
361     Meta::MediaDeviceTrackPtr ptr = Meta::MediaDeviceTrackPtr( this );
362
363     if( m_collection && m_collection.data()->handler() )
364         m_collection.data()->handler()->prepareToPlay( ptr );
365 }
366
367 // TODO: employ observers (e.g. Handler) to take care of updated
368 // data
369 /*
370 void
371 MediaDeviceTrack::subscribe( Observer *observer )
372 {
373     Q_UNUSED( observer )    //read only
374 }
375
376 void
377 MediaDeviceTrack::unsubscribe( Observer *observer )
378 {
379     Q_UNUSED( observer )    //read only
380 }
381 */
382 // TODO: implement this for MediaDeviceCollectionLocation
383 bool
384 MediaDeviceTrack::inCollection() const
385 {
386     return m_collection;  // true is m_collection is not null pointer, false otherwise
387 }
388
389 Collections::Collection*
390 MediaDeviceTrack::collection() const
391 {
392     return m_collection.data();
393 }
394
395 bool
396 MediaDeviceTrack::hasCapabilityInterface( Capabilities::Capability::Type type ) const
397 {
398     if( !m_collection || !m_collection.data()->isWritable() )
399         return false;
400
401     switch( type )
402     {
403         case Capabilities::Capability::Editable:
404             return true;
405         case Capabilities::Capability::Updatable:
406             return true;
407         default:
408             return false;
409     }
410 }
411
412 Capabilities::Capability*
413 MediaDeviceTrack::createCapabilityInterface( Capabilities::Capability::Type type )
414 {
415     if( !m_collection || !m_collection.data()->isWritable() )
416         return false;
417
418     switch( type )
419     {
420         case Capabilities::Capability::Editable:
421             return new EditCapabilityMediaDevice( this );
422         case Capabilities::Capability::Updatable:
423             return new UpdateCapabilityMediaDevice( m_collection.data() );
424         default:
425             return 0;
426     }
427 }
428
429 void
430 MediaDeviceTrack::setAlbum( const QString &newAlbum )
431 {
432     if( !m_collection )
433         return;
434
435     MediaDeviceAlbumPtr albumPtr;
436     MediaDeviceTrackPtr track( this );
437     AlbumMap albumMap = m_collection.data()->memoryCollection()->albumMap();
438
439     // do cleanup of soon to be previous album
440
441     albumPtr = m_album;
442     if ( !albumPtr.isNull() )
443     {
444         // remove track from previous album's tracklist
445         albumPtr->remTrack( track );
446         // if album's tracklist is empty, remove album from albummap
447         if( albumPtr->tracks().isEmpty() )
448             albumMap.remove( albumPtr->name() );
449     }
450
451     // change to a new album
452
453     // check for the existence of the album to be set to,
454     // if album exists, reuse, else create
455
456     if ( albumMap.contains( newAlbum ) )
457     {
458         albumPtr = MediaDeviceAlbumPtr::staticCast( albumMap.value( newAlbum ) );
459     }
460     else
461     {
462         albumPtr = MediaDeviceAlbumPtr( new MediaDeviceAlbum( m_collection.data(), newAlbum ) );
463         albumMap.insert( newAlbum, AlbumPtr::staticCast( albumPtr ) );
464     }
465
466     // add track to album's tracklist
467     albumPtr->addTrack( track );
468     // set track's album to the new album
469     setAlbum( albumPtr );
470
471     m_collection.data()->memoryCollection()->acquireWriteLock();
472     m_collection.data()->memoryCollection()->setAlbumMap( albumMap );
473     m_collection.data()->memoryCollection()->releaseLock();
474 }
475
476 void
477 MediaDeviceTrack::setAlbumArtist( const QString &newAlbumArtist )
478 {
479     if( !m_collection )
480         return;
481
482     if( m_album.isNull() || newAlbumArtist.isEmpty() )
483         return;
484
485     MediaDeviceArtistPtr artistPtr;
486     ArtistMap artistMap = m_collection.data()->memoryCollection()->artistMap();
487
488     if( artistMap.contains( newAlbumArtist ) )
489         artistPtr = MediaDeviceArtistPtr::staticCast( artistMap.value( newAlbumArtist ) );
490     else
491     {
492         artistPtr = MediaDeviceArtistPtr( new MediaDeviceArtist( newAlbumArtist ) );
493         artistMap.insert( newAlbumArtist, ArtistPtr::staticCast( artistPtr ) );
494     }
495
496     m_album->setAlbumArtist( artistPtr );
497
498     m_collection.data()->memoryCollection()->acquireWriteLock();
499     m_collection.data()->memoryCollection()->setArtistMap( artistMap );
500     m_collection.data()->memoryCollection()->releaseLock();
501 }
502
503 void
504 MediaDeviceTrack::setArtist( const QString &newArtist )
505 {
506     if( !m_collection )
507         return;
508
509     MediaDeviceArtistPtr artistPtr;
510     MediaDeviceTrackPtr track( this );
511     ArtistMap artistMap = m_collection.data()->memoryCollection()->artistMap();
512
513     // do cleanup of soon to be previous artist
514
515     artistPtr = m_artist;
516     // remove track from previous artist's tracklist
517     if ( !artistPtr.isNull() )
518     {
519         artistPtr->remTrack( track );
520         // if artist's tracklist is empty, remove artist from artistmap
521         if( artistPtr->tracks().isEmpty() )
522             artistMap.remove( artistPtr->name() );
523     }
524
525     // change to a new artist
526
527     // check for the existence of the artist to be set to,
528     // if artist exists, reuse, else create
529
530     if ( artistMap.contains( newArtist ) )
531     {
532         artistPtr = MediaDeviceArtistPtr::staticCast( artistMap.value( newArtist ) );
533     }
534     else
535     {
536         artistPtr = MediaDeviceArtistPtr( new MediaDeviceArtist( newArtist ) );
537         artistMap.insert( newArtist, ArtistPtr::staticCast( artistPtr ) );
538     }
539
540     // add track to artist's tracklist
541     artistPtr->addTrack( track );
542     // set track's artist to the new artist
543     setArtist( artistPtr );
544
545     m_collection.data()->memoryCollection()->acquireWriteLock();
546     m_collection.data()->memoryCollection()->setArtistMap( artistMap );
547     m_collection.data()->memoryCollection()->releaseLock();
548 }
549
550 void
551 MediaDeviceTrack::setGenre( const QString &newGenre )
552 {
553     if( !m_collection )
554         return;
555
556     MediaDeviceGenrePtr genrePtr;
557     MediaDeviceTrackPtr track( this );
558     GenreMap genreMap = m_collection.data()->memoryCollection()->genreMap();
559
560     // do cleanup of soon to be previous genre
561
562     genrePtr = m_genre;
563     if ( !genrePtr.isNull() )
564     {
565         // remove track from previous genre's tracklist
566         genrePtr->remTrack( track );
567         // if genre's tracklist is empty, remove genre from genremap
568         if( genrePtr->tracks().isEmpty() )
569             genreMap.remove( genrePtr->name() );
570     }
571
572     // change to a new genre
573
574     // check for the existence of the genre to be set to,
575     // if genre exists, reuse, else create
576
577     if ( genreMap.contains( newGenre ) )
578     {
579         genrePtr = MediaDeviceGenrePtr::staticCast( genreMap.value( newGenre ) );
580     }
581     else
582     {
583         genrePtr = MediaDeviceGenrePtr( new MediaDeviceGenre( newGenre ) );
584         genreMap.insert( newGenre, GenrePtr::staticCast( genrePtr ) );
585     }
586
587     // add track to genre's tracklist
588     genrePtr->addTrack( track );
589     // set track's genre to the new genre
590     setGenre( genrePtr );
591
592     m_collection.data()->memoryCollection()->acquireWriteLock();
593     m_collection.data()->memoryCollection()->setGenreMap( genreMap );
594     m_collection.data()->memoryCollection()->releaseLock();
595 }
596
597 void
598 MediaDeviceTrack::setComposer( const QString &newComposer )
599 {
600     if( !m_collection )
601         return;
602
603     MediaDeviceComposerPtr composerPtr;
604     MediaDeviceTrackPtr track( this );
605     ComposerMap composerMap = m_collection.data()->memoryCollection()->composerMap();
606
607     // do cleanup of soon to be previous composer
608
609     composerPtr = m_composer;
610     if ( !composerPtr.isNull() )
611     {
612         // remove track from previous composer's tracklist
613         composerPtr->remTrack( track );
614         // if composer's tracklist is empty, remove composer from composermap
615         if( composerPtr->tracks().isEmpty() )
616             composerMap.remove( composerPtr->name() );
617     }
618
619     // change to a new composer
620
621     // check for the existence of the composer to be set to,
622     // if composer exists, reuse, else create
623
624     if ( composerMap.contains( newComposer ) )
625     {
626         composerPtr = MediaDeviceComposerPtr::staticCast( composerMap.value( newComposer ) );
627     }
628     else
629     {
630         composerPtr = MediaDeviceComposerPtr( new MediaDeviceComposer( newComposer ) );
631         composerMap.insert( newComposer, ComposerPtr::staticCast( composerPtr ) );
632     }
633
634     // add track to composer's tracklist
635     composerPtr->addTrack( track );
636     // set track's composer to the new composer
637     setComposer( composerPtr );
638
639     m_collection.data()->memoryCollection()->acquireWriteLock();
640     m_collection.data()->memoryCollection()->setComposerMap( composerMap );
641     m_collection.data()->memoryCollection()->releaseLock();
642 }
643
644 void
645 MediaDeviceTrack::setYear( int newYear )
646 {
647     if( !m_collection )
648         return;
649
650     MediaDeviceYearPtr yearPtr;
651     MediaDeviceTrackPtr track( this );
652     YearMap yearMap = m_collection.data()->memoryCollection()->yearMap();
653
654     // do cleanup of soon to be previous year
655
656     yearPtr = m_year;
657     if ( !yearPtr.isNull() )
658     {
659         // remove track from previous year's tracklist
660         yearPtr->remTrack( track );
661         // if year's tracklist is empty, remove year from yearmap
662         if( yearPtr->tracks().isEmpty() )
663             yearMap.remove( yearPtr->year() );
664     }
665
666     // change to a new year
667
668     // check for the existence of the year to be set to,
669     // if year exists, reuse, else create
670
671     if ( yearMap.contains( newYear ) )
672     {
673         yearPtr = MediaDeviceYearPtr::staticCast( yearMap.value( newYear ) );
674     }
675     else
676     {
677         yearPtr = MediaDeviceYearPtr( new MediaDeviceYear( QString::number(newYear) ) );
678         yearMap.insert( newYear, YearPtr::staticCast( yearPtr ) );
679     }
680
681     // add track to year's tracklist
682     yearPtr->addTrack( track );
683     // set track's year to the new year
684     setYear( yearPtr );
685
686     m_collection.data()->memoryCollection()->acquireWriteLock();
687     m_collection.data()->memoryCollection()->setYearMap( yearMap );
688     m_collection.data()->memoryCollection()->releaseLock();
689 }
690
691 void
692 MediaDeviceTrack::setAlbum( MediaDeviceAlbumPtr album )
693 {
694     m_album = album;
695 }
696
697 void
698 MediaDeviceTrack::setArtist( MediaDeviceArtistPtr artist )
699 {
700     m_artist = artist;
701 }
702
703 void
704 MediaDeviceTrack::setGenre( MediaDeviceGenrePtr genre )
705 {
706     m_genre = genre;
707 }
708
709 void
710 MediaDeviceTrack::setComposer( MediaDeviceComposerPtr composer )
711 {
712     m_composer = composer;
713 }
714
715 void
716 MediaDeviceTrack::setYear( MediaDeviceYearPtr year )
717 {
718     m_year = year;
719 }
720
721 QString
722 MediaDeviceTrack::title() const
723 {
724     return m_name;
725 }
726
727 void
728 MediaDeviceTrack::setTitle( const QString &title )
729 {
730     m_name = title;
731 }
732
733 void
734 MediaDeviceTrack::setLength( qint64 length )
735 {
736     m_length = length;
737 }
738
739 void
740 MediaDeviceTrack::endMetaDataUpdate()
741 {
742     DEBUG_BLOCK
743     // Update info in local mediadevice database struct
744     debug() << "Observer number: " << m_observers.count();
745     notifyObservers();
746 }
747
748 //MediaDeviceArtist
749
750 MediaDeviceArtist::MediaDeviceArtist( const QString &name )
751     : Meta::Artist()
752     , m_name( name )
753     , m_tracks()
754 {
755     //nothing to do
756 }
757
758 MediaDeviceArtist::~MediaDeviceArtist()
759 {
760     //nothing to do
761 }
762
763 QString
764 MediaDeviceArtist::name() const
765 {
766     return m_name;
767 }
768
769 TrackList
770 MediaDeviceArtist::tracks()
771 {
772     return m_tracks;
773 }
774
775 void
776 MediaDeviceArtist::addTrack( MediaDeviceTrackPtr track )
777 {
778     m_tracks.append( TrackPtr::staticCast( track ) );
779 }
780
781 void
782 MediaDeviceArtist::remTrack( MediaDeviceTrackPtr track )
783 {
784     m_tracks.removeOne( TrackPtr::staticCast( track ) );
785 }
786
787 //---------------MediaDeviceAlbum-----------------------------------
788
789 MediaDeviceAlbum::MediaDeviceAlbum( Collections::MediaDeviceCollection *collection, const QString &name )
790     : Meta::Album()
791     , m_collection( collection )
792     , m_artworkCapability()
793     , m_name( name )
794     , m_tracks()
795     , m_isCompilation( false )
796     , m_hasImagePossibility( true ) // assume it has a cover until proven otherwise
797     , m_hasImageChecked( false )
798     , m_image( QImage() )
799     , m_albumArtist( 0 )
800 {
801     MediaDeviceHandler *handler = m_collection.data()->handler();
802     if( handler && handler->hasCapabilityInterface( Handler::Capability::Artwork ) )
803         m_artworkCapability = handler->create<Handler::ArtworkCapability>();
804 }
805
806 MediaDeviceAlbum::~MediaDeviceAlbum()
807 {
808     if( m_artworkCapability )
809         m_artworkCapability.data()->deleteLater();
810     CoverCache::invalidateAlbum( this );
811 }
812
813 QString
814 MediaDeviceAlbum::name() const
815 {
816     return m_name;
817 }
818
819 bool
820 MediaDeviceAlbum::isCompilation() const
821 {
822     return m_isCompilation;
823 }
824
825 void
826 MediaDeviceAlbum::setIsCompilation( bool compilation )
827 {
828     m_isCompilation = compilation;
829 }
830
831 bool
832 MediaDeviceAlbum::hasAlbumArtist() const
833 {
834     return !m_albumArtist.isNull();
835 }
836
837 ArtistPtr
838 MediaDeviceAlbum::albumArtist() const
839 {
840     return ArtistPtr::staticCast( m_albumArtist );
841 }
842
843 TrackList
844 MediaDeviceAlbum::tracks()
845 {
846     return m_tracks;
847 }
848
849 bool
850 MediaDeviceAlbum::hasImage( int size ) const
851 {
852     Q_UNUSED( size )
853
854     if( !m_hasImageChecked )
855         m_hasImagePossibility = ! const_cast<MediaDeviceAlbum*>( this )->image().isNull();
856     return m_hasImagePossibility;
857 }
858
859 QImage
860 MediaDeviceAlbum::image( int size ) const
861 {
862     if( m_name.isEmpty() || !m_hasImagePossibility || m_tracks.isEmpty() )
863         return Meta::Album::image( size );
864
865     if( m_image.isNull() && m_artworkCapability )
866     {
867         MediaDeviceTrackPtr track = MediaDeviceTrackPtr::staticCast( m_tracks.first() );
868         m_image = m_artworkCapability.data()->getCover( track );
869         m_hasImagePossibility = !m_image.isNull();
870         m_hasImageChecked = true;
871         CoverCache::invalidateAlbum( this );
872     }
873
874     if( !m_image.isNull() )
875     {
876         if( !size )
877             return m_image;
878         return m_image.scaled( QSize( size, size ), Qt::KeepAspectRatio );
879     }
880     return Meta::Album::image( size );
881 }
882
883 bool
884 MediaDeviceAlbum::canUpdateImage() const
885 {
886     if( m_artworkCapability )
887         return m_artworkCapability.data()->canUpdateCover();
888     return false;
889 }
890
891 void
892 MediaDeviceAlbum::setImage( const QImage &image )
893 {
894     if( m_artworkCapability && m_artworkCapability.data()->canUpdateCover() )
895     {
896         // reset to initial values, let next call to image() re-fetch it
897         m_hasImagePossibility = true;
898         m_hasImageChecked = false;
899
900         m_artworkCapability.data()->setCover( MediaDeviceAlbumPtr( this ), image );
901         CoverCache::invalidateAlbum( this );
902     }
903 }
904
905 void
906 MediaDeviceAlbum::setImagePath( const QString &path )
907 {
908     if( m_artworkCapability && m_artworkCapability.data()->canUpdateCover() )
909     {
910         // reset to initial values, let next call to image() re-fetch it
911         m_hasImagePossibility = true;
912         m_hasImageChecked = false;
913
914         m_artworkCapability.data()->setCoverPath( MediaDeviceAlbumPtr( this ), path );
915         CoverCache::invalidateAlbum( this );
916     }
917 }
918
919 bool
920 MediaDeviceAlbum::hasCapabilityInterface( Capabilities::Capability::Type type ) const
921 {
922     switch( type )
923     {
924         case Capabilities::Capability::Actions:
925             return true;
926         default:
927             return false;
928     }
929 }
930
931 Capabilities::Capability*
932 MediaDeviceAlbum::createCapabilityInterface( Capabilities::Capability::Type type )
933 {
934     switch( type )
935     {
936         case Capabilities::Capability::Actions:
937         {
938             QList<QAction*> actions;
939             if( m_collection && canUpdateImage() )
940             {
941                 /* none of media device implementations can currently unset cover,
942                  * so it would only confuse user to see "Unset Cover" action. */
943                 QAction *separator          = new QAction( m_collection.data() );
944                 QAction *displayCoverAction = new DisplayCoverAction( m_collection.data(), AlbumPtr::dynamicCast( MediaDeviceAlbumPtr(this) ) );
945
946                 separator->setSeparator( true );
947
948                 actions.append( separator );
949                 actions.append( displayCoverAction );
950                 actions.append( new FetchCoverAction( m_collection.data(), AlbumPtr::staticCast( MediaDeviceAlbumPtr(this) ) ) );
951                 actions.append( new SetCustomCoverAction( m_collection.data(), AlbumPtr::staticCast( MediaDeviceAlbumPtr(this) ) ) );
952                 if( !hasImage() )
953                 {
954                     displayCoverAction->setEnabled( false );
955                 }
956             }
957             return new Capabilities::ActionsCapability( actions );
958         }
959
960         default:
961             return 0;
962     }
963 }
964
965 void
966 MediaDeviceAlbum::addTrack( MediaDeviceTrackPtr track )
967 {
968     m_tracks.append( TrackPtr::staticCast( track ) );
969 }
970
971 void
972 MediaDeviceAlbum::remTrack( MediaDeviceTrackPtr track )
973 {
974     m_tracks.removeOne( TrackPtr::staticCast( track ) );
975 }
976
977 void
978 MediaDeviceAlbum::setAlbumArtist( MediaDeviceArtistPtr artist )
979 {
980     m_albumArtist = artist;
981 }
982
983 //MediaDeviceComposer
984
985 MediaDeviceComposer::MediaDeviceComposer( const QString &name )
986     : Meta::Composer()
987     , m_name( name )
988     , m_tracks()
989 {
990     //nothing to do
991 }
992
993 MediaDeviceComposer::~MediaDeviceComposer()
994 {
995     //nothing to do
996 }
997
998 QString
999 MediaDeviceComposer::name() const
1000 {
1001     return m_name;
1002 }
1003
1004 TrackList
1005 MediaDeviceComposer::tracks()
1006 {
1007     return m_tracks;
1008 }
1009
1010 void
1011 MediaDeviceComposer::addTrack( MediaDeviceTrackPtr track )
1012 {
1013     m_tracks.append( TrackPtr::staticCast( track ) );
1014 }
1015
1016 void
1017 MediaDeviceComposer::remTrack( MediaDeviceTrackPtr track )
1018 {
1019     m_tracks.removeOne( TrackPtr::staticCast( track ) );
1020 }
1021
1022 //---------------MediaDeviceGenre-----------------------------------
1023
1024 MediaDeviceGenre::MediaDeviceGenre( const QString &name )
1025     : Meta::Genre()
1026     , m_name( name )
1027     , m_tracks()
1028 {
1029     //nothing to do
1030 }
1031
1032 MediaDeviceGenre::~MediaDeviceGenre()
1033 {
1034     //nothing to do
1035 }
1036
1037 QString
1038 MediaDeviceGenre::name() const
1039 {
1040     return m_name;
1041 }
1042
1043 TrackList
1044 MediaDeviceGenre::tracks()
1045 {
1046     return m_tracks;
1047 }
1048
1049 void
1050 MediaDeviceGenre::addTrack( MediaDeviceTrackPtr track )
1051 {
1052     m_tracks.append( TrackPtr::staticCast( track ) );
1053 }
1054
1055 void
1056 MediaDeviceGenre::remTrack( MediaDeviceTrackPtr track )
1057 {
1058     m_tracks.removeOne( TrackPtr::staticCast( track ) );
1059 }
1060
1061
1062 //MediaDeviceYear
1063
1064 MediaDeviceYear::MediaDeviceYear( const QString &name )
1065     : Meta::Year()
1066     , m_name( name )
1067     , m_tracks()
1068 {
1069     //nothing to do
1070 }
1071
1072 MediaDeviceYear::~MediaDeviceYear()
1073 {
1074     //nothing to do
1075 }
1076
1077 QString
1078 MediaDeviceYear::name() const
1079 {
1080     return m_name;
1081 }
1082
1083 TrackList
1084 MediaDeviceYear::tracks()
1085 {
1086     return m_tracks;
1087 }
1088
1089 void
1090 MediaDeviceYear::addTrack( MediaDeviceTrackPtr track )
1091 {
1092     m_tracks.append( TrackPtr::staticCast( track ) );
1093 }
1094
1095 void
1096 MediaDeviceYear::remTrack( MediaDeviceTrackPtr track )
1097 {
1098     m_tracks.removeOne( TrackPtr::staticCast( track ) );
1099 }
1100
1101 #include "mediadevicemeta.moc"