From e13c27d32cc2e8ababd93e51bd086e08e00116a2 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sun, 11 Apr 2021 02:01:27 +0200 Subject: [PATCH] Allow editing of playlist metadata for streams --- src/collection/collectionplaylistitem.h | 2 +- src/core/mainwindow.cpp | 46 ++++++++++++------------- src/core/song.cpp | 7 +++- src/internet/internetplaylistitem.h | 2 ++ src/playlist/playlist.cpp | 12 +++++-- src/playlist/playlistitem.h | 2 ++ src/playlist/playlistmanager.cpp | 2 +- 7 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/collection/collectionplaylistitem.h b/src/collection/collectionplaylistitem.h index b61b2ee1..ec71bf64 100644 --- a/src/collection/collectionplaylistitem.h +++ b/src/collection/collectionplaylistitem.h @@ -42,7 +42,7 @@ class CollectionPlaylistItem : public PlaylistItem { Song Metadata() const override; Song OriginalMetadata() const override { return song_; } - void SetMetadata(const Song &song) { song_ = song; } + void SetMetadata(const Song &song) override { song_ = song; } QUrl Url() const override; diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp index 70d35a3a..7854c9e0 100644 --- a/src/core/mainwindow.cpp +++ b/src/core/mainwindow.cpp @@ -1821,30 +1821,27 @@ void MainWindow::PlaylistRightClick(const QPoint &global_pos, const QModelIndex } // this is available when we have one or many files and at least one of those is not CUE related - ui_->action_edit_track->setEnabled(editable > 0); - ui_->action_edit_track->setVisible(editable > 0); + ui_->action_edit_track->setEnabled(local_songs > 0 && editable > 0); + ui_->action_edit_track->setVisible(local_songs > 0 && editable > 0); #if defined(HAVE_GSTREAMER) && defined(HAVE_CHROMAPRINT) - ui_->action_auto_complete_tags->setEnabled(editable > 0); - ui_->action_auto_complete_tags->setVisible(editable > 0); + ui_->action_auto_complete_tags->setEnabled(local_songs > 0 && editable > 0); + ui_->action_auto_complete_tags->setVisible(local_songs > 0 && editable > 0); #endif - playlist_rescan_songs_->setEnabled(editable > 0); - playlist_rescan_songs_->setVisible(editable > 0); + playlist_rescan_songs_->setEnabled(local_songs > 0 && editable > 0); + playlist_rescan_songs_->setVisible(local_songs > 0 && editable > 0); #ifdef HAVE_GSTREAMER - ui_->action_add_files_to_transcoder->setEnabled(editable); - ui_->action_add_files_to_transcoder->setVisible(editable); + ui_->action_add_files_to_transcoder->setEnabled(local_songs > 0 && editable); + ui_->action_add_files_to_transcoder->setVisible(local_songs > 0 && editable); #endif - // the rest of the read / write actions work only when there are no CUEs involved - if (cue_selected) editable = 0; - playlist_open_in_browser_->setVisible(selected > 0 && local_songs == selected); bool track_column = (index.column() == Playlist::Column_Track); - ui_->action_renumber_tracks->setVisible(editable >= 2 && track_column); - ui_->action_selection_set_value->setVisible(editable >= 2 && !track_column); - ui_->action_edit_value->setVisible(editable > 0); + ui_->action_renumber_tracks->setVisible(local_songs > 0 && !cue_selected && editable >= 2 && track_column); + ui_->action_selection_set_value->setVisible(editable >= 2 && !cue_selected && !track_column); + ui_->action_edit_value->setVisible(editable > 0 && !cue_selected); ui_->action_remove_from_playlist->setEnabled(selected > 0); ui_->action_remove_from_playlist->setVisible(selected > 0); @@ -1900,7 +1897,7 @@ void MainWindow::PlaylistRightClick(const QPoint &global_pos, const QModelIndex else { Playlist::Column column = static_cast(index.column()); - bool column_is_editable = Playlist::column_is_editable(column) && editable > 0; + bool column_is_editable = (Playlist::column_is_editable(column) && editable > 0 && !cue_selected); ui_->action_selection_set_value->setVisible(ui_->action_selection_set_value->isVisible() && column_is_editable); ui_->action_edit_value->setVisible(ui_->action_edit_value->isVisible() && column_is_editable); @@ -1915,21 +1912,21 @@ 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) { - playlist_organize_->setVisible(editable > 0); - playlist_show_in_collection_->setVisible(editable > 0); + playlist_organize_->setVisible(local_songs > 0 && editable > 0 && !cue_selected); + playlist_show_in_collection_->setVisible(true); playlist_open_in_browser_->setVisible(true); } else { - playlist_copy_to_collection_->setVisible(editable > 0); - playlist_move_to_collection_->setVisible(editable > 0); + playlist_copy_to_collection_->setVisible(local_songs > 0); + playlist_move_to_collection_->setVisible(local_songs > 0); } #if defined(HAVE_GSTREAMER) && !defined(Q_OS_WIN) - playlist_copy_to_device_->setVisible(editable > 0); + playlist_copy_to_device_->setVisible(local_songs > 0); #endif #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) - playlist_delete_->setVisible(delete_files_ && editable > 0); + playlist_delete_->setVisible(delete_files_ && local_songs > 0); #endif // Remove old item actions, if any. @@ -2108,12 +2105,15 @@ void MainWindow::SelectionSetValue() { PlaylistItemPtr item = app_->playlist_manager()->current()->item_at(source_index.row()); if (!item) continue; Song song = item->OriginalMetadata(); - if (!song.is_valid() || !song.url().isLocalFile()) continue; - if (Playlist::set_column_value(song, column, column_value)) { + if (!song.is_valid()) continue; + if (song.url().isLocalFile() && Playlist::set_column_value(song, column, column_value)) { TagReaderReply *reply = TagReaderClient::Instance()->SaveFile(song.url().toLocalFile(), song); QPersistentModelIndex persistent_index = QPersistentModelIndex(source_index); QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, persistent_index]() { SongSaveComplete(reply, persistent_index); }, Qt::QueuedConnection); } + else if (song.source() == Song::Source_Stream) { + app_->playlist_manager()->current()->setData(source_index, column_value, 0); + } } } diff --git a/src/core/song.cpp b/src/core/song.cpp index 27d9ac24..2787a026 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -1526,7 +1526,12 @@ bool Song::IsMetadataAndArtEqual(const Song &other) const { } bool Song::IsEditable() const { - return d->valid_ && !d->url_.isEmpty() && !is_stream() && d->source_ != Source_Unknown && d->filetype_ != FileType_Unknown && !has_cue(); + + return d->valid_ && + !d->url_.isEmpty() && + (d->url_.isLocalFile() || d->source_ == Source_Stream) && + !has_cue(); + } bool Song::operator==(const Song &other) const { diff --git a/src/internet/internetplaylistitem.h b/src/internet/internetplaylistitem.h index f0529c42..05b2c240 100644 --- a/src/internet/internetplaylistitem.h +++ b/src/internet/internetplaylistitem.h @@ -44,6 +44,8 @@ class InternetPlaylistItem : public PlaylistItem { Song Metadata() const override; Song OriginalMetadata() const override { return metadata_; } QUrl Url() const override; + + void SetMetadata(const Song &metadata) override { metadata_ = metadata; } void SetArtManual(const QUrl &cover_url) override; protected: diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp index 6346ad35..c9f704a5 100644 --- a/src/playlist/playlist.cpp +++ b/src/playlist/playlist.cpp @@ -388,9 +388,15 @@ bool Playlist::setData(const QModelIndex &idx, const QVariant &value, int role) if (!set_column_value(song, static_cast(idx.column()), value)) return false; - TagReaderReply *reply = TagReaderClient::Instance()->SaveFile(song.url().toLocalFile(), song); - QPersistentModelIndex persistent_index = QPersistentModelIndex(idx); - QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, persistent_index]() { SongSaveComplete(reply, persistent_index); }, Qt::QueuedConnection); + if (song.url().isLocalFile()) { + TagReaderReply *reply = TagReaderClient::Instance()->SaveFile(song.url().toLocalFile(), song); + QPersistentModelIndex persistent_index = QPersistentModelIndex(idx); + QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, persistent_index]() { SongSaveComplete(reply, persistent_index); }, Qt::QueuedConnection); + } + else if (song.source() == Song::Source_Stream) { + item->SetMetadata(song); + Save(); + } return true; diff --git a/src/playlist/playlistitem.h b/src/playlist/playlistitem.h index 473ba0d3..fb26c849 100644 --- a/src/playlist/playlistitem.h +++ b/src/playlist/playlistitem.h @@ -77,6 +77,8 @@ class PlaylistItem : public std::enable_shared_from_this { virtual Song OriginalMetadata() const = 0; virtual QUrl Url() const = 0; + virtual void SetMetadata(const Song&) {} + void SetTemporaryMetadata(const Song &metadata); void UpdateTemporaryMetadata(const Song &metadata); void ClearTemporaryMetadata(); diff --git a/src/playlist/playlistmanager.cpp b/src/playlist/playlistmanager.cpp index 98ad1df9..dc143d8f 100644 --- a/src/playlist/playlistmanager.cpp +++ b/src/playlist/playlistmanager.cpp @@ -498,7 +498,7 @@ void PlaylistManager::SongsDiscovered(const SongList &songs) { PlaylistItemList items = data.p->collection_items_by_id(song.id()); for (PlaylistItemPtr item : items) { if (item->Metadata().directory_id() != song.directory_id()) continue; - static_cast(item.get())->SetMetadata(song); + item->SetMetadata(song); if (item->HasTemporaryMetadata()) item->UpdateTemporaryMetadata(song); data.p->ItemChanged(item); }