diff --git a/src/collection/collectionplaylistitem.cpp b/src/collection/collectionplaylistitem.cpp index 58dbc0f11..29363f206 100644 --- a/src/collection/collectionplaylistitem.cpp +++ b/src/collection/collectionplaylistitem.cpp @@ -34,8 +34,6 @@ CollectionPlaylistItem::CollectionPlaylistItem(const Song::Source source) : Play CollectionPlaylistItem::CollectionPlaylistItem(const Song &song) : PlaylistItem(song.source()), song_(song) {} -QUrl CollectionPlaylistItem::Url() const { return song_.url(); } - bool CollectionPlaylistItem::InitFromQuery(const SqlRow &query) { int col = 0; @@ -62,7 +60,7 @@ void CollectionPlaylistItem::Reload() { qLog(Error) << "Could not reload file" << song_.url() << result.error_string(); return; } - UpdateTemporaryMetadata(song_); + UpdateStreamMetadata(song_); } } @@ -78,16 +76,9 @@ QVariant CollectionPlaylistItem::DatabaseValue(const DatabaseColumn database_col } -Song CollectionPlaylistItem::Metadata() const { - - if (HasTemporaryMetadata()) return temp_metadata_; - return song_; - -} - void CollectionPlaylistItem::SetArtManual(const QUrl &cover_url) { song_.set_art_manual(cover_url); - if (HasTemporaryMetadata()) temp_metadata_.set_art_manual(cover_url); + if (HasStreamMetadata()) stream_song_.set_art_manual(cover_url); } diff --git a/src/collection/collectionplaylistitem.h b/src/collection/collectionplaylistitem.h index 9491b1247..5e9dd05be 100644 --- a/src/collection/collectionplaylistitem.h +++ b/src/collection/collectionplaylistitem.h @@ -35,19 +35,17 @@ class CollectionPlaylistItem : public PlaylistItem { explicit CollectionPlaylistItem(const Song::Source source); explicit CollectionPlaylistItem(const Song &song); - QUrl Url() const override; + Song OriginalMetadata() const override { return song_; } + void SetOriginalMetadata(const Song &song) override { song_ = song; } + + QUrl OriginalUrl() const override { return song_.url(); } + bool IsLocalCollectionItem() const override { return song_.source() == Song::Source::Collection; } bool InitFromQuery(const SqlRow &query) override; void Reload() override; - Song Metadata() const override; - Song OriginalMetadata() const override { return song_; } - void SetMetadata(const Song &song) override { song_ = song; } - void SetArtManual(const QUrl &cover_url) override; - bool IsLocalCollectionItem() const override { return song_.source() == Song::Source::Collection; } - protected: QVariant DatabaseValue(const DatabaseColumn database_column) const override; Song DatabaseSongMetadata() const override { return Song(source_); } diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp index da9c95035..2f6a112ae 100644 --- a/src/core/mainwindow.cpp +++ b/src/core/mainwindow.cpp @@ -1515,8 +1515,8 @@ void MainWindow::SendNowPlaying() { // Send now playing to scrobble services Playlist *playlist = app_->playlist_manager()->active(); - if (app_->scrobbler()->enabled() && playlist && playlist->current_item() && playlist->current_item()->Metadata().is_metadata_good()) { - app_->scrobbler()->UpdateNowPlaying(playlist->current_item()->Metadata()); + if (app_->scrobbler()->enabled() && playlist && playlist->current_item() && playlist->current_item()->EffectiveMetadata().is_metadata_good()) { + app_->scrobbler()->UpdateNowPlaying(playlist->current_item()->EffectiveMetadata()); ui_->action_love->setEnabled(true); ui_->button_love->setEnabled(true); tray_icon_->LoveStateChanged(true); @@ -1562,9 +1562,9 @@ void MainWindow::TrackSkipped(PlaylistItemPtr item) { // If it was a collection item then we have to increment its skipped count in the database. - if (item && item->IsLocalCollectionItem() && item->Metadata().id() != -1) { + if (item && item->IsLocalCollectionItem() && item->EffectiveMetadata().id() != -1) { - Song song = item->Metadata(); + Song song = item->EffectiveMetadata(); const qint64 position = app_->player()->engine()->position_nanosec(); const qint64 length = app_->player()->engine()->length_nanosec(); const float percentage = (length == 0 ? 1 : static_cast(position) / static_cast(length)); @@ -1758,7 +1758,7 @@ void MainWindow::FilePathChanged(const QString &path) { void MainWindow::Seeked(const qint64 microseconds) { const qint64 position = microseconds / kUsecPerSec; - const qint64 length = app_->player()->GetCurrentItem()->Metadata().length_nanosec() / kNsecPerSec; + const qint64 length = app_->player()->GetCurrentItem()->EffectiveMetadata().length_nanosec() / kNsecPerSec; tray_icon_->SetProgress(static_cast(static_cast(position) / static_cast(length) * 100.0)); #ifdef HAVE_DBUS @@ -1774,7 +1774,7 @@ void MainWindow::UpdateTrackPosition() { PlaylistItemPtr item(app_->player()->GetCurrentItem()); if (!item) return; - const qint64 length = (item->Metadata().length_nanosec() / kNsecPerSec); + const qint64 length = (item->EffectiveMetadata().length_nanosec() / kNsecPerSec); if (length <= 0) return; const int position = std::floor(static_cast(app_->player()->engine()->position_nanosec()) / static_cast(kNsecPerSec) + 0.5); @@ -1788,12 +1788,12 @@ void MainWindow::UpdateTrackPosition() { #endif // Send Scrobble - if (app_->scrobbler()->enabled() && item->Metadata().is_metadata_good()) { + if (app_->scrobbler()->enabled() && item->EffectiveMetadata().is_metadata_good()) { Playlist *playlist = app_->playlist_manager()->active(); if (playlist && !playlist->scrobbled()) { const qint64 scrobble_point = (playlist->scrobble_point_nanosec() / kNsecPerSec); if (position >= scrobble_point) { - app_->scrobbler()->Scrobble(item->Metadata(), scrobble_point); + app_->scrobbler()->Scrobble(item->EffectiveMetadata(), scrobble_point); playlist->set_scrobbled(true); } } @@ -1910,7 +1910,7 @@ void MainWindow::AddToPlaylistFromAction(QAction *action) { PlaylistItemPtr item = app_->playlist_manager()->current()->item_at(source_index.row()); if (!item) continue; items << item; - songs << item->Metadata(); + songs << item->EffectiveMetadata(); } // We're creating a new playlist @@ -1989,12 +1989,12 @@ void MainWindow::PlaylistRightClick(const QPoint global_pos, const QModelIndex & PlaylistItemPtr item = app_->playlist_manager()->current()->item_at(src_idx.row()); if (!item) continue; - if (item->Metadata().url().isLocalFile()) ++local_songs; + if (item->EffectiveMetadata().url().isLocalFile()) ++local_songs; - if (item->Metadata().has_cue()) { + if (item->EffectiveMetadata().has_cue()) { cue_selected = true; } - else if (item->Metadata().IsEditable()) { + else if (item->EffectiveMetadata().IsEditable()) { ++editable; } @@ -2097,7 +2097,7 @@ void MainWindow::PlaylistRightClick(const QPoint global_pos, const QModelIndex & // Is it a collection item? PlaylistItemPtr item = app_->playlist_manager()->current()->item_at(source_index.row()); - if (item && item->IsLocalCollectionItem() && item->Metadata().id() != -1) { + if (item && item->IsLocalCollectionItem() && item->EffectiveMetadata().id() != -1) { playlist_organize_->setVisible(local_songs > 0 && editable > 0 && !cue_selected); playlist_show_in_collection_->setVisible(true); playlist_open_in_browser_->setVisible(true); @@ -2189,9 +2189,9 @@ void MainWindow::RescanSongs() { PlaylistItemPtr item(app_->playlist_manager()->current()->item_at(source_index.row())); if (!item) continue; if (item->IsLocalCollectionItem()) { - songs << item->Metadata(); + songs << item->EffectiveMetadata(); } - else if (item->Metadata().source() == Song::Source::LocalFile) { + else if (item->EffectiveMetadata().source() == Song::Source::LocalFile) { QPersistentModelIndex persistent_index = QPersistentModelIndex(source_index); app_->playlist_manager()->current()->ItemReload(persistent_index, item->OriginalMetadata(), false); } @@ -2823,7 +2823,7 @@ void MainWindow::PlaylistOpenInBrowser() { for (const QModelIndex &proxy_index : proxy_indexes) { const QModelIndex source_index = app_->playlist_manager()->current()->filter()->mapToSource(proxy_index); if (!source_index.isValid()) continue; - urls << QUrl(source_index.sibling(source_index.row(), static_cast(Playlist::Column::Filename)).data().toString()); + urls << QUrl(source_index.sibling(source_index.row(), static_cast(Playlist::Column::URL)).data().toString()); } Utilities::OpenInFileBrowser(urls); @@ -2839,7 +2839,7 @@ void MainWindow::PlaylistCopyUrl() { if (!source_index.isValid()) continue; PlaylistItemPtr item = app_->playlist_manager()->current()->item_at(source_index.row()); if (!item) continue; - urls << item->StreamUrl(); + urls << item->EffectiveUrl(); } if (urls.count() > 0) { @@ -3321,10 +3321,10 @@ void MainWindow::PlaylistDelete() { for (const QModelIndex &proxy_idx : proxy_indexes) { QModelIndex source_idx = app_->playlist_manager()->current()->filter()->mapToSource(proxy_idx); PlaylistItemPtr item = app_->playlist_manager()->current()->item_at(source_idx.row()); - if (!item || !item->Metadata().url().isLocalFile()) continue; - QString filename = item->Metadata().url().toLocalFile(); + if (!item || !item->EffectiveMetadata().url().isLocalFile()) continue; + QString filename = item->EffectiveMetadata().url().toLocalFile(); if (files.contains(filename)) continue; - selected_songs << item->Metadata(); + selected_songs << item->EffectiveMetadata(); files << filename; if (item == app_->player()->GetCurrentItem()) is_current_item = true; } diff --git a/src/core/player.cpp b/src/core/player.cpp index 5dcf8a5b7..1f430d375 100644 --- a/src/core/player.cpp +++ b/src/core/player.cpp @@ -288,10 +288,10 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { bool is_current = false; bool is_next = false; - if (result.media_url_ == current_item->Url()) { + if (result.media_url_ == current_item->OriginalUrl()) { is_current = true; } - else if (has_next_row && next_item->Url() == result.media_url_) { + else if (has_next_row && next_item->OriginalUrl() == result.media_url_) { is_next = true; } else { @@ -316,8 +316,8 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { qLog(Debug) << "URL handler for" << result.media_url_ << "returned" << result.stream_url_; Song song; - if (is_current) song = current_item->Metadata(); - else if (is_next) song = next_item->Metadata(); + if (is_current) song = current_item->EffectiveMetadata(); + else if (is_next) song = next_item->EffectiveMetadata(); bool update = false; @@ -325,7 +325,7 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { if ( (result.stream_url_.isValid()) && - (result.stream_url_ != song.url()) + (result.stream_url_ != song.effective_url()) ) { song.set_stream_url(result.stream_url_); @@ -371,14 +371,14 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { } if (is_current) { - qLog(Debug) << "Playing song" << current_item->Metadata().title() << result.stream_url_ << "position" << play_offset_nanosec_; + qLog(Debug) << "Playing song" << current_item->EffectiveMetadata().title() << result.stream_url_ << "position" << play_offset_nanosec_; engine_->Play(result.media_url_, result.stream_url_, pause_, stream_change_type_, song.has_cue(), static_cast(song.beginning_nanosec()), song.end_nanosec(), play_offset_nanosec_, song.ebur128_integrated_loudness_lufs()); current_item_ = current_item; play_offset_nanosec_ = 0; } - else if (is_next && !current_item->Metadata().is_module_music()) { - qLog(Debug) << "Preloading next song" << next_item->Metadata().title() << result.stream_url_; - engine_->StartPreloading(next_item->Url(), result.stream_url_, song.has_cue(), song.beginning_nanosec(), song.end_nanosec()); + else if (is_next && !current_item->EffectiveMetadata().is_module_music()) { + qLog(Debug) << "Preloading next song" << next_item->EffectiveMetadata().title() << result.stream_url_; + engine_->StartPreloading(next_item->OriginalUrl(), result.stream_url_, song.has_cue(), song.beginning_nanosec(), song.end_nanosec()); } break; @@ -504,8 +504,8 @@ bool Player::HandleStopAfter(const Playlist::AutoScroll autoscroll) { void Player::TrackEnded() { - if (current_item_ && current_item_->IsLocalCollectionItem() && current_item_->Metadata().id() != -1) { - playlist_manager_->collection_backend()->IncrementPlayCountAsync(current_item_->Metadata().id()); + if (current_item_ && current_item_->IsLocalCollectionItem() && current_item_->EffectiveMetadata().id() != -1) { + playlist_manager_->collection_backend()->IncrementPlayCountAsync(current_item_->EffectiveMetadata().id()); } if (HandleStopAfter(Playlist::AutoScroll::Maybe)) return; @@ -554,7 +554,7 @@ void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll void Player::UnPause() { if (current_item_ && pause_time_.isValid()) { - const Song &song = current_item_->Metadata(); + const Song &song = current_item_->EffectiveMetadata(); if (url_handlers_->CanHandle(song.url()) && song.stream_url_can_expire()) { const qint64 time = QDateTime::currentSecsSinceEpoch() - pause_time_.toSecsSinceEpoch(); if (time >= 30) { // Stream URL might be expired. @@ -745,7 +745,7 @@ void Player::PlayAt(const int index, const bool pause, const quint64 offset_nano Q_EMIT TrackSkipped(current_item_); } - if (current_item_ && playlist_manager_->active()->has_item_at(index) && current_item_->Metadata().IsOnSameAlbum(playlist_manager_->active()->item_at(index)->Metadata())) { + if (current_item_ && playlist_manager_->active()->has_item_at(index) && current_item_->EffectiveMetadata().IsOnSameAlbum(playlist_manager_->active()->item_at(index)->EffectiveMetadata())) { change |= EngineBase::TrackChangeType::SameAlbum; } @@ -758,7 +758,7 @@ void Player::PlayAt(const int index, const bool pause, const quint64 offset_nano } current_item_ = playlist_manager_->active()->current_item(); - const QUrl url = current_item_->StreamUrl(); + const QUrl url = current_item_->EffectiveUrl(); if (url_handlers_->CanHandle(url)) { // It's already loading @@ -773,8 +773,8 @@ void Player::PlayAt(const int index, const bool pause, const quint64 offset_nano HandleLoadResult(url_handler->StartLoading(url)); } else { - qLog(Debug) << "Playing song" << current_item_->Metadata().title() << url << "position" << offset_nanosec; - engine_->Play(current_item_->Url(), url, pause, change, current_item_->Metadata().has_cue(), static_cast(current_item_->effective_beginning_nanosec()), current_item_->effective_end_nanosec(), offset_nanosec, current_item_->effective_ebur128_integrated_loudness_lufs()); + qLog(Debug) << "Playing song" << current_item_->EffectiveMetadata().title() << url << "position" << offset_nanosec; + engine_->Play(current_item_->OriginalUrl(), url, pause, change, current_item_->EffectiveMetadata().has_cue(), static_cast(current_item_->effective_beginning_nanosec()), current_item_->effective_end_nanosec(), offset_nanosec, current_item_->EffectiveMetadata().ebur128_integrated_loudness_lufs()); } } @@ -823,8 +823,8 @@ void Player::EngineMetadataReceived(const EngineMetadata &engine_metadata) { const int current_row = playlist_manager_->active()->current_row(); if (current_row != -1) { PlaylistItemPtr item = playlist_manager_->active()->current_item(); - if (item && engine_metadata.media_url == item->Url()) { - Song song = item->Metadata(); + if (item && engine_metadata.media_url == item->OriginalUrl()) { + Song song = item->EffectiveMetadata(); song.MergeFromEngineMetadata(engine_metadata); playlist_manager_->active()->UpdateItemMetadata(current_row, item, song, true); return; @@ -836,8 +836,8 @@ void Player::EngineMetadataReceived(const EngineMetadata &engine_metadata) { const int next_row = playlist_manager_->active()->next_row(); if (next_row != -1) { PlaylistItemPtr next_item = playlist_manager_->active()->item_at(next_row); - if (engine_metadata.media_url == next_item->Url()) { - Song song = next_item->Metadata(); + if (engine_metadata.media_url == next_item->OriginalUrl()) { + Song song = next_item->EffectiveMetadata(); song.MergeFromEngineMetadata(engine_metadata); playlist_manager_->active()->UpdateItemMetadata(next_row, next_item, song, true); } @@ -905,11 +905,11 @@ void Player::PlayWithPause(const quint64 offset_nanosec) { } void Player::ShowOSD() { - if (current_item_) Q_EMIT ForceShowOSD(current_item_->Metadata(), false); + if (current_item_) Q_EMIT ForceShowOSD(current_item_->EffectiveMetadata(), false); } void Player::TogglePrettyOSD() { - if (current_item_) Q_EMIT ForceShowOSD(current_item_->Metadata(), true); + if (current_item_) Q_EMIT ForceShowOSD(current_item_->EffectiveMetadata(), true); } void Player::TrackAboutToEnd() { @@ -932,7 +932,7 @@ void Player::TrackAboutToEnd() { // If the next track is on the same album (or same cue file), // and the user doesn't want to crossfade between tracks on the same album, then don't do this automatic crossfading. - if (engine_->crossfade_same_album() || !has_next_row || !next_item || !current_item_->Metadata().IsOnSameAlbum(next_item->Metadata())) { + if (engine_->crossfade_same_album() || !has_next_row || !next_item || !current_item_->EffectiveMetadata().IsOnSameAlbum(next_item->EffectiveMetadata())) { TrackEnded(); return; } @@ -941,7 +941,7 @@ void Player::TrackAboutToEnd() { // Crossfade is off, so start preloading the next track, so we don't get a gap between songs. if (!has_next_row || !next_item) return; - QUrl url = next_item->StreamUrl(); + QUrl url = next_item->EffectiveUrl(); // Get the actual track URL rather than the stream URL. if (url_handlers_->CanHandle(url)) { @@ -961,20 +961,20 @@ void Player::TrackAboutToEnd() { case UrlHandler::LoadResult::Type::TrackAvailable: qLog(Debug) << "URL handler for" << result.media_url_ << "returned" << result.stream_url_; url = result.stream_url_; - Song song = next_item->Metadata(); + Song song = next_item->EffectiveMetadata(); song.set_stream_url(url); - next_item->SetTemporaryMetadata(song); + next_item->SetStreamMetadata(song); break; } } // Preloading any format while currently playing module music is broken in GStreamer. // See: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/769 - if (current_item_ && current_item_->Metadata().is_module_music()) { + if (current_item_ && current_item_->EffectiveMetadata().is_module_music()) { return; } - engine_->StartPreloading(next_item->Url(), url, next_item->Metadata().has_cue(), next_item->effective_beginning_nanosec(), next_item->effective_end_nanosec()); + engine_->StartPreloading(next_item->OriginalUrl(), url, next_item->EffectiveMetadata().has_cue(), next_item->effective_beginning_nanosec(), next_item->effective_end_nanosec()); } diff --git a/src/core/song.cpp b/src/core/song.cpp index 7f661529b..8ce562707 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -342,7 +342,7 @@ struct Song::Private : public QSharedData { QString artist_sortable_; QString albumartist_sortable_; - QUrl stream_url_; // Temporary stream url set by the URL handler. + QUrl stream_url_; // Temporary stream URL set by the URL handler. }; @@ -653,7 +653,7 @@ void Song::set_musicbrainz_disc_id(const TagLib::String &v) { d->musicbrainz_dis void Song::set_musicbrainz_release_group_id(const TagLib::String &v) { d->musicbrainz_release_group_id_ = TagLibStringToQString(v).remove(u' ').replace(u';', u'/'); } void Song::set_musicbrainz_work_id(const TagLib::String &v) { d->musicbrainz_work_id_ = TagLibStringToQString(v).remove(u' ').replace(u';', u'/'); } -const QUrl &Song::effective_stream_url() const { return !d->stream_url_.isEmpty() && d->stream_url_.isValid() ? d->stream_url_ : d->url_; } +const QUrl &Song::effective_url() const { return !d->stream_url_.isEmpty() && d->stream_url_.isValid() ? d->stream_url_ : d->url_; } const QString &Song::effective_albumartist() const { return d->albumartist_.isEmpty() ? d->artist_ : d->albumartist_; } const QString &Song::effective_albumartist_sortable() const { return d->albumartist_.isEmpty() ? d->artist_sortable_ : d->albumartist_sortable_; } const QString &Song::effective_album() const { return d->album_.isEmpty() ? d->title_ : d->album_; } @@ -923,39 +923,54 @@ bool Song::IsEditable() const { return d->valid_ && d->url_.isValid() && ((d->url_.isLocalFile() && write_tags_supported() && !has_cue()) || d->source_ == Source::Stream); } +bool Song::IsFileInfoEqual(const Song &other) const { + + return d->beginning_ == other.d->beginning_ && + d->end_ == other.d->end_ && + d->url_ == other.d->url_ && + d->basefilename_ == other.d->basefilename_ && + d->filetype_ == other.d->filetype_ && + d->filesize_ == other.d->filesize_ && + d->mtime_ == other.d->mtime_ && + d->ctime_ == other.d->ctime_ && + d->mtime_ == other.d->mtime_ && + d->stream_url_ == other.d->stream_url_; + +} + bool Song::IsMetadataEqual(const Song &other) const { return d->title_ == other.d->title_ && - d->album_ == other.d->album_ && - d->artist_ == other.d->artist_ && - d->albumartist_ == other.d->albumartist_ && - d->track_ == other.d->track_ && - d->disc_ == other.d->disc_ && - d->year_ == other.d->year_ && - d->originalyear_ == other.d->originalyear_ && - d->genre_ == other.d->genre_ && - d->compilation_ == other.d->compilation_ && - d->composer_ == other.d->composer_ && - d->performer_ == other.d->performer_ && - d->grouping_ == other.d->grouping_ && - d->comment_ == other.d->comment_ && - d->lyrics_ == other.d->lyrics_ && - d->artist_id_ == other.d->artist_id_ && - d->album_id_ == other.d->album_id_ && - d->song_id_ == other.d->song_id_ && - d->beginning_ == other.d->beginning_ && - length_nanosec() == other.length_nanosec() && - d->bitrate_ == other.d->bitrate_ && - d->samplerate_ == other.d->samplerate_ && - d->bitdepth_ == other.d->bitdepth_ && - d->cue_path_ == other.d->cue_path_; + d->album_ == other.d->album_ && + d->artist_ == other.d->artist_ && + d->albumartist_ == other.d->albumartist_ && + d->track_ == other.d->track_ && + d->disc_ == other.d->disc_ && + d->year_ == other.d->year_ && + d->originalyear_ == other.d->originalyear_ && + d->genre_ == other.d->genre_ && + d->compilation_ == other.d->compilation_ && + d->composer_ == other.d->composer_ && + d->performer_ == other.d->performer_ && + d->grouping_ == other.d->grouping_ && + d->comment_ == other.d->comment_ && + d->lyrics_ == other.d->lyrics_ && + d->artist_id_ == other.d->artist_id_ && + d->album_id_ == other.d->album_id_ && + d->song_id_ == other.d->song_id_ && + d->beginning_ == other.d->beginning_ && + length_nanosec() == other.length_nanosec() && + d->bitrate_ == other.d->bitrate_ && + d->samplerate_ == other.d->samplerate_ && + d->bitdepth_ == other.d->bitdepth_ && + d->cue_path_ == other.d->cue_path_; } bool Song::IsPlayStatisticsEqual(const Song &other) const { return d->playcount_ == other.d->playcount_ && - d->skipcount_ == other.d->skipcount_ && - d->lastplayed_ == other.d->lastplayed_; + d->skipcount_ == other.d->skipcount_ && + d->lastplayed_ == other.d->lastplayed_; } @@ -980,42 +995,70 @@ bool Song::IsAcoustIdEqual(const Song &other) const { bool Song::IsMusicBrainzEqual(const Song &other) const { return d->musicbrainz_album_artist_id_ == other.d->musicbrainz_album_artist_id_ && - d->musicbrainz_artist_id_ == other.d->musicbrainz_artist_id_ && - d->musicbrainz_original_artist_id_ == other.d->musicbrainz_original_artist_id_ && - d->musicbrainz_album_id_ == other.d->musicbrainz_album_id_ && - d->musicbrainz_original_album_id_ == other.d->musicbrainz_original_album_id_ && - d->musicbrainz_recording_id_ == other.d->musicbrainz_recording_id_ && - d->musicbrainz_track_id_ == other.d->musicbrainz_track_id_ && - d->musicbrainz_disc_id_ == other.d->musicbrainz_disc_id_ && - d->musicbrainz_release_group_id_ == other.d->musicbrainz_release_group_id_ && - d->musicbrainz_work_id_ == other.d->musicbrainz_work_id_; + d->musicbrainz_artist_id_ == other.d->musicbrainz_artist_id_ && + d->musicbrainz_original_artist_id_ == other.d->musicbrainz_original_artist_id_ && + d->musicbrainz_album_id_ == other.d->musicbrainz_album_id_ && + d->musicbrainz_original_album_id_ == other.d->musicbrainz_original_album_id_ && + d->musicbrainz_recording_id_ == other.d->musicbrainz_recording_id_ && + d->musicbrainz_track_id_ == other.d->musicbrainz_track_id_ && + d->musicbrainz_disc_id_ == other.d->musicbrainz_disc_id_ && + d->musicbrainz_release_group_id_ == other.d->musicbrainz_release_group_id_ && + d->musicbrainz_work_id_ == other.d->musicbrainz_work_id_; } bool Song::IsEBUR128Equal(const Song &other) const { return d->ebur128_integrated_loudness_lufs_ == other.d->ebur128_integrated_loudness_lufs_ && - d->ebur128_loudness_range_lu_ == other.d->ebur128_loudness_range_lu_; + d->ebur128_loudness_range_lu_ == other.d->ebur128_loudness_range_lu_; } bool Song::IsArtEqual(const Song &other) const { return d->art_embedded_ == other.d->art_embedded_ && - d->art_automatic_ == other.d->art_automatic_ && - d->art_manual_ == other.d->art_manual_ && - d->art_unset_ == other.d->art_unset_; + d->art_automatic_ == other.d->art_automatic_ && + d->art_manual_ == other.d->art_manual_ && + d->art_unset_ == other.d->art_unset_; + +} + +bool Song::IsCompilationEqual(const Song &other) const { + + return d->compilation_ == other.d->compilation_ && + d->compilation_detected_ == other.d->compilation_detected_ && + d->compilation_on_ == other.d->compilation_on_ && + d->compilation_off_ == other.d->compilation_off_; + +} + +bool Song::IsSettingsEqual(const Song &other) const { + + return d->source_ == other.d->source_ && + d->directory_id_ == other.d->directory_id_ && + d->unavailable_ == other.d->unavailable_; } bool Song::IsAllMetadataEqual(const Song &other) const { return IsMetadataEqual(other) && - IsPlayStatisticsEqual(other) && - IsRatingEqual(other) && - IsAcoustIdEqual(other) && - IsMusicBrainzEqual(other) && - IsArtEqual(other); + IsPlayStatisticsEqual(other) && + IsRatingEqual(other) && + IsAcoustIdEqual(other) && + IsMusicBrainzEqual(other) && + IsArtEqual(other) && + IsEBUR128Equal(other); + +} + +bool Song::IsEqual(const Song &other) const { + + return IsFileInfoEqual(other) && + IsSettingsEqual(other) && + IsAllMetadataEqual(other) && + IsFingerprintEqual(other) && + IsCompilationEqual(other); } @@ -1819,7 +1862,7 @@ void Song::ToXesam(QVariantMap *map) const { using mpris::AddMetadataAsList; using mpris::AsMPRISDateTimeType; - AddMetadata(u"xesam:url"_s, effective_stream_url().toString(), map); + AddMetadata(u"xesam:url"_s, effective_url().toString(), map); AddMetadata(u"xesam:title"_s, PrettyTitle(), map); AddMetadataAsList(u"xesam:artist"_s, artist(), map); AddMetadata(u"xesam:album"_s, album(), map); diff --git a/src/core/song.h b/src/core/song.h index 9c4e51c57..0a92128c4 100644 --- a/src/core/song.h +++ b/src/core/song.h @@ -365,7 +365,7 @@ class Song { void set_musicbrainz_release_group_id(const TagLib::String &v); void set_musicbrainz_work_id(const TagLib::String &v); - const QUrl &effective_stream_url() const; + const QUrl &effective_url() const; const QString &effective_albumartist() const; const QString &effective_albumartist_sortable() const; const QString &effective_album() const; @@ -430,6 +430,7 @@ class Song { bool IsEditable() const; // Comparison functions + bool IsFileInfoEqual(const Song &other) const; bool IsMetadataEqual(const Song &other) const; bool IsPlayStatisticsEqual(const Song &other) const; bool IsRatingEqual(const Song &other) const; @@ -438,7 +439,10 @@ class Song { bool IsMusicBrainzEqual(const Song &other) const; bool IsEBUR128Equal(const Song &other) const; bool IsArtEqual(const Song &other) const; + bool IsCompilationEqual(const Song &other) const; + bool IsSettingsEqual(const Song &other) const; bool IsAllMetadataEqual(const Song &other) const; + bool IsEqual(const Song &other) const; bool IsOnSameAlbum(const Song &other) const; bool IsSimilar(const Song &other) const; diff --git a/src/filterparser/filtertree.cpp b/src/filterparser/filtertree.cpp index 50f1bf1c5..1b6d4cfb4 100644 --- a/src/filterparser/filtertree.cpp +++ b/src/filterparser/filtertree.cpp @@ -51,7 +51,7 @@ QVariant FilterTree::DataFromColumn(const QString &column, const Song &metadata) if (column == "playcount"_L1) return metadata.playcount(); if (column == "skipcount"_L1) return metadata.skipcount(); if (column == "filename"_L1) return metadata.basefilename(); - if (column == "url"_L1) return metadata.effective_stream_url().toString(); + if (column == "url"_L1) return metadata.effective_url().toString(); return QVariant(); diff --git a/src/moodbar/moodbarcontroller.cpp b/src/moodbar/moodbarcontroller.cpp index e09fad077..8c22ea1b9 100644 --- a/src/moodbar/moodbarcontroller.cpp +++ b/src/moodbar/moodbarcontroller.cpp @@ -97,7 +97,7 @@ void MoodbarController::AsyncLoadComplete(MoodbarPipelinePtr pipeline, const QUr // Is this song still playing? PlaylistItemPtr current_item = player_->GetCurrentItem(); - if (current_item && current_item->Url() != url) { + if (current_item && current_item->OriginalUrl() != url) { return; } // Did we stop the song? diff --git a/src/moodbar/moodbaritemdelegate.cpp b/src/moodbar/moodbaritemdelegate.cpp index cd3438140..7543f4ed8 100644 --- a/src/moodbar/moodbaritemdelegate.cpp +++ b/src/moodbar/moodbaritemdelegate.cpp @@ -108,7 +108,7 @@ void MoodbarItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o QPixmap MoodbarItemDelegate::PixmapForIndex(const QModelIndex &idx, const QSize size) { // Pixmaps are keyed off URL. - const QUrl url = idx.sibling(idx.row(), static_cast(Playlist::Column::Filename)).data().toUrl(); + const QUrl url = idx.sibling(idx.row(), static_cast(Playlist::Column::URL)).data().toUrl(); const bool has_cue = idx.sibling(idx.row(), static_cast(Playlist::Column::HasCUE)).data().toBool(); Data *data = nullptr; @@ -294,7 +294,7 @@ void MoodbarItemDelegate::ImageLoaded(const QUrl &url, const QImage &image) { // Update all the indices with the new pixmap. for (const QPersistentModelIndex &idx : std::as_const(data->indexes_)) { - if (idx.isValid() && idx.sibling(idx.row(), static_cast(Playlist::Column::Filename)).data().toUrl() == url) { + if (idx.isValid() && idx.sibling(idx.row(), static_cast(Playlist::Column::URL)).data().toUrl() == url) { QModelIndex source_index = idx; if (idx.model() == filter) { source_index = filter->mapToSource(source_index); diff --git a/src/mpris2/mpris2.cpp b/src/mpris2/mpris2.cpp index cc5450769..d7b49c643 100644 --- a/src/mpris2/mpris2.cpp +++ b/src/mpris2/mpris2.cpp @@ -522,7 +522,7 @@ bool Mpris2::CanSeek() const { } bool Mpris2::CanSeek(EngineBase::State state) const { - return player_->GetCurrentItem() && state != EngineBase::State::Empty && !player_->GetCurrentItem()->Metadata().is_stream(); + return player_->GetCurrentItem() && state != EngineBase::State::Empty && !player_->GetCurrentItem()->EffectiveMetadata().is_stream(); } bool Mpris2::CanControl() const { return true; } @@ -586,7 +586,7 @@ void Mpris2::SetPosition(const QDBusObjectPath &trackId, qint64 offset) { if (CanSeek() && trackId == current_track_id(current_row) && offset >= 0) { offset *= kNsecPerUsec; - if (offset < player_->GetCurrentItem()->Metadata().length_nanosec()) { + if (offset < player_->GetCurrentItem()->EffectiveMetadata().length_nanosec()) { player_->SeekTo(offset / kNsecPerSec); } } diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp index cdaf8eccf..30cd6bd81 100644 --- a/src/playlist/playlist.cpp +++ b/src/playlist/playlist.cpp @@ -308,13 +308,13 @@ QVariant Playlist::data(const QModelIndex &idx, const int role) const { return queue_->PositionOf(idx); case Role_CanSetRating: - return static_cast(idx.column()) == Column::Rating && items_[idx.row()]->IsLocalCollectionItem() && items_[idx.row()]->Metadata().id() != -1; + return static_cast(idx.column()) == Column::Rating && items_[idx.row()]->IsLocalCollectionItem() && items_[idx.row()]->EffectiveMetadata().id() != -1; case Qt::EditRole: case Qt::ToolTipRole: case Qt::DisplayRole:{ const PlaylistItemPtr item = items_[idx.row()]; - const Song song = item->Metadata(); + const Song song = item->EffectiveMetadata(); // Don't forget to change Playlist::CompareItems when adding new columns switch (static_cast(idx.column())) { @@ -340,7 +340,7 @@ QVariant Playlist::data(const QModelIndex &idx, const int role) const { case Column::Bitdepth: return song.bitdepth(); case Column::Bitrate: return song.bitrate(); - case Column::Filename: return song.effective_stream_url(); + case Column::URL: return song.effective_url(); case Column::BaseFilename: return song.basefilename(); case Column::Filesize: return song.filesize(); case Column::Filetype: return QVariant::fromValue(song.filetype()); @@ -441,7 +441,7 @@ bool Playlist::setData(const QModelIndex &idx, const QVariant &value, const int }, Qt::QueuedConnection); } else if (song.is_radio()) { - item->SetMetadata(song); + item->SetOriginalMetadata(song); ScheduleSave(); } @@ -489,13 +489,13 @@ void Playlist::ItemReloadComplete(const QPersistentModelIndex &idx, const Song & if (idx.isValid()) { const PlaylistItemPtr item = item_at(idx.row()); if (item) { - ItemChanged(idx.row(), ChangedColumns(old_metadata, item->Metadata())); + RowDataChanged(idx.row(), ChangedColumns(old_metadata, item->EffectiveMetadata())); if (idx.row() == current_row()) { - if (MinorMetadataChange(old_metadata, item->Metadata())) { - Q_EMIT CurrentSongMetadataChanged(item->Metadata()); + if (MinorMetadataChange(old_metadata, item->EffectiveMetadata())) { + Q_EMIT CurrentSongMetadataChanged(item->EffectiveMetadata()); } else { - Q_EMIT CurrentSongChanged(item->Metadata()); + Q_EMIT CurrentSongChanged(item->EffectiveMetadata()); } } if (metadata_edit) { @@ -560,7 +560,7 @@ int Playlist::NextVirtualIndex(int i, const bool ignore_repeat_track) const { if (item_at(virtual_items_[j])->GetShouldSkip()) { continue; } - const Song this_song = item_at(virtual_items_[j])->Metadata(); + const Song this_song = item_at(virtual_items_[j])->EffectiveMetadata(); if (((last_song.is_compilation() && this_song.is_compilation()) || last_song.effective_albumartist() == this_song.effective_albumartist()) && last_song.album() == this_song.album() && @@ -600,7 +600,7 @@ int Playlist::PreviousVirtualIndex(int i, const bool ignore_repeat_track) const if (item_at(virtual_items_[j])->GetShouldSkip()) { continue; } - Song this_song = item_at(virtual_items_[j])->Metadata(); + Song this_song = item_at(virtual_items_[j])->EffectiveMetadata(); if (((last_song.is_compilation() && this_song.is_compilation()) || last_song.artist() == this_song.artist()) && last_song.album() == this_song.album() && FilterContainsVirtualIndex(j)) { return j; // Found one } @@ -687,7 +687,7 @@ void Playlist::set_current_row(const int i, const AutoScroll autoscroll, const b if (nextrow != -1 && nextrow != i) { PlaylistItemPtr next_item = item_at(nextrow); if (next_item) { - next_item->ClearTemporaryMetadata(); + next_item->ClearStreamMetadata(); Q_EMIT dataChanged(index(nextrow, 0), index(nextrow, ColumnCount - 1)); } } @@ -788,7 +788,7 @@ Qt::ItemFlags Playlist::flags(const QModelIndex &idx) const { if (idx.isValid()) { Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; - if (item_at(idx.row())->Metadata().IsEditable() && column_is_editable(static_cast(idx.column()))) flags |= Qt::ItemIsEditable; + if (item_at(idx.row())->EffectiveMetadata().IsEditable() && column_is_editable(static_cast(idx.column()))) flags |= Qt::ItemIsEditable; return flags; } @@ -1131,9 +1131,9 @@ void Playlist::InsertItemsWithoutUndo(const PlaylistItemPtrList &items, const in virtual_items_ << static_cast(virtual_items_.count()); if (Song::IsLinkedCollectionSource(item->source())) { - const int id = item->Metadata().id(); + const int id = item->EffectiveMetadata().id(); if (id != -1) { - collection_items_[item->Metadata().source_id()].insert(id, item); + collection_items_[item->EffectiveMetadata().source_id()].insert(id, item); } } @@ -1235,7 +1235,7 @@ void Playlist::UpdateItems(SongList songs) { while (it.hasNext()) { const Song &song = it.next(); const PlaylistItemPtr item = items_.value(i); - if (item->Metadata().url() == song.url() && (item->Metadata().filetype() == Song::FileType::Unknown || item->Metadata().filetype() == Song::FileType::Stream || item->Metadata().filetype() == Song::FileType::CDDA || !item->Metadata().init_from_file())) { + if (item->EffectiveMetadata().url() == song.url() && (item->EffectiveMetadata().filetype() == Song::FileType::Unknown || item->EffectiveMetadata().filetype() == Song::FileType::Stream || item->EffectiveMetadata().filetype() == Song::FileType::CDDA || !item->EffectiveMetadata().init_from_file())) { PlaylistItemPtr new_item; if (song.is_linked_collection_song()) { new_item = make_shared(song); @@ -1290,7 +1290,7 @@ QMimeData *Playlist::mimeData(const QModelIndexList &indexes) const { for (const QModelIndex &idx : indexes) { if (idx.column() != first_column) continue; - urls << items_[idx.row()]->Url(); + urls << items_[idx.row()]->OriginalUrl(); rows << idx.row(); } @@ -1321,8 +1321,8 @@ bool Playlist::CompareItems(const Column column, const Qt::SortOrder order, Play PlaylistItemPtr a = order == Qt::AscendingOrder ? _a : _b; PlaylistItemPtr b = order == Qt::AscendingOrder ? _b : _a; -#define cmp(field) return a->Metadata().field() < b->Metadata().field() -#define strcmp(field) return QString::localeAwareCompare(a->Metadata().field().toLower(), b->Metadata().field().toLower()) < 0; +#define cmp(field) return a->EffectiveMetadata().field() < b->EffectiveMetadata().field() +#define strcmp(field) return QString::localeAwareCompare(a->EffectiveMetadata().field().toLower(), b->EffectiveMetadata().field().toLower()) < 0; switch (column) { case Column::Title: strcmp(title_sortable); @@ -1346,8 +1346,8 @@ bool Playlist::CompareItems(const Column column, const Qt::SortOrder order, Play case Column::Bitrate: cmp(bitrate); case Column::Samplerate: cmp(samplerate); case Column::Bitdepth: cmp(bitdepth); - case Column::Filename: - return QString::localeAwareCompare(a->Url().path(), b->Url().path()) < 0; + case Column::URL: + return QString::localeAwareCompare(a->OriginalUrl().path(), b->OriginalUrl().path()) < 0; case Column::BaseFilename: cmp(basefilename); case Column::Filesize: cmp(filesize); case Column::Filetype: cmp(filetype); @@ -1401,7 +1401,7 @@ QString Playlist::column_name(const Column column) { case Column::Bitdepth: return tr("Bit Depth"); case Column::Bitrate: return tr("Bitrate"); - case Column::Filename: return tr("File Name"); + case Column::URL: return tr("URL"); case Column::BaseFilename: return tr("File Name (without path)"); case Column::Filesize: return tr("File Size"); case Column::Filetype: return tr("File Type"); @@ -1595,7 +1595,7 @@ void Playlist::ItemsLoaded() { while (it.hasNext()) { PlaylistItemPtr item = it.next(); - if (item->IsLocalCollectionItem() && item->Metadata().url().isEmpty()) { + if (item->IsLocalCollectionItem() && item->EffectiveMetadata().url().isEmpty()) { it.remove(); } } @@ -1727,8 +1727,8 @@ PlaylistItemPtrList Playlist::RemoveItemsWithoutUndo(const int row, const int co for (int i = 0; i < count; ++i) { PlaylistItemPtr item(items_.takeAt(row)); items << item; - const int id = item->Metadata().id(); - const int source_id = item->Metadata().source_id(); + const int id = item->EffectiveMetadata().id(); + const int source_id = item->EffectiveMetadata().source_id(); if (id != -1 && collection_items_[source_id].contains(id, item)) { collection_items_[source_id].remove(id, item); } @@ -1792,11 +1792,11 @@ void Playlist::ClearStreamMetadata() { if (!current_item() || !current_item_index_.isValid()) return; - const Song old_metadata = current_item()->Metadata(); - current_item()->ClearTemporaryMetadata(); - const Song &new_metadata = current_item()->Metadata(); + const Song old_metadata = current_item()->EffectiveMetadata(); + current_item()->ClearStreamMetadata(); + const Song &new_metadata = current_item()->EffectiveMetadata(); - ItemChanged(current_row(), ChangedColumns(old_metadata, new_metadata)); + RowDataChanged(current_row(), ChangedColumns(old_metadata, new_metadata)); if (old_metadata.length_nanosec() != new_metadata.length_nanosec()) { UpdateScrobblePoint(); @@ -1832,7 +1832,7 @@ PlaylistItem::Options Playlist::current_item_options() const { Song Playlist::current_item_metadata() const { if (!current_item()) return Song(); - return current_item()->Metadata(); + return current_item()->EffectiveMetadata(); } void Playlist::Clear() { @@ -1910,7 +1910,7 @@ void Playlist::ReloadItems(const QList &rows) { const PlaylistItemPtr item = item_at(row); const QPersistentModelIndex idx = index(row, 0); if (idx.isValid()) { - ItemReload(idx, item->Metadata(), false); + ItemReload(idx, item->EffectiveMetadata(), false); } } @@ -1981,7 +1981,7 @@ void Playlist::ReshuffleIndices() { // Find all the unique albums in the playlist for (QList::const_iterator it = virtual_items_.constBegin(); it != virtual_items_.constEnd(); ++it) { const int index = *it; - const QString key = items_[index]->Metadata().AlbumKey(); + const QString key = items_[index]->EffectiveMetadata().AlbumKey(); album_keys[index] = key; album_key_set << key; } @@ -1993,7 +1993,7 @@ void Playlist::ReshuffleIndices() { // If the user is currently playing a song, force its album to be first if (current_row() != -1) { - const QString key = items_[current_row()]->Metadata().AlbumKey(); + const QString key = items_[current_row()]->EffectiveMetadata().AlbumKey(); const qint64 pos = shuffled_album_keys.indexOf(key); if (pos >= 1) { std::swap(shuffled_album_keys[0], shuffled_album_keys[pos]); @@ -2039,7 +2039,7 @@ SongList Playlist::GetAllSongs() const { SongList songs; songs.reserve(items_.count()); for (PlaylistItemPtr item : items_) { // clazy:exclude=range-loop-reference - songs << item->Metadata(); + songs << item->EffectiveMetadata(); } return songs; @@ -2051,7 +2051,7 @@ quint64 Playlist::GetTotalLength() const { quint64 total_length = 0; for (PlaylistItemPtr item : items_) { // clazy:exclude=range-loop-reference - qint64 length = item->Metadata().length_nanosec(); + qint64 length = item->EffectiveMetadata().length_nanosec(); if (length > 0) total_length += length; } @@ -2151,8 +2151,9 @@ Playlist::Columns Playlist::ChangedColumns(const Song &metadata1, const Song &me if (metadata1.bitrate() != metadata2.bitrate()) { columns << Column::Bitrate; } - if (metadata1.url() != metadata2.url()) { - columns << Column::Filename; + if (metadata1.effective_url() != metadata2.effective_url()) { + qLog(Debug) << "URL is changed for" << metadata1.PrettyTitleWithArtist(); + columns << Column::URL; columns << Column::BaseFilename; } if (metadata1.filesize() != metadata2.filesize()) { @@ -2211,36 +2212,38 @@ bool Playlist::MinorMetadataChange(const Song &old_metadata, const Song &new_met } -void Playlist::UpdateItemMetadata(PlaylistItemPtr item, const Song &new_metadata, const bool temporary) { +void Playlist::UpdateItemMetadata(PlaylistItemPtr item, const Song &new_metadata, const bool stream_metadata_update) { if (!items_.contains(item)) { return; } for (int row = static_cast(items_.indexOf(item, 0)); row != -1; row = static_cast(items_.indexOf(item, row + 1))) { - UpdateItemMetadata(row, item, new_metadata, temporary); + UpdateItemMetadata(row, item, new_metadata, stream_metadata_update); } } -void Playlist::UpdateItemMetadata(const int row, PlaylistItemPtr item, const Song &new_metadata, const bool temporary) { +void Playlist::UpdateItemMetadata(const int row, PlaylistItemPtr item, const Song &new_metadata, const bool stream_metadata_update) { - const Song old_metadata = item->Metadata(); + if (new_metadata.IsEqual(stream_metadata_update ? item->EffectiveMetadata() : item->OriginalMetadata())) return; - const Columns columns = ChangedColumns(old_metadata, new_metadata); - if (columns.isEmpty()) return; + const Song old_metadata = item->EffectiveMetadata(); + const Columns changed_columns = ChangedColumns(old_metadata, new_metadata); - if (temporary) { - item->SetTemporaryMetadata(new_metadata); + if (stream_metadata_update) { + item->SetStreamMetadata(new_metadata); } else { - item->SetMetadata(new_metadata); - if (item->HasTemporaryMetadata()) { - item->UpdateTemporaryMetadata(new_metadata); + item->SetOriginalMetadata(new_metadata); + if (item->HasStreamMetadata()) { + item->UpdateStreamMetadata(new_metadata); } } - ItemChanged(row, columns); + if (!changed_columns.isEmpty()) { + RowDataChanged(row, changed_columns); + } if (row == current_row()) { InformOfCurrentSongChange(MinorMetadataChange(old_metadata, new_metadata)); @@ -2251,7 +2254,7 @@ void Playlist::UpdateItemMetadata(const int row, PlaylistItemPtr item, const Son } -void Playlist::ItemChanged(const int row, const Columns &columns) { +void Playlist::RowDataChanged(const int row, const Columns &columns) { if (columns.count() > 5) { const QModelIndex idx_column_first = index(row, 0); @@ -2293,7 +2296,7 @@ void Playlist::InvalidateDeletedSongs() { for (int row = 0; row < items_.count(); ++row) { PlaylistItemPtr item = items_.value(row); - const Song song = item->Metadata(); + const Song song = item->EffectiveMetadata(); if (song.url().isValid() && song.url().isLocalFile()) { const bool exists = QFile::exists(song.url().toLocalFile()); @@ -2322,7 +2325,7 @@ void Playlist::RemoveDeletedSongs() { for (int row = 0; row < items_.count(); ++row) { const PlaylistItemPtr item = items_.value(row); - const Song song = item->Metadata(); + const Song song = item->EffectiveMetadata(); if (song.url().isLocalFile() && !QFile::exists(song.url().toLocalFile())) { rows_to_remove.append(row); // clazy:exclude=reserve-candidates @@ -2356,7 +2359,7 @@ void Playlist::RemoveDuplicateSongs() { for (int row = 0; row < items_.count(); ++row) { const PlaylistItemPtr item = items_.value(row); - const Song &song = item->Metadata(); + const Song &song = item->EffectiveMetadata(); bool found_duplicate = false; @@ -2389,7 +2392,7 @@ void Playlist::RemoveUnavailableSongs() { QList rows_to_remove; for (int row = 0; row < items_.count(); ++row) { const PlaylistItemPtr item = items_.value(row); - const Song &song = item->Metadata(); + const Song &song = item->EffectiveMetadata(); // Check only local files if (song.url().isLocalFile() && !QFile::exists(song.url().toLocalFile())) { @@ -2406,7 +2409,7 @@ bool Playlist::ApplyValidityOnCurrentSong(const QUrl &url, const bool valid) { const PlaylistItemPtr current = current_item(); if (current) { - const Song current_song = current->Metadata(); + const Song current_song = current->EffectiveMetadata(); // If validity has changed, reload the item if (current_song.source() == Song::Source::LocalFile || current_song.source() == Song::Source::Collection) { @@ -2472,7 +2475,7 @@ void Playlist::AlbumCoverLoaded(const Song &song, const AlbumCoverLoaderResult & // Update art_manual for local songs that are not in the collection. if (((result.type == AlbumCoverLoaderResult::Type::Manual && result.album_cover.cover_url.isLocalFile()) || result.type == AlbumCoverLoaderResult::Type::Unset) && (song.source() == Song::Source::LocalFile || song.source() == Song::Source::CDDA || song.source() == Song::Source::Device)) { PlaylistItemPtr item = current_item(); - if (item && item->Metadata() == song && (!item->Metadata().art_manual_is_valid() || (result.type == AlbumCoverLoaderResult::Type::Unset && !item->Metadata().art_unset()))) { + if (item && item->EffectiveMetadata() == song && (!item->EffectiveMetadata().art_manual_is_valid() || (result.type == AlbumCoverLoaderResult::Type::Unset && !item->EffectiveMetadata().art_unset()))) { qLog(Debug) << "Updating art manual for local song" << song.title() << song.album() << song.title() << "to" << result.album_cover.cover_url << "in playlist."; item->SetArtManual(result.album_cover.cover_url); ScheduleSaveAsync(); @@ -2503,8 +2506,8 @@ void Playlist::RateSong(const QModelIndex &idx, const float rating) { if (has_item_at(idx.row())) { const PlaylistItemPtr item = item_at(idx.row()); - if (item && item->IsLocalCollectionItem() && item->Metadata().id() != -1) { - collection_backend_->UpdateSongRatingAsync(item->Metadata().id(), rating); + if (item && item->IsLocalCollectionItem() && item->EffectiveMetadata().id() != -1) { + collection_backend_->UpdateSongRatingAsync(item->EffectiveMetadata().id(), rating); } } @@ -2517,8 +2520,8 @@ void Playlist::RateSongs(const QModelIndexList &index_list, const float rating) const int row = idx.row(); if (has_item_at(row)) { const PlaylistItemPtr item = item_at(row); - if (item && item->IsLocalCollectionItem() && item->Metadata().id() != -1) { - id_list << item->Metadata().id(); // clazy:exclude=reserve-candidates + if (item && item->IsLocalCollectionItem() && item->EffectiveMetadata().id() != -1) { + id_list << item->EffectiveMetadata().id(); // clazy:exclude=reserve-candidates } } } diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h index c02b4be6e..7b1e1cc48 100644 --- a/src/playlist/playlist.h +++ b/src/playlist/playlist.h @@ -115,7 +115,7 @@ class Playlist : public QAbstractListModel { Samplerate, Bitdepth, Bitrate, - Filename, + URL, BaseFilename, Filesize, Filetype, @@ -268,9 +268,9 @@ class Playlist : public QAbstractListModel { static Columns ChangedColumns(const Song &metadata1, const Song &metadata2); static bool MinorMetadataChange(const Song &old_metadata, const Song &new_metadata); - void UpdateItemMetadata(PlaylistItemPtr item, const Song &new_metadata, const bool temporary); - void UpdateItemMetadata(const int row, PlaylistItemPtr item, const Song &new_metadata, const bool temporary); - void ItemChanged(const int row, const Columns &columns); + void UpdateItemMetadata(PlaylistItemPtr item, const Song &new_metadata, const bool stream_metadata_update); + void UpdateItemMetadata(const int row, PlaylistItemPtr item, const Song &new_metadata, const bool stream_metadata_update); + void RowDataChanged(const int row, const Columns &columns); // Changes rating of a song to the given value asynchronously void RateSong(const QModelIndex &idx, const float rating); diff --git a/src/playlist/playlistbackend.cpp b/src/playlist/playlistbackend.cpp index 69419df59..4417d3cb3 100644 --- a/src/playlist/playlistbackend.cpp +++ b/src/playlist/playlistbackend.cpp @@ -273,7 +273,7 @@ PlaylistItemPtr PlaylistBackend::NewPlaylistItemFromQuery(const SqlRow &row, Sha Song PlaylistBackend::NewSongFromQuery(const SqlRow &row, SharedPtr state) { - return NewPlaylistItemFromQuery(row, state)->Metadata(); + return NewPlaylistItemFromQuery(row, state)->EffectiveMetadata(); } @@ -286,7 +286,7 @@ PlaylistItemPtr PlaylistBackend::RestoreCueData(PlaylistItemPtr item, SharedPtr< CueParser cue_parser(tagreader_client_, collection_backend_); - Song song = item->Metadata(); + Song song = item->EffectiveMetadata(); // We're only interested in .cue songs here if (!song.has_cue()) return item; diff --git a/src/playlist/playlistfilter.cpp b/src/playlist/playlistfilter.cpp index 0b579aa0d..8c3b194d0 100644 --- a/src/playlist/playlistfilter.cpp +++ b/src/playlist/playlistfilter.cpp @@ -64,7 +64,7 @@ bool PlaylistFilter::filterAcceptsRow(const int source_row, const QModelIndex &s query_hash_ = hash; } - return filter_tree_->accept(item->Metadata()); + return filter_tree_->accept(item->EffectiveMetadata()); } diff --git a/src/playlist/playlistitem.cpp b/src/playlist/playlistitem.cpp index 33838a3d0..928f560e0 100644 --- a/src/playlist/playlistitem.cpp +++ b/src/playlist/playlistitem.cpp @@ -93,6 +93,28 @@ PlaylistItemPtr PlaylistItem::NewFromSong(const Song &song) { } +void PlaylistItem::SetStreamMetadata(const Song &song) { + stream_song_ = song; +} + +void PlaylistItem::UpdateStreamMetadata(const Song &song) { + + if (!stream_song_.is_valid()) return; + + const Song old_stream_song = stream_song_; + stream_song_ = song; + + // Keep samplerate, bitdepth and bitrate from the old metadata if it's not present in the new. + if (stream_song_.samplerate() <= 0 && old_stream_song.samplerate() > 0) stream_song_.set_samplerate(old_stream_song.samplerate()); + if (stream_song_.bitdepth() <= 0 && old_stream_song.bitdepth() > 0) stream_song_.set_bitdepth(old_stream_song.bitdepth()); + if (stream_song_.bitrate() <= 0 && old_stream_song.bitrate() > 0) stream_song_.set_bitrate(old_stream_song.bitrate()); + +} + +void PlaylistItem::ClearStreamMetadata() { + stream_song_ = Song(); +} + void PlaylistItem::BindToQuery(SqlQuery *query) const { query->BindValue(u":type"_s, static_cast(source_)); @@ -102,28 +124,6 @@ void PlaylistItem::BindToQuery(SqlQuery *query) const { } -void PlaylistItem::SetTemporaryMetadata(const Song &metadata) { - temp_metadata_ = metadata; -} - -void PlaylistItem::UpdateTemporaryMetadata(const Song &metadata) { - - if (!temp_metadata_.is_valid()) return; - - const Song old_metadata = temp_metadata_; - temp_metadata_ = metadata; - - // Keep samplerate, bitdepth and bitrate from the old metadata if it's not present in the new. - if (temp_metadata_.samplerate() <= 0 && old_metadata.samplerate() > 0) temp_metadata_.set_samplerate(old_metadata.samplerate()); - if (temp_metadata_.bitdepth() <= 0 && old_metadata.bitdepth() > 0) temp_metadata_.set_bitdepth(old_metadata.bitdepth()); - if (temp_metadata_.bitrate() <= 0 && old_metadata.bitrate() > 0) temp_metadata_.set_bitrate(old_metadata.bitrate()); - -} - -void PlaylistItem::ClearTemporaryMetadata() { - temp_metadata_ = Song(); -} - static void ReloadPlaylistItem(PlaylistItemPtr item) { item->Reload(); } @@ -135,12 +135,15 @@ QFuture PlaylistItem::BackgroundReload() { void PlaylistItem::SetBackgroundColor(short priority, const QColor &color) { background_colors_[priority] = color; } + bool PlaylistItem::HasBackgroundColor(short priority) const { return background_colors_.contains(priority); } + void PlaylistItem::RemoveBackgroundColor(short priority) { background_colors_.remove(priority); } + QColor PlaylistItem::GetCurrentBackgroundColor() const { if (background_colors_.isEmpty()) { @@ -151,6 +154,7 @@ QColor PlaylistItem::GetCurrentBackgroundColor() const { return background_colors_[background_colors_keys.last()]; } + bool PlaylistItem::HasCurrentBackgroundColor() const { return !background_colors_.isEmpty(); } @@ -158,12 +162,15 @@ bool PlaylistItem::HasCurrentBackgroundColor() const { void PlaylistItem::SetForegroundColor(const short priority, const QColor &color) { foreground_colors_[priority] = color; } + bool PlaylistItem::HasForegroundColor(const short priority) const { return foreground_colors_.contains(priority); } + void PlaylistItem::RemoveForegroundColor(const short priority) { foreground_colors_.remove(priority); } + QColor PlaylistItem::GetCurrentForegroundColor() const { if (foreground_colors_.isEmpty()) return QColor(); @@ -172,8 +179,11 @@ QColor PlaylistItem::GetCurrentForegroundColor() const { return foreground_colors_[foreground_colors_keys.last()]; } + bool PlaylistItem::HasCurrentForegroundColor() const { return !foreground_colors_.isEmpty(); } + void PlaylistItem::SetShouldSkip(const bool should_skip) { should_skip_ = should_skip; } + bool PlaylistItem::GetShouldSkip() const { return should_skip_; } diff --git a/src/playlist/playlistitem.h b/src/playlist/playlistitem.h index cca7fcb04..3a4b59d2a 100644 --- a/src/playlist/playlistitem.h +++ b/src/playlist/playlistitem.h @@ -66,37 +66,31 @@ class PlaylistItem : public enable_shared_from_this { Q_DECLARE_FLAGS(Options, Option) virtual Song::Source source() const { return source_; } - virtual Options options() const { return Option::Default; } - virtual QList actions() { return QList(); } + virtual Song OriginalMetadata() const = 0; + virtual QUrl OriginalUrl() const = 0; + virtual void SetOriginalMetadata(const Song &song) { Q_UNUSED(song); } + + Song EffectiveMetadata() const { return HasStreamMetadata() ? stream_song_ : OriginalMetadata(); } + QUrl EffectiveUrl() const { return stream_song_.effective_url().isValid() ? stream_song_.effective_url() : OriginalUrl(); } + + void SetStreamMetadata(const Song &song); + void UpdateStreamMetadata(const Song &song); + void ClearStreamMetadata(); + bool HasStreamMetadata() const { return stream_song_.is_valid(); } + + qint64 effective_beginning_nanosec() const { return stream_song_.is_valid() && stream_song_.beginning_nanosec() != -1 ? stream_song_.beginning_nanosec() : OriginalMetadata().beginning_nanosec(); } + qint64 effective_end_nanosec() const { return stream_song_.is_valid() && stream_song_.end_nanosec() != -1 ? stream_song_.end_nanosec() : OriginalMetadata().end_nanosec(); } + + virtual void SetArtManual(const QUrl &cover_url) = 0; + virtual bool InitFromQuery(const SqlRow &query) = 0; void BindToQuery(SqlQuery *query) const; virtual void Reload() {} QFuture BackgroundReload(); - virtual Song Metadata() const = 0; - virtual Song OriginalMetadata() const = 0; - virtual QUrl Url() const = 0; - - virtual void SetMetadata(const Song &song) { Q_UNUSED(song); } - - void SetTemporaryMetadata(const Song &metadata); - void UpdateTemporaryMetadata(const Song &metadata); - void ClearTemporaryMetadata(); - bool HasTemporaryMetadata() const { return temp_metadata_.is_valid(); } - - Song StreamMetadata() { return HasTemporaryMetadata() ? temp_metadata_ : Metadata(); } - QUrl StreamUrl() const { return HasTemporaryMetadata() && temp_metadata_.effective_stream_url().isValid() ? temp_metadata_.effective_stream_url() : Url(); } - - std::optional effective_ebur128_integrated_loudness_lufs() const { return HasTemporaryMetadata() && temp_metadata_.is_valid() ? temp_metadata_.ebur128_integrated_loudness_lufs() : Metadata().ebur128_integrated_loudness_lufs(); } - - qint64 effective_beginning_nanosec() const { return HasTemporaryMetadata() && temp_metadata_.is_valid() && temp_metadata_.beginning_nanosec() != -1 ? temp_metadata_.beginning_nanosec() : Metadata().beginning_nanosec(); } - qint64 effective_end_nanosec() const { return HasTemporaryMetadata() && temp_metadata_.is_valid() && temp_metadata_.end_nanosec() != -1 ? temp_metadata_.end_nanosec() : Metadata().end_nanosec(); } - - virtual void SetArtManual(const QUrl &cover_url) = 0; - // Background colors. void SetBackgroundColor(const short priority, const QColor &color); bool HasBackgroundColor(const short priority) const; @@ -128,7 +122,7 @@ class PlaylistItem : public enable_shared_from_this { virtual Song DatabaseSongMetadata() const { return Song(); } Song::Source source_; - Song temp_metadata_; + Song stream_song_; QMap background_colors_; QMap foreground_colors_; diff --git a/src/playlist/playlistmanager.cpp b/src/playlist/playlistmanager.cpp index 202fce24f..aa8c4b520 100644 --- a/src/playlist/playlistmanager.cpp +++ b/src/playlist/playlistmanager.cpp @@ -478,7 +478,7 @@ void PlaylistManager::UpdateCollectionSongs(const SongList &songs) { for (const Data &data : std::as_const(playlists_)) { const PlaylistItemPtrList items = data.p->collection_items(song.source(), song.id()); for (PlaylistItemPtr item : items) { - if (item->Metadata().directory_id() != song.directory_id()) continue; + if (item->EffectiveMetadata().directory_id() != song.directory_id()) continue; data.p->UpdateItemMetadata(item, song, false); } } diff --git a/src/playlist/playlistundocommandinsertitems.cpp b/src/playlist/playlistundocommandinsertitems.cpp index df7d75534..71b184e28 100644 --- a/src/playlist/playlistundocommandinsertitems.cpp +++ b/src/playlist/playlistundocommandinsertitems.cpp @@ -48,7 +48,7 @@ bool PlaylistUndoCommandInsertItems::UpdateItem(const PlaylistItemPtr &updated_i for (int i = 0; i < items_.size(); i++) { PlaylistItemPtr item = items_.value(i); - if (item->Metadata().url() == updated_item->Metadata().url()) { + if (item->EffectiveMetadata().url() == updated_item->EffectiveMetadata().url()) { items_[i] = updated_item; return true; } diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp index ff951269a..eb202bc1e 100644 --- a/src/playlist/playlistview.cpp +++ b/src/playlist/playlistview.cpp @@ -234,7 +234,7 @@ void PlaylistView::SetItemDelegates() { setItemDelegateForColumn(static_cast(Playlist::Column::Bitdepth), new PlaylistDelegateBase(this, tr("Bit"))); setItemDelegateForColumn(static_cast(Playlist::Column::Bitrate), new PlaylistDelegateBase(this, tr("kbps"))); - setItemDelegateForColumn(static_cast(Playlist::Column::Filename), new NativeSeparatorsDelegate(this)); + setItemDelegateForColumn(static_cast(Playlist::Column::URL), new NativeSeparatorsDelegate(this)); setItemDelegateForColumn(static_cast(Playlist::Column::LastPlayed), new LastPlayedItemDelegate(this)); setItemDelegateForColumn(static_cast(Playlist::Column::Source), new SongSourceDelegate(this)); @@ -354,7 +354,7 @@ void PlaylistView::RestoreHeaderState() { header_->HideSection(static_cast(Playlist::Column::OriginalYear)); header_->HideSection(static_cast(Playlist::Column::Disc)); header_->HideSection(static_cast(Playlist::Column::Genre)); - header_->HideSection(static_cast(Playlist::Column::Filename)); + header_->HideSection(static_cast(Playlist::Column::URL)); header_->HideSection(static_cast(Playlist::Column::BaseFilename)); header_->HideSection(static_cast(Playlist::Column::Filesize)); header_->HideSection(static_cast(Playlist::Column::DateCreated)); @@ -1406,7 +1406,7 @@ void PlaylistView::CopyCurrentSongToClipboard() const { } // Get the song's URL - const QUrl url = model()->data(currentIndex().sibling(currentIndex().row(), static_cast(Playlist::Column::Filename))).toUrl(); + const QUrl url = model()->data(currentIndex().sibling(currentIndex().row(), static_cast(Playlist::Column::URL))).toUrl(); QMimeData *mime_data = new QMimeData; mime_data->setUrls(QList() << url); diff --git a/src/playlist/songplaylistitem.cpp b/src/playlist/songplaylistitem.cpp index 9287870ac..c169e51b9 100644 --- a/src/playlist/songplaylistitem.cpp +++ b/src/playlist/songplaylistitem.cpp @@ -38,8 +38,6 @@ bool SongPlaylistItem::InitFromQuery(const SqlRow &query) { return true; } -QUrl SongPlaylistItem::Url() const { return song_.url(); } - void SongPlaylistItem::Reload() { if (!song_.url().isLocalFile()) return; @@ -49,18 +47,13 @@ void SongPlaylistItem::Reload() { qLog(Error) << "Could not reload file" << song_.url() << result.error_string(); } - UpdateTemporaryMetadata(song_); + UpdateStreamMetadata(song_); } -Song SongPlaylistItem::Metadata() const { - if (HasTemporaryMetadata()) return temp_metadata_; - return song_; -} - void SongPlaylistItem::SetArtManual(const QUrl &cover_url) { song_.set_art_manual(cover_url); - if (HasTemporaryMetadata()) temp_metadata_.set_art_manual(cover_url); + if (HasStreamMetadata()) stream_song_.set_art_manual(cover_url); } diff --git a/src/playlist/songplaylistitem.h b/src/playlist/songplaylistitem.h index 02d20771c..0d3b119cc 100644 --- a/src/playlist/songplaylistitem.h +++ b/src/playlist/songplaylistitem.h @@ -40,10 +40,8 @@ class SongPlaylistItem : public PlaylistItem { bool InitFromQuery(const SqlRow &query) override; void Reload() override; - Song Metadata() const override; Song OriginalMetadata() const override { return song_; } - - QUrl Url() const override; + QUrl OriginalUrl() const override { return song_.url(); } void SetArtManual(const QUrl &cover_url) override; diff --git a/src/playlist/streamplaylistitem.cpp b/src/playlist/streamplaylistitem.cpp index dc619741e..b63002e9b 100644 --- a/src/playlist/streamplaylistitem.cpp +++ b/src/playlist/streamplaylistitem.cpp @@ -36,6 +36,15 @@ StreamPlaylistItem::StreamPlaylistItem(const Song &song) InitMetadata(); } +void StreamPlaylistItem::InitMetadata() { + + if (song_.title().isEmpty()) song_.set_title(song_.url().toString()); + if (song_.source() == Song::Source::Unknown) song_.set_source(Song::Source::Stream); + if (song_.filetype() == Song::FileType::Unknown) song_.set_filetype(Song::FileType::Stream); + song_.set_valid(true); + +} + bool StreamPlaylistItem::InitFromQuery(const SqlRow &query) { song_.InitFromQuery(query, false, static_cast(Song::kRowIdColumns.count())); @@ -48,27 +57,9 @@ QVariant StreamPlaylistItem::DatabaseValue(const DatabaseColumn column) const { return PlaylistItem::DatabaseValue(column); } -void StreamPlaylistItem::InitMetadata() { - - if (song_.title().isEmpty()) song_.set_title(song_.url().toString()); - if (song_.source() == Song::Source::Unknown) song_.set_source(Song::Source::Stream); - if (song_.filetype() == Song::FileType::Unknown) song_.set_filetype(Song::FileType::Stream); - song_.set_valid(true); - -} - -Song StreamPlaylistItem::Metadata() const { - - if (HasTemporaryMetadata()) return temp_metadata_; - return song_; - -} - -QUrl StreamPlaylistItem::Url() const { return song_.url(); } - void StreamPlaylistItem::SetArtManual(const QUrl &cover_url) { song_.set_art_manual(cover_url); - temp_metadata_.set_art_manual(cover_url); + stream_song_.set_art_manual(cover_url); } diff --git a/src/playlist/streamplaylistitem.h b/src/playlist/streamplaylistitem.h index 0e7c6ce23..26ff395ab 100644 --- a/src/playlist/streamplaylistitem.h +++ b/src/playlist/streamplaylistitem.h @@ -33,12 +33,10 @@ class StreamPlaylistItem : public PlaylistItem { explicit StreamPlaylistItem(const Song::Source source); explicit StreamPlaylistItem(const Song &song); - bool InitFromQuery(const SqlRow &query) override; - Song Metadata() const override; Song OriginalMetadata() const override { return song_; } - QUrl Url() const override; - - void SetMetadata(const Song &song) override { song_ = song; } + QUrl OriginalUrl() const override { return song_.url(); } + void SetOriginalMetadata(const Song &song) override { song_ = song; } + bool InitFromQuery(const SqlRow &query) override; void SetArtManual(const QUrl &cover_url) override; protected: diff --git a/src/queue/queue.cpp b/src/queue/queue.cpp index 4fc170a18..9fbd4361e 100644 --- a/src/queue/queue.cpp +++ b/src/queue/queue.cpp @@ -241,7 +241,7 @@ void Queue::UpdateTotalLength() { Q_ASSERT(playlist_->has_item_at(id)); - const qint64 length = playlist_->item_at(id)->Metadata().length_nanosec(); + const qint64 length = playlist_->item_at(id)->EffectiveMetadata().length_nanosec(); if (length > 0) total += static_cast(length); } diff --git a/src/smartplaylists/smartplaylistsearchterm.cpp b/src/smartplaylists/smartplaylistsearchterm.cpp index 99fe54552..12dd16f56 100644 --- a/src/smartplaylists/smartplaylistsearchterm.cpp +++ b/src/smartplaylists/smartplaylistsearchterm.cpp @@ -392,7 +392,7 @@ QString SmartPlaylistSearchTerm::FieldName(const Field field) { case Field::Length: return Playlist::column_name(Playlist::Column::Length); case Field::Filepath: - return Playlist::column_name(Playlist::Column::Filename); + return Playlist::column_name(Playlist::Column::URL); case Field::Filetype: return Playlist::column_name(Playlist::Column::Filetype); case Field::Filesize: diff --git a/tests/src/mock_playlistitem.h b/tests/src/mock_playlistitem.h index 4f2e8f3bf..d95589fbd 100644 --- a/tests/src/mock_playlistitem.h +++ b/tests/src/mock_playlistitem.h @@ -36,16 +36,14 @@ class MockPlaylistItem : public PlaylistItem { public: MockPlaylistItem(); MOCK_CONST_METHOD0(options, Options()); + MOCK_CONST_METHOD0(OriginalMetadata, Song()); + MOCK_CONST_METHOD0(OriginalUrl, QUrl()); + MOCK_METHOD1(SetStreamMetadata, void(const Song &song)); + MOCK_METHOD0(ClearStreamMetadata, void()); + MOCK_METHOD1(SetArtManual, void(const QUrl &cover_url)); MOCK_METHOD1(InitFromQuery, bool(const SqlRow &settings)); MOCK_METHOD0(Reload, void()); - MOCK_CONST_METHOD0(Metadata, Song()); - MOCK_CONST_METHOD0(OriginalMetadata, Song()); - MOCK_CONST_METHOD0(Url, QUrl()); - MOCK_METHOD1(SetTemporaryMetadata, void(const Song &metadata)); - MOCK_METHOD0(ClearTemporaryMetadata, void()); - MOCK_METHOD1(SetArtManual, void(const QUrl &cover_url)); MOCK_CONST_METHOD1(DatabaseValue, QVariant(DatabaseColumn)); - }; #endif // MOCK_PLAYLISTITEM_H diff --git a/tests/src/playlist_test.cpp b/tests/src/playlist_test.cpp index 258456742..368572609 100644 --- a/tests/src/playlist_test.cpp +++ b/tests/src/playlist_test.cpp @@ -56,7 +56,7 @@ class PlaylistTest : public ::testing::Test { metadata.Init(title, artist, album, length); MockPlaylistItem *ret = new MockPlaylistItem; - EXPECT_CALL(*ret, Metadata()).WillRepeatedly(Return(metadata)); + EXPECT_CALL(*ret, OriginalMetadata()).WillRepeatedly(Return(metadata)); return ret; } @@ -100,7 +100,7 @@ TEST_F(PlaylistTest, Indexes) { // Start "playing" track 1 playlist_.set_current_row(0); EXPECT_EQ(0, playlist_.current_row()); - EXPECT_EQ(u"One"_s, playlist_.current_item()->Metadata().title()); + EXPECT_EQ(u"One"_s, playlist_.current_item()->EffectiveMetadata().title()); EXPECT_EQ(-1, playlist_.previous_row()); EXPECT_EQ(1, playlist_.next_row()); @@ -113,14 +113,14 @@ TEST_F(PlaylistTest, Indexes) { // Play track 2 playlist_.set_current_row(1); EXPECT_EQ(1, playlist_.current_row()); - EXPECT_EQ(u"Two"_s, playlist_.current_item()->Metadata().title()); + EXPECT_EQ(u"Two"_s, playlist_.current_item()->EffectiveMetadata().title()); EXPECT_EQ(0, playlist_.previous_row()); EXPECT_EQ(2, playlist_.next_row()); // Play track 3 playlist_.set_current_row(2); EXPECT_EQ(2, playlist_.current_row()); - EXPECT_EQ(u"Three"_s, playlist_.current_item()->Metadata().title()); + EXPECT_EQ(u"Three"_s, playlist_.current_item()->EffectiveMetadata().title()); EXPECT_EQ(1, playlist_.previous_row()); EXPECT_EQ(-1, playlist_.next_row()); @@ -453,7 +453,7 @@ TEST_F(PlaylistTest, ShuffleThenNext) { } int index = playlist_.current_row(); - EXPECT_EQ(u"Item 0"_s, playlist_.current_item()->Metadata().title()); + EXPECT_EQ(u"Item 0"_s, playlist_.current_item()->EffectiveMetadata().title()); EXPECT_EQ(u"Item 0"_s, playlist_.data(playlist_.index(index, static_cast(Playlist::Column::Title)))); EXPECT_EQ(index, playlist_.last_played_row()); //EXPECT_EQ(index + 1, playlist_.next_row()); @@ -466,7 +466,7 @@ TEST_F(PlaylistTest, ShuffleThenNext) { //} index = playlist_.current_row(); - EXPECT_EQ(u"Item 0"_s, playlist_.current_item()->Metadata().title()); + EXPECT_EQ(u"Item 0"_s, playlist_.current_item()->EffectiveMetadata().title()); EXPECT_EQ(u"Item 0"_s, playlist_.data(playlist_.index(index, static_cast(Playlist::Column::Title)))); EXPECT_EQ(index, playlist_.last_played_row()); //EXPECT_EQ(-1, playlist_.next_row()); @@ -487,7 +487,7 @@ TEST_F(PlaylistTest, CollectionIdMapSingle) { EXPECT_EQ(0, playlist_.collection_items(Song::Source::Collection, 0).count()); EXPECT_EQ(0, playlist_.collection_items(Song::Source::Collection, 2).count()); ASSERT_EQ(1, playlist_.collection_items(Song::Source::Collection, 1).count()); - EXPECT_EQ(song.title(), playlist_.collection_items(Song::Source::Collection, 1)[0]->Metadata().title()); // clazy:exclude=detaching-temporary + EXPECT_EQ(song.title(), playlist_.collection_items(Song::Source::Collection, 1)[0]->EffectiveMetadata().title()); // clazy:exclude=detaching-temporary playlist_.Clear(); diff --git a/tests/src/songplaylistitem_test.cpp b/tests/src/songplaylistitem_test.cpp index c5ab7984f..eb6ee9e62 100644 --- a/tests/src/songplaylistitem_test.cpp +++ b/tests/src/songplaylistitem_test.cpp @@ -78,7 +78,7 @@ TEST_P(SongPlaylistItemTest, Url) { expected.setScheme(u"file"_s); expected.setPath(absolute_file_name_); - EXPECT_EQ(expected, item_->Url()); + EXPECT_EQ(expected, item_->OriginalUrl()); }