media library: preserve filters/selections on update
This commit is contained in:
@@ -67,18 +67,18 @@ bool SongEntryMatcher(const Regex &rx, const MPD::Song &s);
|
||||
void DisplayAlbums(NC::Menu<AlbumEntry> &menu);
|
||||
void DisplayPrimaryTags(NC::Menu<MediaLibrary::PrimaryTag> &menu);
|
||||
|
||||
bool SortSongsByTrack(const MPD::Song &a, const MPD::Song &b);
|
||||
|
||||
struct SortAllTracks {
|
||||
struct SortSongs {
|
||||
static const std::array<MPD::Song::GetFunction, 3> GetFuns;
|
||||
|
||||
LocaleStringComparison m_cmp;
|
||||
std::ptrdiff_t m_offset;
|
||||
|
||||
public:
|
||||
SortAllTracks() : m_cmp(std::locale(), Config.ignore_leading_the) { }
|
||||
SortSongs(bool disc_only)
|
||||
: m_cmp(std::locale(), Config.ignore_leading_the), m_offset(disc_only ? 2 : 0) { }
|
||||
|
||||
bool operator()(const MPD::Song &a, const MPD::Song &b) {
|
||||
for (auto get = GetFuns.begin(); get != GetFuns.end(); ++get) {
|
||||
for (auto get = GetFuns.begin()+m_offset; get != GetFuns.end(); ++get) {
|
||||
int ret = m_cmp(a.getTags(*get, Config.tags_separator),
|
||||
b.getTags(*get, Config.tags_separator));
|
||||
if (ret != 0)
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
const std::array<MPD::Song::GetFunction, 3> SortAllTracks::GetFuns = {{
|
||||
const std::array<MPD::Song::GetFunction, 3> SortSongs::GetFuns = {{
|
||||
&MPD::Song::getDate,
|
||||
&MPD::Song::getAlbum,
|
||||
&MPD::Song::getDisc
|
||||
@@ -242,9 +242,10 @@ void MediaLibrary::update()
|
||||
|
||||
if (hasTwoColumns)
|
||||
{
|
||||
if (Albums.reallyEmpty())
|
||||
if (Albums.reallyEmpty() || m_albums_update_request)
|
||||
{
|
||||
Songs.clear();
|
||||
Albums.clearSearchResults();
|
||||
m_albums_update_request = false;
|
||||
std::map<std::tuple<std::string, std::string, std::string>, time_t> albums;
|
||||
Mpd.GetDirectoryRecursive("/", [&albums](MPD::Song &&s) {
|
||||
unsigned idx = 0;
|
||||
@@ -260,22 +261,33 @@ void MediaLibrary::update()
|
||||
}
|
||||
while (!(tag = s.get(Config.media_lib_primary_tag, ++idx)).empty());
|
||||
});
|
||||
for (auto it = albums.begin(); it != albums.end(); ++it)
|
||||
Albums.addItem(AlbumEntry(Album(
|
||||
std::move(std::get<0>(it->first)),
|
||||
std::move(std::get<1>(it->first)),
|
||||
std::move(std::get<2>(it->first)),
|
||||
it->second)));
|
||||
withUnfilteredMenuReapplyFilter(Albums, [this, &albums]() {
|
||||
size_t idx = 0;
|
||||
for (auto it = albums.begin(); it != albums.end(); ++it, ++idx)
|
||||
{
|
||||
auto &&entry = AlbumEntry(Album(
|
||||
std::move(std::get<0>(it->first)),
|
||||
std::move(std::get<1>(it->first)),
|
||||
std::move(std::get<2>(it->first)),
|
||||
it->second));
|
||||
if (idx < Albums.size())
|
||||
Albums[idx].value() = entry;
|
||||
else
|
||||
Albums.addItem(entry);
|
||||
}
|
||||
if (idx < Albums.size())
|
||||
Albums.resizeList(idx);
|
||||
std::sort(Albums.beginV(), Albums.endV(), SortAlbumEntries());
|
||||
});
|
||||
Albums.refresh();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Tags.reallyEmpty())
|
||||
if (Tags.reallyEmpty() || m_tags_update_request)
|
||||
{
|
||||
Albums.clear();
|
||||
Songs.clear();
|
||||
Tags.clearSearchResults();
|
||||
m_tags_update_request = false;
|
||||
std::map<std::string, time_t> tags;
|
||||
Mpd.GetDirectoryRecursive("/", [&tags](MPD::Song &&s) {
|
||||
unsigned idx = 0;
|
||||
@@ -290,13 +302,26 @@ void MediaLibrary::update()
|
||||
}
|
||||
while (!(tag = s.get(Config.media_lib_primary_tag, ++idx)).empty());
|
||||
});
|
||||
for (auto it = tags.begin(); it != tags.end(); ++it)
|
||||
Tags.addItem(PrimaryTag(std::move(it->first), it->second));
|
||||
withUnfilteredMenuReapplyFilter(Tags, [this, &tags]() {
|
||||
size_t idx = 0;
|
||||
for (auto it = tags.begin(); it != tags.end(); ++it, ++idx)
|
||||
{
|
||||
auto &&tag = PrimaryTag(std::move(it->first), it->second);
|
||||
if (idx < Tags.size())
|
||||
Tags[idx].value() = tag;
|
||||
else
|
||||
Tags.addItem(tag);
|
||||
}
|
||||
if (idx < Tags.size())
|
||||
Tags.resizeList(idx);
|
||||
});
|
||||
Tags.refresh();
|
||||
}
|
||||
|
||||
if (!Tags.empty() && Albums.reallyEmpty())
|
||||
if ((!Tags.empty() && Albums.reallyEmpty()) || m_albums_update_request)
|
||||
{
|
||||
Albums.clearSearchResults();
|
||||
m_albums_update_request = false;
|
||||
auto &primary_tag = Tags.current().value().tag();
|
||||
Mpd.StartSearch(true);
|
||||
Mpd.AddSearch(Config.media_lib_primary_tag, primary_tag);
|
||||
@@ -309,25 +334,40 @@ void MediaLibrary::update()
|
||||
else
|
||||
it->second = s.getMTime();
|
||||
});
|
||||
for (auto it = albums.begin(); it != albums.end(); ++it)
|
||||
Albums.addItem(AlbumEntry(Album(
|
||||
primary_tag,
|
||||
std::move(std::get<0>(it->first)),
|
||||
std::move(std::get<1>(it->first)),
|
||||
it->second)));
|
||||
std::sort(Albums.beginV(), Albums.endV(), SortAlbumEntries());
|
||||
if (albums.size() > 1)
|
||||
{
|
||||
Albums.addSeparator();
|
||||
Albums.addItem(AlbumEntry::mkAllTracksEntry(primary_tag));
|
||||
}
|
||||
withUnfilteredMenuReapplyFilter(Albums, [this, &albums, &primary_tag]() {
|
||||
size_t idx = 0;
|
||||
for (auto it = albums.begin(); it != albums.end(); ++it, ++idx)
|
||||
{
|
||||
auto &&entry = AlbumEntry(Album(
|
||||
primary_tag,
|
||||
std::move(std::get<0>(it->first)),
|
||||
std::move(std::get<1>(it->first)),
|
||||
it->second));
|
||||
if (idx < Albums.size())
|
||||
{
|
||||
Albums[idx].value() = entry;
|
||||
Albums[idx].setSeparator(false);
|
||||
}
|
||||
else
|
||||
Albums.addItem(entry);
|
||||
}
|
||||
if (idx < Albums.size())
|
||||
Albums.resizeList(idx);
|
||||
std::sort(Albums.beginV(), Albums.endV(), SortAlbumEntries());
|
||||
if (albums.size() > 1)
|
||||
{
|
||||
Albums.addSeparator();
|
||||
Albums.addItem(AlbumEntry::mkAllTracksEntry(primary_tag));
|
||||
}
|
||||
});
|
||||
Albums.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
if (!Albums.empty() && Songs.reallyEmpty())
|
||||
if ((!Albums.empty() && Songs.reallyEmpty()) || m_songs_update_request)
|
||||
{
|
||||
Songs.reset();
|
||||
Songs.clearSearchResults();
|
||||
m_songs_update_request = false;
|
||||
auto &album = Albums.current().value();
|
||||
Mpd.StartSearch(true);
|
||||
Mpd.AddSearch(Config.media_lib_primary_tag, album.entry().tag());
|
||||
@@ -336,15 +376,23 @@ void MediaLibrary::update()
|
||||
Mpd.AddSearch(MPD_TAG_ALBUM, album.entry().album());
|
||||
Mpd.AddSearch(MPD_TAG_DATE, album.entry().date());
|
||||
}
|
||||
Mpd.CommitSearchSongs([this](MPD::Song &&s) {
|
||||
Songs.addItem(s, myPlaylist->checkForSong(s));
|
||||
withUnfilteredMenuReapplyFilter(Songs, [this, &album]() {
|
||||
size_t idx = 0;
|
||||
Mpd.CommitSearchSongs([this, &idx](MPD::Song &&s) {
|
||||
bool is_playlist = myPlaylist->checkForSong(s);
|
||||
if (idx < Songs.size())
|
||||
{
|
||||
Songs[idx].value() = s;
|
||||
Songs[idx].setBold(is_playlist);
|
||||
}
|
||||
else
|
||||
Songs.addItem(s, is_playlist);
|
||||
++idx;
|
||||
});
|
||||
if (idx < Songs.size())
|
||||
Songs.resizeList(idx);
|
||||
std::sort(Songs.beginV(), Songs.endV(), SortSongs(!album.isAllTracksEntry()));
|
||||
});
|
||||
|
||||
if (album.isAllTracksEntry())
|
||||
std::sort(Songs.beginV(), Songs.endV(), SortAllTracks());
|
||||
else
|
||||
std::sort(Songs.beginV(), Songs.endV(), SortSongsByTrack);
|
||||
|
||||
Songs.refresh();
|
||||
}
|
||||
|
||||
@@ -640,7 +688,7 @@ MPD::SongList MediaLibrary::getSelectedSongs()
|
||||
Mpd.CommitSearchSongs([&result](MPD::Song &&s) {
|
||||
result.push_back(s);
|
||||
});
|
||||
std::sort(result.begin()+begin, result.end(), SortSongsByTrack);
|
||||
std::sort(result.begin()+begin, result.end(), SortSongs(false));
|
||||
}
|
||||
}
|
||||
// if no item is selected, add songs from right column
|
||||
@@ -998,14 +1046,4 @@ void DisplayPrimaryTags(NC::Menu<MediaLibrary::PrimaryTag> &menu)
|
||||
menu << tag;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
bool SortSongsByTrack(const MPD::Song &a, const MPD::Song &b)
|
||||
{
|
||||
int cmp = a.getDisc().compare(b.getDisc());
|
||||
if (cmp != 0)
|
||||
return cmp < 0;
|
||||
return a.getTrack() < b.getTrack();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -74,9 +74,14 @@ struct MediaLibrary: Screen<NC::Window *>, Filterable, HasColumns, HasSongs, Sea
|
||||
void LocateSong(const MPD::Song &);
|
||||
ProxySongList songsProxyList();
|
||||
void toggleSortMode();
|
||||
|
||||
|
||||
void requestTagsUpdate() { m_tags_update_request = true; }
|
||||
void requestAlbumsUpdate() { m_albums_update_request = true; }
|
||||
void requestSongsUpdate() { m_songs_update_request = true; }
|
||||
|
||||
struct PrimaryTag
|
||||
{
|
||||
PrimaryTag() : m_mtime(0) { }
|
||||
PrimaryTag(std::string tag_, time_t mtime_)
|
||||
: m_tag(std::move(tag_)), m_mtime(mtime_) { }
|
||||
|
||||
@@ -134,6 +139,10 @@ protected:
|
||||
|
||||
private:
|
||||
void AddToPlaylist(bool);
|
||||
|
||||
bool m_tags_update_request;
|
||||
bool m_albums_update_request;
|
||||
bool m_songs_update_request;
|
||||
};
|
||||
|
||||
extern MediaLibrary *myLibrary;
|
||||
|
||||
@@ -193,10 +193,9 @@ void Status::Changes::database()
|
||||
# ifdef HAVE_TAGLIB_H
|
||||
myTagEditor->Dirs->clear();
|
||||
# endif // HAVE_TAGLIB_H
|
||||
if (myLibrary->Columns() == 2)
|
||||
myLibrary->Albums.clear();
|
||||
else
|
||||
myLibrary->Tags.clear();
|
||||
myLibrary->requestTagsUpdate();
|
||||
myLibrary->requestAlbumsUpdate();
|
||||
myLibrary->requestSongsUpdate();
|
||||
}
|
||||
|
||||
void Status::Changes::playerState()
|
||||
|
||||
Reference in New Issue
Block a user