diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp index 5bc16ba4c..bc7146d6e 100644 --- a/src/playlist/playlist.cpp +++ b/src/playlist/playlist.cpp @@ -173,6 +173,12 @@ Playlist::Playlist(PlaylistBackend* backend, TaskManager* task_manager, settings.endGroup(); + settings.beginGroup(kSettingsGroup); + + grey_unfound_ = settings.value("greyoutdeleted", false).toBool(); + + settings.endGroup(); + qLog(Debug) << "k_max_scrobble_point" << (max_play_count_point_nsecs_ / kNsecPerSec); } @@ -1223,6 +1229,9 @@ void Playlist::UpdateItems(const SongList& songs) { } else { new_item = PlaylistItemPtr(new SongPlaylistItem(song)); } + if (grey_unfound_ && !song.is_valid()) { + new_item->SetForegroundColor(kInvalidSongPriority, kInvalidSongColor); + } items_[i] = new_item; emit dataChanged(index(i, 0), index(i, ColumnCount - 1)); // Also update undo actions @@ -1626,11 +1635,7 @@ void Playlist::ItemsLoaded(QFuture future) { emit RestoreFinished(); - QSettings s; - s.beginGroup(kSettingsGroup); - - // should we gray out deleted songs asynchronously on startup? - if (s.value("greyoutdeleted", false).toBool()) { + if (grey_unfound_) { QtConcurrent::run(this, &Playlist::InvalidateDeletedSongs); } } diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h index 833f311cd..bf26384a7 100644 --- a/src/playlist/playlist.h +++ b/src/playlist/playlist.h @@ -471,6 +471,8 @@ class Playlist : public QAbstractListModel { // Cancel async restore if songs are already replaced bool cancel_restore_; + + bool grey_unfound_; }; // QDataStream& operator <<(QDataStream&, const Playlist*); diff --git a/src/playlistparsers/asxiniparser.cpp b/src/playlistparsers/asxiniparser.cpp index af5cdecbd..a8429e0aa 100644 --- a/src/playlistparsers/asxiniparser.cpp +++ b/src/playlistparsers/asxiniparser.cpp @@ -40,10 +40,7 @@ SongList AsxIniParser::Load(QIODevice* device, const QString& playlist_path, QString value = line.mid(equals + 1); if (key.startsWith("ref")) { - Song song = LoadSong(value, 0, dir); - if (song.is_valid()) { - ret << song; - } + ret << LoadSong(value, 0, dir); } } diff --git a/src/playlistparsers/asxparser.cpp b/src/playlistparsers/asxparser.cpp index 9f31568b3..c63ca21ef 100644 --- a/src/playlistparsers/asxparser.cpp +++ b/src/playlistparsers/asxparser.cpp @@ -71,10 +71,7 @@ SongList ASXParser::Load(QIODevice* device, const QString& playlist_path, } while (!reader.atEnd() && Utilities::ParseUntilElement(&reader, "entry")) { - Song song = ParseTrack(&reader, dir); - if (song.is_valid()) { - ret << song; - } + ret << ParseTrack(&reader, dir); } return ret; } @@ -111,10 +108,14 @@ Song ASXParser::ParseTrack(QXmlStreamReader* reader, const QDir& dir) const { return_song: Song song = LoadSong(ref, 0, dir); - // Override metadata with what was in the playlist - song.set_title(title); - song.set_artist(artist); - song.set_album(album); + // Override metadata with what was in the playlist if the song is not in the + // library. + if (!song.is_library_song()) { + song.set_title(title); + song.set_artist(artist); + song.set_album(album); + } + return song; } diff --git a/src/playlistparsers/cueparser.cpp b/src/playlistparsers/cueparser.cpp index dbca6d851..e99232ffd 100644 --- a/src/playlistparsers/cueparser.cpp +++ b/src/playlistparsers/cueparser.cpp @@ -227,8 +227,30 @@ SongList CueParser::Load(QIODevice* device, const QString& playlist_path, // finalize parsing songs for (int i = 0; i < entries.length(); i++) { CueEntry entry = entries.at(i); + Song song; - Song song = LoadSong(entry.file, IndexToMarker(entry.index), dir); + // override song metadata with metadata from the multi-file cue if the song + // isn't found in the library + if (files == 1) { + song = LoadSong(entry.file, IndexToMarker(entry.index), dir); + } else { + song = LoadSong(entry.file, 0, dir); + + if (!song.is_library_song()) { + song.set_title(entry.title); + song.set_artist(entry.PrettyArtist()); + song.set_album(entry.album); + song.set_albumartist(entry.album_artist); + song.set_genre(entry.genre); + song.set_year(entry.date.toInt()); + song.set_composer(entry.PrettyComposer()); + song.set_disc(entry.disc.toInt()); + } + + ret << song; + + continue; + } // cue song has mtime equal to qMax(media_file_mtime, cue_sheet_mtime) if (cue_mtime.isValid()) { @@ -239,10 +261,8 @@ SongList CueParser::Load(QIODevice* device, const QString& playlist_path, // overwrite the stuff, we may have read from the file or library, using // the current .cue metadata - // set track number only in single-file mode - if (files == 1) { - song.set_track(i + 1); - } + // set track number + song.set_track(i + 1); // the last TRACK for every FILE gets it's 'end' marker from the media // file's diff --git a/src/playlistparsers/m3uparser.cpp b/src/playlistparsers/m3uparser.cpp index 20ef07250..ffd3b549d 100644 --- a/src/playlistparsers/m3uparser.cpp +++ b/src/playlistparsers/m3uparser.cpp @@ -59,15 +59,20 @@ SongList M3UParser::Load(QIODevice* device, const QString& playlist_path, } } else if (!line.isEmpty()) { Song song = LoadSong(line, 0, dir); - if (!current_metadata.title.isEmpty()) { - song.set_title(current_metadata.title); - } - if (!current_metadata.artist.isEmpty()) { - song.set_artist(current_metadata.artist); - } - if (current_metadata.length > 0) { - song.set_length_nanosec(current_metadata.length); + + // Override metadata from playlist if the song is not in the library. + if (!song.is_library_song()) { + if (!current_metadata.title.isEmpty()) { + song.set_title(current_metadata.title); + } + if (!current_metadata.artist.isEmpty()) { + song.set_artist(current_metadata.artist); + } + if (current_metadata.length > 0) { + song.set_length_nanosec(current_metadata.length); + } } + ret << song; current_metadata = Metadata(); diff --git a/src/playlistparsers/plsparser.cpp b/src/playlistparsers/plsparser.cpp index e7a3bdd1f..ed27a810c 100644 --- a/src/playlistparsers/plsparser.cpp +++ b/src/playlistparsers/plsparser.cpp @@ -43,19 +43,21 @@ SongList PLSParser::Load(QIODevice* device, const QString& playlist_path, if (key.startsWith("file")) { Song song = LoadSong(value, 0, dir); - // Use the title and length we've already loaded if any - if (!songs[n].title().isEmpty()) song.set_title(songs[n].title()); - if (songs[n].length_nanosec() != -1) - song.set_length_nanosec(songs[n].length_nanosec()); + // Use the title and length we've already loaded if any and only if the + // song is not in the library. + if (!song.is_library_song()) { + if (!songs[n].title().isEmpty()) song.set_title(songs[n].title()); + if (songs[n].length_nanosec() != -1) + song.set_length_nanosec(songs[n].length_nanosec()); + } songs[n] = song; } else if (key.startsWith("title")) { - songs[n].set_title(value); + if (!songs[n].is_library_song()) songs[n].set_title(value); } else if (key.startsWith("length")) { qint64 seconds = value.toLongLong(); - if (seconds > 0) { + if ((seconds > 0) && !songs[n].is_library_song()) songs[n].set_length_nanosec(seconds * kNsecPerSec); - } } } diff --git a/src/playlistparsers/wplparser.cpp b/src/playlistparsers/wplparser.cpp index ec6fcd539..634a8a7c1 100644 --- a/src/playlistparsers/wplparser.cpp +++ b/src/playlistparsers/wplparser.cpp @@ -55,10 +55,7 @@ void WplParser::ParseSeq(const QDir& dir, QXmlStreamReader* reader, if (name == "media") { QStringRef src = reader->attributes().value("src"); if (!src.isEmpty()) { - Song song = LoadSong(src.toString(), 0, dir); - if (song.is_valid()) { - songs->append(song); - } + songs->append(LoadSong(src.toString(), 0, dir)); } } else { Utilities::ConsumeCurrentElement(reader); diff --git a/src/playlistparsers/xspfparser.cpp b/src/playlistparsers/xspfparser.cpp index f607bd12e..d296d83ea 100644 --- a/src/playlistparsers/xspfparser.cpp +++ b/src/playlistparsers/xspfparser.cpp @@ -102,13 +102,17 @@ Song XSPFParser::ParseTrack(QXmlStreamReader* reader, const QDir& dir) const { return_song: Song song = LoadSong(location, 0, dir); - // Override metadata with what was in the playlist - song.set_title(title); - song.set_artist(artist); - song.set_album(album); - song.set_art_manual(art); - song.set_length_nanosec(nanosec); - song.set_track(track_num); + // If the song is not in the library, fill metadata with what was in the + // playlist. + if (!song.is_library_song()) { + song.set_title(title); + song.set_artist(artist); + song.set_album(album); + song.set_art_manual(art); + song.set_length_nanosec(nanosec); + song.set_track(track_num); + } + return song; }