|
|
|
// Max Howell <max.howell@methylblue.com>, (C) 2004
|
|
|
|
// Alexandre Pereira de Oliveira <aleprj@gmail.com>, (C) 2005
|
|
|
|
// Shane King <kde@dontletsstart.com>, (C) 2006
|
|
|
|
// Peter C. Ndikuwera <pndiku@gmail.com>, (C) 2006
|
|
|
|
// License: GNU General Public License V2
|
|
|
|
|
|
|
|
#ifndef METABUNDLE_H
|
|
|
|
#define METABUNDLE_H
|
|
|
|
|
|
|
|
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
|
|
|
|
#define PRETTY_TITLE_CACHE
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <kurl.h> //inline functions
|
|
|
|
#include <klocale.h> //inline functions
|
|
|
|
#include <taglib/audioproperties.h>
|
|
|
|
#include "expression.h"
|
|
|
|
#include "atomicstring.h"
|
|
|
|
#include "moodbar.h"
|
|
|
|
|
|
|
|
#include "amarok_export.h"
|
|
|
|
|
|
|
|
class KFileMetaInfo;
|
|
|
|
class TQDir;
|
|
|
|
class TQTextStream;
|
|
|
|
template<class T> class TQValueList;
|
|
|
|
namespace TagLib {
|
|
|
|
class ByteVector;
|
|
|
|
class File;
|
|
|
|
class FileRef;
|
|
|
|
class String;
|
|
|
|
namespace ID3v2 {
|
|
|
|
class UniqueFileIdentifierFrame;
|
|
|
|
class Tag;
|
|
|
|
}
|
|
|
|
namespace MPEG {
|
|
|
|
class File;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class PodcastEpisodeBundle;
|
|
|
|
|
|
|
|
namespace LastFm {
|
|
|
|
class Bundle;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class MetaBundle
|
|
|
|
* @author Max Howell <max.howell@methylblue.com>
|
|
|
|
*
|
|
|
|
* If this class doesn't work for you in some way, extend it sensibly :)
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
class LIBAMAROK_EXPORT MetaBundle
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum Column
|
|
|
|
{
|
|
|
|
Filename = 0,
|
|
|
|
Title,
|
|
|
|
Artist,
|
|
|
|
AlbumArtist,
|
|
|
|
Composer,
|
|
|
|
Year,
|
|
|
|
Album,
|
|
|
|
DiscNumber,
|
|
|
|
Track,
|
|
|
|
Bpm,
|
|
|
|
Genre,
|
|
|
|
Comment,
|
|
|
|
Directory,
|
|
|
|
Type,
|
|
|
|
Length,
|
|
|
|
Bitrate,
|
|
|
|
SampleRate,
|
|
|
|
Score,
|
|
|
|
Rating,
|
|
|
|
PlayCount,
|
|
|
|
LastPlayed,
|
|
|
|
Mood,
|
|
|
|
Filesize,
|
|
|
|
NUM_COLUMNS
|
|
|
|
};
|
|
|
|
|
|
|
|
class LIBAMAROK_EXPORT EmbeddedImage {
|
|
|
|
public:
|
|
|
|
EmbeddedImage() {}
|
|
|
|
EmbeddedImage( const TagLib::ByteVector& data, const TagLib::String& description );
|
|
|
|
|
|
|
|
const TQCString &hash() const;
|
|
|
|
const TQString &description() const { return m_description; }
|
|
|
|
bool save( const TQDir& dir ) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
TQByteArray m_data;
|
|
|
|
TQString m_description;
|
|
|
|
mutable TQCString m_hash;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef TQValueList<EmbeddedImage> EmbeddedImageList;
|
|
|
|
|
|
|
|
/** This is a bit vector for selecting columns. It's very fast to compare
|
|
|
|
in matchFast. It might be a good idea to replace the TQValue<int>
|
|
|
|
column masks with this eventually. */
|
|
|
|
typedef TQ_UINT32 ColumnMask;
|
|
|
|
|
|
|
|
/** Returns the name of the column at \p index as a string -- not i18ned, for internal purposes. */
|
|
|
|
static const TQString &exactColumnName( int index );
|
|
|
|
/** Returns the name of the column at \p index as a string -- i18ned, for display purposes. */
|
|
|
|
static const TQString prettyColumnName( int index );
|
|
|
|
/** Returns the index of the column with the not i18ned name \p name. */
|
|
|
|
static int columnIndex( const TQString &name );
|
|
|
|
|
|
|
|
// These values are stored on the Database, so, don't change the order. Only append new ones to the end.
|
|
|
|
enum FileType { other, mp3, ogg, wma, mp4, flac, ra, rv, rm, rmj, rmvb, asf };
|
|
|
|
|
|
|
|
//for the audioproperties
|
|
|
|
static const int Undetermined = -2; /// we haven't yet read the tags
|
|
|
|
static const int Irrelevant = -1; /// not applicable to this stream/media type, eg length for http streams
|
|
|
|
static const int Unavailable = 0; /// cannot be obtained
|
|
|
|
|
|
|
|
// whether file is part of a compilation
|
|
|
|
enum Compilation { CompilationNo = 0, CompilationYes = 1, CompilationUnknown = -1 };
|
|
|
|
|
|
|
|
/// Creates an empty MetaBundle
|
|
|
|
LIBAMAROK_EXPORT MetaBundle();
|
|
|
|
|
|
|
|
/// Creates a MetaBundle for url, tags will be obtained and set
|
|
|
|
LIBAMAROK_EXPORT explicit MetaBundle( const KURL &url,
|
|
|
|
bool noCache = false,
|
|
|
|
TagLib::AudioProperties::ReadStyle = TagLib::AudioProperties::Fast,
|
|
|
|
EmbeddedImageList* images = 0 );
|
|
|
|
|
|
|
|
/** For the StreamProvider */
|
|
|
|
LIBAMAROK_EXPORT MetaBundle( const TQString &title,
|
|
|
|
const TQString &streamUrl,
|
|
|
|
const int bitrate,
|
|
|
|
const TQString &genre,
|
|
|
|
const TQString &streamName,
|
|
|
|
const KURL &url );
|
|
|
|
|
|
|
|
LIBAMAROK_EXPORT MetaBundle( const MetaBundle &bundle );
|
|
|
|
|
|
|
|
~MetaBundle();
|
|
|
|
|
|
|
|
MetaBundle& operator=( const MetaBundle& bundle );
|
|
|
|
bool operator==( const MetaBundle& bundle ) const;
|
|
|
|
bool operator!=( const MetaBundle& bundle ) const;
|
|
|
|
|
|
|
|
/** Test for an empty metabundle */
|
|
|
|
bool isEmpty() const;
|
|
|
|
|
|
|
|
/** Empty the metabundle */
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
/** Is it media that has metadata? Note currently we don't check for an audio mimetype */
|
|
|
|
bool isValidMedia() const;
|
|
|
|
|
|
|
|
/** The bundle doesn't yet know its audioProperties */
|
|
|
|
bool audioPropertiesUndetermined() const;
|
|
|
|
|
|
|
|
/** The embedded artwork in the file (loaded from file into images variable, unmodified if no images present/loadable) */
|
|
|
|
void embeddedImages(EmbeddedImageList &images) const;
|
|
|
|
|
|
|
|
/** If you want Accurate reading say so. If EmbeddedImageList != NULL, embedded art is loaded into it */
|
|
|
|
void readTags( TagLib::AudioProperties::ReadStyle = TagLib::AudioProperties::Fast, EmbeddedImageList* images = 0 );
|
|
|
|
|
|
|
|
/** Saves the changes to the file using the transactional algorithm for safety. */
|
|
|
|
bool safeSave();
|
|
|
|
|
|
|
|
/** Saves the changes to the file. Returns false on error. */
|
|
|
|
bool save( TagLib::FileRef* fileref = 0 );
|
|
|
|
|
|
|
|
/** Saves the MetaBundle's data as XML to a text stream. */
|
|
|
|
bool save( TQTextStream &stream, const TQStringList &attributes = TQStringList() ) const;
|
|
|
|
|
|
|
|
/** Returns whether the url referred to is a local file */
|
|
|
|
bool isFile() const;
|
|
|
|
|
|
|
|
/** Returns whether the url referred to can be accessed via kio slaves */
|
|
|
|
bool isKioUrl() const;
|
|
|
|
|
|
|
|
/** Returns whether url can be accessed via kio slaves */
|
|
|
|
static bool isKioUrl( const KURL &url );
|
|
|
|
|
|
|
|
/** Returns whether composer, disc number and bpm fields are available. */
|
|
|
|
bool hasExtendedMetaInformation() const;
|
|
|
|
|
|
|
|
void copyFrom( const MetaBundle& bundle );
|
|
|
|
|
|
|
|
void copyFrom( const PodcastEpisodeBundle &peb );
|
|
|
|
|
|
|
|
/** Returns a string representation of the tag at \p column, in a format suitable for internal purposes.
|
|
|
|
For example, for a track 3:24 long, it'll return "204" (seconds).
|
|
|
|
This should not be used for displaying the tag to the user. */
|
|
|
|
TQString exactText( int column, bool ensureCached = false ) const;
|
|
|
|
|
|
|
|
/** Sets the tag at \p column from a string in the same format as returned by exactText(). */
|
|
|
|
void setExactText( int column, const TQString &text );
|
|
|
|
|
|
|
|
/** Returns the tag at \p column in a format suitable for displaying to the user. */
|
|
|
|
TQString prettyText( int column ) const;
|
|
|
|
|
|
|
|
/** Returns whether the bundle matches \p expression.
|
|
|
|
This is fast and doesn't take advanced syntax into account,
|
|
|
|
and should only be used when it is certain none is present.
|
|
|
|
The tags in \p columns are checked for matches.
|
|
|
|
@see ExpressionParser::isAdvancedExpression() */
|
|
|
|
bool matchesSimpleExpression( const TQString &expression, const TQValueList<int> &columns ) const;
|
|
|
|
|
|
|
|
/** A faster version of the above, that pre-caches all the data to be
|
|
|
|
searched in a single string, to avoid re-building integer and lower
|
|
|
|
case strings over and over. It is designed to be called from a
|
|
|
|
playlist search *only* -- it is not entirely thread-safe for efficiency,
|
|
|
|
although it's highly unlikely to crash. Consider this the beginning
|
|
|
|
of a real super-efficient index (e.g. suffix tree).
|
|
|
|
\p terms is a list of lower-case words. */
|
|
|
|
bool matchesFast(const TQStringList &terms, ColumnMask columns) const;
|
|
|
|
|
|
|
|
/** Returns whether the bundle matches \p expression.
|
|
|
|
This takes advanced syntax into account, and is slightly slower than matchesSimpleExpression().
|
|
|
|
The tags in \p defaultColumns are checked for matches where the expression doesn't specify any manually. */
|
|
|
|
bool matchesExpression( const TQString &expression, const TQValueList<int> &defaultColumns ) const;
|
|
|
|
|
|
|
|
/** Returns whether the bundle matches the pre-parsed expression \p parsedData.
|
|
|
|
The tags in \p defaultColumns are checked for matches where the expression doesn't specify any manually.
|
|
|
|
@see ExpressionParser */
|
|
|
|
bool matchesParsedExpression( const ParsedExpression &parsedData, const TQValueList<int> &defaultColumns ) const;
|
|
|
|
|
|
|
|
/** PlaylistItem reimplements this so it can be informed of moodbar
|
|
|
|
data events without having to use signals */
|
|
|
|
virtual void moodbarJobEvent( int newState )
|
|
|
|
{ (void) newState; }
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* A class to load MetaBundles from XML.
|
|
|
|
* #include "xmlloader.h"
|
|
|
|
*/
|
|
|
|
class XmlLoader;
|
|
|
|
|
|
|
|
public: //accessors
|
|
|
|
const KURL &url() const;
|
|
|
|
TQString title() const;
|
|
|
|
AtomicString artist() const;
|
|
|
|
AtomicString albumArtist() const;
|
|
|
|
AtomicString composer() const;
|
|
|
|
AtomicString album() const;
|
|
|
|
AtomicString genre() const;
|
|
|
|
AtomicString comment() const;
|
|
|
|
TQString filename() const;
|
|
|
|
TQString directory() const;
|
|
|
|
TQString type() const;
|
|
|
|
int year() const;
|
|
|
|
int discNumber() const;
|
|
|
|
int track() const;
|
|
|
|
float bpm() const;
|
|
|
|
int length() const;
|
|
|
|
int bitrate() const;
|
|
|
|
int sampleRate() const;
|
|
|
|
float score( bool ensureCached = false ) const;
|
|
|
|
int rating( bool ensureCached = false ) const; //returns rating * 2, to accommodate .5 ratings
|
|
|
|
int playCount( bool ensureCached = false ) const;
|
|
|
|
uint lastPlay( bool ensureCached = false ) const;
|
|
|
|
|
|
|
|
Moodbar &moodbar();
|
|
|
|
const Moodbar &moodbar_const() const;
|
|
|
|
|
|
|
|
int filesize() const;
|
|
|
|
|
|
|
|
int compilation() const;
|
|
|
|
int fileType() const; // returns a value from enum FileType
|
|
|
|
bool exists() const; // true for everything but local files that aren't there
|
|
|
|
PodcastEpisodeBundle *podcastBundle() const;
|
|
|
|
LastFm::Bundle *lastFmBundle() const;
|
|
|
|
TQString streamName() const;
|
|
|
|
TQString streamUrl() const;
|
|
|
|
TQString uniqueId() const;
|
|
|
|
|
|
|
|
TQString prettyTitle() const;
|
|
|
|
TQString veryNiceTitle() const;
|
|
|
|
TQString prettyURL() const;
|
|
|
|
TQString prettyBitrate() const;
|
|
|
|
TQString prettyLength() const;
|
|
|
|
TQString prettySampleRate( bool shortened = false ) const;
|
|
|
|
TQString prettyFilesize() const;
|
|
|
|
TQString prettyRating() const;
|
|
|
|
|
|
|
|
bool safeToSave() { return m_safeToSave; }
|
|
|
|
|
|
|
|
TQString getRandomString( int size, bool numbersOnly = false );
|
|
|
|
|
|
|
|
public: //modifiers
|
|
|
|
void setUrl( const KURL &url );
|
|
|
|
void setPath( const TQString &path );
|
|
|
|
void setTitle( const TQString &title );
|
|
|
|
void setArtist( const AtomicString &artist );
|
|
|
|
void setAlbumArtist( const AtomicString &albumArtist );
|
|
|
|
void setComposer( const AtomicString &composer );
|
|
|
|
void setAlbum( const AtomicString &album );
|
|
|
|
void setGenre( const AtomicString &genre );
|
|
|
|
void setComment( const AtomicString &comment );
|
|
|
|
void setYear( int year );
|
|
|
|
void setDiscNumber( int discNumber );
|
|
|
|
void setTrack( int track );
|
|
|
|
void setBpm( float bpm );
|
|
|
|
void setLength( int length );
|
|
|
|
void setBitrate( int bitrate );
|
|
|
|
void setSampleRate( int sampleRate );
|
|
|
|
void setScore( float score );
|
|
|
|
void setRating( int rating );
|
|
|
|
void setPlayCount( int playcount );
|
|
|
|
void setLastPlay( uint lastplay );
|
|
|
|
void setFilesize( int bytes );
|
|
|
|
// No direct moodbar mutator -- moodbar should not be separated
|
|
|
|
// from the metabundle
|
|
|
|
|
|
|
|
void updateFilesize();
|
|
|
|
void setFileType( int type );
|
|
|
|
void setCompilation( int compilation );
|
|
|
|
bool checkExists();
|
|
|
|
void setPodcastBundle( const PodcastEpisodeBundle &peb );
|
|
|
|
void setLastFmBundle( const LastFm::Bundle &last );
|
|
|
|
void setUniqueId(); //uses database for lookup
|
|
|
|
void setUniqueId( const TQString &id ); //SEE COMMENT in .CPP
|
|
|
|
const TagLib::ByteVector readUniqueIdHelper( TagLib::FileRef fileref ) const;
|
|
|
|
TQString readUniqueId( TagLib::FileRef *fileref = 0 );
|
|
|
|
void scannerAcknowledged() {}
|
|
|
|
|
|
|
|
void detach(); // for being able to apply TQDeepCopy<>
|
|
|
|
|
|
|
|
public: //static helper functions
|
|
|
|
static TQString prettyBitrate( int );
|
|
|
|
static TQString prettyLength( int, bool showHours = false ); //must be int, see Unavailable, etc. above
|
|
|
|
static TQString prettyFilesize( int );
|
|
|
|
static TQString prettyRating( int rating, bool trailingzero = false );
|
|
|
|
static TQString ratingDescription( int );
|
|
|
|
static TQStringList ratingList();
|
|
|
|
static TQString prettyTime( uint, bool showHours = true );
|
|
|
|
static TQString fuzzyTime( int );
|
|
|
|
static TQString veryPrettyTime( int );
|
|
|
|
static TQString zeroPad( uint i );
|
|
|
|
static TQString prettyTitle( const TQString &filename );
|
|
|
|
static TQStringList genreList();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
enum ExtendedTags { composerTag, albumArtistTag, discNumberTag, bpmTag, compilationTag };
|
|
|
|
|
|
|
|
/** Called before the tags in \p columns are changed. */
|
|
|
|
virtual void aboutToChange( const TQValueList<int> &columns );
|
|
|
|
|
|
|
|
/** Convenience method. */
|
|
|
|
void aboutToChange( int column );
|
|
|
|
|
|
|
|
/** Called after the tags in \p columns are changed. */
|
|
|
|
virtual void reactToChanges( const TQValueList<int> &columns );
|
|
|
|
|
|
|
|
/** Convenience method. */
|
|
|
|
void reactToChange( int column );
|
|
|
|
|
|
|
|
KURL m_url;
|
|
|
|
TQString m_title;
|
|
|
|
AtomicString m_artist;
|
|
|
|
AtomicString m_albumArtist;
|
|
|
|
AtomicString m_composer;
|
|
|
|
AtomicString m_album;
|
|
|
|
AtomicString m_comment;
|
|
|
|
AtomicString m_genre;
|
|
|
|
TQString m_streamName;
|
|
|
|
TQString m_streamUrl;
|
|
|
|
TQString m_uniqueId;
|
|
|
|
|
|
|
|
int m_year;
|
|
|
|
int m_discNumber;
|
|
|
|
int m_track;
|
|
|
|
float m_bpm;
|
|
|
|
int m_bitrate;
|
|
|
|
int m_length;
|
|
|
|
int m_sampleRate;
|
|
|
|
|
|
|
|
float m_score;
|
|
|
|
int m_rating;
|
|
|
|
int m_playCount;
|
|
|
|
uint m_lastPlay;
|
|
|
|
int m_filesize;
|
|
|
|
|
|
|
|
Moodbar *m_moodbar;
|
|
|
|
|
|
|
|
int m_type;
|
|
|
|
|
|
|
|
bool m_exists: 1;
|
|
|
|
bool m_isValidMedia: 1;
|
|
|
|
bool m_isCompilation: 1;
|
|
|
|
bool m_notCompilation: 1;
|
|
|
|
bool m_safeToSave: 1;
|
|
|
|
int m_waitingOnKIO;
|
|
|
|
TQString m_tempSavePath;
|
|
|
|
TQString m_origRenamedSavePath;
|
|
|
|
TQCString m_tempSaveDigest;
|
|
|
|
TagLib::FileRef* m_saveFileref;
|
|
|
|
|
|
|
|
PodcastEpisodeBundle *m_podcastBundle;
|
|
|
|
LastFm::Bundle *m_lastFmBundle;
|
|
|
|
|
|
|
|
// The vars below are used to optimize search by storing
|
|
|
|
// the full text to be searched. They are mutable, as they
|
|
|
|
// act like a sort of cache for the const method matchesFast
|
|
|
|
|
|
|
|
// whether the search text should be rebuilt
|
|
|
|
volatile mutable bool m_isSearchDirty;
|
|
|
|
// which columns the search string contains
|
|
|
|
mutable ColumnMask m_searchColumns;
|
|
|
|
// the search string: textualized columns separated by space
|
|
|
|
// note that matchFast searches by words, hence a word cannot span
|
|
|
|
// space-separated columns
|
|
|
|
mutable TQString m_searchStr;
|
|
|
|
private:
|
|
|
|
|
|
|
|
static inline TQString prettyGeneric( const TQString &s, const int i )
|
|
|
|
{
|
|
|
|
return (i > 0) ? s.tqarg( i ) : (i == Undetermined) ? "?" : "-";
|
|
|
|
}
|
|
|
|
|
|
|
|
void init( TagLib::AudioProperties *ap = 0 );
|
|
|
|
void init( const KFileMetaInfo& info );
|
|
|
|
|
|
|
|
void setExtendedTag( TagLib::File *file, int tag, const TQString value );
|
|
|
|
|
|
|
|
void loadImagesFromTag( const TagLib::ID3v2::Tag &tag, EmbeddedImageList& images ) const;
|
|
|
|
|
|
|
|
int getRand();
|
|
|
|
};
|
|
|
|
|
|
|
|
/// for your convenience
|
|
|
|
typedef TQValueList<MetaBundle> BundleList;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline bool MetaBundle::operator!=(const MetaBundle &bundle) const { return !operator==( bundle ); }
|
|
|
|
|
|
|
|
inline bool MetaBundle::isEmpty() const { return url().isEmpty(); }
|
|
|
|
|
|
|
|
inline bool MetaBundle::isValidMedia() const { return m_isValidMedia; }
|
|
|
|
|
|
|
|
inline bool MetaBundle::audioPropertiesUndetermined() const
|
|
|
|
{
|
|
|
|
return m_bitrate == Undetermined || m_sampleRate == Undetermined || m_length == Undetermined;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void MetaBundle::aboutToChange( const TQValueList<int>& ) { }
|
|
|
|
inline void MetaBundle::aboutToChange( int column ) { aboutToChange( TQValueList<int>() << column ); }
|
|
|
|
inline void MetaBundle::reactToChange( int column ) { reactToChanges( TQValueList<int>() << column ); }
|
|
|
|
|
|
|
|
inline bool MetaBundle::exists() const { return m_exists; }
|
|
|
|
|
|
|
|
inline bool MetaBundle::isFile() const { return url().isLocalFile(); }
|
|
|
|
inline bool MetaBundle::isKioUrl() const { return isKioUrl( url() ); }
|
|
|
|
inline bool MetaBundle::isKioUrl( const KURL &url ) { return url.protocol() != "daap" && url.protocol() != "cdda" && url.protocol() != "lastfm"; }
|
|
|
|
|
|
|
|
inline int MetaBundle::track() const { return m_track == Undetermined ? 0 : m_track; }
|
|
|
|
inline int MetaBundle::year() const { return m_year == Undetermined ? 0 : m_year; }
|
|
|
|
inline int MetaBundle::length() const { return m_length > 0 ? m_length : 0; }
|
|
|
|
inline int MetaBundle::bitrate() const { return m_bitrate == Undetermined ? 0 : m_bitrate; }
|
|
|
|
inline int MetaBundle::sampleRate() const { return m_sampleRate == Undetermined ? 0 : m_sampleRate; }
|
|
|
|
inline int MetaBundle::filesize() const { return m_filesize == Undetermined ? 0 : m_filesize; }
|
|
|
|
inline int MetaBundle::fileType() const { return m_type; }
|
|
|
|
|
|
|
|
inline Moodbar &MetaBundle::moodbar()
|
|
|
|
{
|
|
|
|
if( m_moodbar == 0 ) m_moodbar = new Moodbar( this );
|
|
|
|
return *m_moodbar;
|
|
|
|
}
|
|
|
|
inline const Moodbar &MetaBundle::moodbar_const() const
|
|
|
|
{
|
|
|
|
// Anyone know of a better way to do this?
|
|
|
|
if( m_moodbar == 0 )
|
|
|
|
const_cast<MetaBundle*>(this)->m_moodbar
|
|
|
|
= new Moodbar( const_cast<MetaBundle*>(this) );
|
|
|
|
return *m_moodbar;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline const KURL& MetaBundle::url() const { return m_url; }
|
|
|
|
inline TQString MetaBundle::filename() const { return url().fileName(); }
|
|
|
|
inline TQString MetaBundle::directory() const
|
|
|
|
{
|
|
|
|
return url().isLocalFile() ? url().directory() : url().upURL().prettyURL();
|
|
|
|
}
|
|
|
|
inline TQString MetaBundle::title() const { return m_title; }
|
|
|
|
inline AtomicString MetaBundle::artist() const { return m_artist; }
|
|
|
|
inline AtomicString MetaBundle::album() const { return m_album; }
|
|
|
|
inline AtomicString MetaBundle::comment() const { return m_comment; }
|
|
|
|
inline AtomicString MetaBundle::genre() const { return m_genre; }
|
|
|
|
inline AtomicString MetaBundle::composer() const { return m_composer; }
|
|
|
|
inline AtomicString MetaBundle::albumArtist() const { return m_albumArtist; }
|
|
|
|
inline TQString MetaBundle::streamName() const { return m_streamName; }
|
|
|
|
inline TQString MetaBundle::streamUrl() const { return m_streamUrl; }
|
|
|
|
inline TQString MetaBundle::uniqueId() const { return m_uniqueId; }
|
|
|
|
|
|
|
|
inline int MetaBundle::discNumber() const { return m_discNumber == Undetermined ? 0 : m_discNumber; }
|
|
|
|
inline float MetaBundle::bpm() const { return m_bpm == Undetermined ? 0 : m_bpm; }
|
|
|
|
inline int MetaBundle::compilation() const
|
|
|
|
{
|
|
|
|
if( m_isCompilation )
|
|
|
|
return CompilationYes;
|
|
|
|
else if( m_notCompilation )
|
|
|
|
return CompilationNo;
|
|
|
|
else
|
|
|
|
return CompilationUnknown;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline TQString MetaBundle::type() const
|
|
|
|
{
|
|
|
|
return isFile()
|
|
|
|
? filename().mid( filename().findRev( '.' ) + 1 )
|
|
|
|
: i18n( "Stream" );
|
|
|
|
}
|
|
|
|
inline PodcastEpisodeBundle *MetaBundle::podcastBundle() const { return m_podcastBundle; }
|
|
|
|
inline LastFm::Bundle *MetaBundle::lastFmBundle() const { return m_lastFmBundle; }
|
|
|
|
|
|
|
|
inline TQString MetaBundle::prettyURL() const { return url().prettyURL(); }
|
|
|
|
inline TQString MetaBundle::prettyBitrate() const { return prettyBitrate( m_bitrate ); }
|
|
|
|
inline TQString MetaBundle::prettyLength() const { return prettyLength( m_length, true ); }
|
|
|
|
inline TQString MetaBundle::prettyFilesize() const { return prettyFilesize( filesize() ); }
|
|
|
|
inline TQString MetaBundle::prettyRating() const { return prettyRating( rating() ); }
|
|
|
|
inline TQString MetaBundle::prettySampleRate( bool shortened ) const
|
|
|
|
{
|
|
|
|
if ( shortened )
|
|
|
|
return prettyGeneric( i18n( "SampleRate", "%1 kHz" ), m_sampleRate / 1000 );
|
|
|
|
else
|
|
|
|
return prettyGeneric( i18n( "SampleRate", "%1 Hz" ), m_sampleRate );
|
|
|
|
}
|
|
|
|
|
|
|
|
inline TQString MetaBundle::zeroPad( uint i ) { return ( i < 10 ) ? TQString( "0%1" ).tqarg( i ) : TQString::number( i ); }
|
|
|
|
|
|
|
|
inline bool MetaBundle::hasExtendedMetaInformation() const
|
|
|
|
{
|
|
|
|
return ( m_type == mp3 || m_type == ogg ||
|
|
|
|
m_type== mp4 || m_type == flac );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|