Add source to songs and playlist_items
This commit is contained in:
@@ -52,7 +52,7 @@
|
||||
#include "scopedtransaction.h"
|
||||
|
||||
const char *Database::kDatabaseFilename = "strawberry.db";
|
||||
const int Database::kSchemaVersion = 2;
|
||||
const int Database::kSchemaVersion = 3;
|
||||
const char *Database::kMagicAllSongsTables = "%allsongstables";
|
||||
|
||||
int Database::sNextConnectionId = 1;
|
||||
|
||||
@@ -293,14 +293,14 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
|
||||
// Icons
|
||||
qLog(Debug) << "Creating UI";
|
||||
|
||||
|
||||
// Help menu
|
||||
|
||||
|
||||
ui_->action_about_strawberry->setIcon(IconLoader::Load("strawberry"));
|
||||
ui_->action_about_qt->setIcon(QIcon(":/qt-project.org/qmessagebox/images/qtlogo-64.png"));
|
||||
|
||||
|
||||
// Music menu
|
||||
|
||||
|
||||
ui_->action_open_file->setIcon(IconLoader::Load("document-open"));
|
||||
ui_->action_open_cd->setIcon(IconLoader::Load("cd"));
|
||||
ui_->action_previous_track->setIcon(IconLoader::Load("media-rewind"));
|
||||
@@ -309,9 +309,9 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
ui_->action_stop_after_this_track->setIcon(IconLoader::Load("media-stop"));
|
||||
ui_->action_next_track->setIcon(IconLoader::Load("media-forward"));
|
||||
ui_->action_quit->setIcon(IconLoader::Load("application-exit"));
|
||||
|
||||
|
||||
// Playlist
|
||||
|
||||
|
||||
ui_->action_add_file->setIcon(IconLoader::Load("document-open"));
|
||||
ui_->action_add_folder->setIcon(IconLoader::Load("document-open-folder"));
|
||||
ui_->action_shuffle_mode->setIcon(IconLoader::Load("media-playlist-shuffle"));
|
||||
@@ -324,11 +324,11 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
ui_->action_shuffle->setIcon(IconLoader::Load("media-playlist-shuffle"));
|
||||
ui_->action_remove_duplicates->setIcon(IconLoader::Load("list-remove"));
|
||||
ui_->action_remove_unavailable->setIcon(IconLoader::Load("list-remove"));
|
||||
|
||||
|
||||
//ui_->action_remove_from_playlist->setIcon(IconLoader::Load("list-remove"));
|
||||
|
||||
|
||||
// Configure
|
||||
|
||||
|
||||
ui_->action_cover_manager->setIcon(IconLoader::Load("document-download"));
|
||||
ui_->action_queue_manager->setIcon(IconLoader::Load("footsteps"));
|
||||
ui_->action_edit_track->setIcon(IconLoader::Load("edit-rename"));
|
||||
@@ -452,9 +452,9 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
connect(ui_->playlist->view(), SIGNAL(BackgroundPropertyChanged()), SLOT(RefreshStyleSheet()));
|
||||
|
||||
connect(ui_->track_slider, SIGNAL(ValueChangedSeconds(int)), app_->player(), SLOT(SeekTo(int)));
|
||||
|
||||
|
||||
// Context connections
|
||||
|
||||
|
||||
connect(context_view_->albums(), SIGNAL(AddToPlaylistSignal(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||
|
||||
// Collection connections
|
||||
@@ -1848,7 +1848,7 @@ void MainWindow::EditFileTags(const QList<QUrl> &urls) {
|
||||
Song song;
|
||||
song.set_url(url);
|
||||
song.set_valid(true);
|
||||
song.set_filetype(Song::Type_MPEG);
|
||||
song.set_filetype(Song::FileType_MPEG);
|
||||
songs << song;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ class MusicStorage {
|
||||
virtual QString LocalPath() const { return QString(); }
|
||||
|
||||
virtual TranscodeMode GetTranscodeMode() const { return Transcode_Never; }
|
||||
virtual Song::FileType GetTranscodeFormat() const { return Song::Type_Unknown; }
|
||||
virtual Song::FileType GetTranscodeFormat() const { return Song::FileType_Unknown; }
|
||||
virtual bool GetSupportedFiletypes(QList<Song::FileType>* ret) { return true; }
|
||||
|
||||
virtual bool StartCopy(QList<Song::FileType>* supported_types) { return true;}
|
||||
|
||||
@@ -154,7 +154,7 @@ void Organise::ProcessSomeFiles() {
|
||||
else {
|
||||
// Figure out if we need to transcode it
|
||||
Song::FileType dest_type = CheckTranscode(song.filetype());
|
||||
if (dest_type != Song::Type_Unknown) {
|
||||
if (dest_type != Song::FileType_Unknown) {
|
||||
// Get the preset
|
||||
TranscoderPreset preset = Transcoder::PresetForFileType(dest_type);
|
||||
qLog(Debug) << "Transcoding with" << preset.name_;
|
||||
@@ -206,28 +206,28 @@ void Organise::ProcessSomeFiles() {
|
||||
|
||||
Song::FileType Organise::CheckTranscode(Song::FileType original_type) const {
|
||||
|
||||
//if (original_type == Song::Type_Stream) return Song::Type_Unknown;
|
||||
if (original_type == Song::FileType_Stream) return Song::FileType_Unknown;
|
||||
|
||||
const MusicStorage::TranscodeMode mode = destination_->GetTranscodeMode();
|
||||
const Song::FileType format = destination_->GetTranscodeFormat();
|
||||
|
||||
switch (mode) {
|
||||
case MusicStorage::Transcode_Never:
|
||||
return Song::Type_Unknown;
|
||||
return Song::FileType_Unknown;
|
||||
|
||||
case MusicStorage::Transcode_Always:
|
||||
if (original_type == format) return Song::Type_Unknown;
|
||||
if (original_type == format) return Song::FileType_Unknown;
|
||||
return format;
|
||||
|
||||
case MusicStorage::Transcode_Unsupported:
|
||||
if (supported_filetypes_.isEmpty() || supported_filetypes_.contains(original_type)) return Song::Type_Unknown;
|
||||
if (supported_filetypes_.isEmpty() || supported_filetypes_.contains(original_type)) return Song::FileType_Unknown;
|
||||
|
||||
if (format != Song::Type_Unknown) return format;
|
||||
if (format != Song::FileType_Unknown) return format;
|
||||
|
||||
// The user hasn't visited the device properties page yet to set a preferred format for the device, so we have to pick the best available one.
|
||||
return Transcoder::PickBestFormat(supported_filetypes_);
|
||||
}
|
||||
return Song::Type_Unknown;
|
||||
return Song::FileType_Unknown;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -38,6 +39,7 @@
|
||||
#include <QRegExp>
|
||||
#include <QUrl>
|
||||
#include <QImage>
|
||||
#include <QIcon>
|
||||
#include <QTextCodec>
|
||||
#include <QSqlQuery>
|
||||
#include <QtDebug>
|
||||
@@ -52,6 +54,7 @@
|
||||
|
||||
#include "core/logging.h"
|
||||
#include "core/messagehandler.h"
|
||||
#include "core/iconloader.h"
|
||||
|
||||
#include "engine/enginebase.h"
|
||||
#include "timeconstants.h"
|
||||
@@ -86,6 +89,7 @@ const QStringList Song::kColumns = QStringList() << "title"
|
||||
<< "samplerate"
|
||||
<< "bitdepth"
|
||||
|
||||
<< "source"
|
||||
<< "directory_id"
|
||||
<< "filename"
|
||||
<< "filetype"
|
||||
@@ -167,6 +171,7 @@ struct Song::Private : public QSharedData {
|
||||
int samplerate_;
|
||||
int bitdepth_;
|
||||
|
||||
Source source_;
|
||||
int directory_id_;
|
||||
QString basefilename_;
|
||||
QUrl url_;
|
||||
@@ -210,14 +215,16 @@ Song::Private::Private()
|
||||
end_(-1),
|
||||
bitrate_(-1),
|
||||
samplerate_(-1),
|
||||
bitdepth_(-1),
|
||||
|
||||
source_(Source_Unknown),
|
||||
directory_id_(-1),
|
||||
filetype_(Type_Unknown),
|
||||
filetype_(FileType_Unknown),
|
||||
filesize_(-1),
|
||||
mtime_(-1),
|
||||
ctime_(-1),
|
||||
unavailable_(false),
|
||||
|
||||
|
||||
playcount_(0),
|
||||
skipcount_(0),
|
||||
lastplayed_(-1),
|
||||
@@ -283,6 +290,7 @@ qint64 Song::length_nanosec() const { return d->end_ - d->beginning_; }
|
||||
int Song::bitrate() const { return d->bitrate_; }
|
||||
int Song::samplerate() const { return d->samplerate_; }
|
||||
int Song::bitdepth() const { return d->bitdepth_; }
|
||||
Song::Source Song::source() const { return d->source_; }
|
||||
int Song::directory_id() const { return d->directory_id_; }
|
||||
const QUrl &Song::url() const { return d->url_; }
|
||||
const QString &Song::basefilename() const { return d->basefilename_; }
|
||||
@@ -290,8 +298,8 @@ uint Song::mtime() const { return d->mtime_; }
|
||||
uint Song::ctime() const { return d->ctime_; }
|
||||
int Song::filesize() const { return d->filesize_; }
|
||||
Song::FileType Song::filetype() const { return d->filetype_; }
|
||||
bool Song::is_stream() const { return d->filetype_ == Type_Stream; }
|
||||
bool Song::is_cdda() const { return d->filetype_ == Type_CDDA; }
|
||||
bool Song::is_stream() const { return d->source_ == Source_Stream || d->source_ == Source_Tidal; }
|
||||
bool Song::is_cdda() const { return d->source_ == Source_CDDA; }
|
||||
bool Song::is_collection_song() const {
|
||||
return !is_cdda() && !is_stream() && id() != -1;
|
||||
}
|
||||
@@ -331,6 +339,7 @@ void Song::set_bitrate(int v) { d->bitrate_ = v; }
|
||||
void Song::set_samplerate(int v) { d->samplerate_ = v; }
|
||||
void Song::set_bitdepth(int v) { d->bitdepth_ = v; }
|
||||
|
||||
void Song::set_source(Source v) { d->source_ = v; }
|
||||
void Song::set_directory_id(int v) { d->directory_id_ = v; }
|
||||
void Song::set_url(const QUrl &v) {
|
||||
if (Application::kIsPortable) {
|
||||
@@ -366,39 +375,93 @@ QString Song::JoinSpec(const QString &table) {
|
||||
return Utilities::Prepend(table + ".", kColumns).join(", ");
|
||||
}
|
||||
|
||||
QString Song::TextForFiletype(FileType type) {
|
||||
QString Song::TextForSource(Source source) {
|
||||
|
||||
switch (type) {
|
||||
case Song::Type_WAV: return QObject::tr("Wav");
|
||||
case Song::Type_FLAC: return QObject::tr("FLAC");
|
||||
case Song::Type_WavPack: return QObject::tr("WavPack");
|
||||
case Song::Type_OggFlac: return QObject::tr("Ogg FLAC");
|
||||
case Song::Type_OggVorbis: return QObject::tr("Ogg Vorbis");
|
||||
case Song::Type_OggOpus: return QObject::tr("Ogg Opus");
|
||||
case Song::Type_OggSpeex: return QObject::tr("Ogg Speex");
|
||||
case Song::Type_MPEG: return QObject::tr("MP3");
|
||||
case Song::Type_MP4: return QObject::tr("MP4 AAC");
|
||||
case Song::Type_ASF: return QObject::tr("Windows Media audio");
|
||||
case Song::Type_AIFF: return QObject::tr("AIFF");
|
||||
case Song::Type_MPC: return QObject::tr("MPC");
|
||||
case Song::Type_TrueAudio: return QObject::tr("TrueAudio");
|
||||
case Song::Type_DSF: return QObject::tr("DSF"); // .dsf
|
||||
case Song::Type_DSDIFF: return QObject::tr("DSDIFF"); // .dff
|
||||
case Song::Type_CDDA: return QObject::tr("CDDA");
|
||||
case Song::Type_Stream: return QObject::tr("Stream");
|
||||
case Song::Type_Unknown:
|
||||
default: return QObject::tr("Unknown");
|
||||
switch (source) {
|
||||
case Song::Source_LocalFile: return QObject::tr("File");
|
||||
case Song::Source_Collection: return QObject::tr("Collection");
|
||||
case Song::Source_CDDA: return QObject::tr("CD");
|
||||
case Song::Source_Device: return QObject::tr("Device");
|
||||
case Song::Source_Stream: return QObject::tr("Stream");
|
||||
case Song::Source_Tidal: return QObject::tr("Tidal");
|
||||
default: return QObject::tr("Unknown");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QIcon Song::IconForSource(Source source) {
|
||||
|
||||
switch (source) {
|
||||
case Song::Source_LocalFile: return IconLoader::Load("folder-sound");
|
||||
case Song::Source_Collection: return IconLoader::Load("vinyl");
|
||||
case Song::Source_CDDA: return IconLoader::Load("cd");
|
||||
case Song::Source_Device: return IconLoader::Load("device");
|
||||
case Song::Source_Stream: return IconLoader::Load("applications-internet");
|
||||
case Song::Source_Tidal: return IconLoader::Load("tidal");
|
||||
default: return IconLoader::Load("edit-delete");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString Song::TextForFiletype(FileType filetype) {
|
||||
|
||||
switch (filetype) {
|
||||
case Song::FileType_WAV: return QObject::tr("Wav");
|
||||
case Song::FileType_FLAC: return QObject::tr("FLAC");
|
||||
case Song::FileType_WavPack: return QObject::tr("WavPack");
|
||||
case Song::FileType_OggFlac: return QObject::tr("Ogg FLAC");
|
||||
case Song::FileType_OggVorbis: return QObject::tr("Ogg Vorbis");
|
||||
case Song::FileType_OggOpus: return QObject::tr("Ogg Opus");
|
||||
case Song::FileType_OggSpeex: return QObject::tr("Ogg Speex");
|
||||
case Song::FileType_MPEG: return QObject::tr("MP3");
|
||||
case Song::FileType_MP4: return QObject::tr("MP4 AAC");
|
||||
case Song::FileType_ASF: return QObject::tr("Windows Media audio");
|
||||
case Song::FileType_AIFF: return QObject::tr("AIFF");
|
||||
case Song::FileType_MPC: return QObject::tr("MPC");
|
||||
case Song::FileType_TrueAudio: return QObject::tr("TrueAudio");
|
||||
case Song::FileType_DSF: return QObject::tr("DSF");
|
||||
case Song::FileType_DSDIFF: return QObject::tr("DSDIFF");
|
||||
case Song::FileType_CDDA: return QObject::tr("CDDA");
|
||||
case Song::FileType_Stream: return QObject::tr("Stream");
|
||||
case Song::FileType_Unknown:
|
||||
default: return QObject::tr("Unknown");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QIcon Song::IconForFiletype(FileType filetype) {
|
||||
|
||||
switch (filetype) {
|
||||
case Song::FileType_WAV: return IconLoader::Load("wav");
|
||||
case Song::FileType_FLAC: return IconLoader::Load("flac");
|
||||
case Song::FileType_WavPack: return IconLoader::Load("wavpack");
|
||||
case Song::FileType_OggFlac: return IconLoader::Load("flac");
|
||||
case Song::FileType_OggVorbis: return IconLoader::Load("vorbis");
|
||||
case Song::FileType_OggOpus: return IconLoader::Load("opus");
|
||||
case Song::FileType_OggSpeex: return IconLoader::Load("speex");
|
||||
case Song::FileType_MPEG: return IconLoader::Load("mp3");
|
||||
case Song::FileType_MP4: return IconLoader::Load("mp4");
|
||||
case Song::FileType_ASF: return IconLoader::Load("wma");
|
||||
case Song::FileType_AIFF: return IconLoader::Load("aiff");
|
||||
case Song::FileType_MPC: return IconLoader::Load("mpc");
|
||||
case Song::FileType_TrueAudio: return IconLoader::Load("trueaudio");
|
||||
case Song::FileType_DSF: return IconLoader::Load("dsf");
|
||||
case Song::FileType_DSDIFF: return IconLoader::Load("dsd");
|
||||
case Song::FileType_CDDA: return IconLoader::Load("cd");
|
||||
case Song::FileType_Stream: return IconLoader::Load("applications-internet");
|
||||
case Song::FileType_Unknown:
|
||||
default: return IconLoader::Load("edit-delete");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Song::IsFileLossless() const {
|
||||
switch (filetype()) {
|
||||
case Song::Type_WAV:
|
||||
case Song::Type_FLAC:
|
||||
case Song::Type_OggFlac:
|
||||
case Song::Type_WavPack:
|
||||
case Song::Type_AIFF:
|
||||
case Song::FileType_WAV:
|
||||
case Song::FileType_FLAC:
|
||||
case Song::FileType_OggFlac:
|
||||
case Song::FileType_WavPack:
|
||||
case Song::FileType_AIFF:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -407,20 +470,20 @@ bool Song::IsFileLossless() const {
|
||||
|
||||
Song::FileType Song::FiletypeByExtension(QString ext) {
|
||||
|
||||
if (ext.toLower() == "wav" || ext.toLower() == "wave") return Song::Type_WAV;
|
||||
else if (ext.toLower() == "flac") return Song::Type_FLAC;
|
||||
else if (ext.toLower() == "wavpack" || ext.toLower() == "wv") return Song::Type_WavPack;
|
||||
else if (ext.toLower() == "ogg" || ext.toLower() == "oga") return Song::Type_OggVorbis;
|
||||
else if (ext.toLower() == "opus") return Song::Type_OggOpus;
|
||||
else if (ext.toLower() == "speex" || ext.toLower() == "spx") return Song::Type_OggSpeex;
|
||||
else if (ext.toLower() == "mp3") return Song::Type_MPEG;
|
||||
else if (ext.toLower() == "mp4" || ext.toLower() == "m4a" || ext.toLower() == "aac") return Song::Type_MP4;
|
||||
else if (ext.toLower() == "asf" || ext.toLower() == "wma") return Song::Type_ASF;
|
||||
else if (ext.toLower() == "aiff" || ext.toLower() == "aif" || ext.toLower() == "aifc") return Song::Type_AIFF;
|
||||
else if (ext.toLower() == "mpc" || ext.toLower() == "mp+" || ext.toLower() == "mpp") return Song::Type_MPC;
|
||||
else if (ext.toLower() == "dsf") return Song::Type_DSF;
|
||||
else if (ext.toLower() == "dsd" || ext.toLower() == "dff") return Song::Type_DSDIFF;
|
||||
else return Song::Type_Unknown;
|
||||
if (ext.toLower() == "wav" || ext.toLower() == "wave") return Song::FileType_WAV;
|
||||
else if (ext.toLower() == "flac") return Song::FileType_FLAC;
|
||||
else if (ext.toLower() == "wavpack" || ext.toLower() == "wv") return Song::FileType_WavPack;
|
||||
else if (ext.toLower() == "ogg" || ext.toLower() == "oga") return Song::FileType_OggVorbis;
|
||||
else if (ext.toLower() == "opus") return Song::FileType_OggOpus;
|
||||
else if (ext.toLower() == "speex" || ext.toLower() == "spx") return Song::FileType_OggSpeex;
|
||||
else if (ext.toLower() == "mp3") return Song::FileType_MPEG;
|
||||
else if (ext.toLower() == "mp4" || ext.toLower() == "m4a" || ext.toLower() == "aac") return Song::FileType_MP4;
|
||||
else if (ext.toLower() == "asf" || ext.toLower() == "wma") return Song::FileType_ASF;
|
||||
else if (ext.toLower() == "aiff" || ext.toLower() == "aif" || ext.toLower() == "aifc") return Song::FileType_AIFF;
|
||||
else if (ext.toLower() == "mpc" || ext.toLower() == "mp+" || ext.toLower() == "mpp") return Song::FileType_MPC;
|
||||
else if (ext.toLower() == "dsf") return Song::FileType_DSF;
|
||||
else if (ext.toLower() == "dsd" || ext.toLower() == "dff") return Song::FileType_DSDIFF;
|
||||
else return Song::FileType_Unknown;
|
||||
|
||||
}
|
||||
|
||||
@@ -547,7 +610,7 @@ void Song::ToProtobuf(pb::tagreader::SongMetadata *pb) const {
|
||||
pb->set_filesize(d->filesize_);
|
||||
pb->set_suspicious_tags(d->suspicious_tags_);
|
||||
pb->set_art_automatic(DataCommaSizeFromQString(d->art_automatic_));
|
||||
pb->set_filetype(static_cast<pb::tagreader::SongMetadata_Type>(d->filetype_));
|
||||
pb->set_filetype(static_cast<pb::tagreader::SongMetadata_FileType>(d->filetype_));
|
||||
}
|
||||
|
||||
#define tostr(n) (q.value(n).isNull() ? QString::null : q.value(n).toString())
|
||||
@@ -635,6 +698,9 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) {
|
||||
d->bitdepth_ = toint(x);
|
||||
}
|
||||
|
||||
else if (Song::kColumns.value(i) == "source") {
|
||||
d->source_ = Source(q.value(x).toInt());
|
||||
}
|
||||
else if (Song::kColumns.value(i) == "directory_id") {
|
||||
d->directory_id_ = toint(x);
|
||||
}
|
||||
@@ -721,8 +787,10 @@ void Song::InitFromFilePartial(const QString &filename) {
|
||||
QString suffix = info.suffix().toLower();
|
||||
|
||||
TagLib::FileRef fileref(filename.toUtf8().constData());
|
||||
//if (TagLib::FileRef::defaultFileExtensions().contains(suffix.toUtf8().constData())) {
|
||||
if (fileref.file()) d->valid_ = true;
|
||||
if (fileref.file()) {
|
||||
d->valid_ = true;
|
||||
d->source_ = Source_LocalFile;
|
||||
}
|
||||
else {
|
||||
d->valid_ = false;
|
||||
qLog(Error) << "File" << filename << "is not recognized by TagLib as a valid audio file.";
|
||||
@@ -772,6 +840,7 @@ void Song::InitFromItdb(const Itdb_Track *track, const QString &prefix) {
|
||||
d->samplerate_ = track->samplerate;
|
||||
d->bitdepth_ = -1; //track->bitdepth;
|
||||
|
||||
d->source_ = Source_Device;
|
||||
QString filename = QString::fromLocal8Bit(track->ipod_path);
|
||||
filename.replace(':', '/');
|
||||
if (prefix.contains("://")) {
|
||||
@@ -780,8 +849,8 @@ void Song::InitFromItdb(const Itdb_Track *track, const QString &prefix) {
|
||||
set_url(QUrl::fromLocalFile(prefix + filename));
|
||||
}
|
||||
d->basefilename_ = QFileInfo(filename).fileName();
|
||||
|
||||
d->filetype_ = track->type2 ? Type_MPEG : Type_MP4;
|
||||
|
||||
d->filetype_ = track->type2 ? FileType_MPEG : FileType_MP4;
|
||||
d->filesize_ = track->size;
|
||||
d->mtime_ = track->time_modified;
|
||||
d->ctime_ = track->time_added;
|
||||
@@ -814,7 +883,7 @@ void Song::ToItdb(Itdb_Track *track) const {
|
||||
//track->bithdepth = d->bithdepth_;
|
||||
|
||||
track->type1 = 0;
|
||||
track->type2 = d->filetype_ == Type_MP4 ? 0 : 1;
|
||||
track->type2 = d->filetype_ == FileType_MP4 ? 0 : 1;
|
||||
track->mediatype = 1; // Audio
|
||||
track->size = d->filesize_;
|
||||
track->time_modified = d->mtime_;
|
||||
@@ -854,18 +923,20 @@ void Song::InitFromMTP(const LIBMTP_track_t *track, const QString &host) {
|
||||
d->playcount_ = track->usecount;
|
||||
|
||||
switch (track->filetype) {
|
||||
case LIBMTP_FILETYPE_WAV: d->filetype_ = Type_WAV; break;
|
||||
case LIBMTP_FILETYPE_MP3: d->filetype_ = Type_MPEG; break;
|
||||
case LIBMTP_FILETYPE_WMA: d->filetype_ = Type_ASF; break;
|
||||
case LIBMTP_FILETYPE_OGG: d->filetype_ = Type_OggVorbis; break;
|
||||
case LIBMTP_FILETYPE_MP4: d->filetype_ = Type_MP4; break;
|
||||
case LIBMTP_FILETYPE_AAC: d->filetype_ = Type_MP4; break;
|
||||
case LIBMTP_FILETYPE_FLAC: d->filetype_ = Type_OggFlac; break;
|
||||
case LIBMTP_FILETYPE_MP2: d->filetype_ = Type_MPEG; break;
|
||||
case LIBMTP_FILETYPE_M4A: d->filetype_ = Type_MP4; break;
|
||||
default: d->filetype_ = Type_Unknown; break;
|
||||
case LIBMTP_FILETYPE_WAV: d->filetype_ = FileType_WAV; break;
|
||||
case LIBMTP_FILETYPE_MP3: d->filetype_ = FileType_MPEG; break;
|
||||
case LIBMTP_FILETYPE_WMA: d->filetype_ = FileType_ASF; break;
|
||||
case LIBMTP_FILETYPE_OGG: d->filetype_ = FileType_OggVorbis; break;
|
||||
case LIBMTP_FILETYPE_MP4: d->filetype_ = FileType_MP4; break;
|
||||
case LIBMTP_FILETYPE_AAC: d->filetype_ = FileType_MP4; break;
|
||||
case LIBMTP_FILETYPE_FLAC: d->filetype_ = FileType_OggFlac; break;
|
||||
case LIBMTP_FILETYPE_MP2: d->filetype_ = FileType_MPEG; break;
|
||||
case LIBMTP_FILETYPE_M4A: d->filetype_ = FileType_MP4; break;
|
||||
default: d->filetype_ = FileType_Unknown; break;
|
||||
}
|
||||
|
||||
d->source_ = Source_Device;
|
||||
|
||||
}
|
||||
|
||||
void Song::ToMTP(LIBMTP_track_t *track) const {
|
||||
@@ -897,15 +968,15 @@ void Song::ToMTP(LIBMTP_track_t *track) const {
|
||||
track->usecount = d->playcount_;
|
||||
|
||||
switch (d->filetype_) {
|
||||
case Type_ASF: track->filetype = LIBMTP_FILETYPE_ASF; break;
|
||||
case Type_MP4: track->filetype = LIBMTP_FILETYPE_MP4; break;
|
||||
case Type_MPEG: track->filetype = LIBMTP_FILETYPE_MP3; break;
|
||||
case Type_FLAC:
|
||||
case Type_OggFlac: track->filetype = LIBMTP_FILETYPE_FLAC; break;
|
||||
case Type_OggSpeex:
|
||||
case Type_OggVorbis: track->filetype = LIBMTP_FILETYPE_OGG; break;
|
||||
case Type_WAV: track->filetype = LIBMTP_FILETYPE_WAV; break;
|
||||
default: track->filetype = LIBMTP_FILETYPE_UNDEF_AUDIO; break;
|
||||
case FileType_ASF: track->filetype = LIBMTP_FILETYPE_ASF; break;
|
||||
case FileType_MP4: track->filetype = LIBMTP_FILETYPE_MP4; break;
|
||||
case FileType_MPEG: track->filetype = LIBMTP_FILETYPE_MP3; break;
|
||||
case FileType_FLAC:
|
||||
case FileType_OggFlac: track->filetype = LIBMTP_FILETYPE_FLAC; break;
|
||||
case FileType_OggSpeex:
|
||||
case FileType_OggVorbis: track->filetype = LIBMTP_FILETYPE_OGG; break;
|
||||
case FileType_WAV: track->filetype = LIBMTP_FILETYPE_WAV; break;
|
||||
default: track->filetype = LIBMTP_FILETYPE_UNDEF_AUDIO; break;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -965,6 +1036,7 @@ void Song::BindToQuery(QSqlQuery *query) const {
|
||||
query->bindValue(":samplerate", intval(d->samplerate_));
|
||||
query->bindValue(":bitdepth", intval(d->bitdepth_));
|
||||
|
||||
query->bindValue(":source", notnullintval(d->source_));
|
||||
query->bindValue(":directory_id", notnullintval(d->directory_id_));
|
||||
|
||||
if (Application::kIsPortable && Utilities::UrlOnSameDriveAsStrawberry(d->url_)) {
|
||||
@@ -1103,7 +1175,7 @@ bool Song::IsMetadataEqual(const Song &other) const {
|
||||
}
|
||||
|
||||
bool Song::IsEditable() const {
|
||||
return d->valid_ && !d->url_.isEmpty() && !is_stream() && d->filetype_ != Type_Unknown && !has_cue();
|
||||
return d->valid_ && !d->url_.isEmpty() && !is_stream() && d->source_ != Source_Unknown && d->filetype_ != FileType_Unknown && !has_cue();
|
||||
}
|
||||
|
||||
bool Song::operator==(const Song &other) const {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -37,6 +38,7 @@
|
||||
#include <QRegExp>
|
||||
#include <QUrl>
|
||||
#include <QImage>
|
||||
#include <QIcon>
|
||||
#include <QTextCodec>
|
||||
#include <QSqlQuery>
|
||||
|
||||
@@ -87,29 +89,48 @@ class Song {
|
||||
|
||||
// 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().
|
||||
enum FileType {
|
||||
Type_Unknown = 0,
|
||||
Type_WAV = 1,
|
||||
Type_FLAC = 2,
|
||||
Type_WavPack = 3,
|
||||
Type_OggFlac = 4,
|
||||
Type_OggVorbis = 5,
|
||||
Type_OggOpus = 6,
|
||||
Type_OggSpeex = 7,
|
||||
Type_MPEG = 8,
|
||||
Type_MP4 = 9,
|
||||
Type_ASF = 10,
|
||||
Type_AIFF = 11,
|
||||
Type_MPC = 12,
|
||||
Type_TrueAudio = 13,
|
||||
Type_DSF = 14,
|
||||
Type_DSDIFF = 15,
|
||||
Type_CDDA = 90,
|
||||
Type_Stream = 91,
|
||||
|
||||
enum Source {
|
||||
Source_Unknown = 0,
|
||||
Source_LocalFile = 1,
|
||||
Source_Collection = 2,
|
||||
Source_CDDA = 3,
|
||||
Source_Device = 4,
|
||||
Source_Stream = 5,
|
||||
Source_Tidal = 6,
|
||||
};
|
||||
|
||||
static QString TextForFiletype(FileType type);
|
||||
enum FileType {
|
||||
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,
|
||||
FileType_CDDA = 90,
|
||||
FileType_Stream = 91,
|
||||
};
|
||||
|
||||
static QString TextForSource(Source source);
|
||||
static QIcon IconForSource(Source source);
|
||||
static QString TextForFiletype(FileType filetype);
|
||||
QIcon IconForFiletype(FileType filetype);
|
||||
|
||||
QString TextForSource() const { return TextForSource(source()); }
|
||||
QIcon IconForSource() const { return IconForSource(source()); }
|
||||
QString TextForFiletype() const { return TextForFiletype(filetype()); }
|
||||
QIcon IconForFiletype(FileType filetype) const { return IconForFiletype(filetype); }
|
||||
|
||||
bool IsFileLossless() const;
|
||||
static FileType FiletypeByExtension(QString ext);
|
||||
|
||||
@@ -182,6 +203,7 @@ class Song {
|
||||
int samplerate() const;
|
||||
int bitdepth() const;
|
||||
|
||||
Source source() const;
|
||||
int directory_id() const;
|
||||
const QUrl &url() const;
|
||||
const QString &basefilename() const;
|
||||
@@ -260,7 +282,8 @@ class Song {
|
||||
void set_bitrate(int v);
|
||||
void set_samplerate(int v);
|
||||
void set_bitdepth(int v);
|
||||
|
||||
|
||||
void set_source(Source v);
|
||||
void set_directory_id(int v);
|
||||
void set_url(const QUrl &v);
|
||||
void set_basefilename(const QString &v);
|
||||
|
||||
@@ -276,7 +276,7 @@ void SongLoader::EffectiveSongLoad(Song *song) {
|
||||
|
||||
if (!song) return;
|
||||
|
||||
if (song->filetype() != Song::Type_Unknown) {
|
||||
if (song->filetype() != Song::FileType_Unknown) {
|
||||
// Maybe we loaded the metadata already, for example from a cuesheet.
|
||||
return;
|
||||
}
|
||||
@@ -335,7 +335,7 @@ void SongLoader::LoadLocalDirectory(const QString &filename) {
|
||||
void SongLoader::AddAsRawStream() {
|
||||
Song song;
|
||||
song.set_valid(true);
|
||||
song.set_filetype(Song::Type_Stream);
|
||||
song.set_filetype(Song::FileType_Stream);
|
||||
song.set_url(url_);
|
||||
song.set_title(url_.toString());
|
||||
songs_ << song;
|
||||
@@ -481,7 +481,7 @@ GstPadProbeReturn SongLoader::DataReady(GstPad*, GstPadProbeInfo *info, gpointer
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
gboolean SongLoader::BusCallback(GstBus *, GstMessage *msg, gpointer self) {
|
||||
|
||||
|
||||
SongLoader *instance = reinterpret_cast<SongLoader*>(self);
|
||||
|
||||
switch (GST_MESSAGE_TYPE(msg)) {
|
||||
|
||||
Reference in New Issue
Block a user