2010-03-24 00:11:46 +01:00
|
|
|
/* This file is part of Clementine.
|
2010-11-20 14:27:10 +01:00
|
|
|
Copyright 2010, David Sansome <me@davidsansome.com>
|
2010-03-24 00:11:46 +01:00
|
|
|
|
|
|
|
Clementine is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Clementine is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
#ifndef SONG_H
|
|
|
|
#define SONG_H
|
|
|
|
|
2010-08-02 16:00:43 +02:00
|
|
|
#include <QFuture>
|
2010-02-25 01:18:32 +01:00
|
|
|
#include <QImage>
|
2009-12-24 20:16:07 +01:00
|
|
|
#include <QList>
|
2010-08-03 21:29:49 +02:00
|
|
|
#include <QMetaType>
|
2010-01-15 22:57:22 +01:00
|
|
|
#include <QSharedData>
|
|
|
|
#include <QSharedDataPointer>
|
2010-02-25 01:18:32 +01:00
|
|
|
#include <QSqlQuery>
|
|
|
|
#include <QString>
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2011-02-04 13:36:56 +01:00
|
|
|
#include <xiphcomment.h>
|
2010-09-15 21:24:31 +02:00
|
|
|
|
2010-07-04 22:52:45 +02:00
|
|
|
#include "config.h"
|
2011-02-14 20:34:37 +01:00
|
|
|
#include "timeconstants.h"
|
2010-04-04 19:50:11 +02:00
|
|
|
#include "engines/engine_fwd.h"
|
2010-02-03 23:20:31 +01:00
|
|
|
|
2010-07-04 22:52:45 +02:00
|
|
|
#ifdef HAVE_LIBGPOD
|
|
|
|
# include <gpod/itdb.h>
|
|
|
|
#endif
|
|
|
|
|
2010-08-14 17:57:05 +02:00
|
|
|
#ifdef HAVE_LIBMTP
|
|
|
|
# include <libmtp.h>
|
|
|
|
#endif
|
|
|
|
|
2010-08-23 21:13:27 +02:00
|
|
|
#ifdef Q_OS_WIN32
|
|
|
|
struct IWMDMMetaData;
|
|
|
|
#endif
|
|
|
|
|
2010-08-03 20:57:17 +02:00
|
|
|
class SqlRow;
|
|
|
|
|
2010-12-18 18:28:02 +01:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
|
|
|
namespace lastfm {
|
|
|
|
class Track;
|
|
|
|
}
|
|
|
|
#endif
|
2009-12-26 23:15:57 +01:00
|
|
|
|
2010-03-06 21:08:01 +01:00
|
|
|
namespace TagLib {
|
|
|
|
class FileRef;
|
2010-08-03 21:29:49 +02:00
|
|
|
class String;
|
2010-03-29 15:15:47 +02:00
|
|
|
|
|
|
|
namespace ID3v2 {
|
|
|
|
class Tag;
|
|
|
|
}
|
2010-03-06 21:08:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
class FileRefFactory {
|
|
|
|
public:
|
|
|
|
virtual ~FileRefFactory() {}
|
|
|
|
virtual TagLib::FileRef* GetFileRef(const QString& filename) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
class TagLibFileRefFactory : public FileRefFactory {
|
|
|
|
public:
|
|
|
|
virtual TagLib::FileRef* GetFileRef(const QString& filename);
|
|
|
|
};
|
|
|
|
|
2011-02-14 20:34:37 +01:00
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
class Song {
|
|
|
|
public:
|
|
|
|
Song();
|
2010-01-15 22:57:22 +01:00
|
|
|
Song(const Song& other);
|
2010-03-06 21:08:01 +01:00
|
|
|
Song(FileRefFactory* factory);
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-04-14 23:03:00 +02:00
|
|
|
static const QStringList kColumns;
|
|
|
|
static const QString kColumnSpec;
|
|
|
|
static const QString kBindSpec;
|
|
|
|
static const QString kUpdateSpec;
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-06-20 18:30:10 +02:00
|
|
|
static const QStringList kFtsColumns;
|
|
|
|
static const QString kFtsColumnSpec;
|
|
|
|
static const QString kFtsBindSpec;
|
|
|
|
static const QString kFtsUpdateSpec;
|
|
|
|
|
2011-02-02 22:01:08 +01:00
|
|
|
static const QString kManuallyUnsetCover;
|
|
|
|
static const QString kEmbeddedCover;
|
|
|
|
|
2010-05-10 16:19:43 +02:00
|
|
|
static QString JoinSpec(const QString& table);
|
|
|
|
|
2010-03-07 23:46:41 +01:00
|
|
|
// Don't change these values - they're stored in the database
|
|
|
|
enum FileType {
|
|
|
|
Type_Unknown = 0,
|
|
|
|
Type_Asf = 1,
|
|
|
|
Type_Flac = 2,
|
|
|
|
Type_Mp4 = 3,
|
|
|
|
Type_Mpc = 4,
|
|
|
|
Type_Mpeg = 5,
|
|
|
|
Type_OggFlac = 6,
|
|
|
|
Type_OggSpeex = 7,
|
|
|
|
Type_OggVorbis = 8,
|
|
|
|
Type_Aiff = 9,
|
|
|
|
Type_Wav = 10,
|
|
|
|
Type_TrueAudio = 11,
|
|
|
|
|
|
|
|
Type_Stream = 99,
|
|
|
|
};
|
2010-07-31 16:14:03 +02:00
|
|
|
static QString TextForFiletype(FileType type);
|
|
|
|
QString TextForFiletype() const { return TextForFiletype(filetype()); }
|
2010-03-07 23:46:41 +01:00
|
|
|
|
2011-01-24 21:06:59 +01:00
|
|
|
// Helper function to load embedded cover art from a music file. This is not
|
|
|
|
// actually used by the Song class, but instead it is called by
|
|
|
|
// AlbumCoverLoader and is here so it can lock on the taglib mutex.
|
|
|
|
static QImage LoadEmbeddedArt(const QString& filename);
|
2011-02-05 14:43:04 +01:00
|
|
|
// Checks if this Song can be properly initialized from it's media file.
|
|
|
|
// This requires the 'filename' attribute to be set first.
|
|
|
|
bool HasProperMediaFile() const;
|
2011-01-24 21:06:59 +01:00
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Constructors
|
2011-02-27 18:16:22 +01:00
|
|
|
void Init(const QString& title, const QString& artist, const QString& album, qint64 length_nanosec);
|
2011-02-13 19:34:30 +01:00
|
|
|
void Init(const QString& title, const QString& artist, const QString& album, qint64 beginning, qint64 end);
|
2009-12-24 20:16:07 +01:00
|
|
|
void InitFromFile(const QString& filename, int directory_id);
|
2010-08-03 20:57:17 +02:00
|
|
|
void InitFromQuery(const SqlRow& query, int col = 0);
|
2010-12-18 18:28:02 +01:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2009-12-26 23:15:57 +01:00
|
|
|
void InitFromLastFM(const lastfm::Track& track);
|
2010-12-18 18:28:02 +01:00
|
|
|
#endif
|
2010-07-04 22:52:45 +02:00
|
|
|
|
2010-04-21 16:04:40 +02:00
|
|
|
void MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle& bundle);
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-07-04 22:52:45 +02:00
|
|
|
#ifdef HAVE_LIBGPOD
|
2010-08-08 19:41:06 +02:00
|
|
|
void InitFromItdb(const Itdb_Track* track);
|
2010-07-24 18:58:14 +02:00
|
|
|
void ToItdb(Itdb_Track* track) const;
|
2010-07-04 22:52:45 +02:00
|
|
|
#endif
|
|
|
|
|
2010-08-14 17:57:05 +02:00
|
|
|
#ifdef HAVE_LIBMTP
|
|
|
|
void InitFromMTP(const LIBMTP_track_t* track);
|
2010-08-14 18:39:45 +02:00
|
|
|
void ToMTP(LIBMTP_track_t* track) const;
|
2010-08-14 17:57:05 +02:00
|
|
|
#endif
|
|
|
|
|
2010-08-23 21:13:27 +02:00
|
|
|
#ifdef Q_OS_WIN32
|
|
|
|
void InitFromWmdm(IWMDMMetaData* metadata);
|
|
|
|
void ToWmdm(IWMDMMetaData* metadata) const;
|
|
|
|
#endif
|
|
|
|
|
2011-03-06 17:39:36 +01:00
|
|
|
static QString Decode(const TagLib::String& tag, const QTextCodec* codec = NULL);
|
|
|
|
static QString Decode(const QString& tag, const QTextCodec* codec = NULL);
|
2010-06-03 14:36:43 +02:00
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Save
|
|
|
|
void BindToQuery(QSqlQuery* query) const;
|
2010-06-20 18:30:10 +02:00
|
|
|
void BindToFtsQuery(QSqlQuery* query) const;
|
2010-12-18 18:28:02 +01:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2009-12-29 20:22:02 +01:00
|
|
|
void ToLastFM(lastfm::Track* track) const;
|
2010-12-18 18:28:02 +01:00
|
|
|
#endif
|
2009-12-24 20:16:07 +01:00
|
|
|
|
|
|
|
// Simple accessors
|
2010-01-15 22:57:22 +01:00
|
|
|
bool is_valid() const { return d->valid_; }
|
|
|
|
int id() const { return d->id_; }
|
|
|
|
|
2010-02-28 01:35:20 +01:00
|
|
|
const QString& title() const { return d->title_; }
|
|
|
|
const QString& album() const { return d->album_; }
|
|
|
|
const QString& artist() const { return d->artist_; }
|
|
|
|
const QString& albumartist() const { return d->albumartist_; }
|
|
|
|
const QString& composer() const { return d->composer_; }
|
2010-01-15 22:57:22 +01:00
|
|
|
int track() const { return d->track_; }
|
|
|
|
int disc() const { return d->disc_; }
|
|
|
|
float bpm() const { return d->bpm_; }
|
|
|
|
int year() const { return d->year_; }
|
2010-02-28 01:35:20 +01:00
|
|
|
const QString& genre() const { return d->genre_; }
|
|
|
|
const QString& comment() const { return d->comment_; }
|
2010-03-21 00:59:39 +01:00
|
|
|
bool is_compilation() const {
|
|
|
|
return (d->compilation_ || d->sampler_ || d->forced_compilation_on_)
|
|
|
|
&& ! d->forced_compilation_off_;
|
|
|
|
}
|
2010-10-17 18:03:49 +02:00
|
|
|
float rating() const { return d->rating_; }
|
|
|
|
int playcount() const { return d->playcount_; }
|
2010-10-17 19:50:20 +02:00
|
|
|
int skipcount() const { return d->skipcount_; }
|
|
|
|
int lastplayed() const { return d->lastplayed_; }
|
2010-11-01 22:15:52 +01:00
|
|
|
int score() const { return d->score_; }
|
2010-01-15 22:57:22 +01:00
|
|
|
|
2011-01-15 19:46:23 +01:00
|
|
|
const QString& cue_path() const { return d->cue_path_; }
|
|
|
|
bool has_cue() const { return !d->cue_path_.isEmpty(); }
|
|
|
|
|
2011-02-13 19:34:30 +01:00
|
|
|
qint64 beginning_nanosec() const { return d->beginning_; }
|
|
|
|
qint64 end_nanosec() const { return d->end_; }
|
2010-12-23 22:13:43 +01:00
|
|
|
|
2011-02-13 19:34:30 +01:00
|
|
|
qint64 length_nanosec() const { return d->end_ - d->beginning_; }
|
2010-12-23 22:13:43 +01:00
|
|
|
|
2010-01-15 22:57:22 +01:00
|
|
|
int bitrate() const { return d->bitrate_; }
|
|
|
|
int samplerate() const { return d->samplerate_; }
|
|
|
|
|
|
|
|
int directory_id() const { return d->directory_id_; }
|
2010-02-28 01:35:20 +01:00
|
|
|
const QString& filename() const { return d->filename_; }
|
2011-03-10 19:01:35 +01:00
|
|
|
// Returns this Song's URL which may point either to a file or to another type
|
|
|
|
// of stream.
|
|
|
|
QUrl url() const;
|
2010-03-19 11:39:22 +01:00
|
|
|
const QString& basefilename() const { return d->basefilename_; }
|
2010-01-15 22:57:22 +01:00
|
|
|
uint mtime() const { return d->mtime_; }
|
|
|
|
uint ctime() const { return d->ctime_; }
|
|
|
|
int filesize() const { return d->filesize_; }
|
2010-03-07 23:46:41 +01:00
|
|
|
FileType filetype() const { return d->filetype_; }
|
2011-03-20 13:43:10 +01:00
|
|
|
bool is_stream() const { return d->filetype_ == Type_Stream; }
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-02-28 01:35:20 +01:00
|
|
|
const QString& art_automatic() const { return d->art_automatic_; }
|
|
|
|
const QString& art_manual() const { return d->art_manual_; }
|
|
|
|
|
2011-02-02 22:01:08 +01:00
|
|
|
// Returns true if this Song had it's cover manually unset by user.
|
|
|
|
bool has_manually_unset_cover() const { return d->art_manual_ == kManuallyUnsetCover; }
|
|
|
|
// This method represents an explicit request to unset this song's
|
|
|
|
// cover.
|
|
|
|
void manually_unset_cover() { d->art_manual_ = kManuallyUnsetCover; }
|
|
|
|
|
|
|
|
// Returns true if this song (it's media file) has an embedded cover.
|
|
|
|
bool has_embedded_cover() const { return d->art_automatic_ == kEmbeddedCover; }
|
|
|
|
// Sets a flag saying that this song (it's media file) has an embedded
|
|
|
|
// cover.
|
|
|
|
void set_embedded_cover() { d->art_automatic_ = kEmbeddedCover; }
|
|
|
|
|
2010-02-25 01:18:32 +01:00
|
|
|
const QImage& image() const { return d->image_; }
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Pretty accessors
|
|
|
|
QString PrettyTitle() const;
|
|
|
|
QString PrettyTitleWithArtist() const;
|
|
|
|
QString PrettyLength() const;
|
2010-12-06 00:41:41 +01:00
|
|
|
QString PrettyYear() const;
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-11-21 22:36:27 +01:00
|
|
|
QString TitleWithCompilationArtist() const;
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Setters
|
2010-06-25 01:36:39 +02:00
|
|
|
bool IsEditable() const;
|
2010-01-16 17:12:47 +01:00
|
|
|
bool Save() const;
|
2010-08-02 16:00:43 +02:00
|
|
|
QFuture<bool> BackgroundSave() const;
|
2010-01-16 17:12:47 +01:00
|
|
|
|
2010-01-15 22:57:22 +01:00
|
|
|
void set_id(int id) { d->id_ = id; }
|
2010-05-09 20:50:54 +02:00
|
|
|
void set_valid(bool v) { d->valid_ = v; }
|
2010-01-16 17:12:47 +01:00
|
|
|
void set_title(const QString& v) { d->title_ = v; }
|
|
|
|
|
|
|
|
void set_album(const QString& v) { d->album_ = v; }
|
|
|
|
void set_artist(const QString& v) { d->artist_ = v; }
|
|
|
|
void set_albumartist(const QString& v) { d->albumartist_ = v; }
|
|
|
|
void set_composer(const QString& v) { d->composer_ = v; }
|
|
|
|
void set_track(int v) { d->track_ = v; }
|
|
|
|
void set_disc(int v) { d->disc_ = v; }
|
|
|
|
void set_bpm(float v) { d->bpm_ = v; }
|
|
|
|
void set_year(int v) { d->year_ = v; }
|
|
|
|
void set_genre(const QString& v) { d->genre_ = v; }
|
2011-02-27 18:16:22 +01:00
|
|
|
void set_genre_id3(int id);
|
2010-01-16 17:12:47 +01:00
|
|
|
void set_comment(const QString& v) { d->comment_ = v; }
|
|
|
|
void set_compilation(bool v) { d->compilation_ = v; }
|
2010-02-27 21:12:22 +01:00
|
|
|
void set_sampler(bool v) { d->sampler_ = v; }
|
2011-02-13 19:34:30 +01:00
|
|
|
void set_beginning_nanosec(qint64 v) { d->beginning_ = qMax(0ll, v); }
|
|
|
|
void set_end_nanosec(qint64 v) { d->end_ = v; }
|
|
|
|
void set_length_nanosec(qint64 v) { d->end_ = d->beginning_ + v; }
|
2010-01-16 17:12:47 +01:00
|
|
|
void set_bitrate(int v) { d->bitrate_ = v; }
|
|
|
|
void set_samplerate(int v) { d->samplerate_ = v; }
|
|
|
|
void set_mtime(int v) { d->mtime_ = v; }
|
|
|
|
void set_ctime(int v) { d->ctime_ = v; }
|
|
|
|
void set_filesize(int v) { d->filesize_ = v; }
|
2010-03-07 23:46:41 +01:00
|
|
|
void set_filetype(FileType v) { d->filetype_ = v; }
|
2010-02-28 01:35:20 +01:00
|
|
|
void set_art_automatic(const QString& v) { d->art_automatic_ = v; }
|
|
|
|
void set_art_manual(const QString& v) { d->art_manual_ = v; }
|
2010-02-25 01:18:32 +01:00
|
|
|
void set_image(const QImage& i) { d->image_ = i; }
|
2010-03-24 20:05:49 +01:00
|
|
|
void set_forced_compilation_on(bool v) { d->forced_compilation_on_ = v; }
|
|
|
|
void set_forced_compilation_off(bool v) { d->forced_compilation_off_ = v; }
|
2010-10-17 18:03:49 +02:00
|
|
|
void set_rating(float v) { d->rating_ = v; }
|
|
|
|
void set_playcount(int v) { d->playcount_ = v; }
|
2010-10-17 19:50:20 +02:00
|
|
|
void set_skipcount(int v) { d->skipcount_ = v; }
|
|
|
|
void set_lastplayed(int v) { d->lastplayed_ = v; }
|
2010-11-21 16:38:26 +01:00
|
|
|
void set_score(int v) { d->score_ = qBound(0, v, 100); }
|
2011-01-15 19:46:23 +01:00
|
|
|
void set_cue_path(const QString& v) { d->cue_path_ = v; }
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-03-03 00:37:12 +01:00
|
|
|
// Setters that should only be used by tests
|
|
|
|
void set_filename(const QString& v) { d->filename_ = v; }
|
2010-03-19 11:39:22 +01:00
|
|
|
void set_basefilename(const QString& v) { d->basefilename_ = v; }
|
2010-03-03 00:37:12 +01:00
|
|
|
void set_directory_id(int v) { d->directory_id_ = v; }
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Comparison functions
|
|
|
|
bool IsMetadataEqual(const Song& other) const;
|
2011-03-13 19:37:46 +01:00
|
|
|
bool IsOnSameAlbum(const Song& other) const;
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2011-01-17 00:46:58 +01:00
|
|
|
bool operator==(const Song& other) const;
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
private:
|
2010-03-07 23:46:41 +01:00
|
|
|
void GuessFileType(TagLib::FileRef* fileref);
|
2010-08-02 16:00:43 +02:00
|
|
|
static bool Save(const Song& song);
|
2010-03-07 23:46:41 +01:00
|
|
|
|
2010-03-29 15:15:47 +02:00
|
|
|
// Helper methods for taglib
|
2010-03-29 15:28:29 +02:00
|
|
|
static void SetTextFrame(const QString& id, const QString& value,
|
|
|
|
TagLib::ID3v2::Tag* tag);
|
2010-10-17 18:03:49 +02:00
|
|
|
void ParseFMPSFrame(const QString& name, const QString& value);
|
2010-03-29 15:15:47 +02:00
|
|
|
|
2010-03-07 23:46:41 +01:00
|
|
|
private:
|
|
|
|
struct Private : public QSharedData {
|
|
|
|
Private();
|
|
|
|
|
|
|
|
bool valid_;
|
|
|
|
int id_;
|
|
|
|
|
|
|
|
QString title_;
|
|
|
|
QString album_;
|
|
|
|
QString artist_;
|
|
|
|
QString albumartist_;
|
|
|
|
QString composer_;
|
|
|
|
int track_;
|
|
|
|
int disc_;
|
|
|
|
float bpm_;
|
|
|
|
int year_;
|
|
|
|
QString genre_;
|
|
|
|
QString comment_;
|
2010-03-21 00:59:39 +01:00
|
|
|
bool compilation_; // From the file tag
|
|
|
|
bool sampler_; // From the library scanner
|
|
|
|
bool forced_compilation_on_; // Set by the user
|
|
|
|
bool forced_compilation_off_; // Set by the user
|
2010-03-07 23:46:41 +01:00
|
|
|
|
2010-10-17 18:03:49 +02:00
|
|
|
float rating_;
|
|
|
|
int playcount_;
|
2010-10-17 19:50:20 +02:00
|
|
|
int skipcount_;
|
|
|
|
int lastplayed_;
|
2010-11-01 22:15:52 +01:00
|
|
|
int score_;
|
2010-10-17 18:03:49 +02:00
|
|
|
|
2010-12-23 22:13:43 +01:00
|
|
|
// The beginning of the song in seconds. In case of single-part media
|
|
|
|
// streams, this will equal to 0. In case of multi-part streams on the
|
|
|
|
// other hand, this will mark the beginning of a section represented by
|
2011-01-02 19:53:45 +01:00
|
|
|
// this Song object. This is always greater than 0.
|
2011-02-13 19:34:30 +01:00
|
|
|
qint64 beginning_;
|
2010-12-23 22:13:43 +01:00
|
|
|
// The end of the song in seconds. In case of single-part media
|
|
|
|
// streams, this will equal to the song's length. In case of multi-part
|
|
|
|
// streams on the other hand, this will mark the end of a section
|
|
|
|
// represented by this Song object.
|
2011-01-02 19:53:45 +01:00
|
|
|
// This may be negative indicating that the length of this song is
|
|
|
|
// unknown.
|
2011-02-13 19:34:30 +01:00
|
|
|
qint64 end_;
|
2010-12-23 22:13:43 +01:00
|
|
|
|
2010-03-07 23:46:41 +01:00
|
|
|
int bitrate_;
|
|
|
|
int samplerate_;
|
|
|
|
|
|
|
|
int directory_id_;
|
|
|
|
QString filename_;
|
2010-03-19 11:39:22 +01:00
|
|
|
QString basefilename_;
|
2010-03-07 23:46:41 +01:00
|
|
|
int mtime_;
|
|
|
|
int ctime_;
|
|
|
|
int filesize_;
|
|
|
|
FileType filetype_;
|
|
|
|
|
2011-01-15 19:46:23 +01:00
|
|
|
// If the song has a CUE, this contains it's path.
|
|
|
|
QString cue_path_;
|
|
|
|
|
2010-03-07 23:46:41 +01:00
|
|
|
// Filenames to album art for this song.
|
|
|
|
QString art_automatic_; // Guessed by LibraryWatcher
|
|
|
|
QString art_manual_; // Set by the user - should take priority
|
|
|
|
|
|
|
|
QImage image_;
|
2010-10-12 13:55:45 +02:00
|
|
|
|
|
|
|
// Whether this song was loaded from a file using taglib.
|
|
|
|
bool init_from_file_;
|
2011-03-06 17:39:36 +01:00
|
|
|
// Whether our encoding guesser thinks these tags might be incorrectly encoded.
|
|
|
|
bool suspicious_tags_;
|
2010-03-07 23:46:41 +01:00
|
|
|
};
|
|
|
|
|
2010-09-15 21:24:31 +02:00
|
|
|
void ParseOggTag(const TagLib::Ogg::FieldListMap& map, const QTextCodec* codec, QString* disc, QString* compilation);
|
|
|
|
|
2010-03-07 23:46:41 +01:00
|
|
|
private:
|
|
|
|
QSharedDataPointer<Private> d;
|
2010-03-06 21:08:01 +01:00
|
|
|
FileRefFactory* factory_;
|
|
|
|
|
|
|
|
static TagLibFileRefFactory kDefaultFactory;
|
2010-08-08 14:35:23 +02:00
|
|
|
|
|
|
|
static QMutex taglib_mutex_;
|
2009-12-24 20:16:07 +01:00
|
|
|
};
|
2010-03-03 01:33:31 +01:00
|
|
|
Q_DECLARE_METATYPE(Song);
|
2009-12-24 20:16:07 +01:00
|
|
|
|
|
|
|
typedef QList<Song> SongList;
|
2010-03-03 01:33:31 +01:00
|
|
|
Q_DECLARE_METATYPE(SongList);
|
2009-12-24 20:16:07 +01:00
|
|
|
|
|
|
|
#endif // SONG_H
|