File indexing completed on 2025-01-05 04:26:11
0001 /**************************************************************************************** 0002 * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.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 #ifndef AMAROK_METAPROXY_P_H 0018 #define AMAROK_METAPROXY_P_H 0019 0020 #include "core/collections/Collection.h" 0021 #include "core/meta/Meta.h" 0022 #include "core/meta/Observer.h" 0023 #include "core-impl/meta/stream/Stream.h" 0024 0025 #include <QImage> 0026 #include <QList> 0027 #include <QObject> 0028 #include <QStringList> 0029 0030 #include <kio/job.h> 0031 #include <kio/jobclasses.h> 0032 0033 0034 using namespace MetaProxy; 0035 0036 class MetaProxy::Track::Private : public QObject, public Meta::Observer 0037 { 0038 Q_OBJECT 0039 0040 public: 0041 Track *proxy; 0042 QUrl url; 0043 0044 Meta::TrackPtr realTrack; 0045 0046 QString cachedArtist; 0047 QString cachedAlbum; 0048 QString cachedName; 0049 QString cachedGenre; 0050 QString cachedComposer; 0051 int cachedYear; 0052 qint64 cachedLength; 0053 qreal cachedBpm; 0054 int cachedTrackNumber; 0055 int cachedDiscNumber; 0056 0057 Meta::ArtistPtr artistPtr; 0058 Meta::AlbumPtr albumPtr; 0059 Meta::GenrePtr genrePtr; 0060 Meta::ComposerPtr composerPtr; 0061 Meta::YearPtr yearPtr; 0062 0063 public: 0064 using Observer::metadataChanged; 0065 void metadataChanged( const Meta::TrackPtr &track ) override 0066 { 0067 Q_UNUSED( track ) 0068 proxy->notifyObservers(); 0069 } 0070 0071 public Q_SLOTS: 0072 void slotUpdateTrack( const Meta::TrackPtr &track ) 0073 { 0074 if( track ) 0075 { 0076 // special handling for streams that cannot fetch metadata until played, bug 305389 0077 MetaStream::Track *stream = dynamic_cast<MetaStream::Track *>( track.data() ); 0078 if( stream ) 0079 stream->setInitialInfo( cachedArtist, cachedAlbum, cachedName, 0080 cachedLength, cachedTrackNumber ); 0081 0082 subscribeTo( track ); 0083 realTrack = track; 0084 0085 // clear memory of now-unused cached fields: 0086 url.clear(); 0087 cachedArtist.clear(); 0088 cachedAlbum.clear(); 0089 cachedName.clear(); 0090 cachedGenre.clear(); 0091 cachedComposer.clear(); 0092 0093 proxy->notifyObservers(); 0094 } 0095 } 0096 }; 0097 0098 // internal helper classes 0099 0100 class ProxyArtist : public Meta::Artist 0101 { 0102 public: 0103 explicit ProxyArtist( MetaProxy::Track::Private *dptr ) 0104 : Meta::Artist() 0105 , d( dptr ) 0106 {} 0107 0108 Meta::TrackList tracks() override 0109 { 0110 Meta::TrackPtr realTrack = d ? d->realTrack : Meta::TrackPtr(); 0111 Meta::ArtistPtr artist = realTrack ? realTrack->artist() : Meta::ArtistPtr(); 0112 return artist ? artist->tracks() : Meta::TrackList(); 0113 } 0114 0115 QString name() const override 0116 { 0117 Meta::TrackPtr realTrack = d ? d->realTrack : Meta::TrackPtr(); 0118 if( realTrack ) 0119 { 0120 Meta::ArtistPtr artist = realTrack ? realTrack->artist() : Meta::ArtistPtr(); 0121 return artist ? artist->name() : QString(); 0122 } 0123 return d ? d->cachedArtist : QString(); 0124 } 0125 0126 QString prettyName() const override 0127 { 0128 Meta::TrackPtr realTrack = d ? d->realTrack : Meta::TrackPtr(); 0129 if( realTrack ) 0130 { 0131 Meta::ArtistPtr artist = realTrack ? realTrack->artist() : Meta::ArtistPtr(); 0132 return artist ? artist->prettyName() : QString(); 0133 } 0134 return d ? d->cachedArtist : QString(); 0135 } 0136 0137 bool operator==( const Meta::Artist &artist ) const override 0138 { 0139 const ProxyArtist *proxy = dynamic_cast<const ProxyArtist*>( &artist ); 0140 if( proxy ) 0141 { 0142 return d && proxy->d && d->realTrack && proxy->d->realTrack && d->realTrack->artist() && d->realTrack->artist() == proxy->d->realTrack->artist(); 0143 } 0144 else 0145 { 0146 return d && d->realTrack && d->realTrack->artist() && d->realTrack->artist().data() == &artist; 0147 } 0148 } 0149 0150 MetaProxy::Track::Private * const d; 0151 }; 0152 0153 /** TODO: what about MetaDataChanged? */ 0154 class ProxyAlbum : public Meta::Album 0155 { 0156 public: 0157 explicit ProxyAlbum( MetaProxy::Track::Private *dptr ) 0158 : Meta::Album() 0159 , d( dptr ) 0160 {} 0161 0162 bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override 0163 { 0164 if( d && d->realTrack && d->realTrack->album() ) 0165 return d->realTrack->album()->hasCapabilityInterface( type ); 0166 else 0167 return false; 0168 } 0169 0170 Capabilities::Capability* createCapabilityInterface( Capabilities::Capability::Type type ) override 0171 { 0172 if( d && d->realTrack && d->realTrack->album() ) 0173 return d->realTrack->album()->createCapabilityInterface( type ); 0174 else 0175 return nullptr; 0176 } 0177 0178 bool isCompilation() const override 0179 { 0180 if( d && d->realTrack && d->realTrack->album() ) 0181 return d->realTrack->album()->isCompilation(); 0182 else 0183 return false; 0184 } 0185 0186 bool canUpdateCompilation() const override 0187 { 0188 if( d && d->realTrack && d->realTrack->album() ) 0189 return d->realTrack->album()->canUpdateCompilation(); 0190 else 0191 return Meta::Album::canUpdateCompilation(); 0192 } 0193 0194 void setCompilation( bool isCompilation ) override 0195 { 0196 if( d && d->realTrack && d->realTrack->album() ) 0197 d->realTrack->album()->setCompilation( isCompilation ); 0198 } 0199 0200 bool hasAlbumArtist() const override 0201 { 0202 if( d && d->realTrack && d->realTrack->album() ) 0203 return d->realTrack->album()->hasAlbumArtist(); 0204 else 0205 return false; 0206 } 0207 0208 Meta::ArtistPtr albumArtist() const override 0209 { 0210 if( d && d->realTrack && d->realTrack->album() ) 0211 return d->realTrack->album()->albumArtist(); 0212 else 0213 return Meta::ArtistPtr(); 0214 } 0215 0216 Meta::TrackList tracks() override 0217 { 0218 if( d && d->realTrack && d->realTrack->album() ) 0219 return d->realTrack->album()->tracks(); 0220 else 0221 return Meta::TrackList(); 0222 } 0223 0224 QString name() const override 0225 { 0226 if( d && d->realTrack ) 0227 { 0228 if ( d->realTrack->album() ) 0229 return d->realTrack->album()->name(); 0230 return QString(); 0231 } 0232 else if ( d ) 0233 return d->cachedAlbum; 0234 else 0235 return QString(); 0236 } 0237 0238 QString prettyName() const override 0239 { 0240 if( d && d->realTrack && d->realTrack->album() ) 0241 return d->realTrack->album()->prettyName(); 0242 else 0243 return name(); 0244 } 0245 0246 QImage image( int size ) const override 0247 { 0248 if( d && d->realTrack && d->realTrack->album() ) 0249 return d->realTrack->album()->image( size ); 0250 else 0251 return Meta::Album::image( size ); 0252 } 0253 0254 bool hasImage( int size ) const override 0255 { 0256 if( d && d->realTrack && d->realTrack->album() ) 0257 return d->realTrack->album()->hasImage( size ); 0258 else 0259 return Meta::Album::hasImage( size ); 0260 } 0261 0262 QUrl imageLocation( int size = 0 ) override 0263 { 0264 if( d && d->realTrack && d->realTrack->album() ) 0265 return d->realTrack->album()->imageLocation( size ); 0266 else 0267 return Meta::Album::imageLocation( size ); 0268 } 0269 0270 bool canUpdateImage() const override 0271 { 0272 if( d && d->realTrack && d->realTrack->album() ) 0273 return d->realTrack->album()->canUpdateImage(); 0274 else 0275 return Meta::Album::canUpdateImage(); 0276 } 0277 0278 void setImage( const QImage &image ) override 0279 { 0280 if( d && d->realTrack && d->realTrack->album() ) 0281 d->realTrack->album()->setImage( image ); 0282 } 0283 0284 void removeImage() override 0285 { 0286 if( d && d->realTrack && d->realTrack->album() ) 0287 d->realTrack->album()->removeImage(); 0288 } 0289 0290 bool operator==( const Meta::Album &album ) const override 0291 { 0292 const ProxyAlbum *proxy = dynamic_cast<const ProxyAlbum*>( &album ); 0293 if( proxy ) 0294 { 0295 return d && proxy->d && d->realTrack && proxy->d->realTrack && d->realTrack->album() && ( *d->realTrack->album().data() ) == ( *proxy->d->realTrack->album().data() ); 0296 } 0297 else 0298 { 0299 return d && d->realTrack && d->realTrack->album() && ( *d->realTrack->album().data() ) == album; 0300 } 0301 } 0302 0303 MetaProxy::Track::Private * const d; 0304 }; 0305 0306 class ProxyGenre : public Meta::Genre 0307 { 0308 public: 0309 explicit ProxyGenre( MetaProxy::Track::Private *dptr ) 0310 : Meta::Genre() 0311 , d( dptr ) 0312 {} 0313 0314 QString name() const override 0315 { 0316 if( d && d->realTrack && d->realTrack->genre() ) 0317 return d->realTrack->genre()->name(); 0318 else if( d ) 0319 return d->cachedGenre; 0320 else 0321 return QString(); 0322 } 0323 0324 QString prettyName() const override 0325 { 0326 if( d && d->realTrack && d->realTrack->genre() ) 0327 return d->realTrack->genre()->prettyName(); 0328 else 0329 return QString(); 0330 } 0331 0332 Meta::TrackList tracks() override 0333 { 0334 if( d && d->realTrack && d->realTrack->genre() ) 0335 return d->realTrack->genre()->tracks(); 0336 else 0337 return Meta::TrackList(); 0338 } 0339 0340 bool operator==( const Meta::Genre &genre ) const override 0341 { 0342 const ProxyGenre *proxy = dynamic_cast<const ProxyGenre*>( &genre ); 0343 if( proxy ) 0344 { 0345 return d && proxy->d && d->realTrack && proxy->d->realTrack && d->realTrack->genre() && d->realTrack->genre() == proxy->d->realTrack->genre(); 0346 } 0347 else 0348 { 0349 return d && d->realTrack && d->realTrack->genre() && d->realTrack->genre().data() == &genre; 0350 } 0351 } 0352 0353 MetaProxy::Track::Private * const d; 0354 }; 0355 0356 class ProxyComposer : public Meta::Composer 0357 { 0358 public: 0359 explicit ProxyComposer( MetaProxy::Track::Private *dptr ) 0360 : Meta::Composer() 0361 , d( dptr ) 0362 {} 0363 0364 QString name() const override 0365 { 0366 if( d && d->realTrack && d->realTrack->composer() ) 0367 return d->realTrack->composer()->name(); 0368 else if ( d ) 0369 return d->cachedComposer; 0370 else 0371 return QString(); 0372 } 0373 0374 QString prettyName() const override 0375 { 0376 if( d && d->realTrack && d->realTrack->composer()) 0377 return d->realTrack->composer()->prettyName(); 0378 else 0379 return name(); 0380 } 0381 0382 Meta::TrackList tracks() override 0383 { 0384 if( d && d->realTrack && d->realTrack->composer() ) 0385 return d->realTrack->composer()->tracks(); 0386 else 0387 return Meta::TrackList(); 0388 } 0389 0390 bool operator==( const Meta::Composer &composer ) const override 0391 { 0392 const ProxyComposer *proxy = dynamic_cast<const ProxyComposer*>( &composer ); 0393 if( proxy ) 0394 { 0395 return d && proxy->d && d->realTrack && proxy->d->realTrack && d->realTrack->composer() && d->realTrack->composer() == proxy->d->realTrack->composer(); 0396 } 0397 else 0398 { 0399 return d && d->realTrack && d->realTrack->composer() && d->realTrack->composer().data() == &composer; 0400 } 0401 } 0402 0403 MetaProxy::Track::Private * const d; 0404 }; 0405 0406 class ProxyYear : public Meta::Year 0407 { 0408 public: 0409 explicit ProxyYear( MetaProxy::Track::Private *dptr ) 0410 : Meta::Year() 0411 , d( dptr ) 0412 {} 0413 0414 QString name() const override 0415 { 0416 if( d && d->realTrack && d->realTrack->year() ) 0417 return d->realTrack->year()->name(); 0418 else if( d ) 0419 return QString::number(d->cachedYear); 0420 else 0421 return QString(); 0422 } 0423 0424 QString prettyName() const override 0425 { 0426 if( d && d->realTrack && d->realTrack->year() ) 0427 return d->realTrack->year()->prettyName(); 0428 else 0429 return name(); 0430 } 0431 0432 Meta::TrackList tracks() override 0433 { 0434 if( d && d->realTrack && d->realTrack->year() ) 0435 return d->realTrack->year()->tracks(); 0436 else 0437 return Meta::TrackList(); 0438 } 0439 0440 bool operator==( const Meta::Year &year ) const override 0441 { 0442 const ProxyYear *proxy = dynamic_cast<const ProxyYear*>( &year ); 0443 if( proxy ) 0444 { 0445 return d && proxy->d && d->realTrack && proxy->d->realTrack && d->realTrack->year() && d->realTrack->year() == proxy->d->realTrack->year(); 0446 } 0447 else 0448 { 0449 return d && d->realTrack && d->realTrack->year() && d->realTrack->year().data() == &year; 0450 } 0451 } 0452 0453 MetaProxy::Track::Private * const d; 0454 }; 0455 0456 #endif