2018-02-27 18:06:05 +01:00
|
|
|
/*
|
|
|
|
* Strawberry Music Player
|
|
|
|
* This file was part of Clementine.
|
|
|
|
* Copyright 2010, David Sansome <me@davidsansome.com>
|
2021-03-20 21:14:47 +01:00
|
|
|
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
2018-02-27 18:06:05 +01:00
|
|
|
*
|
|
|
|
* Strawberry 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.
|
|
|
|
*
|
|
|
|
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
2018-08-09 18:10:03 +02:00
|
|
|
*
|
2018-02-27 18:06:05 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SONG_H
|
|
|
|
#define SONG_H
|
|
|
|
|
2018-05-01 00:41:33 +02:00
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <QtGlobal>
|
|
|
|
#include <QSharedData>
|
2018-02-27 18:06:05 +01:00
|
|
|
#include <QSharedDataPointer>
|
2018-05-01 00:41:33 +02:00
|
|
|
#include <QMetaType>
|
|
|
|
#include <QList>
|
|
|
|
#include <QSet>
|
2021-09-19 15:41:36 +02:00
|
|
|
#include <QMap>
|
2018-05-01 00:41:33 +02:00
|
|
|
#include <QVariant>
|
|
|
|
#include <QString>
|
|
|
|
#include <QStringList>
|
2020-07-18 04:05:07 +02:00
|
|
|
#include <QRegularExpression>
|
2018-05-01 00:41:33 +02:00
|
|
|
#include <QUrl>
|
2021-07-02 01:15:16 +02:00
|
|
|
#include <QFileInfo>
|
2018-05-01 00:41:33 +02:00
|
|
|
#include <QImage>
|
2018-09-08 12:38:02 +02:00
|
|
|
#include <QIcon>
|
2020-02-08 03:40:30 +01:00
|
|
|
|
2021-09-09 21:45:46 +02:00
|
|
|
class SqlQuery;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2018-05-01 00:41:33 +02:00
|
|
|
namespace Engine {
|
|
|
|
struct SimpleMetaBundle;
|
|
|
|
} // namespace Engine
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2021-02-20 17:06:55 +01:00
|
|
|
namespace spb {
|
2018-02-27 18:06:05 +01:00
|
|
|
namespace tagreader {
|
|
|
|
class SongMetadata;
|
|
|
|
} // namespace tagreader
|
2021-02-20 17:06:55 +01:00
|
|
|
} // namespace spb
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
#ifdef HAVE_LIBGPOD
|
|
|
|
struct _Itdb_Track;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBMTP
|
|
|
|
struct LIBMTP_track_struct;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
class SqlRow;
|
|
|
|
|
|
|
|
class Song {
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2018-09-08 12:38:02 +02:00
|
|
|
enum Source {
|
|
|
|
Source_Unknown = 0,
|
|
|
|
Source_LocalFile = 1,
|
|
|
|
Source_Collection = 2,
|
|
|
|
Source_CDDA = 3,
|
|
|
|
Source_Device = 4,
|
|
|
|
Source_Stream = 5,
|
|
|
|
Source_Tidal = 6,
|
2019-06-17 23:54:24 +02:00
|
|
|
Source_Subsonic = 7,
|
2019-06-19 02:22:11 +02:00
|
|
|
Source_Qobuz = 8,
|
2021-07-11 01:02:53 +02:00
|
|
|
Source_SomaFM = 9,
|
|
|
|
Source_RadioParadise = 10
|
2018-09-08 12:38:02 +02:00
|
|
|
};
|
|
|
|
|
2019-04-08 23:00:07 +02:00
|
|
|
// Don't change these values - they're stored in the database, and defined in the tag reader protobuf.
|
|
|
|
// If a new lossless file is added, also add it to IsFileLossless().
|
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
enum FileType {
|
2018-09-08 12:38:02 +02:00
|
|
|
FileType_Unknown = 0,
|
|
|
|
FileType_WAV = 1,
|
|
|
|
FileType_FLAC = 2,
|
|
|
|
FileType_WavPack = 3,
|
|
|
|
FileType_OggFlac = 4,
|
|
|
|
FileType_OggVorbis = 5,
|
|
|
|
FileType_OggOpus = 6,
|
|
|
|
FileType_OggSpeex = 7,
|
|
|
|
FileType_MPEG = 8,
|
|
|
|
FileType_MP4 = 9,
|
|
|
|
FileType_ASF = 10,
|
|
|
|
FileType_AIFF = 11,
|
|
|
|
FileType_MPC = 12,
|
|
|
|
FileType_TrueAudio = 13,
|
|
|
|
FileType_DSF = 14,
|
|
|
|
FileType_DSDIFF = 15,
|
2018-10-23 20:21:01 +02:00
|
|
|
FileType_PCM = 16,
|
2019-01-06 00:32:58 +01:00
|
|
|
FileType_APE = 17,
|
2018-09-08 12:38:02 +02:00
|
|
|
FileType_CDDA = 90,
|
|
|
|
FileType_Stream = 91,
|
2018-02-27 18:06:05 +01:00
|
|
|
};
|
|
|
|
|
2020-12-23 20:24:15 +01:00
|
|
|
Song(Song::Source source = Song::Source_Unknown);
|
2019-04-08 23:00:07 +02:00
|
|
|
Song(const Song &other);
|
|
|
|
~Song();
|
|
|
|
|
|
|
|
static const QStringList kColumns;
|
|
|
|
static const QString kColumnSpec;
|
|
|
|
static const QString kBindSpec;
|
|
|
|
static const QString kUpdateSpec;
|
|
|
|
|
|
|
|
static const QStringList kFtsColumns;
|
|
|
|
static const QString kFtsColumnSpec;
|
|
|
|
static const QString kFtsBindSpec;
|
|
|
|
static const QString kFtsUpdateSpec;
|
|
|
|
|
|
|
|
static const QString kManuallyUnsetCover;
|
|
|
|
static const QString kEmbeddedCover;
|
|
|
|
|
2020-07-18 04:05:07 +02:00
|
|
|
static const QRegularExpression kAlbumRemoveDisc;
|
|
|
|
static const QRegularExpression kAlbumRemoveMisc;
|
|
|
|
static const QRegularExpression kTitleRemoveMisc;
|
2019-04-08 23:00:07 +02:00
|
|
|
|
2019-11-20 21:30:41 +01:00
|
|
|
static const QString kVariousArtists;
|
|
|
|
|
2019-07-05 00:13:51 +02:00
|
|
|
static const QStringList kArticles;
|
|
|
|
|
2021-03-21 19:19:35 +01:00
|
|
|
static const QStringList kAcceptedExtensions;
|
|
|
|
|
2019-04-08 23:00:07 +02:00
|
|
|
static QString JoinSpec(const QString &table);
|
|
|
|
|
2019-03-22 23:16:18 +01:00
|
|
|
static Source SourceFromURL(const QUrl &url);
|
2018-09-08 12:38:02 +02:00
|
|
|
static QString TextForSource(Source source);
|
2021-07-11 01:02:53 +02:00
|
|
|
static QString DescriptionForSource(Source source);
|
2020-08-25 23:44:27 +02:00
|
|
|
static Song::Source SourceFromText(const QString &source);
|
2018-09-08 12:38:02 +02:00
|
|
|
static QIcon IconForSource(Source source);
|
|
|
|
static QString TextForFiletype(FileType filetype);
|
2019-03-23 02:24:09 +01:00
|
|
|
static QString ExtensionForFiletype(FileType filetype);
|
2018-09-12 21:52:30 +02:00
|
|
|
static QIcon IconForFiletype(FileType filetype);
|
2018-09-08 12:38:02 +02:00
|
|
|
|
|
|
|
QString TextForSource() const { return TextForSource(source()); }
|
2021-07-11 01:02:53 +02:00
|
|
|
QString DescriptionForSource() const { return DescriptionForSource(source()); }
|
2018-09-08 12:38:02 +02:00
|
|
|
QIcon IconForSource() const { return IconForSource(source()); }
|
2018-02-27 18:06:05 +01:00
|
|
|
QString TextForFiletype() const { return TextForFiletype(filetype()); }
|
2018-09-12 21:52:30 +02:00
|
|
|
QIcon IconForFiletype() const { return IconForFiletype(filetype()); }
|
2018-09-08 12:38:02 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
bool IsFileLossless() const;
|
2019-09-09 22:11:13 +02:00
|
|
|
static FileType FiletypeByMimetype(const QString &mimetype);
|
|
|
|
static FileType FiletypeByDescription(const QString &text);
|
|
|
|
static FileType FiletypeByExtension(const QString &ext);
|
2020-04-20 18:03:18 +02:00
|
|
|
static QString ImageCacheDir(const Song::Source source);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
// Sort songs alphabetically using their pretty title
|
2020-04-23 21:08:28 +02:00
|
|
|
static int CompareSongsName(const Song &song1, const Song &song2);
|
2018-02-27 18:06:05 +01:00
|
|
|
static void SortSongsListAlphabetically(QList<Song> *songs);
|
|
|
|
|
|
|
|
// Constructors
|
|
|
|
void Init(const QString &title, const QString &artist, const QString &album, qint64 length_nanosec);
|
|
|
|
void Init(const QString &title, const QString &artist, const QString &album, qint64 beginning, qint64 end);
|
2021-02-20 17:06:55 +01:00
|
|
|
void InitFromProtobuf(const spb::tagreader::SongMetadata &pb);
|
2018-02-27 18:06:05 +01:00
|
|
|
void InitFromQuery(const SqlRow &query, bool reliable_metadata, int col = 0);
|
2021-07-02 01:15:16 +02:00
|
|
|
void InitFromFilePartial(const QString &filename, const QFileInfo &fileinfo);
|
|
|
|
void InitArtManual();
|
2021-02-26 21:03:51 +01:00
|
|
|
void InitArtAutomatic();
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2019-09-07 23:34:13 +02:00
|
|
|
bool MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
#ifdef HAVE_LIBGPOD
|
2020-09-01 01:04:01 +02:00
|
|
|
void InitFromItdb(_Itdb_Track *track, const QString &prefix);
|
2018-02-27 18:06:05 +01:00
|
|
|
void ToItdb(_Itdb_Track *track) const;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBMTP
|
|
|
|
void InitFromMTP(const LIBMTP_track_struct *track, const QString &host);
|
|
|
|
void ToMTP(LIBMTP_track_struct *track) const;
|
|
|
|
#endif
|
|
|
|
|
2018-05-01 00:41:33 +02:00
|
|
|
// Copies important statistics from the other song to this one, overwriting any data that already exists.
|
|
|
|
// Useful when you want updated tags from disk but you want to keep user stats.
|
2018-02-27 18:06:05 +01:00
|
|
|
void MergeUserSetData(const Song &other);
|
|
|
|
|
|
|
|
// Save
|
2021-09-09 21:45:46 +02:00
|
|
|
void BindToQuery(SqlQuery *query) const;
|
|
|
|
void BindToFtsQuery(SqlQuery *query) const;
|
2018-02-27 18:06:05 +01:00
|
|
|
void ToXesam(QVariantMap *map) const;
|
2021-02-20 17:06:55 +01:00
|
|
|
void ToProtobuf(spb::tagreader::SongMetadata *pb) const;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
// Simple accessors
|
|
|
|
bool is_valid() const;
|
|
|
|
bool is_unavailable() const;
|
|
|
|
int id() const;
|
|
|
|
|
|
|
|
const QString &title() const;
|
2019-07-05 00:13:51 +02:00
|
|
|
const QString &title_sortable() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
const QString &album() const;
|
2019-07-05 00:13:51 +02:00
|
|
|
const QString &album_sortable() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
const QString &artist() const;
|
2019-07-11 16:51:25 +02:00
|
|
|
const QString &artist_sortable() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
const QString &albumartist() const;
|
2019-07-11 16:51:25 +02:00
|
|
|
const QString &albumartist_sortable() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
int track() const;
|
|
|
|
int disc() const;
|
|
|
|
int year() const;
|
|
|
|
int originalyear() const;
|
|
|
|
const QString &genre() const;
|
2019-11-03 23:23:04 +01:00
|
|
|
bool compilation() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
const QString &composer() const;
|
|
|
|
const QString &performer() const;
|
|
|
|
const QString &grouping() const;
|
|
|
|
const QString &comment() const;
|
2018-09-06 20:04:29 +02:00
|
|
|
const QString &lyrics() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2020-04-13 03:39:51 +02:00
|
|
|
QString artist_id() const;
|
2019-06-20 02:14:44 +02:00
|
|
|
QString album_id() const;
|
2020-04-13 03:39:51 +02:00
|
|
|
QString song_id() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
qint64 beginning_nanosec() const;
|
|
|
|
qint64 end_nanosec() const;
|
|
|
|
qint64 length_nanosec() const;
|
|
|
|
|
|
|
|
int bitrate() const;
|
|
|
|
int samplerate() const;
|
|
|
|
int bitdepth() const;
|
|
|
|
|
2018-09-08 12:38:02 +02:00
|
|
|
Source source() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
int directory_id() const;
|
|
|
|
const QUrl &url() const;
|
|
|
|
const QString &basefilename() const;
|
|
|
|
FileType filetype() const;
|
|
|
|
int filesize() const;
|
2020-08-13 21:09:06 +02:00
|
|
|
qint64 mtime() const;
|
|
|
|
qint64 ctime() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2021-04-25 21:16:44 +02:00
|
|
|
QString fingerprint() const;
|
|
|
|
|
2019-05-30 18:04:30 +02:00
|
|
|
int playcount() const;
|
|
|
|
int skipcount() const;
|
2021-02-10 18:27:40 +01:00
|
|
|
qint64 lastplayed() const;
|
2021-04-25 21:16:44 +02:00
|
|
|
qint64 lastseen() const;
|
2019-05-30 18:04:30 +02:00
|
|
|
|
2019-11-03 23:23:04 +01:00
|
|
|
bool compilation_detected() const;
|
|
|
|
bool compilation_off() const;
|
|
|
|
bool compilation_on() const;
|
|
|
|
|
2019-07-07 21:14:24 +02:00
|
|
|
const QUrl &art_automatic() const;
|
|
|
|
const QUrl &art_manual() const;
|
2018-10-02 00:38:52 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
const QString &cue_path() const;
|
|
|
|
bool has_cue() const;
|
2018-10-02 00:38:52 +02:00
|
|
|
|
2021-03-21 18:53:02 +01:00
|
|
|
double rating() const;
|
2020-09-17 17:50:17 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
const QString &effective_album() const;
|
|
|
|
int effective_originalyear() const;
|
|
|
|
const QString &effective_albumartist() const;
|
2019-07-11 16:51:25 +02:00
|
|
|
const QString &effective_albumartist_sortable() const;
|
2018-10-02 00:38:52 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
bool is_collection_song() const;
|
2018-08-09 18:10:03 +02:00
|
|
|
bool is_stream() const;
|
2021-07-11 05:18:39 +02:00
|
|
|
bool is_radio() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
bool is_cdda() const;
|
2018-12-23 18:54:27 +01:00
|
|
|
bool is_metadata_good() const;
|
2019-07-07 21:14:24 +02:00
|
|
|
bool art_automatic_is_valid() const;
|
|
|
|
bool art_manual_is_valid() const;
|
2021-02-26 21:03:51 +01:00
|
|
|
bool has_valid_art() const;
|
2019-11-03 23:23:04 +01:00
|
|
|
bool is_compilation() const;
|
2021-06-10 23:13:03 +02:00
|
|
|
bool stream_url_can_expire() const;
|
2018-10-02 00:38:52 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
// Playlist views are special because you don't want to fill in album artists automatically for compilations, but you do for normal albums:
|
|
|
|
const QString &playlist_albumartist() const;
|
2019-10-03 18:25:50 +02:00
|
|
|
const QString &playlist_albumartist_sortable() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
// Returns true if this Song had it's cover manually unset by user.
|
|
|
|
bool has_manually_unset_cover() const;
|
2018-05-01 00:41:33 +02:00
|
|
|
// This method represents an explicit request to unset this song's cover.
|
2021-02-26 21:03:51 +01:00
|
|
|
void set_manually_unset_cover();
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
// Returns true if this song (it's media file) has an embedded cover.
|
|
|
|
bool has_embedded_cover() const;
|
|
|
|
// Sets a flag saying that this song (it's media file) has an embedded cover.
|
|
|
|
void set_embedded_cover();
|
|
|
|
|
2021-02-26 21:03:51 +01:00
|
|
|
void clear_art_automatic();
|
|
|
|
void clear_art_manual();
|
|
|
|
|
|
|
|
static bool save_embedded_cover_supported(const FileType filetype);
|
|
|
|
bool save_embedded_cover_supported() const { return url().isLocalFile() && save_embedded_cover_supported(filetype()) && !has_cue(); };
|
|
|
|
|
2019-07-31 22:26:51 +02:00
|
|
|
const QUrl &stream_url() const;
|
|
|
|
const QUrl &effective_stream_url() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
const QImage &image() const;
|
2021-07-28 22:25:33 +02:00
|
|
|
bool init_from_file() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
// Pretty accessors
|
|
|
|
QString PrettyTitle() const;
|
|
|
|
QString PrettyTitleWithArtist() const;
|
|
|
|
QString PrettyLength() const;
|
|
|
|
QString PrettyYear() const;
|
2020-12-11 23:59:38 +01:00
|
|
|
QString PrettyOriginalYear() const;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
QString TitleWithCompilationArtist() const;
|
2018-10-02 00:38:52 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
QString SampleRateBitDepthToText() const;
|
|
|
|
|
2020-09-17 17:50:17 +02:00
|
|
|
QString PrettyRating() const;
|
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
// Setters
|
|
|
|
bool IsEditable() const;
|
|
|
|
|
|
|
|
void set_id(int id);
|
|
|
|
void set_valid(bool v);
|
|
|
|
|
|
|
|
void set_title(const QString &v);
|
|
|
|
void set_album(const QString &v);
|
|
|
|
void set_artist(const QString &v);
|
|
|
|
void set_albumartist(const QString &v);
|
|
|
|
void set_track(int v);
|
|
|
|
void set_disc(int v);
|
|
|
|
void set_year(int v);
|
|
|
|
void set_originalyear(int v);
|
|
|
|
void set_genre(const QString &v);
|
|
|
|
void set_compilation(bool v);
|
|
|
|
void set_composer(const QString &v);
|
|
|
|
void set_performer(const QString &v);
|
|
|
|
void set_grouping(const QString &v);
|
|
|
|
void set_comment(const QString &v);
|
2018-09-06 20:04:29 +02:00
|
|
|
void set_lyrics(const QString &v);
|
|
|
|
|
2020-04-13 03:39:51 +02:00
|
|
|
void set_artist_id(const QString &v);
|
2019-06-20 02:14:44 +02:00
|
|
|
void set_album_id(const QString &v);
|
2020-04-13 03:39:51 +02:00
|
|
|
void set_song_id(const QString &v);
|
2019-05-30 18:04:30 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
void set_beginning_nanosec(qint64 v);
|
|
|
|
void set_end_nanosec(qint64 v);
|
|
|
|
void set_length_nanosec(qint64 v);
|
|
|
|
|
|
|
|
void set_bitrate(int v);
|
|
|
|
void set_samplerate(int v);
|
|
|
|
void set_bitdepth(int v);
|
2018-09-08 12:38:02 +02:00
|
|
|
|
|
|
|
void set_source(Source v);
|
2018-02-27 18:06:05 +01:00
|
|
|
void set_directory_id(int v);
|
|
|
|
void set_url(const QUrl &v);
|
|
|
|
void set_basefilename(const QString &v);
|
|
|
|
void set_filetype(FileType v);
|
|
|
|
void set_filesize(int v);
|
2020-08-13 21:09:06 +02:00
|
|
|
void set_mtime(qint64 v);
|
|
|
|
void set_ctime(qint64 v);
|
2018-02-27 18:06:05 +01:00
|
|
|
void set_unavailable(bool v);
|
2018-10-02 00:38:52 +02:00
|
|
|
|
2021-04-25 21:16:44 +02:00
|
|
|
void set_fingerprint(const QString &v);
|
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
void set_playcount(int v);
|
|
|
|
void set_skipcount(int v);
|
2021-02-10 18:27:40 +01:00
|
|
|
void set_lastplayed(qint64 v);
|
2021-04-25 21:16:44 +02:00
|
|
|
void set_lastseen(qint64 v);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
void set_compilation_detected(bool v);
|
|
|
|
void set_compilation_on(bool v);
|
|
|
|
void set_compilation_off(bool v);
|
2018-10-02 00:38:52 +02:00
|
|
|
|
2019-07-07 21:14:24 +02:00
|
|
|
void set_art_automatic(const QUrl &v);
|
|
|
|
void set_art_manual(const QUrl &v);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
void set_cue_path(const QString &v);
|
2018-10-02 00:38:52 +02:00
|
|
|
|
2021-03-21 18:53:02 +01:00
|
|
|
void set_rating(const double v);
|
2020-09-17 17:50:17 +02:00
|
|
|
|
2019-07-31 22:26:51 +02:00
|
|
|
void set_stream_url(const QUrl &v);
|
2018-02-27 18:06:05 +01:00
|
|
|
void set_image(const QImage &i);
|
|
|
|
|
|
|
|
// Comparison functions
|
|
|
|
bool IsMetadataEqual(const Song &other) const;
|
2021-04-25 21:16:44 +02:00
|
|
|
bool IsMetadataAndMoreEqual(const Song &other) const;
|
2018-02-27 18:06:05 +01:00
|
|
|
bool IsOnSameAlbum(const Song &other) const;
|
|
|
|
bool IsSimilar(const Song &other) const;
|
|
|
|
|
|
|
|
bool operator==(const Song &other) const;
|
2019-07-30 21:31:26 +02:00
|
|
|
bool operator!=(const Song &other) const;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2018-05-01 00:41:33 +02:00
|
|
|
// Two songs that are on the same album will have the same AlbumKey.
|
|
|
|
// It is more efficient to use IsOnSameAlbum, but this function can be used when you need to hash the key to do fast lookups.
|
2018-02-27 18:06:05 +01:00
|
|
|
QString AlbumKey() const;
|
|
|
|
|
|
|
|
Song &operator=(const Song &other);
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct Private;
|
2018-05-01 00:41:33 +02:00
|
|
|
|
2021-07-11 09:49:38 +02:00
|
|
|
static QString sortable(const QString &v);
|
2019-07-05 00:13:51 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
QSharedDataPointer<Private> d;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef QList<Song> SongList;
|
2021-09-19 15:41:36 +02:00
|
|
|
typedef QMap<QString, Song> SongMap;
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(Song)
|
|
|
|
Q_DECLARE_METATYPE(SongList)
|
|
|
|
Q_DECLARE_METATYPE(SongMap)
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2020-11-17 01:22:38 +01:00
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
|
|
size_t qHash(const Song &song);
|
|
|
|
#else
|
2018-02-27 18:06:05 +01:00
|
|
|
uint qHash(const Song &song);
|
2020-11-17 01:22:38 +01:00
|
|
|
#endif
|
2018-02-27 18:06:05 +01:00
|
|
|
// Hash function using field checked in IsSimilar function
|
2021-06-20 19:04:08 +02:00
|
|
|
size_t HashSimilar(const Song &song);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
#endif // SONG_H
|