Beispiel #1
0
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;
}
Beispiel #2
0
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();
	}
}
Beispiel #3
0
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();
	}
}
Beispiel #4
0
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());
	}
}