00001 #ifndef METADATA_H_
00002 #define METADATA_H_
00003
00004
00005 #include <vector>
00006 #include <iostream>
00007 #include <stdint.h>
00008
00009 using namespace std;
00010
00011
00012 #include <QStringList>
00013 #include <QMap>
00014 #include <QDateTime>
00015 #include <QImage>
00016 #include <QMetaType>
00017
00018
00019
00020 #include "mythexp.h"
00021 #include <mthread.h>
00022
00023
00024
00025
00026 class AllMusic;
00027 class AlbumArtImages;
00028 class PlaylistContainer;
00029 class MetaIO;
00030
00031 enum ImageType
00032 {
00033 IT_UNKNOWN = 0,
00034 IT_FRONTCOVER,
00035 IT_BACKCOVER,
00036 IT_CD,
00037 IT_INLAY,
00038 IT_ARTIST,
00039 IT_LAST
00040 };
00041
00042 class AlbumArtImage
00043 {
00044 public:
00045 AlbumArtImage(void) :
00046 id(0), filename(""), imageType(IT_UNKNOWN),
00047 description(""), embedded(false) {}
00048 AlbumArtImage(AlbumArtImage *image) :
00049 id(image->id), filename(image->filename), imageType(image->imageType),
00050 description(image->description), embedded(image->embedded) {}
00051 int id;
00052 QString filename;
00053 ImageType imageType;
00054 QString description;
00055 bool embedded;
00056 };
00057
00058 typedef QList<AlbumArtImage*> AlbumArtList;
00059 typedef QHash<QString,QString> MetadataMap;
00060
00061
00062 enum RepoType
00063 {
00064 RT_Database = 0,
00065 RT_CD = 1,
00066 RT_Radio = 2
00067 };
00068
00069 #define METADATA_BITS_FOR_REPO 8
00070 #define METADATA_REPO_SHIFT 24
00071 #define METADATA_REPO_MASK 0xff000000
00072 #define METADATA_ID_MASK 0x00ffffff
00073
00074 #define ID_TO_ID(x) x & METADATA_ID_MASK;
00075 #define ID_TO_REPO(x) x >> METADATA_REPO_SHIFT
00076
00077 class Metadata
00078 {
00079 public:
00080
00081 typedef uint32_t IdType;
00082
00083 Metadata(QString lfilename = "", QString lartist = "", QString lcompilation_artist = "",
00084 QString lalbum = "", QString ltitle = "", QString lgenre = "",
00085 int lyear = 0, int ltracknum = 0, int llength = 0, int lid = 0,
00086 int lrating = 0, int lplaycount = 0, QDateTime llastplay = QDateTime(),
00087 QDateTime ldateadded = QDateTime(), bool lcompilation = false, QString lformat = "")
00088 : m_artist(lartist),
00089 m_compilation_artist(lcompilation_artist),
00090 m_album(lalbum),
00091 m_title(ltitle),
00092 m_formattedartist(""),
00093 m_formattedtitle(""),
00094 m_genre(lgenre),
00095 m_format(lformat),
00096 m_year(lyear),
00097 m_tracknum(ltracknum),
00098 m_trackCount(0),
00099 m_length(llength),
00100 m_rating(lrating),
00101 m_directoryid(-1),
00102 m_artistid(-1),
00103 m_compartistid(-1),
00104 m_albumid(-1),
00105 m_genreid(-1),
00106 m_lastplay(llastplay),
00107 m_templastplay(QDateTime()),
00108 m_dateadded(ldateadded),
00109 m_playcount(lplaycount),
00110 m_tempplaycount(0),
00111 m_compilation(lcompilation),
00112 m_albumArt(NULL),
00113 m_id(lid),
00114 m_filename(lfilename),
00115 m_changed(false)
00116 {
00117 checkEmptyFields();
00118 }
00119
00120 ~Metadata();
00121
00122 Metadata(const Metadata &other)
00123 {
00124 *this = other;
00125 m_changed = false;
00126 }
00127
00128 Metadata& operator=(const Metadata &other);
00129
00130 QString Artist() const { return m_artist; }
00131 void setArtist(const QString &lartist)
00132 {
00133 m_artist = lartist; m_formattedartist.clear(); m_formattedtitle.clear();
00134 }
00135
00136 QString CompilationArtist() const { return m_compilation_artist; }
00137 void setCompilationArtist(const QString &lcompilation_artist)
00138 {
00139 m_compilation_artist = lcompilation_artist;
00140 m_formattedartist.clear(); m_formattedtitle.clear();
00141 }
00142
00143 QString Album() const { return m_album; }
00144 void setAlbum(const QString &lalbum)
00145 {
00146 m_album = lalbum; m_formattedartist.clear(); m_formattedtitle.clear();
00147 }
00148
00149 QString Title() const { return m_title; }
00150 void setTitle(const QString <itle) { m_title = ltitle; }
00151
00152 QString FormatArtist();
00153 QString FormatTitle();
00154
00155 QString Genre() const { return m_genre; }
00156 void setGenre(const QString &lgenre) { m_genre = lgenre; }
00157
00158 void setDirectoryId(int ldirectoryid) { m_directoryid = ldirectoryid; }
00159 int getDirectoryId() const { return m_directoryid; }
00160
00161 void setArtistId(int lartistid) { m_artistid = lartistid; }
00162 int getArtistId() const { return m_artistid; }
00163
00164 void setAlbumId(int lalbumid) { m_albumid = lalbumid; }
00165 int getAlbumId() const { return m_albumid; }
00166
00167 void setGenreId(int lgenreid) { m_genreid = lgenreid; }
00168 int getGenreId() const { return m_genreid; }
00169
00170 int Year() const { return m_year; }
00171 void setYear(int lyear) { m_year = lyear; }
00172
00173 int Track() const { return m_tracknum; }
00174 void setTrack(int ltrack) { m_tracknum = ltrack; }
00175
00176 int GetTrackCount() const { return m_trackCount; }
00177 void setTrackCount(int ltrackcount) { m_trackCount = ltrackcount; }
00178
00179 int Length() const { return m_length; }
00180 void setLength(int llength) { m_length = llength; }
00181
00182 int Playcount() const { return m_playcount; }
00183 void setPlaycount(int lplaycount) { m_playcount = lplaycount; }
00184
00185 IdType ID() const { return m_id; }
00186 void setID(IdType lid) { m_id = lid; }
00187 void setRepo(RepoType repo) { m_id = (m_id & METADATA_ID_MASK) | (repo << METADATA_REPO_SHIFT); }
00188
00189 bool isCDTrack(void) const { return ID_TO_REPO(m_id) == RT_CD; }
00190
00191 QString Filename(bool find = true) const;
00192 void setFilename(const QString &lfilename) { m_filename = lfilename; }
00193
00194 QString Format() const { return m_format; }
00195 void setFormat(const QString &lformat) { m_format = lformat; }
00196
00197 int Rating() const { return m_rating; }
00198 void decRating();
00199 void incRating();
00200 void setRating(int lrating) { m_rating = lrating; }
00201
00202 QDateTime LastPlay() const { return m_lastplay; }
00203 void setLastPlay();
00204
00205 int PlayCount() const { return m_playcount; }
00206 void incPlayCount();
00207
00208
00209 bool Compilation() const { return m_compilation; }
00210 void setCompilation(bool state)
00211 {
00212 m_compilation = state;
00213 m_formattedartist.clear();
00214 m_formattedtitle.clear();
00215 }
00216 bool determineIfCompilation(bool cd = false);
00217
00218 void setEmbeddedAlbumArt(AlbumArtList &albumart);
00219
00220 bool isInDatabase(void);
00221 void dumpToDatabase(void);
00222 void setField(const QString &field, const QString &data);
00223 void getField(const QString& field, QString *data);
00224 void toMap(MetadataMap &metadataMap, const QString &prefix = "");
00225
00226 void persist(void);
00227 void UpdateModTime(void) const;
00228 bool hasChanged() const { return m_changed; }
00229 int compare(const Metadata *other) const;
00230
00231
00232 static void setArtistAndTrackFormats();
00233 static QStringList fillFieldList(QString field);
00234
00235
00236 QString getAlbumArtFile(void);
00237
00238 QString getAlbumArtFile(ImageType type);
00239
00240 AlbumArtImages *getAlbumArtImages(void);
00241 void reloadAlbumArtImages(void);
00242
00243 MetaIO *getTagger(void);
00244
00245 private:
00246 void setCompilationFormatting(bool cd = false);
00247 QString formatReplaceSymbols(const QString &format);
00248 void checkEmptyFields(void);
00249
00250 QString m_artist;
00251 QString m_compilation_artist;
00252 QString m_album;
00253 QString m_title;
00254 QString m_formattedartist;
00255 QString m_formattedtitle;
00256 QString m_genre;
00257 QString m_format;
00258 int m_year;
00259 int m_tracknum;
00260 int m_trackCount;
00261 int m_length;
00262 int m_rating;
00263 int m_directoryid;
00264 int m_artistid;
00265 int m_compartistid;
00266 int m_albumid;
00267 int m_genreid;
00268 QDateTime m_lastplay;
00269 QDateTime m_templastplay;
00270 QDateTime m_dateadded;
00271 int m_playcount;
00272 int m_tempplaycount;
00273 bool m_compilation;
00274
00275 AlbumArtImages *m_albumArt;
00276
00277 IdType m_id;
00278 QString m_filename;
00279 bool m_changed;
00280
00281
00282 static QString m_formatnormalfileartist;
00283 static QString m_formatnormalfiletrack;
00284 static QString m_formatnormalcdartist;
00285 static QString m_formatnormalcdtrack;
00286
00287 static QString m_formatcompilationfileartist;
00288 static QString m_formatcompilationfiletrack;
00289 static QString m_formatcompilationcdartist;
00290 static QString m_formatcompilationcdtrack;
00291 };
00292
00293 bool operator==(const Metadata& a, const Metadata& b);
00294 bool operator!=(const Metadata& a, const Metadata& b);
00295
00296 Q_DECLARE_METATYPE(Metadata *)
00297
00298 typedef QList<Metadata*> MetadataPtrList;
00299 Q_DECLARE_METATYPE(MetadataPtrList *)
00300
00301
00302
00303 class MetadataLoadingThread : public MThread
00304 {
00305
00306 public:
00307
00308 MetadataLoadingThread(AllMusic *parent_ptr);
00309 virtual void run();
00310
00311 private:
00312
00313 AllMusic *parent;
00314 };
00315
00316
00317
00318 class AllMusic
00319 {
00320 public:
00321
00322 AllMusic(void);
00323 ~AllMusic();
00324
00325 Metadata* getMetadata(int an_id);
00326 bool updateMetadata(int an_id, Metadata *the_track);
00327 int count() const { return m_numPcs; }
00328 int countLoaded() const { return m_numLoaded; }
00329 void save();
00330 bool startLoading(void);
00331 void resync();
00332
00333
00334 void clearCDData(void);
00335 void addCDTrack(const Metadata &the_track);
00336 bool checkCDTrack(Metadata *the_track);
00337 Metadata* getCDMetadata(int m_the_track);
00338 QString getCDTitle(void) const { return m_cdTitle; }
00339 void setCDTitle(const QString &a_title) { m_cdTitle = a_title; }
00340 int getCDTrackCount(void) const { return m_cdData.count(); }
00341
00342 bool doneLoading() const { return m_done_loading; }
00343 bool cleanOutThreads();
00344
00345 MetadataPtrList *getAllMetadata(void) { return &m_all_music; }
00346
00347 bool isValidID(int an_id);
00348
00349 private:
00350 MetadataPtrList m_all_music;
00351
00352 int m_numPcs;
00353 int m_numLoaded;
00354
00355 typedef QMap<int, Metadata*> MusicMap;
00356 MusicMap music_map;
00357
00358
00359 MetadataPtrList m_cdData;
00360 QString m_cdTitle;
00361
00362 MetadataLoadingThread *m_metadata_loader;
00363 bool m_done_loading;
00364 int m_last_listed;
00365
00366 int m_playcountMin;
00367 int m_playcountMax;
00368 double m_lastplayMin;
00369 double m_lastplayMax;
00370 };
00371
00372
00373
00374 class MusicData : public QObject
00375 {
00376 Q_OBJECT
00377
00378 public:
00379
00380 MusicData();
00381 ~MusicData();
00382
00383 public slots:
00384 void reloadMusic(void);
00385
00386 public:
00387 QString musicDir;
00388 PlaylistContainer *all_playlists;
00389 AllMusic *all_music;
00390 bool initialized;
00391 };
00392
00393
00394 extern MPUBLIC MusicData *gMusicData;
00395
00396
00397
00398
00399 class AlbumArtImages
00400 {
00401 public:
00402 AlbumArtImages(Metadata *metadata);
00403 ~AlbumArtImages();
00404
00405 void addImage(const AlbumArtImage &newImage);
00406 uint getImageCount() { return m_imageList.size(); }
00407 AlbumArtImage *getImage(ImageType type);
00408 QStringList getImageFilenames(void) const;
00409 AlbumArtList *getImageList(void) { return &m_imageList; }
00410 AlbumArtImage *getImageAt(uint index);
00411
00412 void dumpToDatabase(void);
00413
00414 static ImageType guessImageType(const QString &filename);
00415 static QString getTypeName(ImageType type);
00416 static QString getTypeFilename(ImageType type);
00417
00418 private:
00419 void findImages(void);
00420
00421 Metadata *m_parent;
00422 AlbumArtList m_imageList;
00423 };
00424
00425 Q_DECLARE_METATYPE(AlbumArtImage*);
00426
00427 #endif