diff --git a/src/browser.cpp b/src/browser.cpp index 1fcd5411..6a409439 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -148,9 +148,7 @@ void Browser::EnterPressed() } case itSong: { - size_t i = w->choice(); - bool res = myPlaylist->Add(*item.song, w->at(i).isBold(), 1); - w->at(i).setBold(res); + myPlaylist->Add(*item.song, 1); break; } case itPlaylist: @@ -209,9 +207,7 @@ void Browser::SpacePressed() } case itSong: { - i = w->choice(); - bool res = myPlaylist->Add(*item.song, w->at(i).isBold(), 0); - w->at(i).setBold(res); + myPlaylist->Add(*item.song, 0); break; } case itPlaylist: @@ -618,10 +614,9 @@ bool Browser::deleteItem(const MPD::Item &item) void Browser::UpdateItemList() { - for (size_t i = 0; i < w->size(); ++i) - if ((*w)[i].value().type == itSong) - w->at(i).setBold(myPlaylist->checkForSong(*(*w)[i].value().song)); - w->refresh(); + for (auto it = w->begin(); it != w->end(); ++it) + if (it->value().type == itSong) + it->setBold(myPlaylist->checkForSong(*it->value().song)); } namespace {// diff --git a/src/media_library.cpp b/src/media_library.cpp index 46168eab..67fcde91 100644 --- a/src/media_library.cpp +++ b/src/media_library.cpp @@ -802,10 +802,7 @@ void MediaLibrary::LocateSong(const MPD::Song &s) void MediaLibrary::AddToPlaylist(bool add_n_play) { if (w == Songs && !Songs->empty()) - { - bool res = myPlaylist->Add(Songs->current().value(), Songs->current().isBold(), add_n_play); - Songs->current().setBold(res); - } + myPlaylist->Add(Songs->current().value(), add_n_play); else { auto list = getSelectedSongs(); diff --git a/src/playlist.cpp b/src/playlist.cpp index 7094a67a..22111e52 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -594,11 +594,11 @@ const MPD::Song *Playlist::NowPlayingSong() return s; } -bool Playlist::Add(const MPD::Song &s, bool in_playlist, bool play, int position) +bool Playlist::Add(const MPD::Song &s, bool play, int position) { - if (Config.ncmpc_like_songs_adding && in_playlist) + if (Config.ncmpc_like_songs_adding && checkForSong(s)) { - unsigned hash = s.getHash(); + size_t hash = s.getHash(); if (play) { for (size_t i = 0; i < Items->size(); ++i) @@ -615,14 +615,8 @@ bool Playlist::Add(const MPD::Song &s, bool in_playlist, bool play, int position { Mpd.StartCommandsList(); for (size_t i = 0; i < Items->size(); ++i) - { if ((*Items)[i].value().getHash() == hash) - { Mpd.Delete(i); - Items->deleteItem(i); - i--; - } - } Mpd.CommitCommandsList(); return false; } @@ -692,12 +686,24 @@ void Playlist::SetSelectedItemsPriority(int prio) ShowMessage("Priority set"); } -bool Playlist::checkForSong (const MPD::Song &s) +bool Playlist::checkForSong(const MPD::Song &s) { - for (size_t i = 0; i < Items->size(); ++i) - if (s.getHash() == (*Items)[i].value().getHash()) - return true; - return false; + return itsSongHashes.find(s.getHash()) != itsSongHashes.end(); +} + +void Playlist::registerHash(size_t hash) +{ + itsSongHashes[hash] += 1; +} + +void Playlist::unregisterHash(size_t hash) +{ + auto it = itsSongHashes.find(hash); + assert(it != itsSongHashes.end()); + if (it->second == 1) + itsSongHashes.erase(it); + else + it->second -= 1; } namespace {// diff --git a/src/playlist.h b/src/playlist.h index 21127c8d..809e4d7a 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -21,6 +21,8 @@ #ifndef _PLAYLIST_H #define _PLAYLIST_H +#include + #include "interfaces.h" #include "screen.h" #include "song.h" @@ -80,7 +82,7 @@ class Playlist : public Screen, public Filterable, public HasSongs, void UpdateTimer() { time(&itsTimer); } time_t Timer() const { return itsTimer; } - bool Add(const MPD::Song &s, bool in_playlist, bool play, int position = -1); + bool Add(const MPD::Song &s, bool play, int position = -1); bool Add(const MPD::SongList &l, bool play, int position = -1); void PlayNewlyAddedSongs(); @@ -88,6 +90,9 @@ class Playlist : public Screen, public Filterable, public HasSongs, bool checkForSong(const MPD::Song &s); + void registerHash(size_t hash); + void unregisterHash(size_t hash); + //static std::string SongToString(const MPD::Song &s); //static std::string SongInColumnsToString(const MPD::Song &s); @@ -106,6 +111,8 @@ class Playlist : public Screen, public Filterable, public HasSongs, std::string TotalLength(); std::string itsBufferedStats; + std::map itsSongHashes; + size_t itsTotalLength; size_t itsRemainingTime; size_t itsScrollBegin; diff --git a/src/playlist_editor.cpp b/src/playlist_editor.cpp index e20735a7..d306d685 100644 --- a/src/playlist_editor.cpp +++ b/src/playlist_editor.cpp @@ -345,10 +345,7 @@ void PlaylistEditor::AddToPlaylist(bool add_n_play) } } else if (w == Content && !Content->empty()) - { - bool res = myPlaylist->Add(Content->current().value(), Content->current().isBold(), add_n_play); - Content->current().setBold(res); - } + myPlaylist->Add(Content->current().value(), add_n_play); if (!add_n_play) w->scroll(NC::wDown); diff --git a/src/search_engine.cpp b/src/search_engine.cpp index 22e00381..cf4d511b 100644 --- a/src/search_engine.cpp +++ b/src/search_engine.cpp @@ -224,10 +224,7 @@ void SearchEngine::EnterPressed() reset(); } else - { - bool res = myPlaylist->Add(w->current().value().song(), w->current().isBold(), 1); - w->current().setBold(res); - } + myPlaylist->Add(w->current().value().song(), 1); if (option < SearchButton) UnlockStatusbar(); @@ -245,8 +242,7 @@ void SearchEngine::SpacePressed() return; } - bool res = myPlaylist->Add(w->current().value().song(), w->current().isBold(), 0); - w->current().setBold(res); + myPlaylist->Add(w->current().value().song(), 0); w->scroll(NC::wDown); } diff --git a/src/status.cpp b/src/status.cpp index af11938c..b05cc878 100644 --- a/src/status.cpp +++ b/src/status.cpp @@ -234,7 +234,13 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *) size_t playlist_length = Mpd.GetPlaylistLength(); if (playlist_length < myPlaylist->Items->size()) + { + auto it = myPlaylist->Items->begin()+playlist_length; + auto end = myPlaylist->Items->end(); + for (; it != end; ++it) + myPlaylist->unregisterHash(it->value().getHash()); myPlaylist->Items->resizeList(playlist_length); + } auto songs = Mpd.GetPlaylistChanges(Mpd.GetOldPlaylistID()); for (auto s = songs.begin(); s != songs.end(); ++s) @@ -243,13 +249,16 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *) if (pos < myPlaylist->Items->size()) { // if song's already in playlist, replace it with a new one - myPlaylist->Items->at(pos).value() = *s; + MPD::Song &old_s = myPlaylist->Items->at(pos).value(); + myPlaylist->unregisterHash(old_s.getHash()); + old_s = *s; } else { // otherwise just add it to playlist myPlaylist->Items->addItem(*s); } + myPlaylist->registerHash(s->getHash()); } if (is_filtered) @@ -266,21 +275,13 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *) myPlaylist->Items->reset(); if (isVisible(myBrowser)) - { myBrowser->UpdateItemList(); - } - else if (isVisible(mySearcher)) - { + if (isVisible(mySearcher)) mySearcher->UpdateFoundList(); - } - else if (isVisible(myLibrary)) - { + if (isVisible(myLibrary)) UpdateSongList(myLibrary->Songs); - } - else if (isVisible(myPlaylistEditor)) - { + if (isVisible(myPlaylistEditor)) UpdateSongList(myPlaylistEditor->Content); - } } if (changed.Database) {