File indexing completed on 2024-05-05 04:48:16

0001 /****************************************************************************************
0002  * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com>            *
0003  * Copyright (c) 2008 Mark Kretschmann <kretschmann@kde.org>                            *
0004  *                                                                                      *
0005  * This program is free software; you can redistribute it and/or modify it under        *
0006  * the terms of the GNU General Public License as published by the Free Software        *
0007  * Foundation; either version 2 of the License, or (at your option) any later           *
0008  * version.                                                                             *
0009  *                                                                                      *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0012  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0013  *                                                                                      *
0014  * You should have received a copy of the GNU General Public License along with         *
0015  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0016  ****************************************************************************************/
0017 
0018 #ifndef AMAROK_META_H
0019 #define AMAROK_META_H
0020 
0021 #include "MetaReplayGain.h"
0022 #include "core/meta/Base.h"
0023 
0024 #include <QList>
0025 #include <QMutex>
0026 #include <QImage>
0027 #include <QDateTime>
0028 #include <QSharedData>
0029 
0030 #include <QUrl>
0031 
0032 namespace Collections
0033 {
0034     class Collection;
0035 }
0036 class PersistentStatisticsStore;
0037 
0038 namespace Meta
0039 {
0040     class AMAROKCORE_EXPORT Track : public Base
0041     {
0042         public:
0043             /** used to display the trackname, should never be empty, returns prettyUrl() by default if name() is empty */
0044             QString prettyName() const override;
0045             /** an url which can be played by the engine backends */
0046             virtual QUrl playableUrl() const = 0;
0047             /** an url for display purposes */
0048             virtual QString prettyUrl() const = 0;
0049 
0050             /**
0051              * A fake url which is unique for this track. Use this if you need a key for
0052              * the track.
0053              */
0054             virtual QString uidUrl() const = 0;
0055 
0056             /**
0057              * Return whether playableUrl() will return a valid & readable playable url.
0058              *
0059              * Convenience method that just checks whether notPlayableReason() is empty.
0060              */
0061             bool isPlayable() const;
0062 
0063             /**
0064              * Return user-readable localized reason why isPlayable() is false.
0065              *
0066              * Subclasses must return a non-empty (localized) string if this track is not
0067              * playable (i.e. playableUrl() won't return a valid url) and an empty string
0068              * otherwise.
0069              *
0070              * This method is used to implement convenience Meta::Track::isPlayable()
0071              * method.
0072              */
0073             virtual QString notPlayableReason() const = 0;
0074 
0075             /** Returns the album this track belongs to */
0076             virtual AlbumPtr album() const = 0;
0077             /** Returns the artist of this track */
0078             virtual ArtistPtr artist() const = 0;
0079             /** Returns the composer of this track */
0080             virtual ComposerPtr composer() const = 0;
0081             /** Returns the genre of this track */
0082             virtual GenrePtr genre() const = 0;
0083             /** Returns the year of this track */
0084             virtual YearPtr year() const = 0;
0085             /**
0086               * Returns the labels that are assigned to a track.
0087               */
0088             virtual Meta::LabelList labels() const;
0089             /** Returns the BPM of this track */
0090             virtual qreal bpm() const = 0;
0091             /** Returns the comment of this track */
0092             virtual QString comment() const = 0;
0093             /** Returns the length of this track in milliseconds, or 0 if unknown */
0094             virtual qint64 length() const = 0;
0095             /** Returns the filesize of this track in bytes */
0096             virtual int filesize() const = 0;
0097             /** Returns the sample rate of this track */
0098             virtual int sampleRate() const = 0;
0099             /** Returns the bitrate o this track in kbps (kilo BITS per second) */
0100             virtual int bitrate() const = 0;
0101             /** Returns the time when the track was added to the collection,
0102                 or an invalid QDateTime if the time is not known. */
0103             virtual QDateTime createDate() const;
0104             /** Returns the time when the track was last modified (before being added to the collection)
0105                 or an invalid QDateTime if the time is not known. */
0106             virtual QDateTime modifyDate() const;
0107             /** Returns the track number of this track */
0108             virtual int trackNumber() const = 0;
0109             /** Returns the discnumber of this track */
0110             virtual int discNumber() const = 0;
0111             /**
0112              * Returns the gain adjustment for a given replay gain mode.
0113              *
0114              * Should return @c 0 if no replay gain value is known.
0115              *
0116              * Should return the track replay gain if the album gain is requested but
0117              * is not available.
0118              */
0119             virtual qreal replayGain( ReplayGainTag mode ) const;
0120 
0121             /**
0122              * Returns the type of this track, e.g. "ogg", "mp3", "stream"
0123              *
0124              * TODO: change return type to Amarok::FileType enum. Clients needing
0125              * user-representation would call FileTypeSupport::toLocalizedString()
0126              */
0127             virtual QString type() const = 0;
0128 
0129             /** tell the track to perform any prerequisite
0130              * operations before playing */
0131             virtual void prepareToPlay();
0132 
0133             /** tell the track object that amarok finished playing it.
0134                 The argument is the percentage of the track which was played, in the range 0 to 1*/
0135             virtual void finishedPlaying( double playedFraction );
0136 
0137             /** returns true if the track is part of a collection false otherwise */
0138             virtual bool inCollection() const;
0139             /**
0140                 returns the collection that the track is part of, or 0 iff
0141                 inCollection() returns false */
0142             virtual Collections::Collection* collection() const;
0143 
0144             /** get the cached lyrics for the track. returns an empty string if
0145                 no cached lyrics are available */
0146             virtual QString cachedLyrics() const;
0147             /**
0148                 set the cached lyrics for the track
0149             */
0150             virtual void setCachedLyrics( const QString &lyrics );
0151 
0152             /**
0153               Adds a label to the track.
0154               Does nothing if the track already has the given label.
0155              */
0156             virtual void addLabel( const QString &label );
0157             /**
0158               Adds a label to the track.
0159               Does nothing if the track already has the given label.
0160              */
0161             virtual void addLabel( const Meta::LabelPtr &label );
0162 
0163             /**
0164               Removes a lbel from a track.
0165               Does nothing if the track does not actually have the label assigned to it.
0166              */
0167             virtual void removeLabel( const Meta::LabelPtr &label );
0168 
0169             virtual bool operator==( const Track &track ) const;
0170 
0171             static bool lessThan( const TrackPtr& left, const TrackPtr& right );
0172 
0173             /**
0174              * Return a pointer to TrackEditor interface that allows you to edit metadata
0175              * of this track. May be null, which signifies that the track is not editable.
0176              *
0177              * This is a replacement to \::create<Capabilities::EditCapability>() with more
0178              * well-defined memory management and nicer implementation possibilities.
0179              * (multiple inheritance and returning self)
0180              *
0181              * Default implementation returns null pointer.
0182              */
0183             virtual TrackEditorPtr editor();
0184 
0185             /**
0186              * Return a pointer to track's Statistics interface. May never be null.
0187              *
0188              * Subclasses: always return the default implementation instead of returning 0.
0189              */
0190             virtual StatisticsPtr statistics();
0191             ConstStatisticsPtr statistics() const; // allow const statistics methods on const tracks
0192 
0193         protected:
0194             friend class ::PersistentStatisticsStore; // so that it can call notifyObservers
0195             virtual void notifyObservers() const;
0196 
0197             /**
0198              * Helper method for subclasses to implement notPlayableReason().
0199              * Checks network status and returns a non-empty reason string if
0200              * it isn't online.
0201              */
0202             QString networkNotPlayableReason() const;
0203 
0204             /**
0205              * Helper method for subclasses to implement notPlayableReason().
0206              * Checks, in order, if the file exists, if it is a file and if
0207              * the file is readable
0208              */
0209             QString localFileNotPlayableReason( const QString &path ) const;
0210     };
0211 
0212     class AMAROKCORE_EXPORT Artist : public Base
0213     {
0214         public:
0215             QString prettyName() const override;
0216 
0217             /** returns all tracks by this artist */
0218             virtual TrackList tracks() = 0;
0219 
0220             virtual bool operator==( const Meta::Artist &artist ) const;
0221 
0222             QString sortableName() const override;
0223 
0224         protected:
0225             virtual void notifyObservers() const;
0226 
0227         private:
0228             mutable QString m_sortableName;
0229     };
0230 
0231     /**
0232      * Represents an album.
0233      *
0234      * Most collections do not store a specific album object. Instead an album is just
0235      * a property of a track, a container containing one or more tracks.
0236      *
0237      * Collections should provide an album for every track as the collection browser
0238      * will, depending on the setting, only display tracks inside albums.
0239      *
0240      * For all albums in a compilation the pair album-title/album-artist should be
0241      * unique as this pair is used as a key in several places.
0242      *
0243      * Albums without an artist are called compilations. Albums without a title but
0244      * with an artist should contain all singles of the specific artist. There should
0245      * be one album without title and artist for all the rest.
0246      */
0247     class AMAROKCORE_EXPORT Album : public Base
0248     {
0249         public:
0250             QString prettyName() const override;
0251 
0252             /**
0253              * Whether this album is considered to be a compilation of tracks from various
0254              * artists.
0255              */
0256             virtual bool isCompilation() const = 0;
0257             /**
0258              * Whether toggling the compilation status is currently supported. Default
0259              * implementation returns false.
0260              */
0261             virtual bool canUpdateCompilation() const { return false; }
0262             /**
0263              * Set compilation status. You should check canUpdateCompilation() first.
0264              */
0265             virtual void setCompilation( bool isCompilation ) { Q_UNUSED( isCompilation ) }
0266 
0267             /** Returns true if this album has an album artist */
0268             virtual bool hasAlbumArtist() const = 0;
0269             /** Returns a pointer to the album's artist */
0270             virtual ArtistPtr albumArtist() const = 0;
0271             /** returns all tracks on this album */
0272             virtual TrackList tracks() = 0;
0273 
0274             /**
0275              * A note about image sizes:
0276              *  when size is <= 1, return the full size image
0277              */
0278             /** returns true if the album has a cover set */
0279             virtual bool hasImage( int size = 0 ) const { Q_UNUSED( size ); return false; }
0280 
0281             /** Returns the image for the album, usually the cover image.
0282                 The default implementation returns an null image.
0283                 If you need a pixmap call The::coverCache()->getCover( album, size )
0284                 instead. That function also returns a "nocover" pixmap
0285             */
0286             virtual QImage image( int size = 0 ) const;
0287 
0288             /** Returns the image location on disk.
0289                 The mpris interface is using this information for notifications so
0290                 it better is a local file url.
0291             */
0292             virtual QUrl imageLocation( int size = 0 ) { Q_UNUSED( size ); return QUrl(); }
0293 
0294             /** Returns true if it is possible to update the cover of the album */
0295             virtual bool canUpdateImage() const { return false; }
0296 
0297             /** updates the cover of the album
0298                 @param image The large scale image that should be used as cover for the album.
0299                 Note: the parameter should not be a QPixmap as a pixmap can only be created reliable in a UI thread.
0300             */
0301             virtual void setImage( const QImage &image ) { Q_UNUSED( image ); }
0302 
0303             /** removes the album art */
0304             virtual void removeImage() { }
0305 
0306             /** don't automatically fetch artwork */
0307             virtual void setSuppressImageAutoFetch( const bool suppress ) { Q_UNUSED( suppress ); }
0308             /** should automatic artwork retrieval be suppressed? */
0309             virtual bool suppressImageAutoFetch() const { return false; }
0310 
0311             virtual bool operator==( const Meta::Album &album ) const;
0312 
0313         protected:
0314             virtual void notifyObservers() const;
0315     };
0316 
0317     class AMAROKCORE_EXPORT Composer : public Base
0318     {
0319         public:
0320             QString prettyName() const override;
0321 
0322             /** returns all tracks by this composer */
0323             virtual TrackList tracks() = 0;
0324 
0325             virtual bool operator==( const Meta::Composer &composer ) const;
0326 
0327         protected:
0328             virtual void notifyObservers() const;
0329     };
0330 
0331     class AMAROKCORE_EXPORT Genre : public Base
0332     {
0333         public:
0334             QString prettyName() const override;
0335 
0336             /** returns all tracks which belong to the genre */
0337             virtual TrackList tracks() = 0;
0338 
0339             virtual bool operator==( const Meta::Genre &genre ) const;
0340 
0341         protected:
0342             virtual void notifyObservers() const;
0343     };
0344 
0345     class AMAROKCORE_EXPORT Year : public Base
0346     {
0347         public:
0348             /**
0349              * Returns the year this object represents.
0350              * number of 0 is considered unset.
0351              */
0352             virtual int year() const { return name().toInt(); }
0353 
0354             /** returns all tracks which are tagged with this year */
0355             virtual TrackList tracks() = 0;
0356 
0357             virtual bool operator==( const Meta::Year &year ) const;
0358 
0359         protected:
0360             virtual void notifyObservers() const;
0361     };
0362 
0363     /**
0364      * A Label represents an arbitrary classification of a Track.
0365      */
0366     class AMAROKCORE_EXPORT Label : public Base
0367     {
0368         // we need nothing more than what Meta::Base has
0369     };
0370 }
0371 
0372 Q_DECLARE_METATYPE( Meta::TrackPtr )
0373 Q_DECLARE_METATYPE( Meta::TrackList )
0374 Q_DECLARE_METATYPE( Meta::ArtistPtr )
0375 Q_DECLARE_METATYPE( Meta::ArtistList )
0376 Q_DECLARE_METATYPE( Meta::AlbumPtr )
0377 Q_DECLARE_METATYPE( Meta::AlbumList )
0378 Q_DECLARE_METATYPE( Meta::ComposerPtr )
0379 Q_DECLARE_METATYPE( Meta::ComposerList )
0380 Q_DECLARE_METATYPE( Meta::GenrePtr )
0381 Q_DECLARE_METATYPE( Meta::GenreList )
0382 Q_DECLARE_METATYPE( Meta::YearPtr )
0383 Q_DECLARE_METATYPE( Meta::YearList )
0384 Q_DECLARE_METATYPE( Meta::LabelPtr )
0385 Q_DECLARE_METATYPE( Meta::LabelList )
0386 
0387 #endif /* AMAROK_META_H */