Add source to songs and playlist_items
This commit is contained in:
@@ -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_ptr<Playlist
|
||||
case Column_DateCreated: cmp(ctime);
|
||||
|
||||
case Column_Comment: strcmp(comment);
|
||||
case Column_Source: cmp(url);
|
||||
case Column_Source: cmp(source);
|
||||
}
|
||||
|
||||
#undef cmp
|
||||
@@ -1143,7 +1150,7 @@ QString Playlist::column_name(Column column) {
|
||||
case Column_LastPlayed: return tr("Last played");
|
||||
|
||||
case Column_Samplerate: return tr("Sample rate");
|
||||
case Column_Bitdepth: return tr("Bit depth");
|
||||
case Column_Bitdepth: return tr("Bit depth");
|
||||
case Column_Bitrate: return tr("Bitrate");
|
||||
|
||||
case Column_Filename: return tr("File name");
|
||||
@@ -1155,7 +1162,7 @@ QString Playlist::column_name(Column column) {
|
||||
|
||||
case Column_Comment: return tr("Comment");
|
||||
case Column_Source: return tr("Source");
|
||||
default: return QString();
|
||||
default: return QString();
|
||||
}
|
||||
return "";
|
||||
|
||||
@@ -1395,7 +1402,7 @@ PlaylistItemList Playlist::RemoveItemsWithoutUndo(int row, int count) {
|
||||
PlaylistItemPtr item(items_.takeAt(row));
|
||||
ret << item;
|
||||
|
||||
if (item->type() == "Collection") {
|
||||
if (item->source() == Song::Source_Collection) {
|
||||
int id = item->Metadata().id();
|
||||
if (id != -1) {
|
||||
collection_items_by_id_.remove(id, item);
|
||||
|
||||
@@ -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<NewSon
|
||||
|
||||
PlaylistItemPtr PlaylistBackend::RestoreCueData(PlaylistItemPtr item, std::shared_ptr<NewSongFromQueryState> 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");
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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_;
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -46,11 +47,11 @@ class SqlRow;
|
||||
|
||||
class PlaylistItem : public std::enable_shared_from_this<PlaylistItem> {
|
||||
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<PlaylistItem> {
|
||||
};
|
||||
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<PlaylistItem> {
|
||||
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_;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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_);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user