diff --git a/data/data.qrc b/data/data.qrc
index a24df5e34..b8fd2e22b 100644
--- a/data/data.qrc
+++ b/data/data.qrc
@@ -3,6 +3,7 @@
schema/schema.sql
schema/schema-1.sql
schema/schema-2.sql
+ schema/schema-3.sql
schema/device-schema.sql
style/strawberry.css
misc/playing_tooltip.txt
diff --git a/data/schema/device-schema.sql b/data/schema/device-schema.sql
index 804faf5a4..b2c8b0590 100644
--- a/data/schema/device-schema.sql
+++ b/data/schema/device-schema.sql
@@ -11,8 +11,6 @@ CREATE TABLE device_%deviceid_subdirectories (
CREATE TABLE device_%deviceid_songs (
- /* Metadata from taglib */
-
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
@@ -27,6 +25,7 @@ CREATE TABLE device_%deviceid_songs (
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
+ lyrics TEXT NOT NULL,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@@ -35,8 +34,7 @@ CREATE TABLE device_%deviceid_songs (
samplerate INTEGER NOT NULL DEFAULT 0,
bitdepth INTEGER NOT NULL DEFAULT 0,
- /* Information about the file on disk */
-
+ source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL,
filename TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
@@ -45,8 +43,6 @@ CREATE TABLE device_%deviceid_songs (
ctime INTEGER NOT NULL,
unavailable INTEGER DEFAULT 0,
- /* Other */
-
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT 0,
diff --git a/data/schema/schema-3.sql b/data/schema/schema-3.sql
new file mode 100644
index 000000000..f37fe5f82
--- /dev/null
+++ b/data/schema/schema-3.sql
@@ -0,0 +1,65 @@
+ALTER TABLE songs ADD COLUMN source INTEGER NOT NULL DEFAULT 0;
+
+UPDATE songs SET source = 2 WHERE source = 0;
+
+DROP TABLE playlist_items;
+
+CREATE TABLE IF NOT EXISTS playlist_items (
+
+ playlist INTEGER NOT NULL,
+ type INTEGER NOT NULL DEFAULT 0,
+ collection_id INTEGER,
+ url TEXT,
+
+ title TEXT NOT NULL,
+ album TEXT NOT NULL,
+ artist TEXT NOT NULL,
+ albumartist TEXT NOT NULL,
+ track INTEGER NOT NULL DEFAULT -1,
+ disc INTEGER NOT NULL DEFAULT -1,
+ year INTEGER NOT NULL DEFAULT -1,
+ originalyear INTEGER NOT NULL DEFAULT 0,
+ genre TEXT NOT NULL,
+ compilation INTEGER NOT NULL DEFAULT -1,
+ composer TEXT NOT NULL,
+ performer TEXT NOT NULL,
+ grouping TEXT NOT NULL,
+ comment TEXT NOT NULL,
+ lyrics TEXT NOT NULL,
+
+ beginning INTEGER NOT NULL DEFAULT 0,
+ length INTEGER NOT NULL DEFAULT 0,
+
+ bitrate INTEGER NOT NULL DEFAULT 0,
+ samplerate INTEGER NOT NULL DEFAULT 0,
+ bitdepth INTEGER NOT NULL DEFAULT 0,
+
+ source INTEGER NOT NULL DEFAULT 0,
+ directory_id INTEGER,
+ filename TEXT,
+ filetype INTEGER NOT NULL DEFAULT 0,
+ filesize INTEGER,
+ mtime INTEGER,
+ ctime INTEGER,
+ unavailable INTEGER DEFAULT 0,
+
+ playcount INTEGER NOT NULL DEFAULT 0,
+ skipcount INTEGER NOT NULL DEFAULT 0,
+ lastplayed INTEGER NOT NULL DEFAULT 0,
+
+ compilation_detected INTEGER DEFAULT 0,
+ compilation_on INTEGER NOT NULL DEFAULT 0,
+ compilation_off INTEGER NOT NULL DEFAULT 0,
+ compilation_effective INTEGER NOT NULL DEFAULT 0,
+
+ art_automatic TEXT,
+ art_manual TEXT,
+
+ effective_albumartist TEXT,
+ effective_originalyear INTEGER NOT NULL DEFAULT 0,
+
+ cue_path TEXT
+
+);
+
+UPDATE schema_version SET version=3;
diff --git a/data/schema/schema.sql b/data/schema/schema.sql
index 26e815cf2..942e7cff6 100644
--- a/data/schema/schema.sql
+++ b/data/schema/schema.sql
@@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS schema_version (
DELETE FROM schema_version;
-INSERT INTO schema_version (version) VALUES (2);
+INSERT INTO schema_version (version) VALUES (3);
CREATE TABLE IF NOT EXISTS directories (
path TEXT NOT NULL,
@@ -19,8 +19,6 @@ CREATE TABLE IF NOT EXISTS subdirectories (
CREATE TABLE IF NOT EXISTS songs (
- /* Metadata from taglib */
-
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
@@ -44,8 +42,7 @@ CREATE TABLE IF NOT EXISTS songs (
samplerate INTEGER NOT NULL DEFAULT 0,
bitdepth INTEGER NOT NULL DEFAULT 0,
- /* Information about the file on disk */
-
+ source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL,
filename TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
@@ -54,8 +51,6 @@ CREATE TABLE IF NOT EXISTS songs (
ctime INTEGER NOT NULL,
unavailable INTEGER DEFAULT 0,
- /* Other */
-
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT 0,
@@ -89,13 +84,10 @@ CREATE TABLE IF NOT EXISTS playlists (
CREATE TABLE IF NOT EXISTS playlist_items (
playlist INTEGER NOT NULL,
- type TEXT NOT NULL,
+ type INTEGER NOT NULL DEFAULT 0,
collection_id INTEGER,
- internet_service TEXT,
url TEXT,
- /* Metadata from taglib */
-
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
@@ -119,8 +111,7 @@ CREATE TABLE IF NOT EXISTS playlist_items (
samplerate INTEGER NOT NULL DEFAULT 0,
bitdepth INTEGER NOT NULL DEFAULT 0,
- /* Information about the file on disk */
-
+ source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER,
filename TEXT,
filetype INTEGER NOT NULL DEFAULT 0,
@@ -129,8 +120,6 @@ CREATE TABLE IF NOT EXISTS playlist_items (
ctime INTEGER,
unavailable INTEGER DEFAULT 0,
- /* Other */
-
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT 0,
diff --git a/ext/libstrawberry-tagreader/tagreader.cpp b/ext/libstrawberry-tagreader/tagreader.cpp
index e0e1e2ef9..ee904c110 100644
--- a/ext/libstrawberry-tagreader/tagreader.cpp
+++ b/ext/libstrawberry-tagreader/tagreader.cpp
@@ -1,5 +1,6 @@
/* This file is part of Strawberry.
Copyright 2013, David Sansome
+ Copyright 2018, Jonas Kvinge
Strawberry is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -474,27 +475,27 @@ void TagReader::SetVorbisComments(TagLib::Ogg::XiphComment *vorbis_comments, con
}
-pb::tagreader::SongMetadata_Type TagReader::GuessFileType(TagLib::FileRef *fileref) const {
+pb::tagreader::SongMetadata_FileType TagReader::GuessFileType(TagLib::FileRef *fileref) const {
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_WAV;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_FLAC;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_WAVPACK;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_OGGFLAC;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_OGGVORBIS;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_OGGOPUS;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_OGGSPEEX;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_MPEG;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_MP4;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_ASF;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_AIFF;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_MPC;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_TRUEAUDIO;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_WAV;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_FLAC;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_WAVPACK;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_OGGFLAC;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_OGGVORBIS;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_OGGOPUS;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_OGGSPEEX;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_MPEG;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_MP4;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_ASF;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_AIFF;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_MPC;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_TRUEAUDIO;
#ifdef HAVE_TAGLIB_DSFFILE
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_DSF;
- if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_Type_DSDIFF;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_DSF;
+ if (dynamic_cast(fileref->file())) return pb::tagreader::SongMetadata_FileType_DSDIFF;
#endif
- return pb::tagreader::SongMetadata_Type_UNKNOWN;
+ return pb::tagreader::SongMetadata_FileType_UNKNOWN;
}
diff --git a/ext/libstrawberry-tagreader/tagreader.h b/ext/libstrawberry-tagreader/tagreader.h
index 3cd94d688..354a0f0e3 100644
--- a/ext/libstrawberry-tagreader/tagreader.h
+++ b/ext/libstrawberry-tagreader/tagreader.h
@@ -1,5 +1,6 @@
/* This file is part of Strawberry.
Copyright 2013, David Sansome
+ Copyright 2018, Jonas Kvinge
Strawberry is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -64,7 +65,7 @@ class TagReader {
void ParseOggTag(const TagLib::Ogg::FieldListMap &map, const QTextCodec *codec, QString *disc, QString *compilation, pb::tagreader::SongMetadata *song) const;
void SetVorbisComments(TagLib::Ogg::XiphComment *vorbis_comments, const pb::tagreader::SongMetadata &song) const;
- pb::tagreader::SongMetadata_Type GuessFileType(TagLib::FileRef *fileref) const;
+ pb::tagreader::SongMetadata_FileType GuessFileType(TagLib::FileRef *fileref) const;
void SetUserTextFrame(const QString &description, const QString &value, TagLib::ID3v2::Tag *tag) const;
void SetUserTextFrame(const std::string &description, const std::string& value, TagLib::ID3v2::Tag *tag) const;
diff --git a/ext/libstrawberry-tagreader/tagreadermessages.proto b/ext/libstrawberry-tagreader/tagreadermessages.proto
index c54206c15..3802110e3 100644
--- a/ext/libstrawberry-tagreader/tagreadermessages.proto
+++ b/ext/libstrawberry-tagreader/tagreadermessages.proto
@@ -4,7 +4,7 @@ package pb.tagreader;
message SongMetadata {
- enum Type {
+ enum FileType {
UNKNOWN = 0;
WAV = 1;
FLAC = 2;
@@ -51,7 +51,7 @@ message SongMetadata {
optional string url = 21;
optional string basefilename = 22;
- optional Type filetype = 23;
+ optional FileType filetype = 23;
optional int32 filesize = 24;
optional int32 mtime = 25;
optional int32 ctime = 26;
diff --git a/src/collection/collection.cpp b/src/collection/collection.cpp
index 94eba5889..0e48366b4 100644
--- a/src/collection/collection.cpp
+++ b/src/collection/collection.cpp
@@ -63,7 +63,6 @@ SCollection::SCollection(Application *app, QObject *parent)
}
SCollection::~SCollection() {
-
watcher_->deleteLater();
watcher_thread_->exit();
watcher_thread_->wait(5000 /* five seconds */);
diff --git a/src/collection/collectionbackend.cpp b/src/collection/collectionbackend.cpp
index 19ebbcad1..7c11d2d4d 100644
--- a/src/collection/collectionbackend.cpp
+++ b/src/collection/collectionbackend.cpp
@@ -720,7 +720,6 @@ SongList CollectionBackend::GetSongsByUrl(const QUrl &url) {
while (query.Next()) {
Song song;
song.InitFromQuery(query, true);
-
songlist << song;
}
}
diff --git a/src/collection/collectionplaylistitem.cpp b/src/collection/collectionplaylistitem.cpp
index bf380c502..74d2ef24a 100644
--- a/src/collection/collectionplaylistitem.cpp
+++ b/src/collection/collectionplaylistitem.cpp
@@ -29,11 +29,13 @@
class SqlRow;
-CollectionPlaylistItem::CollectionPlaylistItem(const QString &type)
- : PlaylistItem(type) {}
+CollectionPlaylistItem::CollectionPlaylistItem(const Song::Source &source)
+ : PlaylistItem(source) {}
CollectionPlaylistItem::CollectionPlaylistItem(const Song &song)
- : PlaylistItem("Collection"), song_(song) {}
+ : PlaylistItem(Song::Source_Collection), song_(song) {
+ song_.set_source(Song::Source_Collection);
+}
QUrl CollectionPlaylistItem::Url() const { return song_.url(); }
@@ -44,7 +46,6 @@ void CollectionPlaylistItem::Reload() {
bool CollectionPlaylistItem::InitFromQuery(const SqlRow &query) {
// Rows from the songs tables come first
song_.InitFromQuery(query, true);
-
return song_.is_valid();
}
@@ -59,4 +60,3 @@ Song CollectionPlaylistItem::Metadata() const {
if (HasTemporaryMetadata()) return temp_metadata_;
return song_;
}
-
diff --git a/src/collection/collectionplaylistitem.h b/src/collection/collectionplaylistitem.h
index c17419d5e..0af69afec 100644
--- a/src/collection/collectionplaylistitem.h
+++ b/src/collection/collectionplaylistitem.h
@@ -36,7 +36,7 @@ class SqlRow;
class CollectionPlaylistItem : public PlaylistItem {
public:
- CollectionPlaylistItem(const QString &type);
+ CollectionPlaylistItem(const Song::Source &source);
CollectionPlaylistItem(const Song &song);
bool InitFromQuery(const SqlRow &query);
diff --git a/src/collection/collectionwatcher.cpp b/src/collection/collectionwatcher.cpp
index 4a5832307..c86ddacbc 100644
--- a/src/collection/collectionwatcher.cpp
+++ b/src/collection/collectionwatcher.cpp
@@ -134,7 +134,7 @@ CollectionWatcher::ScanTransaction::~ScanTransaction() {
if (watcher_->monitor_) {
// Watch the new subdirectories
- for (const Subdirectory& subdir : new_subdirs) {
+ for (const Subdirectory &subdir : new_subdirs) {
watcher_->AddWatch(watcher_->watched_dirs_[dir_], subdir.path);
}
}
@@ -197,8 +197,7 @@ SubdirectoryList CollectionWatcher::ScanTransaction::GetImmediateSubdirs(const Q
SubdirectoryList ret;
for (const Subdirectory &subdir : known_subdirs_) {
- if (subdir.path.left(subdir.path.lastIndexOf(QDir::separator())) == path &&
- subdir.mtime != 0) {
+ if (subdir.path.left(subdir.path.lastIndexOf(QDir::separator())) == path && subdir.mtime != 0) {
ret << subdir;
}
}
@@ -251,7 +250,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const Subdirectory
// Do not scan symlinked dirs that are already in collection
if (path_info.isSymLink()) {
QString real_path = path_info.symLinkTarget();
- for (const Directory& dir : watched_dirs_) {
+ for (const Directory &dir : watched_dirs_) {
if (real_path.startsWith(dir.path)) {
t->AddToProgress(1);
return;
@@ -278,7 +277,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const Subdirectory
// If a directory is moved then only its parent gets a changed notification, so we need to look and see if any of our children don't exist any more.
// If one has been removed, "rescan" it to get the deleted songs
SubdirectoryList previous_subdirs = t->GetImmediateSubdirs(path);
- for (const Subdirectory& subdir : previous_subdirs) {
+ for (const Subdirectory &subdir : previous_subdirs) {
if (!QFile::exists(subdir.path) && subdir.path != path) {
t->AddToProgressMax(1);
ScanSubdirectory(subdir.path, subdir, t, true);
@@ -322,7 +321,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const Subdirectory
QSet cues_processed;
// Now compare the list from the database with the list of files on disk
- for (const QString& file : files_on_disk) {
+ for (const QString &file : files_on_disk) {
if (stop_requested_) return;
// associated cue
@@ -389,16 +388,16 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const Subdirectory
QString image = ImageForSong(file, album_art);
for (Song song : song_list) {
+ song.set_source(Song::Source_Collection);
song.set_directory_id(t->dir());
if (song.art_automatic().isEmpty()) song.set_art_automatic(image);
-
t->new_songs << song;
}
}
}
// Look for deleted songs
- for (const Song& song : songs_in_db) {
+ for (const Song &song : songs_in_db) {
if (!song.is_unavailable() && !files_on_disk.contains(song.url().toLocalFile())) {
qLog(Debug) << "Song deleted from disk:" << song.url().toLocalFile();
t->deleted_songs << song;
@@ -420,7 +419,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const Subdirectory
// Recurse into the new subdirs that we found
t->AddToProgressMax(my_new_subdirs.count());
- for (const Subdirectory& my_new_subdir : my_new_subdirs) {
+ for (const Subdirectory &my_new_subdir : my_new_subdirs) {
if (stop_requested_) return;
ScanSubdirectory(my_new_subdir.path, my_new_subdir, t, true);
}
@@ -435,7 +434,7 @@ void CollectionWatcher::UpdateCueAssociatedSongs(const QString &file, const QStr
SongList old_sections = backend_->GetSongsByUrl(QUrl::fromLocalFile(file));
QHash sections_map;
- for (const Song& song : old_sections) {
+ for (const Song &song : old_sections) {
sections_map[song.beginning_nanosec()] = song;
}
@@ -443,6 +442,7 @@ void CollectionWatcher::UpdateCueAssociatedSongs(const QString &file, const QStr
// Update every song that's in the cue and collection
for (Song cue_song : cue_parser_->Load(&cue, matching_cue, path)) {
+ cue_song.set_source(Song::Source_Collection);
cue_song.set_directory_id(t->dir());
Song matching = sections_map[cue_song.beginning_nanosec()];
@@ -450,7 +450,8 @@ void CollectionWatcher::UpdateCueAssociatedSongs(const QString &file, const QStr
if (!matching.is_valid()) {
t->new_songs << cue_song;
// changed section
- } else {
+ }
+ else {
PreserveUserSetData(file, image, matching, &cue_song, t);
used_ids.insert(matching.id());
}
@@ -469,8 +470,7 @@ void CollectionWatcher::UpdateNonCueAssociatedSong(const QString &file, const So
// If a cue got deleted, we turn it's first section into the new 'raw' (cueless) song and we just remove the rest of the sections from the collection
if (cue_deleted) {
- for (const Song &song :
- backend_->GetSongsByUrl(QUrl::fromLocalFile(file))) {
+ for (const Song &song : backend_->GetSongsByUrl(QUrl::fromLocalFile(file))) {
if (!song.IsMetadataEqual(matching_song)) {
t->deleted_songs << song;
}
@@ -478,6 +478,7 @@ void CollectionWatcher::UpdateNonCueAssociatedSong(const QString &file, const So
}
Song song_on_disk;
+ song_on_disk.set_source(Song::Source_Collection);
song_on_disk.set_directory_id(t->dir());
TagReaderClient::Instance()->ReadFileBlocking(file, &song_on_disk);
@@ -504,7 +505,7 @@ SongList CollectionWatcher::ScanNewFile(const QString &file, const QString &path
// Also, watch out for incorrect media files.
// Playlist parser for CUEs considers every entry in sheet valid and we don't want invalid media getting into collection!
QString file_nfd = file.normalized(QString::NormalizationForm_D);
- for (const Song& cue_song : cue_parser_->Load(&cue, matching_cue, path)) {
+ for (const Song &cue_song : cue_parser_->Load(&cue, matching_cue, path)) {
if (cue_song.url().toLocalFile().normalized(QString::NormalizationForm_D) == file_nfd) {
if (TagReaderClient::Instance()->IsMediaFileBlocking(file)) {
song_list << cue_song;
@@ -663,7 +664,7 @@ QString CollectionWatcher::PickBestImage(const QStringList &images) {
for (const QString &filter_text : best_image_filters_) {
// The images in the images list are represented by a full path, so we need to isolate just the filename
- for (const QString& image : images) {
+ for (const QString &image : images) {
QFileInfo file_info(image);
QString filename(file_info.fileName());
if (filename.contains(filter_text, Qt::CaseInsensitive))
@@ -683,7 +684,7 @@ QString CollectionWatcher::PickBestImage(const QStringList &images) {
int biggest_size = 0;
QString biggest_path;
- for (const QString& path : filtered) {
+ for (const QString &path : filtered) {
QImage image(path);
if (image.isNull()) continue;
diff --git a/src/core/database.cpp b/src/core/database.cpp
index 99b13fb35..5847933a1 100644
--- a/src/core/database.cpp
+++ b/src/core/database.cpp
@@ -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;
diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp
index 3d37cf5ba..f2a072722 100644
--- a/src/core/mainwindow.cpp
+++ b/src/core/mainwindow.cpp
@@ -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 &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;
}
diff --git a/src/core/musicstorage.h b/src/core/musicstorage.h
index ea75953fe..05b2dbd02 100644
--- a/src/core/musicstorage.h
+++ b/src/core/musicstorage.h
@@ -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* ret) { return true; }
virtual bool StartCopy(QList* supported_types) { return true;}
diff --git a/src/core/organise.cpp b/src/core/organise.cpp
index 10d9a7b9b..f271e1952 100644
--- a/src/core/organise.cpp
+++ b/src/core/organise.cpp
@@ -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;
}
diff --git a/src/core/player.cpp b/src/core/player.cpp
index 7169fc1e9..e092e4ea2 100644
--- a/src/core/player.cpp
+++ b/src/core/player.cpp
@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome
+ * Copyright 2018, Jonas Kvinge
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/core/player.h b/src/core/player.h
index f38bc656b..4bce66a7a 100644
--- a/src/core/player.h
+++ b/src/core/player.h
@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome
+ * Copyright 2018, Jonas Kvinge
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/core/song.cpp b/src/core/song.cpp
index 66581443d..ca3e89b19 100644
--- a/src/core/song.cpp
+++ b/src/core/song.cpp
@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome
+ * Copyright 2018, Jonas Kvinge
*
* 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
#include
#include
+#include
#include
#include
#include
@@ -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(d->filetype_));
+ pb->set_filetype(static_cast(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 {
diff --git a/src/core/song.h b/src/core/song.h
index e8b775af0..93feb1e33 100644
--- a/src/core/song.h
+++ b/src/core/song.h
@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome
+ * Copyright 2018, Jonas Kvinge
*
* 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
#include
#include
+#include
#include
#include
@@ -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);
diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp
index 6f9633765..4cf15da4e 100644
--- a/src/core/songloader.cpp
+++ b/src/core/songloader.cpp
@@ -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(self);
switch (GST_MESSAGE_TYPE(msg)) {
diff --git a/src/device/cddasongloader.cpp b/src/device/cddasongloader.cpp
index 8bcbf3fab..e2ef24298 100644
--- a/src/device/cddasongloader.cpp
+++ b/src/device/cddasongloader.cpp
@@ -110,7 +110,8 @@ void CddaSongLoader::LoadSongs() {
Song song;
song.set_id(track_number);
song.set_valid(true);
- song.set_filetype(Song::Type_CDDA);
+ song.set_source(Song::Source_CDDA);
+ song.set_filetype(Song::FileType_CDDA);
song.set_url(GetUrlFromTrack(track_number));
song.set_title(QString("Track %1").arg(track_number));
song.set_track(track_number);
@@ -207,7 +208,8 @@ void CddaSongLoader::AudioCDTagsLoaded(const QString &artist, const QString &alb
song.set_track(track_number);
song.set_year(ret.year_);
song.set_id(track_number);
- song.set_filetype(Song::Type_CDDA);
+ song.set_source(Song::Source_CDDA);
+ song.set_filetype(Song::FileType_CDDA);
song.set_valid(true);
// We need to set url: that's how playlist will find the correct item to update
song.set_url(GetUrlFromTrack(track_number++));
diff --git a/src/device/devicemanager.cpp b/src/device/devicemanager.cpp
index 740b67c5a..04a559abf 100644
--- a/src/device/devicemanager.cpp
+++ b/src/device/devicemanager.cpp
@@ -100,7 +100,7 @@ const int DeviceManager::kDeviceIconOverlaySize = 16;
DeviceManager::DeviceInfo::DeviceInfo()
: database_id_(-1),
transcode_mode_(MusicStorage::Transcode_Unsupported),
- transcode_format_(Song::Type_Unknown),
+ transcode_format_(Song::FileType_Unknown),
task_percentage_(-1) {}
DeviceDatabaseBackend::Device DeviceManager::DeviceInfo::SaveToDb() const {
diff --git a/src/device/deviceproperties.cpp b/src/device/deviceproperties.cpp
index 0b55647cd..9d600877b 100644
--- a/src/device/deviceproperties.cpp
+++ b/src/device/deviceproperties.cpp
@@ -308,7 +308,7 @@ void DeviceProperties::UpdateFormatsFinished(QFuture future) {
#ifdef HAVE_GSTREAMER
// Set the format combobox item
TranscoderPreset preset = Transcoder::PresetForFileType(Song::FileType(index_.data(DeviceManager::Role_TranscodeFormat).toInt()));
- if (preset.type_ == Song::Type_Unknown) {
+ if (preset.type_ == Song::FileType_Unknown) {
// The user hasn't chosen a format for this device yet,
// so work our way down a list of some preferred formats, picking the first one that is supported
preset = Transcoder::PresetForFileType(Transcoder::PickBestFormat(supported_formats_));
diff --git a/src/device/gpoddevice.cpp b/src/device/gpoddevice.cpp
index efb6bd039..487a1e353 100644
--- a/src/device/gpoddevice.cpp
+++ b/src/device/gpoddevice.cpp
@@ -248,8 +248,8 @@ void GPodDevice::FinishDelete(bool success) {
}
bool GPodDevice::GetSupportedFiletypes(QList *ret) {
- *ret << Song::Type_MP4;
- *ret << Song::Type_MPEG;
+ *ret << Song::FileType_MP4;
+ *ret << Song::FileType_MPEG;
return true;
}
diff --git a/src/device/gpodloader.cpp b/src/device/gpodloader.cpp
index 73ec6aa00..7a954e525 100644
--- a/src/device/gpodloader.cpp
+++ b/src/device/gpodloader.cpp
@@ -39,7 +39,7 @@ GPodLoader::GPodLoader(const QString &mount_point, TaskManager *task_manager, Co
: QObject(nullptr),
device_(device),
mount_point_(mount_point),
- type_(Song::Type_Unknown),
+ type_(Song::FileType_Unknown),
task_manager_(task_manager),
backend_(backend) {
original_thread_ = thread();
@@ -81,7 +81,7 @@ void GPodLoader::LoadDatabase() {
song.InitFromItdb(track, prefix);
song.set_directory_id(1);
- if (type_ != Song::Type_Unknown) song.set_filetype(type_);
+ if (type_ != Song::FileType_Unknown) song.set_filetype(type_);
songs << song;
}
diff --git a/src/device/mtpdevice.cpp b/src/device/mtpdevice.cpp
index 74db3d8bf..9597657c5 100644
--- a/src/device/mtpdevice.cpp
+++ b/src/device/mtpdevice.cpp
@@ -209,21 +209,21 @@ bool MtpDevice::GetSupportedFiletypes(QList *ret, LIBMTP_mtpdevi
for (int i = 0; i < length; ++i) {
switch (LIBMTP_filetype_t(list[i])) {
- case LIBMTP_FILETYPE_WAV: *ret << Song::Type_WAV; break;
+ case LIBMTP_FILETYPE_WAV: *ret << Song::FileType_WAV; break;
case LIBMTP_FILETYPE_MP2:
- case LIBMTP_FILETYPE_MP3: *ret << Song::Type_MPEG; break;
- case LIBMTP_FILETYPE_WMA: *ret << Song::Type_ASF; break;
+ case LIBMTP_FILETYPE_MP3: *ret << Song::FileType_MPEG; break;
+ case LIBMTP_FILETYPE_WMA: *ret << Song::FileType_ASF; break;
case LIBMTP_FILETYPE_MP4:
case LIBMTP_FILETYPE_M4A:
- case LIBMTP_FILETYPE_AAC: *ret << Song::Type_MP4; break;
+ case LIBMTP_FILETYPE_AAC: *ret << Song::FileType_MP4; break;
case LIBMTP_FILETYPE_FLAC:
- *ret << Song::Type_FLAC;
- *ret << Song::Type_OggFlac;
+ *ret << Song::FileType_FLAC;
+ *ret << Song::FileType_OggFlac;
break;
case LIBMTP_FILETYPE_OGG:
- *ret << Song::Type_OggVorbis;
- *ret << Song::Type_OggSpeex;
- *ret << Song::Type_OggFlac;
+ *ret << Song::FileType_OggVorbis;
+ *ret << Song::FileType_OggSpeex;
+ *ret << Song::FileType_OggFlac;
break;
default:
qLog(Error) << "Unknown MTP file format" << LIBMTP_Get_Filetype_Description(LIBMTP_filetype_t(list[i]));
diff --git a/src/internet/internetmodel.cpp b/src/internet/internetmodel.cpp
index 81d8433a0..7891f4bc1 100644
--- a/src/internet/internetmodel.cpp
+++ b/src/internet/internetmodel.cpp
@@ -32,13 +32,13 @@
#include "internetservice.h"
#include "tidal/tidalservice.h"
-QMap* InternetModel::sServices = nullptr;
+QMap* InternetModel::sServices = nullptr;
InternetModel::InternetModel(Application *app, QObject *parent)
: QStandardItemModel(parent),
app_(app) {
- if (!sServices) sServices = new QMap;
+ if (!sServices) sServices = new QMap;
Q_ASSERT(sServices->isEmpty());
AddService(new TidalService(app, this));
@@ -47,7 +47,7 @@ InternetModel::InternetModel(Application *app, QObject *parent)
void InternetModel::AddService(InternetService *service) {
qLog(Debug) << "Adding internet service:" << service->name();
- sServices->insert(service->name(), service);
+ sServices->insert(service->source(), service);
connect(service, SIGNAL(destroyed()), SLOT(ServiceDeleted()));
if (service->has_initial_load_settings()) service->InitialLoadSettings();
else service->ReloadSettings();
@@ -56,8 +56,8 @@ void InternetModel::AddService(InternetService *service) {
void InternetModel::RemoveService(InternetService *service) {
- if (!sServices->contains(service->name())) return;
- sServices->remove(service->name());
+ if (!sServices->contains(service->source())) return;
+ sServices->remove(service->source());
disconnect(service, 0, this, 0);
}
@@ -69,9 +69,9 @@ void InternetModel::ServiceDeleted() {
}
-InternetService *InternetModel::ServiceByName(const QString &name) {
+InternetService *InternetModel::ServiceBySource(const Song::Source &source) {
- if (sServices->contains(name)) return sServices->value(name);
+ if (sServices->contains(source)) return sServices->value(source);
return nullptr;
}
diff --git a/src/internet/internetmodel.h b/src/internet/internetmodel.h
index af3cf83da..9e6500615 100644
--- a/src/internet/internetmodel.h
+++ b/src/internet/internetmodel.h
@@ -105,11 +105,13 @@ class InternetModel : public QStandardItemModel {
};
// Needs to be static for InternetPlaylistItem::restore
- static InternetService *ServiceByName(const QString &name);
+ static InternetService *ServiceBySource(const Song::Source &source);
+ //static InternetService *ServiceByName(const QString &name);
template
static T *Service() {
- return static_cast(ServiceByName(T::kServiceName));
+ //return static_cast(ServiceByName(T::kServiceName));
+ return static_cast(ServiceBySource(T::kSource));
}
// Add and remove services. Ownership is not transferred and the service is not reparented.
@@ -124,7 +126,8 @@ class InternetModel : public QStandardItemModel {
void ServiceDeleted();
private:
- static QMap *sServices;
+ //static QMap *sServices;
+ static QMap *sServices;
Application *app_;
};
diff --git a/src/internet/internetplaylistitem.cpp b/src/internet/internetplaylistitem.cpp
index 51e955ad5..612923d15 100644
--- a/src/internet/internetplaylistitem.cpp
+++ b/src/internet/internetplaylistitem.cpp
@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome
+ * Copyright 2018, Jonas Kvinge
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,72 +34,39 @@
#include "collection/sqlrow.h"
#include "playlist/playlistbackend.h"
-InternetPlaylistItem::InternetPlaylistItem(const QString &type)
- : PlaylistItem(type), set_service_icon_(false) {}
+InternetPlaylistItem::InternetPlaylistItem(const Song::Source &source)
+ : PlaylistItem(source) {}
InternetPlaylistItem::InternetPlaylistItem(InternetService *service, const Song &metadata)
- : PlaylistItem("Internet"),
- service_name_(service->name()),
- set_service_icon_(false),
+ : PlaylistItem(Song::Source_Stream),
+ source_(service->source()),
metadata_(metadata) {
InitMetadata();
}
bool InternetPlaylistItem::InitFromQuery(const SqlRow &query) {
-
- // The song tables gets joined first, plus one each for the song ROWIDs
- const int row = (Song::kColumns.count() + 1) * PlaylistBackend::kSongTableJoins;
-
- service_name_ = query.value(row + 1).toString();
-
metadata_.InitFromQuery(query, false, (Song::kColumns.count() + 1) * 1);
InitMetadata();
-
return true;
-
}
InternetService *InternetPlaylistItem::service() const {
-
- InternetService *ret = InternetModel::ServiceByName(service_name_);
-
- if (ret && !set_service_icon_) {
- const_cast(this)->set_service_icon_ = true;
-
- QString icon = ret->Icon();
- if (!icon.isEmpty()) {
- const_cast(this)->metadata_.set_art_manual(icon);
- }
- }
-
+ InternetService *ret = InternetModel::ServiceBySource(source_);
return ret;
-
}
QVariant InternetPlaylistItem::DatabaseValue(DatabaseColumn column) const {
- switch (column) {
- case Column_InternetService:
- return service_name_;
- default:
- return PlaylistItem::DatabaseValue(column);
- }
+ return PlaylistItem::DatabaseValue(column);
}
void InternetPlaylistItem::InitMetadata() {
-
- if (metadata_.title().isEmpty())
- metadata_.set_title(metadata_.url().toString());
- if (metadata_.filetype() == Song::Type_Unknown) metadata_.set_filetype(Song::Type_Stream);
+ if (metadata_.title().isEmpty()) metadata_.set_title(metadata_.url().toString());
+ if (metadata_.source() == Song::Source_Unknown) metadata_.set_source(Song::Source_Stream);
+ if (metadata_.filetype() == Song::FileType_Unknown) metadata_.set_filetype(Song::FileType_Stream);
metadata_.set_valid(true);
-
}
Song InternetPlaylistItem::Metadata() const {
- if (!set_service_icon_) {
- // Get the icon if we don't have it already
- service();
- }
-
if (HasTemporaryMetadata()) return temp_metadata_;
return metadata_;
}
diff --git a/src/internet/internetplaylistitem.h b/src/internet/internetplaylistitem.h
index 2a6d8f98f..b83d2c556 100644
--- a/src/internet/internetplaylistitem.h
+++ b/src/internet/internetplaylistitem.h
@@ -35,7 +35,7 @@ class InternetService;
class InternetPlaylistItem : public PlaylistItem {
public:
- explicit InternetPlaylistItem(const QString &type);
+ explicit InternetPlaylistItem(const Song::Source &type);
InternetPlaylistItem(InternetService *service, const Song &metadata);
bool InitFromQuery(const SqlRow &query);
Song Metadata() const;
@@ -50,8 +50,7 @@ class InternetPlaylistItem : public PlaylistItem {
InternetService *service() const;
private:
- QString service_name_;
- bool set_service_icon_;
+ Song::Source source_;
Song metadata_;
};
diff --git a/src/internet/internetservice.cpp b/src/internet/internetservice.cpp
index 25139ba6f..c0a6572ca 100644
--- a/src/internet/internetservice.cpp
+++ b/src/internet/internetservice.cpp
@@ -27,6 +27,6 @@
#include "internetmodel.h"
#include "internetservice.h"
-InternetService::InternetService(const QString &name, Application *app, InternetModel *model, QObject *parent)
- : QObject(parent), app_(app), model_(model), name_(name) {
+InternetService::InternetService(Song::Source source, const QString &name, Application *app, InternetModel *model, QObject *parent)
+ : QObject(parent), app_(app), model_(model), source_(source), name_(name) {
}
diff --git a/src/internet/internetservice.h b/src/internet/internetservice.h
index 808648f49..6ac95d01f 100644
--- a/src/internet/internetservice.h
+++ b/src/internet/internetservice.h
@@ -27,8 +27,10 @@
#include
#include
#include
+#include
#include "core/song.h"
+#include "core/iconloader.h"
#include "playlist/playlistitem.h"
#include "settings/settingsdialog.h"
@@ -40,14 +42,15 @@ class InternetService : public QObject {
Q_OBJECT
public:
- InternetService(const QString &name, Application *app, InternetModel *model, QObject *parent = nullptr);
+ InternetService(Song::Source source, const QString &name, Application *app, InternetModel *model, QObject *parent = nullptr);
virtual ~InternetService() {}
+ Song::Source source() const { return source_; }
QString name() const { return name_; }
InternetModel *model() const { return model_; }
virtual bool has_initial_load_settings() const { return false; }
virtual void InitialLoadSettings() {}
virtual void ReloadSettings() {}
- virtual QString Icon() { return QString(); }
+ virtual QIcon Icon() { return Song::IconForSource(source_); }
public slots:
virtual void ShowConfig() {}
@@ -56,6 +59,7 @@ class InternetService : public QObject {
Application *app_;
private:
InternetModel *model_;
+ Song::Source source_;
QString name_;
};
diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp
index 324f280ee..339694a41 100644
--- a/src/playlist/playlist.cpp
+++ b/src/playlist/playlist.cpp
@@ -67,6 +67,7 @@
#include "core/logging.h"
#include "core/mimedata.h"
#include "core/tagreaderclient.h"
+#include "core/song.h"
#include "collection/collection.h"
#include "collection/collectionbackend.h"
#include "collection/collectionplaylistitem.h"
@@ -249,11 +250,11 @@ bool Playlist::set_column_value(Song &song, Playlist::Column column, const QVari
break;
}
return true;
-
+
}
QVariant Playlist::data(const QModelIndex &index, int role) const {
-
+
switch (role) {
case Role_IsCurrent:
return current_item_index_.isValid() && index.row() == current_item_index_.row();
@@ -275,40 +276,40 @@ QVariant Playlist::data(const QModelIndex &index, int role) const {
// Don't forget to change Playlist::CompareItems when adding new columns
switch (index.column()) {
- case Column_Title: return song.PrettyTitle();
- case Column_Artist: return song.artist();
- case Column_Album: return song.album();
- case Column_Length: return song.length_nanosec();
- case Column_Track: return song.track();
- case Column_Disc: return song.disc();
- case Column_Year: return song.year();
- case Column_OriginalYear: return song.effective_originalyear();
- case Column_Genre: return song.genre();
- case Column_AlbumArtist: return song.playlist_albumartist();
- case Column_Composer: return song.composer();
- case Column_Performer: return song.performer();
- case Column_Grouping: return song.grouping();
+ case Column_Title: return song.PrettyTitle();
+ case Column_Artist: return song.artist();
+ case Column_Album: return song.album();
+ case Column_Length: return song.length_nanosec();
+ case Column_Track: return song.track();
+ case Column_Disc: return song.disc();
+ case Column_Year: return song.year();
+ case Column_OriginalYear: return song.effective_originalyear();
+ case Column_Genre: return song.genre();
+ case Column_AlbumArtist: return song.playlist_albumartist();
+ case Column_Composer: return song.composer();
+ case Column_Performer: return song.performer();
+ case Column_Grouping: return song.grouping();
- case Column_PlayCount: return song.playcount();
- case Column_SkipCount: return song.skipcount();
- case Column_LastPlayed: return song.lastplayed();
+ case Column_PlayCount: return song.playcount();
+ case Column_SkipCount: return song.skipcount();
+ case Column_LastPlayed: return song.lastplayed();
- case Column_Samplerate: return song.samplerate();
- case Column_Bitdepth: return song.bitdepth();
- case Column_Bitrate: return song.bitrate();
+ case Column_Samplerate: return song.samplerate();
+ case Column_Bitdepth: return song.bitdepth();
+ case Column_Bitrate: return song.bitrate();
- case Column_Filename: return song.url();
- case Column_BaseFilename: return song.basefilename();
- case Column_Filesize: return song.filesize();
- case Column_Filetype: return song.filetype();
- case Column_DateModified: return song.mtime();
- case Column_DateCreated: return song.ctime();
+ case Column_Filename: return song.url();
+ case Column_BaseFilename: return song.basefilename();
+ case Column_Filesize: return song.filesize();
+ case Column_Filetype: return song.filetype();
+ case Column_DateModified: return song.mtime();
+ case Column_DateCreated: return song.ctime();
case Column_Comment:
- if (role == Qt::DisplayRole) return song.comment().simplified();
+ if (role == Qt::DisplayRole) return song.comment().simplified();
return song.comment();
- case Column_Source: return item->Url();
+ case Column_Source: return song.source();
}
@@ -910,7 +911,7 @@ void Playlist::InsertItemsWithoutUndo(const PlaylistItemList &items, int pos, bo
items_.insert(i, item);
virtual_items_ << virtual_items_.count();
- if (item->type() == "Collection") {
+ if (item->source() == Song::Source_Collection) {
int id = item->Metadata().id();
if (id != -1) {
collection_items_by_id_.insertMulti(id, item);
@@ -990,16 +991,22 @@ void Playlist::UpdateItems(const SongList &songs) {
const Song &song = it.next();
PlaylistItemPtr &item = items_[i];
if (item->Metadata().url() == song.url() &&
- (item->Metadata().filetype() == Song::Type_Unknown ||
+ (
+ item->Metadata().source() == Song::Source_Unknown ||
+ item->Metadata().filetype() == Song::FileType_Unknown ||
// Stream may change and may need to be updated too
- item->Metadata().filetype() == Song::Type_Stream ||
+ item->Metadata().source() == Song::Source_Stream ||
+ item->Metadata().source() == Song::Source_Tidal ||
// And CD tracks as well (tags are loaded in a second step)
- item->Metadata().filetype() == Song::Type_CDDA)) {
+ item->Metadata().source() == Song::Source_CDDA
+ )
+ ) {
PlaylistItemPtr new_item;
if (song.is_collection_song()) {
new_item = PlaylistItemPtr(new CollectionPlaylistItem(song));
collection_items_by_id_.insertMulti(song.id(), new_item);
- } else {
+ }
+ else {
new_item = PlaylistItemPtr(new SongPlaylistItem(song));
}
items_[i] = new_item;
@@ -1099,7 +1106,7 @@ bool Playlist::CompareItems(int column, Qt::SortOrder order, shared_ptrtype() == "Collection") {
+ if (item->source() == Song::Source_Collection) {
int id = item->Metadata().id();
if (id != -1) {
collection_items_by_id_.remove(id, item);
diff --git a/src/playlist/playlistbackend.cpp b/src/playlist/playlistbackend.cpp
index e38e41ac7..fa6429ada 100644
--- a/src/playlist/playlistbackend.cpp
+++ b/src/playlist/playlistbackend.cpp
@@ -145,7 +145,7 @@ QSqlQuery PlaylistBackend::GetPlaylistRows(int playlist) {
" p.ROWID, " +
Song::JoinSpec("p") +
","
- " p.type, p.internet_service"
+ " p.type"
" FROM playlist_items AS p"
" LEFT JOIN songs"
" ON p.collection_id = songs.ROWID"
@@ -198,7 +198,7 @@ PlaylistItemPtr PlaylistBackend::NewPlaylistItemFromQuery(const SqlRow &row, std
// The song tables get joined first, plus one each for the song ROWIDs
const int playlist_row = (Song::kColumns.count() + 1) * kSongTableJoins;
- PlaylistItemPtr item(PlaylistItem::NewFromType(row.value(playlist_row).toString()));
+ PlaylistItemPtr item(PlaylistItem::NewFromSource(Song::Source(row.value(playlist_row).toInt())));
if (item) {
item->InitFromQuery(row);
return RestoreCueData(item, state);
@@ -219,8 +219,8 @@ Song PlaylistBackend::NewSongFromQuery(const SqlRow &row, std::shared_ptr state) {
- // we need collection to run a CueParser; also, this method applies only to file-type PlaylistItems
- if (item->type() != "File") return item;
+ // We need collection to run a CueParser; also, this method applies only to file-type PlaylistItems
+ if (item->source() != Song::Source_LocalFile) return item;
CueParser cue_parser(app_->collection_backend());
@@ -279,7 +279,7 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList &items,
QSqlQuery clear(db);
clear.prepare("DELETE FROM playlist_items WHERE playlist = :playlist");
QSqlQuery insert(db);
- insert.prepare("INSERT INTO playlist_items (playlist, type, collection_id, internet_service, " + Song::kColumnSpec + ") VALUES (:playlist, :type, :collection_id, :internet_service, " + Song::kBindSpec + ")");
+ insert.prepare("INSERT INTO playlist_items (playlist, type, collection_id, " + Song::kColumnSpec + ") VALUES (:playlist, :type, :collection_id, " + Song::kBindSpec + ")");
QSqlQuery update(db);
update.prepare("UPDATE playlists SET last_played=:last_played WHERE ROWID=:playlist");
diff --git a/src/playlist/playlistdelegates.cpp b/src/playlist/playlistdelegates.cpp
index 6ae34349e..1939b816d 100644
--- a/src/playlist/playlistdelegates.cpp
+++ b/src/playlist/playlistdelegates.cpp
@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome
+ * Copyright 2018, Jonas Kvinge
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -348,12 +349,6 @@ QString FileTypeItemDelegate::displayText(const QVariant &value, const QLocale &
}
-QString SamplerateBitdepthItemDelegate::displayText(const QVariant &value, const QLocale &locale) const {
-
- return value.toString();
-
-}
-
QWidget *TextItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
return new QLineEdit(parent);
@@ -442,37 +437,16 @@ QString SongSourceDelegate::displayText(const QVariant &value, const QLocale&) c
return QString();
}
-QPixmap SongSourceDelegate::LookupPixmap(const QUrl &url, const QSize &size) const {
+QPixmap SongSourceDelegate::LookupPixmap(const Song::Source &source, const QSize &size) const {
QPixmap pixmap;
- if (cache_.find(url.scheme(), &pixmap)) {
+ if (cache_.find(Song::TextForSource(source), &pixmap)) {
return pixmap;
}
- QIcon icon;
- const UrlHandler *handler = player_->HandlerForUrl(url);
- if (handler) {
- icon = handler->icon();
- }
- else {
- if (url.scheme() == "file") {
- icon = IconLoader::Load("folder-sound");
- }
- else if (url.scheme() == "cdda") {
- icon = IconLoader::Load("cd");
- }
- else if (url.scheme() == "http" || url.scheme() == "https") {
- if (url.host().contains(QRegExp(".*.tidal.com")))
- icon = IconLoader::Load("tidal");
- else
- icon = IconLoader::Load("download");
- }
- else {
- icon = IconLoader::Load("folder-sound");
- }
- }
+ QIcon icon(Song::IconForSource(source));
pixmap = icon.pixmap(size.height());
- cache_.insert(url.scheme(), pixmap);
+ cache_.insert(Song::TextForSource(source), pixmap);
return pixmap;
@@ -486,9 +460,8 @@ void SongSourceDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
QStyleOptionViewItem option_copy(option);
initStyleOption(&option_copy, index);
- // Find the pixmap to use for this URL
- const QUrl &url = index.data().toUrl();
- QPixmap pixmap = LookupPixmap(url, option_copy.decorationSize);
+ const Song::Source &source = Song::Source(index.data().toInt());
+ QPixmap pixmap = LookupPixmap(source, option_copy.decorationSize);
float device_pixel_ratio = 1.0f;
#ifdef Q_OS_MACOS
diff --git a/src/playlist/playlistdelegates.h b/src/playlist/playlistdelegates.h
index 98ec2b806..ae9e47bdd 100644
--- a/src/playlist/playlistdelegates.h
+++ b/src/playlist/playlistdelegates.h
@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome
+ * Copyright 2018, Jonas Kvinge
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -125,12 +126,6 @@ class FileTypeItemDelegate : public PlaylistDelegateBase {
QString displayText(const QVariant &value, const QLocale &locale) const;
};
-class SamplerateBitdepthItemDelegate : public PlaylistDelegateBase {
- public:
- SamplerateBitdepthItemDelegate(QObject *parent) : PlaylistDelegateBase(parent) {}
- QString displayText(const QVariant &value, const QLocale &locale) const;
-};
-
class TextItemDelegate : public PlaylistDelegateBase {
public:
TextItemDelegate(QObject *parent) : PlaylistDelegateBase(parent) {}
@@ -182,7 +177,7 @@ class SongSourceDelegate : public PlaylistDelegateBase {
void paint(QPainter *paint, const QStyleOptionViewItem &option, const QModelIndex &index) const;
private:
- QPixmap LookupPixmap(const QUrl &url, const QSize &size) const;
+ QPixmap LookupPixmap(const Song::Source &type, const QSize &size) const;
Player *player_;
mutable QPixmapCache cache_;
diff --git a/src/playlist/playlistitem.cpp b/src/playlist/playlistitem.cpp
index 13eb7a1b6..5782f7464 100644
--- a/src/playlist/playlistitem.cpp
+++ b/src/playlist/playlistitem.cpp
@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome
+ * Copyright 2018, Jonas Kvinge
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -42,20 +43,18 @@
PlaylistItem::~PlaylistItem() {
}
-PlaylistItem* PlaylistItem::NewFromType(const QString &type) {
+PlaylistItem *PlaylistItem::NewFromSource(const Song::Source &source) {
- if (type == "Collection") return new CollectionPlaylistItem(type);
- else if (type == "File") return new SongPlaylistItem(type);
- else if (type == "Internet") return new InternetPlaylistItem("Internet");
- else if (type == "Tidal") return new InternetPlaylistItem("Tidal");
-
- qLog(Warning) << "Invalid PlaylistItem type:" << type;
-
- return nullptr;
+ switch (source) {
+ case Song::Source_Collection: return new CollectionPlaylistItem(source);
+ case Song::Source_Tidal:
+ case Song::Source_Stream: return new InternetPlaylistItem(source);
+ default: return new SongPlaylistItem(source);
+ }
}
-PlaylistItem* PlaylistItem::NewFromSongsTable(const QString &table, const Song &song) {
+PlaylistItem *PlaylistItem::NewFromSongsTable(const QString &table, const Song &song) {
if (table == SCollection::kSongsTable)
return new CollectionPlaylistItem(song);
@@ -67,9 +66,8 @@ PlaylistItem* PlaylistItem::NewFromSongsTable(const QString &table, const Song &
void PlaylistItem::BindToQuery(QSqlQuery *query) const {
- query->bindValue(":type", type());
+ query->bindValue(":type", source());
query->bindValue(":collection_id", DatabaseValue(Column_CollectionId));
- query->bindValue(":internet_service", DatabaseValue(Column_InternetService));
DatabaseSongMetadata().BindToQuery(query);
diff --git a/src/playlist/playlistitem.h b/src/playlist/playlistitem.h
index a7358bb1c..dce221108 100644
--- a/src/playlist/playlistitem.h
+++ b/src/playlist/playlistitem.h
@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome
+ * Copyright 2018, Jonas Kvinge
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,11 +47,11 @@ class SqlRow;
class PlaylistItem : public std::enable_shared_from_this {
public:
- PlaylistItem(const QString &type) : should_skip_(false), type_(type) {}
+ PlaylistItem(const Song::Source &source) : should_skip_(false), source_(source) {}
virtual ~PlaylistItem();
- static PlaylistItem* NewFromType(const QString &type);
- static PlaylistItem* NewFromSongsTable(const QString &table, const Song &song);
+ static PlaylistItem *NewFromSource(const Song::Source &source);
+ static PlaylistItem *NewFromSongsTable(const QString &table, const Song &song);
enum Option {
Default = 0x00,
@@ -63,7 +64,7 @@ class PlaylistItem : public std::enable_shared_from_this {
};
Q_DECLARE_FLAGS(Options, Option);
- virtual QString type() const { return type_; }
+ virtual Song::Source source() const { return source_; }
virtual Options options() const { return Default; }
@@ -104,14 +105,14 @@ class PlaylistItem : public std::enable_shared_from_this {
protected:
bool should_skip_;
- enum DatabaseColumn { Column_CollectionId, Column_InternetService };
+ enum DatabaseColumn { Column_CollectionId };
virtual QVariant DatabaseValue(DatabaseColumn) const {
return QVariant(QVariant::String);
}
virtual Song DatabaseSongMetadata() const { return Song(); }
- QString type_;
+ Song::Source source_;
Song temp_metadata_;
diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp
index f8301e02c..435a49a63 100644
--- a/src/playlist/playlistview.cpp
+++ b/src/playlist/playlistview.cpp
@@ -1057,11 +1057,10 @@ void PlaylistView::StretchChanged(bool stretch) {
bool PlaylistView::eventFilter(QObject *object, QEvent *event) {
if (event->type() == QEvent::Enter && (object == horizontalScrollBar() || object == verticalScrollBar())) {
- //RatingHoverOut();
return false;
}
return QObject::eventFilter(object, event);
-
+
}
void PlaylistView::rowsInserted(const QModelIndex &parent, int start, int end) {
diff --git a/src/playlist/songplaylistitem.cpp b/src/playlist/songplaylistitem.cpp
index fbd00d5d8..252f50ac3 100644
--- a/src/playlist/songplaylistitem.cpp
+++ b/src/playlist/songplaylistitem.cpp
@@ -29,15 +29,13 @@
#include "playlistitem.h"
#include "songplaylistitem.h"
-SongPlaylistItem::SongPlaylistItem(const QString &type) : PlaylistItem(type) {}
+SongPlaylistItem::SongPlaylistItem(const Song::Source &source) : PlaylistItem(source) {}
SongPlaylistItem::SongPlaylistItem(const Song &song)
- : PlaylistItem("File"), song_(song) {}
+ : PlaylistItem(Song::Source_LocalFile), song_(song) {}
bool SongPlaylistItem::InitFromQuery(const SqlRow &query) {
-
song_.InitFromQuery(query, false, (Song::kColumns.count()+1));
-
return true;
}
@@ -45,7 +43,6 @@ QUrl SongPlaylistItem::Url() const { return song_.url(); }
void SongPlaylistItem::Reload() {
if (song_.url().scheme() != "file") return;
-
TagReaderClient::Instance()->ReadFileBlocking(song_.url().toLocalFile(), &song_);
}
diff --git a/src/playlist/songplaylistitem.h b/src/playlist/songplaylistitem.h
index 7def90f86..8bd7b171d 100644
--- a/src/playlist/songplaylistitem.h
+++ b/src/playlist/songplaylistitem.h
@@ -33,7 +33,7 @@
class SongPlaylistItem : public PlaylistItem {
public:
- SongPlaylistItem(const QString &type);
+ SongPlaylistItem(const Song::Source &source);
SongPlaylistItem(const Song &song);
// Restores a stream- or file-related playlist item using query row.
diff --git a/src/tidal/tidalsearch.h b/src/tidal/tidalsearch.h
index 702358b5e..fa211e614 100644
--- a/src/tidal/tidalsearch.h
+++ b/src/tidal/tidalsearch.h
@@ -140,6 +140,7 @@ class TidalSearch : public QObject {
Application *app_;
TidalService *service_;
+ Song::Source source_;
QString name_;
QString id_;
QIcon icon_;
diff --git a/src/tidal/tidalservice.cpp b/src/tidal/tidalservice.cpp
index 49ad29277..2aca35de8 100644
--- a/src/tidal/tidalservice.cpp
+++ b/src/tidal/tidalservice.cpp
@@ -53,6 +53,7 @@
#include "tidalsearch.h"
#include "settings/tidalsettingspage.h"
+const Song::Source TidalService::kSource = Song::Source_Tidal;
const char *TidalService::kServiceName = "Tidal";
const char *TidalService::kApiUrl = "https://listen.tidal.com/v1";
const char *TidalService::kAuthUrl = "https://listen.tidal.com/v1/login/username";
@@ -62,7 +63,7 @@ const char *TidalService::kApiToken = "P5Xbeo5LFvESeDy6";
typedef QPair Param;
TidalService::TidalService(Application *app, InternetModel *parent)
- : InternetService(kServiceName, app, parent, parent),
+ : InternetService(kSource, kServiceName, app, parent, parent),
network_(new NetworkAccessManager(this)),
timer_searchdelay_(new QTimer(this)),
searchdelay_(1500),
@@ -730,7 +731,7 @@ Song TidalService::ParseSong(const int album_id_requested, const QJsonValue &val
}
int album_id = json_album["id"].toInt();
if (album_id_requested != 0 && album_id_requested != album_id) {
- qLog(Error) << "Tidal: Invalid Json reply, track album is wrong.";
+ qLog(Error) << "Tidal: Invalid Json reply, track album id is wrong.";
qLog(Debug) << json_album;
return song;
}
@@ -745,6 +746,7 @@ Song TidalService::ParseSong(const int album_id_requested, const QJsonValue &val
//qLog(Debug) << "id" << id << "track" << track << "disc" << disc << "title" << title << "album" << album << "artist" << artist << cover << allow_streaming << url;
+ song.set_source(Song::Source_Tidal);
song.set_id(song_id);
song.set_album_id(album_id);
song.set_artist(artist);
@@ -819,9 +821,9 @@ void TidalService::GetStreamURLFinished(QNetworkReply *reply, const int search_i
QString codec = json_obj["codec"].toString().toLower();
song.set_filetype(Song::FiletypeByExtension(codec));
- if (song.filetype() == Song::Type_Unknown) {
+ if (song.filetype() == Song::FileType_Unknown) {
qLog(Debug) << "Tidal: Unknown codec" << codec;
- song.set_filetype(Song::Type_Stream);
+ song.set_filetype(Song::FileType_Stream);
}
song.set_valid(true);
diff --git a/src/tidal/tidalservice.h b/src/tidal/tidalservice.h
index 75432c97d..a880af566 100644
--- a/src/tidal/tidalservice.h
+++ b/src/tidal/tidalservice.h
@@ -47,6 +47,7 @@ class TidalService : public InternetService {
TidalService(Application *app, InternetModel *parent);
~TidalService();
+ static const Song::Source kSource;
static const char *kServiceName;
void ReloadSettings();
diff --git a/src/transcoder/transcoder.cpp b/src/transcoder/transcoder.cpp
index dcc74429c..5e4ba092a 100644
--- a/src/transcoder/transcoder.cpp
+++ b/src/transcoder/transcoder.cpp
@@ -222,15 +222,15 @@ Transcoder::Transcoder(QObject *parent, const QString &settings_postfix)
QList Transcoder::GetAllPresets() {
QList ret;
- ret << PresetForFileType(Song::Type_FLAC);
- ret << PresetForFileType(Song::Type_MP4);
- ret << PresetForFileType(Song::Type_MPEG);
- ret << PresetForFileType(Song::Type_OggVorbis);
- ret << PresetForFileType(Song::Type_OggFlac);
- ret << PresetForFileType(Song::Type_OggSpeex);
- ret << PresetForFileType(Song::Type_ASF);
- ret << PresetForFileType(Song::Type_WAV);
- ret << PresetForFileType(Song::Type_OggOpus);
+ ret << PresetForFileType(Song::FileType_FLAC);
+ ret << PresetForFileType(Song::FileType_MP4);
+ ret << PresetForFileType(Song::FileType_MPEG);
+ ret << PresetForFileType(Song::FileType_OggVorbis);
+ ret << PresetForFileType(Song::FileType_OggFlac);
+ ret << PresetForFileType(Song::FileType_OggSpeex);
+ ret << PresetForFileType(Song::FileType_ASF);
+ ret << PresetForFileType(Song::FileType_WAV);
+ ret << PresetForFileType(Song::FileType_OggOpus);
return ret;
}
@@ -238,23 +238,23 @@ QList Transcoder::GetAllPresets() {
TranscoderPreset Transcoder::PresetForFileType(Song::FileType type) {
switch (type) {
- case Song::Type_FLAC:
+ case Song::FileType_FLAC:
return TranscoderPreset(type, tr("FLAC"), "flac", "audio/x-flac");
- case Song::Type_MP4:
+ case Song::FileType_MP4:
return TranscoderPreset(type, tr("M4A AAC"), "mp4", "audio/mpeg, mpegversion=(int)4", "audio/mp4");
- case Song::Type_MPEG:
+ case Song::FileType_MPEG:
return TranscoderPreset(type, tr("MP3"), "mp3", "audio/mpeg, mpegversion=(int)1, layer=(int)3");
- case Song::Type_OggVorbis:
+ case Song::FileType_OggVorbis:
return TranscoderPreset(type, tr("Ogg Vorbis"), "ogg", "audio/x-vorbis", "application/ogg");
- case Song::Type_OggFlac:
+ case Song::FileType_OggFlac:
return TranscoderPreset(type, tr("Ogg FLAC"), "ogg", "audio/x-flac", "application/ogg");
- case Song::Type_OggSpeex:
+ case Song::FileType_OggSpeex:
return TranscoderPreset(type, tr("Ogg Speex"), "spx", "audio/x-speex", "application/ogg");
- case Song::Type_OggOpus:
+ case Song::FileType_OggOpus:
return TranscoderPreset(type, tr("Ogg Opus"), "opus", "audio/x-opus", "application/ogg");
- case Song::Type_ASF:
+ case Song::FileType_ASF:
return TranscoderPreset(type, tr("Windows Media audio"), "wma", "audio/x-wma", "video/x-ms-asf");
- case Song::Type_WAV:
+ case Song::FileType_WAV:
return TranscoderPreset(type, tr("Wav"), "wav", QString(), "audio/x-wav");
default:
qLog(Warning) << "Unsupported format in PresetForFileType:" << type;
@@ -265,12 +265,12 @@ TranscoderPreset Transcoder::PresetForFileType(Song::FileType type) {
Song::FileType Transcoder::PickBestFormat(QList supported) {
- if (supported.isEmpty()) return Song::Type_Unknown;
+ if (supported.isEmpty()) return Song::FileType_Unknown;
QList best_formats;
- best_formats << Song::Type_MPEG;
- best_formats << Song::Type_OggVorbis;
- best_formats << Song::Type_ASF;
+ best_formats << Song::FileType_MPEG;
+ best_formats << Song::FileType_OggVorbis;
+ best_formats << Song::FileType_ASF;
for (Song::FileType type : best_formats) {
if (supported.isEmpty() || supported.contains(type)) return type;
diff --git a/src/transcoder/transcoder.h b/src/transcoder/transcoder.h
index 64a6be7f2..a5e80348b 100644
--- a/src/transcoder/transcoder.h
+++ b/src/transcoder/transcoder.h
@@ -41,7 +41,7 @@
#include "core/song.h"
struct TranscoderPreset {
- TranscoderPreset() : type_(Song::Type_Unknown) {}
+ TranscoderPreset() : type_(Song::FileType_Unknown) {}
TranscoderPreset(Song::FileType type, const QString &name, const QString &extension, const QString &codec_mimetype, const QString &muxer_mimetype_ = QString());
Song::FileType type_;
diff --git a/src/transcoder/transcoderoptionsdialog.cpp b/src/transcoder/transcoderoptionsdialog.cpp
index 798e0aee2..83563d25f 100644
--- a/src/transcoder/transcoderoptionsdialog.cpp
+++ b/src/transcoder/transcoderoptionsdialog.cpp
@@ -44,14 +44,14 @@ TranscoderOptionsDialog::TranscoderOptionsDialog(Song::FileType type, QWidget *p
ui_->setupUi(this);
switch (type) {
- case Song::Type_FLAC:
- case Song::Type_OggFlac: options_ = new TranscoderOptionsFlac(this); break;
- case Song::Type_MP4: options_ = new TranscoderOptionsAAC(this); break;
- case Song::Type_MPEG: options_ = new TranscoderOptionsMP3(this); break;
- case Song::Type_OggVorbis: options_ = new TranscoderOptionsVorbis(this); break;
- case Song::Type_OggOpus: options_ = new TranscoderOptionsOpus(this); break;
- case Song::Type_OggSpeex: options_ = new TranscoderOptionsSpeex(this); break;
- case Song::Type_ASF: options_ = new TranscoderOptionsWma(this); break;
+ case Song::FileType_FLAC:
+ case Song::FileType_OggFlac: options_ = new TranscoderOptionsFlac(this); break;
+ case Song::FileType_MP4: options_ = new TranscoderOptionsAAC(this); break;
+ case Song::FileType_MPEG: options_ = new TranscoderOptionsMP3(this); break;
+ case Song::FileType_OggVorbis: options_ = new TranscoderOptionsVorbis(this); break;
+ case Song::FileType_OggOpus: options_ = new TranscoderOptionsOpus(this); break;
+ case Song::FileType_OggSpeex: options_ = new TranscoderOptionsSpeex(this); break;
+ case Song::FileType_ASF: options_ = new TranscoderOptionsWma(this); break;
default:
break;
}