bool Connection::AddRandomTag(mpd_tag_type tag, size_t number) { std::vector<std::string> tags( std::make_move_iterator(GetList(tag)), std::make_move_iterator(StringIterator()) ); if (number > tags.size()) return false; std::random_shuffle(tags.begin(), tags.end()); auto it = tags.begin()+rand()%(tags.size()-number); for (size_t i = 0; i < number && it != tags.end(); ++i) { StartSearch(true); AddSearch(tag, *it++); std::vector<std::string> paths; MPD::SongIterator s = CommitSearchSongs(), end; for (; s != end; ++s) paths.push_back(s->getURI()); StartCommandsList(); for (const auto &path : paths) AddSong(path); CommitCommandsList(); } return true; }
void Status::Changes::playlist(unsigned previous_version) { { ScopedUnfilteredMenu<MPD::Song> sunfilter(ReapplyFilter::Yes, myPlaylist->main()); if (m_playlist_length < myPlaylist->main().size()) { auto it = myPlaylist->main().begin()+m_playlist_length; auto end = myPlaylist->main().end(); for (; it != end; ++it) myPlaylist->unregisterSong(it->value()); myPlaylist->main().resizeList(m_playlist_length); } MPD::SongIterator s = Mpd.GetPlaylistChanges(previous_version), end; for (; s != end; ++s) { size_t pos = s->getPosition(); myPlaylist->registerSong(*s); if (pos < myPlaylist->main().size()) { // if song's already in playlist, replace it with a new one MPD::Song &old_s = myPlaylist->main()[pos].value(); myPlaylist->unregisterSong(old_s); old_s = std::move(*s); } else // otherwise just add it to playlist myPlaylist->main().addItem(std::move(*s)); } } myPlaylist->reloadTotalLength(); myPlaylist->reloadRemaining(); if (isVisible(myBrowser)) markSongsInPlaylist(myBrowser->main()); if (isVisible(mySearcher)) markSongsInPlaylist(mySearcher->main()); if (isVisible(myLibrary)) { markSongsInPlaylist(myLibrary->Songs); myLibrary->Songs.refresh(); } if (isVisible(myPlaylistEditor)) { markSongsInPlaylist(myPlaylistEditor->Content); myPlaylistEditor->Content.refresh(); } }
void MediaLibrary::update() { if (hasTwoColumns) { if (Albums.empty() || m_albums_update_request) { m_albums_update_request = false; std::map<std::tuple<std::string, std::string, std::string>, time_t> albums; for (MPD::SongIterator s = getDatabaseIterator(Mpd), end; s != end; ++s) { std::string tag; unsigned idx = 0; while (!(tag = s->get(Config.media_lib_primary_tag, idx++)).empty()) { auto key = std::make_tuple(std::move(tag), s->getAlbum(), s->getDate()); auto it = albums.find(key); if (it == albums.end()) albums[std::move(key)] = s->getMTime(); else it->second = s->getMTime(); } } size_t idx = 0; for (const auto &album : albums) { auto entry = AlbumEntry(Album( std::move(std::get<0>(album.first)), std::move(std::get<1>(album.first)), std::move(std::get<2>(album.first)), album.second) ); if (idx < Albums.size()) Albums[idx].value() = std::move(entry); else Albums.addItem(std::move(entry)); ++idx; } if (idx < Albums.size()) Albums.resizeList(idx); std::sort(Albums.beginV(), Albums.endV(), SortAlbumEntries()); Albums.refresh(); } } else { if (Tags.empty() || m_tags_update_request) { m_tags_update_request = false; std::map<std::string, time_t> tags; if (Config.media_library_sort_by_mtime) { for (MPD::SongIterator s = getDatabaseIterator(Mpd), end; s != end; ++s) { std::string tag; unsigned idx = 0; while (!(tag = s->get(Config.media_lib_primary_tag, idx++)).empty()) { auto it = tags.find(tag); if (it == tags.end()) tags[std::move(tag)] = s->getMTime(); else it->second = std::max(it->second, s->getMTime()); } } } else { MPD::StringIterator tag = Mpd.GetList(Config.media_lib_primary_tag), end; for (; tag != end; ++tag) tags[std::move(*tag)] = 0; } size_t idx = 0; for (const auto &tag : tags) { auto ptag = PrimaryTag(std::move(tag.first), tag.second); if (idx < Tags.size()) Tags[idx].value() = std::move(ptag); else Tags.addItem(std::move(ptag)); ++idx; } if (idx < Tags.size()) Tags.resizeList(idx); std::sort(Tags.beginV(), Tags.endV(), SortPrimaryTags()); Tags.refresh(); } if (!Tags.empty() && ((Albums.empty() && Global::Timer - m_timer > m_fetching_delay) || m_albums_update_request) ) { m_albums_update_request = false; auto &primary_tag = Tags.current()->value().tag(); Mpd.StartSearch(true); Mpd.AddSearch(Config.media_lib_primary_tag, primary_tag); std::map<std::tuple<std::string, std::string>, time_t> albums; for (MPD::SongIterator s = Mpd.CommitSearchSongs(), end; s != end; ++s) { auto key = std::make_tuple(s->getAlbum(), s->getDate()); auto it = albums.find(key); if (it == albums.end()) albums[std::move(key)] = s->getMTime(); else it->second = std::max(it->second, s->getMTime()); }; size_t idx = 0; for (const auto &album : albums) { auto entry = AlbumEntry(Album( primary_tag, std::move(std::get<0>(album.first)), std::move(std::get<1>(album.first)), album.second) ); if (idx < Albums.size()) { Albums[idx].value() = std::move(entry); Albums[idx].setSeparator(false); } else Albums.addItem(std::move(entry)); ++idx; } 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.empty() && Global::Timer - m_timer > m_fetching_delay) || m_songs_update_request) ) { m_songs_update_request = false; auto &album = Albums.current()->value(); Mpd.StartSearch(true); Mpd.AddSearch(Config.media_lib_primary_tag, album.entry().tag()); if (!album.isAllTracksEntry()) { Mpd.AddSearch(MPD_TAG_ALBUM, album.entry().album()); Mpd.AddSearch(MPD_TAG_DATE, album.entry().date()); } size_t idx = 0; for (MPD::SongIterator s = Mpd.CommitSearchSongs(), end; s != end; ++s, ++idx) { bool in_playlist = myPlaylist->checkForSong(*s); if (idx < Songs.size()) { Songs[idx].value() = std::move(*s); Songs[idx].setBold(in_playlist); } else { auto properties = NC::List::Properties::Selectable; if (in_playlist) properties |= NC::List::Properties::Bold; Songs.addItem(std::move(*s), properties); } }; if (idx < Songs.size()) Songs.resizeList(idx); std::sort(Songs.begin(), Songs.end(), SortSongs(!album.isAllTracksEntry())); Songs.refresh(); } }
void MediaLibrary::update() { if (hasTwoColumns) { ScopedUnfilteredMenu<AlbumEntry> sunfilter_albums(ReapplyFilter::No, Albums); if (Albums.empty() || m_albums_update_request) { m_albums_update_request = false; sunfilter_albums.set(ReapplyFilter::Yes, true); std::map<std::tuple<std::string, std::string, std::string>, time_t> albums; for (MPD::SongIterator s = getDatabaseIterator(Mpd), end; s != end; ++s) { std::string tag; unsigned idx = 0; while (!(tag = s->get(Config.media_lib_primary_tag, idx++)).empty()) { auto key = std::make_tuple( std::move(tag), s->getAlbum(), Date_(s->getDate())); auto it = albums.find(key); if (it == albums.end()) albums[std::move(key)] = s->getMTime(); else it->second = s->getMTime(); } } size_t idx = 0; for (const auto &album : albums) { auto entry = AlbumEntry( Album(std::move(std::get<0>(album.first)), std::move(std::get<1>(album.first)), std::move(std::get<2>(album.first)), album.second)); if (idx < Albums.size()) Albums[idx].value() = std::move(entry); else Albums.addItem(std::move(entry)); ++idx; } if (idx < Albums.size()) Albums.resizeList(idx); std::sort(Albums.beginV(), Albums.endV(), SortAlbumEntries()); } } else { { ScopedUnfilteredMenu<PrimaryTag> sunfilter_tags(ReapplyFilter::No, Tags); if (Tags.empty() || m_tags_update_request) { m_tags_update_request = false; sunfilter_tags.set(ReapplyFilter::Yes, true); std::map<std::string, time_t> tags; if (Config.media_library_sort_by_mtime) { for (MPD::SongIterator s = getDatabaseIterator(Mpd), end; s != end; ++s) { std::string tag; unsigned idx = 0; while (!(tag = s->get(Config.media_lib_primary_tag, idx++)).empty()) { auto it = tags.find(tag); if (it == tags.end()) tags[std::move(tag)] = s->getMTime(); else it->second = std::max(it->second, s->getMTime()); } } } else { MPD::StringIterator tag = Mpd.GetList(Config.media_lib_primary_tag), end; for (; tag != end; ++tag) tags[std::move(*tag)] = 0; } size_t idx = 0; for (const auto &tag : tags) { auto ptag = PrimaryTag(std::move(tag.first), tag.second); if (idx < Tags.size()) Tags[idx].value() = std::move(ptag); else Tags.addItem(std::move(ptag)); ++idx; } if (idx < Tags.size()) Tags.resizeList(idx); std::sort(Tags.beginV(), Tags.endV(), SortPrimaryTags()); } } { ScopedUnfilteredMenu<AlbumEntry> sunfilter_albums(ReapplyFilter::No, Albums); if (!Tags.empty() && ((Albums.empty() && Global::Timer - m_timer > m_fetching_delay) || m_albums_update_request)) { m_albums_update_request = false; sunfilter_albums.set(ReapplyFilter::Yes, true); auto &primary_tag = Tags.current()->value().tag(); Mpd.StartSearch(true); Mpd.AddSearch(Config.media_lib_primary_tag, primary_tag); std::map<std::tuple<std::string, std::string>, time_t> albums; for (MPD::SongIterator s = Mpd.CommitSearchSongs(), end; s != end; ++s) { auto key = std::make_tuple(s->getAlbum(), Date_(s->getDate())); auto it = albums.find(key); if (it == albums.end()) albums[std::move(key)] = s->getMTime(); else it->second = std::max(it->second, s->getMTime()); }; size_t idx = 0; for (const auto &album : albums) { auto entry = AlbumEntry( Album(primary_tag, std::move(std::get<0>(album.first)), std::move(std::get<1>(album.first)), album.second)); if (idx < Albums.size()) { Albums[idx].value() = std::move(entry); Albums[idx].setSeparator(false); } else Albums.addItem(std::move(entry)); ++idx; } 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)); } } } } ScopedUnfilteredMenu<MPD::Song> sunfilter_songs(ReapplyFilter::No, Songs); if (!Albums.empty() && ((Songs.empty() && Global::Timer - m_timer > m_fetching_delay) || m_songs_update_request)) { m_songs_update_request = false; sunfilter_songs.set(ReapplyFilter::Yes, true); auto &album = Albums.current()->value(); size_t idx = 0; for (MPD::SongIterator s = getSongsFromAlbum(album), end; s != end; ++s, ++idx) { if (idx < Songs.size()) Songs[idx].value() = std::move(*s); else Songs.addItem(std::move(*s)); }; if (idx < Songs.size()) Songs.resizeList(idx); std::sort(Songs.begin(), Songs.end(), SortSongs()); } }