File indexing completed on 2025-01-19 04:24:39

0001 /****************************************************************************************
0002  * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org>                                *
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 "core-impl/meta/timecode/TimecodeMeta.h"
0018 
0019 #include "core/support/Debug.h"
0020 #include "covermanager/CoverCache.h"
0021 #include "covermanager/CoverFetchingActions.h"
0022 #include "covermanager/CoverFetcher.h"
0023 #include "core/capabilities/ActionsCapability.h"
0024 #include "core/capabilities/Capability.h"
0025 #include "core/capabilities/BoundedPlaybackCapability.h"
0026 #include "core-impl/capabilities/AlbumActionsCapability.h"
0027 #include "core-impl/capabilities/timecode/TimecodeBoundedPlaybackCapability.h"
0028 
0029 #include <KLocalizedString>
0030 
0031 using namespace Meta;
0032 using namespace Capabilities;
0033 
0034 ////////////////// TRACK //////////////////
0035 
0036 TimecodeTrack::TimecodeTrack( const QString &name, const QUrl &url, qint64 start, qint64 end )
0037     : m_name( name )
0038     , m_start( start )
0039     , m_end( end )
0040     , m_length( end - start )
0041     , m_bpm( -1.0 )
0042     , m_trackNumber( 0 )
0043     , m_discNumber( 0 )
0044     , m_comment( QString() )
0045     , m_playableUrl( url )
0046     , m_updatedFields( 0 )
0047 {
0048     m_displayUrl = url.toDisplayString() + QLatin1Char(':') + QString::number( start ) + '-' + QString::number( end );
0049 }
0050 
0051 TimecodeTrack::~ TimecodeTrack()
0052 {
0053 }
0054 
0055 QString
0056 TimecodeTrack::name() const
0057 {
0058     return m_name;
0059 }
0060 
0061 QUrl
0062 TimecodeTrack::playableUrl() const
0063 {
0064     return m_playableUrl;
0065 }
0066 
0067 QString
0068 TimecodeTrack::uidUrl() const
0069 {
0070     return m_displayUrl;
0071 }
0072 
0073 QString
0074 TimecodeTrack::prettyUrl() const
0075 {
0076     return m_displayUrl;
0077 }
0078 
0079 QString
0080 TimecodeTrack::notPlayableReason() const
0081 {
0082     if( !m_playableUrl.isLocalFile() )
0083         return i18n( "Url is not a local file" );
0084 
0085     return localFileNotPlayableReason( m_playableUrl.toLocalFile() );
0086 }
0087 
0088 AlbumPtr
0089 TimecodeTrack::album() const
0090 {
0091     return AlbumPtr::staticCast( m_album );
0092 }
0093 
0094 ArtistPtr
0095 TimecodeTrack::artist() const
0096 {
0097     return ArtistPtr::staticCast( m_artist );
0098 }
0099 
0100 GenrePtr
0101 TimecodeTrack::genre() const
0102 {
0103     return GenrePtr::staticCast( m_genre );
0104 }
0105 
0106 ComposerPtr
0107 TimecodeTrack::composer() const
0108 {
0109     return ComposerPtr::staticCast( m_composer );
0110 }
0111 
0112 YearPtr
0113 TimecodeTrack::year() const
0114 {
0115     return YearPtr::staticCast( m_year );
0116 }
0117 
0118 qreal
0119 TimecodeTrack::bpm() const
0120 {
0121     return m_bpm;
0122 }
0123 
0124 QString
0125 TimecodeTrack::comment() const
0126 {
0127     return m_comment;
0128 }
0129 
0130 int
0131 TimecodeTrack::bitrate() const
0132 {
0133     return -1;
0134 }
0135 
0136 int
0137 TimecodeTrack::sampleRate() const
0138 {
0139     return -1;
0140 }
0141 
0142 int
0143 TimecodeTrack::filesize() const
0144 {
0145     return -1;
0146 }
0147 
0148 qint64
0149 TimecodeTrack::length() const
0150 {
0151     return m_length;
0152 }
0153 
0154 int
0155 TimecodeTrack::trackNumber() const
0156 {
0157     return m_trackNumber;
0158 }
0159 
0160 int
0161 TimecodeTrack::discNumber() const
0162 {
0163     return m_discNumber;
0164 }
0165 
0166 QString
0167 TimecodeTrack::type() const
0168 {
0169     return QString();
0170 }
0171 
0172 void
0173 TimecodeTrack::setAlbum( const QString &newAlbum )
0174 {
0175     m_updatedFields |= ALBUM_UPDATED;
0176     m_fields.insert( ALBUM_UPDATED, newAlbum );
0177 }
0178 
0179 void
0180 TimecodeTrack::setArtist( const QString &newArtist )
0181 {
0182     m_updatedFields |= ARTIST_UPDATED;
0183     m_fields.insert( ARTIST_UPDATED, newArtist );
0184 }
0185 
0186 void
0187 TimecodeTrack::setComposer( const QString &newComposer )
0188 {
0189     m_updatedFields |= COMPOSER_UPDATED;
0190     m_fields.insert( COMPOSER_UPDATED, newComposer );
0191 }
0192 
0193 void
0194 TimecodeTrack::setGenre( const QString &newGenre )
0195 {
0196     m_updatedFields |= GENRE_UPDATED;
0197     m_fields.insert( GENRE_UPDATED, newGenre );
0198 }
0199 
0200 void
0201 TimecodeTrack::setYear( int newYear )
0202 {
0203     m_updatedFields |= YEAR_UPDATED;
0204     m_fields.insert( YEAR_UPDATED, QString::number( newYear ) );
0205 }
0206 
0207 void
0208 TimecodeTrack::setBpm( const qreal newBpm )
0209 {
0210     m_updatedFields |= BPM_UPDATED;
0211     m_fields.insert( BPM_UPDATED, QString::number( (qreal) newBpm ) );
0212 }
0213 
0214 void
0215 TimecodeTrack::setTitle( const QString &newTitle )
0216 {
0217     m_updatedFields |= TITLE_UPDATED;
0218     m_fields.insert( TITLE_UPDATED, newTitle );
0219 }
0220 
0221 void
0222 TimecodeTrack::setComment( const QString &newComment )
0223 {
0224     m_updatedFields |= COMMENT_UPDATED;
0225     m_fields.insert( COMMENT_UPDATED, newComment );
0226 }
0227 
0228 void
0229 TimecodeTrack::setTrackNumber( int newTrackNumber )
0230 {
0231     m_updatedFields |= TRACKNUMBER_UPDATED;
0232     m_fields.insert( TRACKNUMBER_UPDATED, QString::number( newTrackNumber ) );
0233 }
0234 
0235 void
0236 TimecodeTrack::setDiscNumber( int newDiscNumber )
0237 {
0238     m_updatedFields |= DISCNUMBER_UPDATED;
0239     m_fields.insert( DISCNUMBER_UPDATED, QString::number( newDiscNumber ) );
0240 }
0241 
0242 void TimecodeTrack::beginUpdate()
0243 {
0244     m_updatedFields = 0;
0245     m_fields.clear();
0246 }
0247 
0248 void TimecodeTrack::endUpdate()
0249 {
0250 
0251     bool updateCover = false;
0252 
0253     if ( m_updatedFields & ALBUM_UPDATED )
0254     {
0255         //create a new album:
0256         m_album = TimecodeAlbumPtr( new TimecodeAlbum( m_fields.value( ALBUM_UPDATED ) ) );
0257         m_album->addTrack( TimecodeTrackPtr( this ) );
0258         setAlbum( m_album );
0259         m_album->setAlbumArtist( m_artist );
0260     }
0261 
0262     if ( m_updatedFields & ARTIST_UPDATED )
0263     {
0264         //create a new album:
0265         m_artist = TimecodeArtistPtr( new TimecodeArtist( m_fields.value( ARTIST_UPDATED ) ) );
0266         m_artist->addTrack( TimecodeTrackPtr( this ) );
0267         setArtist( m_artist );
0268         m_album->setAlbumArtist( m_artist );
0269         updateCover = true;
0270     }
0271 
0272     if ( m_updatedFields & COMPOSER_UPDATED )
0273     {
0274         //create a new album:
0275         m_composer = TimecodeComposerPtr( new TimecodeComposer( m_fields.value( COMPOSER_UPDATED ) ) );
0276         m_composer->addTrack( TimecodeTrackPtr( this ) );
0277         setComposer( m_composer );
0278     }
0279 
0280     if ( m_updatedFields & GENRE_UPDATED )
0281     {
0282         //create a new album:
0283         m_genre = TimecodeGenrePtr( new TimecodeGenre( m_fields.value( GENRE_UPDATED ) ) );
0284         m_genre->addTrack( TimecodeTrackPtr( this ) );
0285         setGenre( m_genre );
0286     }
0287 
0288     if ( m_updatedFields & YEAR_UPDATED )
0289     {
0290         //create a new album:
0291         m_year = TimecodeYearPtr( new TimecodeYear( m_fields.value( YEAR_UPDATED ) ) );
0292         m_year->addTrack( TimecodeTrackPtr( this ) );
0293         setYear( m_year );
0294     }
0295 
0296     if ( m_updatedFields & BPM_UPDATED )
0297     {
0298         m_bpm = m_fields.value( BPM_UPDATED ).toDouble();
0299     }
0300 
0301     if ( m_updatedFields & TITLE_UPDATED )
0302     {
0303         //create a new album:
0304         m_name = m_fields.value( TITLE_UPDATED );
0305         updateCover = true;
0306     }
0307 
0308     if ( m_updatedFields & COMMENT_UPDATED )
0309     {
0310         //create a new album:
0311         m_comment = m_fields.value( COMMENT_UPDATED );
0312     }
0313 
0314     if ( m_updatedFields & TRACKNUMBER_UPDATED )
0315     {
0316         //create a new album:
0317         m_trackNumber = m_fields.value( TRACKNUMBER_UPDATED ).toInt();
0318     }
0319 
0320     if ( m_updatedFields & DISCNUMBER_UPDATED )
0321     {
0322         //create a new album:
0323         m_discNumber = m_fields.value( DISCNUMBER_UPDATED ).toInt();
0324     }
0325 
0326     if ( updateCover )
0327         The::coverFetcher()->queueAlbum( AlbumPtr::staticCast( m_album ) );
0328 
0329     m_updatedFields = 0;
0330     m_fields.clear();
0331 
0332     notifyObservers();
0333 }
0334 
0335 void
0336 TimecodeTrack::setAlbum( const TimecodeAlbumPtr &album )
0337 {
0338     m_album = album;
0339 }
0340 
0341 void
0342 TimecodeTrack::setAlbumArtist( const QString & )
0343 {
0344     // no support for it
0345 }
0346 
0347 void
0348 TimecodeTrack::setYear( const TimecodeYearPtr &year )
0349 {
0350     m_year = year;
0351 }
0352 
0353 void
0354 TimecodeTrack::setGenre( const TimecodeGenrePtr &genre )
0355 {
0356     m_genre = genre;
0357 }
0358 
0359 void
0360 TimecodeTrack::setComposer( const TimecodeComposerPtr &composer )
0361 {
0362     m_composer = composer;
0363 }
0364 
0365 void
0366 TimecodeTrack::setArtist( const TimecodeArtistPtr &artist )
0367 {
0368     m_artist = artist;
0369 }
0370 
0371 
0372 bool
0373 TimecodeTrack::hasCapabilityInterface( Capabilities::Capability::Type type ) const
0374 {
0375     return type == Capabilities::Capability::BoundedPlayback;
0376 }
0377 
0378 Capabilities::Capability *
0379 TimecodeTrack::createCapabilityInterface( Capabilities::Capability::Type type )
0380 {
0381     DEBUG_BLOCK
0382 
0383     if ( type == Capabilities::Capability::BoundedPlayback )
0384         return new Capabilities::TimecodeBoundedPlaybackCapability( this );
0385     else
0386         return nullptr;
0387 }
0388 
0389 TrackEditorPtr
0390 TimecodeTrack::editor()
0391 {
0392     return TrackEditorPtr( this );
0393 }
0394 
0395 qint64 Meta::TimecodeTrack::start()
0396 {
0397     return m_start;
0398 }
0399 
0400 qint64 Meta::TimecodeTrack::end()
0401 {
0402     return m_end;
0403 }
0404 
0405 
0406 ////////////////// ARTIST //////////////////
0407 
0408 TimecodeArtist::TimecodeArtist( const QString & name )
0409     : m_name( name )
0410 {
0411 }
0412 
0413 TimecodeArtist::~ TimecodeArtist()
0414 {
0415 }
0416 
0417 QString
0418 TimecodeArtist::name() const
0419 {
0420     return m_name;
0421 }
0422 
0423 TrackList
0424 TimecodeArtist::tracks()
0425 {
0426     return m_tracks;
0427 }
0428 
0429 AlbumList
0430 TimecodeArtist::albums()
0431 {
0432     return AlbumList();
0433 }
0434 
0435 void
0436 TimecodeArtist::addTrack( const TimecodeTrackPtr &track )
0437 {
0438     m_tracks.append( TrackPtr::staticCast( track ) );
0439 }
0440 
0441 ////////////////// ALBUM //////////////////
0442 
0443 TimecodeAlbum::TimecodeAlbum( const QString & name )
0444     : QObject()
0445     , m_name( name )
0446     , m_isCompilation( false )
0447 {
0448 }
0449 
0450 TimecodeAlbum::~ TimecodeAlbum()
0451 {
0452     CoverCache::invalidateAlbum( this );
0453 }
0454 
0455 QString
0456 TimecodeAlbum::name() const
0457 {
0458     return m_name;
0459 }
0460 
0461 bool
0462 TimecodeAlbum::isCompilation() const
0463 {
0464     return m_isCompilation;
0465 }
0466 
0467 bool TimecodeAlbum::hasAlbumArtist() const
0468 {
0469     return !m_albumArtist.isNull();
0470 }
0471 
0472 ArtistPtr TimecodeAlbum::albumArtist() const
0473 {
0474     return ArtistPtr::staticCast( m_albumArtist );
0475 }
0476 
0477 TrackList
0478 TimecodeAlbum::tracks()
0479 {
0480     return m_tracks;
0481 }
0482 
0483 QImage
0484 TimecodeAlbum::image( int size ) const
0485 {
0486     if( m_cover.isNull() )
0487         return Meta::Album::image( size );
0488     else
0489         return m_cover.scaled( size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
0490 }
0491 
0492 bool
0493 TimecodeAlbum::canUpdateImage() const
0494 {
0495     return true;
0496 }
0497 
0498 void
0499 TimecodeAlbum::setImage( const QImage &image )
0500 {
0501     m_cover = image;
0502     CoverCache::invalidateAlbum( this );
0503     notifyObservers();
0504 }
0505 
0506 void
0507 TimecodeAlbum::addTrack( const TimecodeTrackPtr &track )
0508 {
0509     m_tracks.append( TrackPtr::staticCast( track ) );
0510 }
0511 
0512 void TimecodeAlbum::setAlbumArtist( const TimecodeArtistPtr &artist )
0513 {
0514     m_albumArtist = artist;
0515 }
0516 
0517 bool TimecodeAlbum::hasCapabilityInterface( Capabilities::Capability::Type type ) const
0518 {
0519     switch( type )
0520     {
0521         case Capabilities::Capability::Actions:
0522             return true;
0523         default:
0524             return false;
0525     }
0526 }
0527 
0528 Capabilities::Capability* TimecodeAlbum::createCapabilityInterface( Capabilities::Capability::Type type )
0529 {
0530     switch( type )
0531     {
0532         case Capabilities::Capability::Actions:
0533             return new AlbumActionsCapability( Meta::AlbumPtr( this ) );
0534         default:
0535             return nullptr;
0536     }
0537 }
0538 
0539 ////////////////// GENRE //////////////////
0540 
0541 TimecodeGenre::TimecodeGenre(const QString & name)
0542     : m_name( name )
0543 {
0544 }
0545 
0546 TimecodeGenre::~ TimecodeGenre()
0547 {
0548 }
0549 
0550 QString
0551 TimecodeGenre::name() const
0552 {
0553     return m_name;
0554 }
0555 
0556 TrackList
0557 TimecodeGenre::tracks()
0558 {
0559     return m_tracks;
0560 }
0561 
0562 void
0563 TimecodeGenre::addTrack( const TimecodeTrackPtr &track )
0564 {
0565     m_tracks.append( TrackPtr::staticCast( track ) );
0566 }
0567 
0568 ////////////////// COMPOSER //////////////////
0569 
0570 TimecodeComposer::TimecodeComposer( const QString & name )
0571     : m_name( name )
0572 {
0573 }
0574 
0575 TimecodeComposer::~ TimecodeComposer()
0576 {
0577 }
0578 
0579 QString
0580 TimecodeComposer::name() const
0581 {
0582     return m_name;
0583 }
0584 
0585 TrackList
0586 TimecodeComposer::tracks()
0587 {
0588     return m_tracks;
0589 }
0590 
0591 void
0592 TimecodeComposer::addTrack( const TimecodeTrackPtr &track )
0593 {
0594     m_tracks.append( TrackPtr::staticCast( track ) );
0595 }
0596 
0597 ////////////////// YEAR //////////////////
0598 
0599 TimecodeYear::TimecodeYear( const QString & name )
0600     : m_name( name )
0601 {
0602 }
0603 
0604 TimecodeYear::~ TimecodeYear()
0605 {
0606 }
0607 
0608 QString
0609 TimecodeYear::name() const
0610 {
0611     return m_name;
0612 }
0613 
0614 TrackList
0615 TimecodeYear::tracks()
0616 {
0617     return m_tracks;
0618 }
0619 
0620 void
0621 TimecodeYear::addTrack( const TimecodeTrackPtr &track )
0622 {
0623     m_tracks.append( TrackPtr::staticCast( track ) );
0624 }
0625