mpd: make functions take item consumer instead of returning vector of items

This commit is contained in:
Andrzej Rybczak
2012-10-01 20:44:22 +02:00
parent 60faa15462
commit 9a292ca20d
14 changed files with 206 additions and 209 deletions

View File

@@ -1407,24 +1407,28 @@ void EditLibraryTag::Run()
MPD::MutableSong::SetFunction set = tagTypeToSetFunction(Config.media_lib_primary_tag); MPD::MutableSong::SetFunction set = tagTypeToSetFunction(Config.media_lib_primary_tag);
assert(set); assert(set);
bool success = true; bool success = true;
MPD::SongList songs = Mpd.CommitSearchSongs(); std::string dir_to_update;
for (auto s = songs.begin(); s != songs.end(); ++s) Mpd.CommitSearchSongs([set, &dir_to_update, &new_tag, &success](MPD::Song &&s) {
{ if (!success)
MPD::MutableSong es = *s; return;
es.setTags(set, new_tag, Config.tags_separator); MPD::MutableSong ms = s;
Statusbar::msg("Updating tags in \"%s\"...", es.getName().c_str()); ms.setTags(set, new_tag, Config.tags_separator);
std::string path = Config.mpd_music_dir + es.getURI(); Statusbar::msg("Updating tags in \"%s\"...", ms.getName().c_str());
if (!Tags::write(es)) std::string path = Config.mpd_music_dir + ms.getURI();
if (!Tags::write(ms))
{ {
const char msg[] = "Error while updating tags in \"%ls\""; const char msg[] = "Error while updating tags in \"%ls\"";
Statusbar::msg(msg, wideShorten(ToWString(es.getURI()), COLS-const_strlen(msg)).c_str()); Statusbar::msg(msg, wideShorten(ToWString(ms.getURI()), COLS-const_strlen(msg)).c_str());
success = false; success = false;
break;
} }
} if (dir_to_update.empty())
dir_to_update = s.getURI();
else
dir_to_update = getSharedDirectory(dir_to_update, s.getURI());
});
if (success) if (success)
{ {
Mpd.UpdateDirectory(getSharedDirectory(songs.begin(), songs.end())); Mpd.UpdateDirectory(dir_to_update);
Statusbar::msg("Tags updated successfully"); Statusbar::msg("Tags updated successfully");
} }
} }

View File

@@ -325,16 +325,18 @@ MPD::SongList Browser::getSelectedSongs()
else else
# endif // !WIN32 # endif // !WIN32
{ {
auto list = Mpd.GetDirectoryRecursive(item.name); Mpd.GetDirectoryRecursive(item.name, [&result](MPD::Song &&s) {
result.insert(result.end(), list.begin(), list.end()); result.push_back(s);
});
} }
} }
else if (item.type == itSong) else if (item.type == itSong)
result.push_back(*item.song); result.push_back(*item.song);
else if (item.type == itPlaylist) else if (item.type == itPlaylist)
{ {
auto list = Mpd.GetPlaylistContent(item.name); Mpd.GetPlaylistContent(item.name, [&result](MPD::Song &&s) {
result.insert(result.end(), list.begin(), list.end()); result.push_back(s);
});
} }
}; };
for (auto it = w.begin(); it != w.end(); ++it) for (auto it = w.begin(); it != w.end(); ++it)
@@ -395,7 +397,9 @@ void Browser::GetDirectory(std::string dir, std::string subdir)
if (isLocal()) if (isLocal())
GetLocalDirectory(list); GetLocalDirectory(list);
else else
list = Mpd.GetDirectory(dir); Mpd.GetDirectory(dir, [&list](MPD::Item &&item) {
list.push_back(item);
});
# else # else
list = Mpd.GetDirectory(dir); list = Mpd.GetDirectory(dir);
# endif // !WIN32 # endif // !WIN32

View File

@@ -324,9 +324,9 @@ void MediaLibrary::update()
Mpd.AddSearch(Config.media_lib_primary_tag, Mpd.AddSearch(Config.media_lib_primary_tag,
Tags.current().value().tag()); Tags.current().value().tag());
Mpd.AddSearch(MPD_TAG_ALBUM, album); Mpd.AddSearch(MPD_TAG_ALBUM, album);
auto dates = Mpd.CommitSearchTags(); Mpd.CommitSearchTags([this, &album, &mtime](std::string &&date) {
for (auto date = dates.begin(); date != dates.end(); ++date) Albums.addItem(SearchConstraints(album, date, mtime));
Albums.addItem(SearchConstraints(album, *date, mtime)); });
} }
else else
Albums.addItem(SearchConstraints(album, "", mtime)); Albums.addItem(SearchConstraints(album, "", mtime));
@@ -347,7 +347,10 @@ void MediaLibrary::update()
Albums << NC::XY(0, 0) << "Fetching albums..."; Albums << NC::XY(0, 0) << "Fetching albums...";
Albums.Window::refresh(); Albums.Window::refresh();
Mpd.BlockIdle(true); Mpd.BlockIdle(true);
auto artists = Mpd.GetList(Config.media_lib_primary_tag); MPD::StringList artists;
Mpd.GetList(Config.media_lib_primary_tag, [&artists](std::string &&artist) {
artists.push_back(artist);
});
for (auto artist = artists.begin(); artist != artists.end(); ++artist) for (auto artist = artists.begin(); artist != artists.end(); ++artist)
{ {
Mpd.StartFieldSearchMTime(MPD_TAG_ALBUM, Config.media_library_sort_by_mtime); Mpd.StartFieldSearchMTime(MPD_TAG_ALBUM, Config.media_library_sort_by_mtime);
@@ -364,9 +367,9 @@ void MediaLibrary::update()
Mpd.StartFieldSearch(MPD_TAG_DATE); Mpd.StartFieldSearch(MPD_TAG_DATE);
Mpd.AddSearch(Config.media_lib_primary_tag, *artist); Mpd.AddSearch(Config.media_lib_primary_tag, *artist);
Mpd.AddSearch(MPD_TAG_ALBUM, album); Mpd.AddSearch(MPD_TAG_ALBUM, album);
auto dates = Mpd.CommitSearchTags(); Mpd.CommitSearchTags([this, &artist, &album, &mtime](std::string &&date) {
for (auto date = dates.begin(); date != dates.end(); ++date) Albums.addItem(SearchConstraints(*artist, album, date, mtime));
Albums.addItem(SearchConstraints(*artist, album, *date, mtime)); });
} }
else else
Albums.addItem(SearchConstraints(*artist, album, *artist, mtime)); Albums.addItem(SearchConstraints(*artist, album, *artist, mtime));
@@ -403,9 +406,9 @@ void MediaLibrary::update()
if (Config.media_library_display_date) if (Config.media_library_display_date)
Mpd.AddSearch(MPD_TAG_DATE, Albums.current().value().Date); Mpd.AddSearch(MPD_TAG_DATE, Albums.current().value().Date);
} }
auto songs = Mpd.CommitSearchSongs(); Mpd.CommitSearchSongs([this](MPD::Song &&s) {
for (auto s = songs.begin(); s != songs.end(); ++s) Songs.addItem(s, myPlaylist->checkForSong(s));
Songs.addItem(*s, myPlaylist->checkForSong(*s)); });
if (Albums.current().value().Date == AllTracksMarker) if (Albums.current().value().Date == AllTracksMarker)
std::sort(Songs.beginV(), Songs.endV(), SortAllTracks()); std::sort(Songs.beginV(), Songs.endV(), SortAllTracks());
@@ -675,9 +678,9 @@ MPD::SongList MediaLibrary::getSelectedSongs()
auto tag_handler = [&result](const std::string &tag) { auto tag_handler = [&result](const std::string &tag) {
Mpd.StartSearch(true); Mpd.StartSearch(true);
Mpd.AddSearch(Config.media_lib_primary_tag, tag); Mpd.AddSearch(Config.media_lib_primary_tag, tag);
auto songs = Mpd.CommitSearchSongs(); Mpd.CommitSearchSongs([&result](MPD::Song &&s) {
std::sort(songs.begin(), songs.end(), SortAllTracks()); result.push_back(s);
result.insert(result.end(), songs.begin(), songs.end()); });
}; };
for (auto it = Tags.begin(); it != Tags.end(); ++it) for (auto it = Tags.begin(); it != Tags.end(); ++it)
if (it->isSelected()) if (it->isSelected())
@@ -701,9 +704,11 @@ MPD::SongList MediaLibrary::getSelectedSongs()
Tags.current().value().tag()); Tags.current().value().tag());
Mpd.AddSearch(MPD_TAG_ALBUM, sc.Album); Mpd.AddSearch(MPD_TAG_ALBUM, sc.Album);
Mpd.AddSearch(MPD_TAG_DATE, sc.Date); Mpd.AddSearch(MPD_TAG_DATE, sc.Date);
auto songs = Mpd.CommitSearchSongs(); size_t begin = result.size();
std::sort(songs.begin(), songs.end(), SortSongsByTrack); Mpd.CommitSearchSongs([&result](MPD::Song &&s) {
result.insert(result.end(), songs.begin(), songs.end()); result.push_back(s);
});
std::sort(result.begin()+begin, result.end(), SortSongsByTrack);
} }
} }
// if no item is selected, add songs from right column // if no item is selected, add songs from right column

View File

@@ -663,19 +663,17 @@ bool Connection::Rename(const std::string &from, const std::string &to)
} }
} }
SongList Connection::GetPlaylistChanges(unsigned version) void Connection::GetPlaylistChanges(unsigned version, SongConsumer f)
{ {
SongList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_send_queue_changes_meta(itsConnection, version); mpd_send_queue_changes_meta(itsConnection, version);
while (mpd_song *s = mpd_recv_song(itsConnection)) while (mpd_song *s = mpd_recv_song(itsConnection))
result.push_back(Song(s)); f(Song(s));
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
Song Connection::GetSong(const std::string &path) Song Connection::GetSong(const std::string &path)
@@ -706,19 +704,17 @@ Song Connection::GetCurrentlyPlayingSong()
return result; return result;
} }
SongList Connection::GetPlaylistContent(const std::string &path) void Connection::GetPlaylistContent(const std::string &path, SongConsumer f)
{ {
SongList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_send_list_playlist_meta(itsConnection, path.c_str()); mpd_send_list_playlist_meta(itsConnection, path.c_str());
while (mpd_song *s = mpd_recv_song(itsConnection)) while (mpd_song *s = mpd_recv_song(itsConnection))
result.push_back(Song(s)); f(Song(s));
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
void Connection::GetSupportedExtensions(std::set<std::string> &acc) void Connection::GetSupportedExtensions(std::set<std::string> &acc)
@@ -944,7 +940,10 @@ bool Connection::AddRandomTag(mpd_tag_type tag, size_t number)
return false; return false;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
auto tags = GetList(tag); StringList tags;
GetList(tag, [&tags](std::string &&tag_name) {
tags.push_back(tag_name);
});
if (number > tags.size()) if (number > tags.size())
{ {
if (itsErrorHandler) if (itsErrorHandler)
@@ -959,7 +958,10 @@ bool Connection::AddRandomTag(mpd_tag_type tag, size_t number)
{ {
StartSearch(1); StartSearch(1);
AddSearch(tag, *it++); AddSearch(tag, *it++);
auto songs = CommitSearchSongs(); SongList songs;
CommitSearchSongs([&songs](MPD::Song &&s) {
songs.push_back(s);
});
StartCommandsList(); StartCommandsList();
for (auto s = songs.begin(); s != songs.end(); ++s) for (auto s = songs.begin(); s != songs.end(); ++s)
AddSong(*s); AddSong(*s);
@@ -1110,35 +1112,31 @@ int Connection::SavePlaylist(const std::string &name)
return CheckForErrors(); return CheckForErrors();
} }
StringList Connection::GetPlaylists() void Connection::GetPlaylists(StringConsumer f)
{ {
StringList result;
if (!itsConnection) if (!itsConnection)
return result; return;
auto items = GetDirectory("/"); GetDirectory("/", [&f](Item &&item) {
for (auto it = items.begin(); it != items.end(); ++it) if (item.type == itPlaylist)
if (it->type == itPlaylist) f(std::move(item.name));
result.push_back(it->name); });
return result;
} }
StringList Connection::GetList(mpd_tag_type type) void Connection::GetList(mpd_tag_type type, StringConsumer f)
{ {
StringList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_search_db_tags(itsConnection, type); mpd_search_db_tags(itsConnection, type);
mpd_search_commit(itsConnection); mpd_search_commit(itsConnection);
while (mpd_pair *item = mpd_recv_pair_tag(itsConnection, type)) while (mpd_pair *item = mpd_recv_pair_tag(itsConnection, type))
{ {
result.push_back(item->value); f(std::string(item->value));
mpd_return_pair(itsConnection, item); mpd_return_pair(itsConnection, item);
} }
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
TagMTimeList Connection::GetListMTime(mpd_tag_type type, bool get_mtime) TagMTimeList Connection::GetListMTime(mpd_tag_type type, bool get_mtime)
@@ -1237,37 +1235,33 @@ void Connection::AddSearchURI(const std::string &str) const
mpd_search_add_uri_constraint(itsConnection, MPD_OPERATOR_DEFAULT, str.c_str()); mpd_search_add_uri_constraint(itsConnection, MPD_OPERATOR_DEFAULT, str.c_str());
} }
SongList Connection::CommitSearchSongs() void Connection::CommitSearchSongs(SongConsumer f)
{ {
SongList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_search_commit(itsConnection); mpd_search_commit(itsConnection);
while (mpd_song *s = mpd_recv_song(itsConnection)) while (mpd_song *s = mpd_recv_song(itsConnection))
result.push_back(Song(s)); f(Song(s));
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
StringList Connection::CommitSearchTags() void Connection::CommitSearchTags(StringConsumer f)
{ {
StringList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_search_commit(itsConnection); mpd_search_commit(itsConnection);
while (mpd_pair *tag = mpd_recv_pair_tag(itsConnection, itsSearchedField)) while (mpd_pair *tag = mpd_recv_pair_tag(itsConnection, itsSearchedField))
{ {
result.push_back(tag->value); f(std::string(tag->value));
mpd_return_pair(itsConnection, tag); mpd_return_pair(itsConnection, tag);
} }
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
TagMTimeList Connection::CommitSearchTagsMTime() TagMTimeList Connection::CommitSearchTagsMTime()
@@ -1314,14 +1308,13 @@ TagMTimeList Connection::CommitSearchTagsMTime()
return result; return result;
} }
ItemList Connection::GetDirectory(const std::string &path) void Connection::GetDirectory(const std::string &directory, ItemConsumer f)
{ {
ItemList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_send_list_meta(itsConnection, path.c_str()); mpd_send_list_meta(itsConnection, directory.c_str());
while (mpd_entity *item = mpd_recv_entity(itsConnection)) while (mpd_entity *item = mpd_recv_entity(itsConnection))
{ {
Item it; Item it;
@@ -1343,77 +1336,68 @@ ItemList Connection::GetDirectory(const std::string &path)
assert(false); assert(false);
} }
mpd_entity_free(item); mpd_entity_free(item);
result.push_back(std::move(it)); f(std::move(it));
} }
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
SongList Connection::GetDirectoryRecursive(const std::string &path) void Connection::GetDirectoryRecursive(const std::string &directory, SongConsumer f)
{ {
SongList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_send_list_all_meta(itsConnection, path.c_str()); mpd_send_list_all_meta(itsConnection, directory.c_str());
while (mpd_song *s = mpd_recv_song(itsConnection)) while (mpd_song *s = mpd_recv_song(itsConnection))
result.push_back(Song(s)); f(Song(s));
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
StringList Connection::GetDirectories(const std::string &path) void Connection::GetDirectories(const std::string &directory, StringConsumer f)
{ {
StringList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_send_list_meta(itsConnection, path.c_str()); mpd_send_list_meta(itsConnection, directory.c_str());
while (mpd_directory *dir = mpd_recv_directory(itsConnection)) while (mpd_directory *dir = mpd_recv_directory(itsConnection))
{ {
result.push_back(mpd_directory_get_path(dir)); f(std::string(mpd_directory_get_path(dir)));
mpd_directory_free(dir); mpd_directory_free(dir);
} }
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
SongList Connection::GetSongs(const std::string &path) void Connection::GetSongs(const std::string &directory, SongConsumer f)
{ {
SongList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_send_list_meta(itsConnection, path.c_str()); mpd_send_list_meta(itsConnection, directory.c_str());
while (mpd_song *s = mpd_recv_song(itsConnection)) while (mpd_song *s = mpd_recv_song(itsConnection))
result.push_back(Song(s)); f(Song(s));
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
OutputList Connection::GetOutputs() void Connection::GetOutputs(OutputConsumer f)
{ {
OutputList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_send_outputs(itsConnection); mpd_send_outputs(itsConnection);
while (mpd_output *output = mpd_recv_output(itsConnection)) while (mpd_output *output = mpd_recv_output(itsConnection))
{ {
result.push_back(Output(mpd_output_get_name(output), mpd_output_get_enabled(output))); f(Output(mpd_output_get_name(output), mpd_output_get_enabled(output)));
mpd_output_free(output); mpd_output_free(output);
} }
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
bool Connection::EnableOutput(int id) bool Connection::EnableOutput(int id)
@@ -1448,40 +1432,36 @@ bool Connection::DisableOutput(int id)
} }
} }
StringList Connection::GetURLHandlers() void Connection::GetURLHandlers(StringConsumer f)
{ {
StringList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_send_list_url_schemes(itsConnection); mpd_send_list_url_schemes(itsConnection);
while (mpd_pair *handler = mpd_recv_pair_named(itsConnection, "handler")) while (mpd_pair *handler = mpd_recv_pair_named(itsConnection, "handler"))
{ {
result.push_back(handler->value); f(std::string(handler->value));
mpd_return_pair(itsConnection, handler); mpd_return_pair(itsConnection, handler);
} }
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
StringList Connection::GetTagTypes() void Connection::GetTagTypes(StringConsumer f)
{ {
StringList result;
if (!itsConnection) if (!itsConnection)
return result; return;
assert(!isCommandsListEnabled); assert(!isCommandsListEnabled);
GoBusy(); GoBusy();
mpd_send_list_tag_types(itsConnection); mpd_send_list_tag_types(itsConnection);
while (mpd_pair *tag_type = mpd_recv_pair_named(itsConnection, "tagtype")) while (mpd_pair *tag_type = mpd_recv_pair_named(itsConnection, "tagtype"))
{ {
result.push_back(tag_type->value); f(std::string(tag_type->value));
mpd_return_pair(itsConnection, tag_type); mpd_return_pair(itsConnection, tag_type);
} }
mpd_response_finish(itsConnection); mpd_response_finish(itsConnection);
GoIdle(); GoIdle();
return result;
} }
int Connection::CheckForErrors() int Connection::CheckForErrors()

View File

@@ -128,11 +128,14 @@ typedef std::vector<Output> OutputList;
class Connection class Connection
{ {
friend struct Statistics;
typedef void (*StatusUpdater) (Connection *, StatusChanges, void *); typedef void (*StatusUpdater) (Connection *, StatusChanges, void *);
typedef void (*ErrorHandler) (Connection *, int, const char *, void *); typedef void (*ErrorHandler) (Connection *, int, const char *, void *);
typedef std::function<void(Item &&)> ItemConsumer;
typedef std::function<void(Output &&)> OutputConsumer;
typedef std::function<void(Song &&)> SongConsumer;
typedef std::function<void(std::string &&)> StringConsumer;
public: public:
Connection(); Connection();
~Connection(); ~Connection();
@@ -197,14 +200,14 @@ public:
unsigned GetBitrate() const { return itsCurrentStatus ? mpd_status_get_kbit_rate(itsCurrentStatus) : 0; } unsigned GetBitrate() const { return itsCurrentStatus ? mpd_status_get_kbit_rate(itsCurrentStatus) : 0; }
size_t GetPlaylistLength() const { return itsCurrentStatus ? mpd_status_get_queue_length(itsCurrentStatus) : 0; } size_t GetPlaylistLength() const { return itsCurrentStatus ? mpd_status_get_queue_length(itsCurrentStatus) : 0; }
SongList GetPlaylistChanges(unsigned); void GetPlaylistChanges(unsigned, SongConsumer f);
const std::string &GetErrorMessage() const { return itsErrorMessage; } const std::string &GetErrorMessage() const { return itsErrorMessage; }
Song GetCurrentlyPlayingSong(); Song GetCurrentlyPlayingSong();
int GetCurrentSongPos() const; int GetCurrentSongPos() const;
Song GetSong(const std::string &); Song GetSong(const std::string &);
SongList GetPlaylistContent(const std::string &); void GetPlaylistContent(const std::string &name, SongConsumer f);
void GetSupportedExtensions(std::set<std::string> &); void GetSupportedExtensions(std::set<std::string> &);
@@ -246,28 +249,26 @@ public:
void AddSearch(mpd_tag_type, const std::string &) const; void AddSearch(mpd_tag_type, const std::string &) const;
void AddSearchAny(const std::string &str) const; void AddSearchAny(const std::string &str) const;
void AddSearchURI(const std::string &str) const; void AddSearchURI(const std::string &str) const;
SongList CommitSearchSongs(); void CommitSearchSongs(SongConsumer f);
StringList CommitSearchTags(); void CommitSearchTags(StringConsumer f);
TagMTimeList CommitSearchTagsMTime(); TagMTimeList CommitSearchTagsMTime();
StringList GetPlaylists(); void GetPlaylists(StringConsumer f);
StringList GetList(mpd_tag_type); void GetList(mpd_tag_type type, StringConsumer f);
TagMTimeList GetListMTime(mpd_tag_type, bool); TagMTimeList GetListMTime(mpd_tag_type, bool);
ItemList GetDirectory(const std::string &); void GetDirectory(const std::string &directory, ItemConsumer f);
SongList GetDirectoryRecursive(const std::string &); void GetDirectoryRecursive(const std::string &directory, SongConsumer f);
SongList GetSongs(const std::string &); void GetSongs(const std::string &directory, SongConsumer f);
StringList GetDirectories(const std::string &); void GetDirectories(const std::string &directory, StringConsumer f);
OutputList GetOutputs(); void GetOutputs(OutputConsumer f);
bool EnableOutput(int); bool EnableOutput(int);
bool DisableOutput(int); bool DisableOutput(int);
StringList GetURLHandlers(); void GetURLHandlers(StringConsumer f);
StringList GetTagTypes(); void GetTagTypes(StringConsumer f);
private: private:
//void check
void GoIdle(); void GoIdle();
int GoBusy(); int GoBusy();

View File

@@ -99,9 +99,9 @@ void Outputs::mouseButtonPressed(MEVENT me)
void Outputs::FetchList() void Outputs::FetchList()
{ {
w.clear(); w.clear();
auto outputs = Mpd.GetOutputs(); Mpd.GetOutputs([this](MPD::Output &&output) {
for (auto o = outputs.begin(); o != outputs.end(); ++o) w.addItem(output, output.isEnabled());
w.addItem(*o, o->isEnabled()); });
if (myScreen == this) if (myScreen == this)
w.refresh(); w.refresh();
} }

View File

@@ -130,16 +130,18 @@ void PlaylistEditor::update()
playlistsUpdateRequested = false; playlistsUpdateRequested = false;
Playlists.clearSearchResults(); Playlists.clearSearchResults();
withUnfilteredMenuReapplyFilter(Playlists, [this]() { withUnfilteredMenuReapplyFilter(Playlists, [this]() {
auto list = Mpd.GetPlaylists(); size_t idx = 0;
std::sort(list.begin(), list.end(), Mpd.GetPlaylists([this, &idx](std::string &&playlist) {
if (idx < Playlists.size())
Playlists[idx].value() = playlist;
else
Playlists.addItem(playlist);
++idx;
});
if (idx < Playlists.size())
Playlists.resizeList(idx);
std::sort(Playlists.beginV(), Playlists.endV(),
LocaleBasedSorting(std::locale(), Config.ignore_leading_the)); LocaleBasedSorting(std::locale(), Config.ignore_leading_the));
auto playlist = list.begin();
if (Playlists.size() > list.size())
Playlists.resizeList(list.size());
for (auto it = Playlists.begin(); it != Playlists.end(); ++it, ++playlist)
it->value() = *playlist;
for (; playlist != list.end(); ++playlist)
Playlists.addItem(*playlist);
}); });
Playlists.refresh(); Playlists.refresh();
} }
@@ -149,25 +151,27 @@ void PlaylistEditor::update()
contentUpdateRequested = false; contentUpdateRequested = false;
Content.clearSearchResults(); Content.clearSearchResults();
withUnfilteredMenuReapplyFilter(Content, [this]() { withUnfilteredMenuReapplyFilter(Content, [this]() {
auto list = Mpd.GetPlaylistContent(Playlists.current().value()); size_t idx = 0;
auto song = list.begin(); Mpd.GetPlaylistContent(Playlists.current().value(), [this, &idx](MPD::Song &&s) {
if (Content.size() > list.size()) if (idx < Content.size())
Content.resizeList(list.size()); {
for (auto it = Content.begin(); it != Content.end(); ++it, ++song) Content[idx].value() = s;
{ Content[idx].setBold(myPlaylist->checkForSong(s));
it->value() = *song; }
it->setBold(myPlaylist->checkForSong(*song)); else
} Content.addItem(s, myPlaylist->checkForSong(s));
for (; song != list.end(); ++song) ++idx;
Content.addItem(*song, myPlaylist->checkForSong(*song)); });
if (idx < Content.size())
Content.resizeList(idx);
std::string title; std::string title;
if (Config.titles_visibility) if (Config.titles_visibility)
{ {
title = "Playlist content"; title = "Playlist content";
title += " ("; title += " (";
title += unsignedLongIntTo<std::string>::apply(list.size()); title += unsignedLongIntTo<std::string>::apply(Content.size());
title += " item"; title += " item";
if (list.size() == 1) if (Content.size() == 1)
title += ")"; title += ")";
else else
title += "s)"; title += "s)";
@@ -418,8 +422,9 @@ MPD::SongList PlaylistEditor::getSelectedSongs()
if (it->isSelected()) if (it->isSelected())
{ {
any_selected = true; any_selected = true;
auto songs = Mpd.GetPlaylistContent(it->value()); Mpd.GetPlaylistContent(it->value(), [&result](MPD::Song &&s) {
result.insert(result.end(), songs.begin(), songs.end()); result.push_back(s);
});
} }
} }
// we don't check for empty result here as it's possible that // we don't check for empty result here as it's possible that

View File

@@ -410,21 +410,19 @@ void SearchEngine::Search()
Mpd.AddSearch(MPD_TAG_DATE, itsConstraints[9]); Mpd.AddSearch(MPD_TAG_DATE, itsConstraints[9]);
if (!itsConstraints[10].empty()) if (!itsConstraints[10].empty())
Mpd.AddSearch(MPD_TAG_COMMENT, itsConstraints[10]); Mpd.AddSearch(MPD_TAG_COMMENT, itsConstraints[10]);
auto songs = Mpd.CommitSearchSongs(); Mpd.CommitSearchSongs([this](MPD::Song &&s) {
for (auto s = songs.begin(); s != songs.end(); ++s) w.addItem(s);
w.addItem(*s); });
return; return;
} }
MPD::SongList list; MPD::SongList list;
if (Config.search_in_db) if (Config.search_in_db)
list = Mpd.GetDirectoryRecursive("/"); Mpd.GetDirectoryRecursive("/", [&list](MPD::Song &&s) {
list.push_back(s);
});
else else
{ list.insert(list.end(), myPlaylist->main().beginV(), myPlaylist->main().endV());
list.reserve(myPlaylist->main().size());
for (auto s = myPlaylist->main().beginV(); s != myPlaylist->main().endV(); ++s)
list.push_back(*s);
}
bool any_found = 1; bool any_found = 1;
bool found = 1; bool found = 1;

View File

@@ -198,16 +198,15 @@ void SelectedItemsAdder::populatePlaylistSelector(BaseScreen *old_screen)
// stored playlists don't support songs from outside of mpd database // stored playlists don't support songs from outside of mpd database
if (old_screen != myBrowser || !myBrowser->isLocal()) if (old_screen != myBrowser || !myBrowser->isLocal())
{ {
auto playlists = Mpd.GetPlaylists(); size_t begin = m_playlist_selector.size();
std::sort(playlists.begin(), playlists.end(), Mpd.GetPlaylists([this](std::string &&playlist) {
LocaleBasedSorting(std::locale(), Config.ignore_leading_the)); m_playlist_selector.addItem(Component::Item::Type(playlist,
for (auto pl = playlists.begin(); pl != playlists.end(); ++pl) std::bind(&Self::addToExistingPlaylist, this, playlist)
{
m_playlist_selector.addItem(Component::Item::Type(*pl,
std::bind(&Self::addToExistingPlaylist, this, *pl)
)); ));
} });
if (!playlists.empty()) std::sort(m_playlist_selector.beginV()+begin, m_playlist_selector.endV(),
LocaleBasedSorting(std::locale(), Config.ignore_leading_the));
if (begin < m_playlist_selector.size())
m_playlist_selector.addSeparator(); m_playlist_selector.addSeparator();
} }
m_playlist_selector.addItem(Component::Item::Type("Cancel", m_playlist_selector.addItem(Component::Item::Type("Cancel",

View File

@@ -36,8 +36,12 @@ ServerInfo::ServerInfo()
{ {
SetDimensions(); SetDimensions();
w = NC::Scrollpad((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "MPD server info", Config.main_color, Config.window_border); w = NC::Scrollpad((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "MPD server info", Config.main_color, Config.window_border);
itsURLHandlers = Mpd.GetURLHandlers(); Mpd.GetURLHandlers([this](std::string &&handler) {
itsTagTypes = Mpd.GetTagTypes(); itsURLHandlers.push_back(handler);
});
Mpd.GetTagTypes([this](std::string &&tag_type) {
itsTagTypes.push_back(tag_type);
});
} }
void ServerInfo::switchTo() void ServerInfo::switchTo()

View File

@@ -141,21 +141,19 @@ void Status::Changes::playlist()
myPlaylist->main().resizeList(playlist_length); myPlaylist->main().resizeList(playlist_length);
} }
auto songs = Mpd.GetPlaylistChanges(Mpd.GetOldPlaylistID()); Mpd.GetPlaylistChanges(Mpd.GetOldPlaylistID(), [](MPD::Song &&s) {
for (auto s = songs.begin(); s != songs.end(); ++s) size_t pos = s.getPosition();
{
size_t pos = s->getPosition();
if (pos < myPlaylist->main().size()) if (pos < myPlaylist->main().size())
{ {
// if song's already in playlist, replace it with a new one // if song's already in playlist, replace it with a new one
MPD::Song &old_s = myPlaylist->main()[pos].value(); MPD::Song &old_s = myPlaylist->main()[pos].value();
myPlaylist->unregisterHash(old_s.getHash()); myPlaylist->unregisterHash(old_s.getHash());
old_s = *s; old_s = s;
} }
else // otherwise just add it to playlist else // otherwise just add it to playlist
myPlaylist->main().addItem(*s); myPlaylist->main().addItem(s);
myPlaylist->registerHash(s->getHash()); myPlaylist->registerHash(s.getHash());
} });
}); });
if (Mpd.isPlaying()) if (Mpd.isPlaying())

View File

@@ -226,39 +226,28 @@ void TagEditor::update()
Dirs->Window::clear(); Dirs->Window::clear();
Tags->clear(); Tags->clear();
int highlightme = -1;
auto dirs = Mpd.GetDirectories(itsBrowsedDir);
std::sort(dirs.begin(), dirs.end(), LocaleBasedSorting(std::locale(), Config.ignore_leading_the));
if (itsBrowsedDir != "/") if (itsBrowsedDir != "/")
{ Dirs->addItem(std::make_pair("..", getParentDirectory(itsBrowsedDir)));
size_t slash = itsBrowsedDir.rfind("/");
std::string parent = slash != std::string::npos ? itsBrowsedDir.substr(0, slash) : "/";
Dirs->addItem(make_pair("..", parent));
}
else else
Dirs->addItem(std::make_pair(".", "/")); Dirs->addItem(std::make_pair(".", "/"));
for (auto dir = dirs.begin(); dir != dirs.end(); ++dir) Mpd.GetDirectories(itsBrowsedDir, [this](std::string &&directory) {
{ Dirs->addItem(std::make_pair(getBasename(directory), directory));
size_t slash = dir->rfind("/"); if (directory == itsHighlightedDir)
std::string to_display = slash != std::string::npos ? dir->substr(slash+1) : *dir; Dirs->highlight(Dirs->size()-1);
Dirs->addItem(make_pair(to_display, *dir)); });
if (*dir == itsHighlightedDir) std::sort(Dirs->beginV()+1, Dirs->endV(),
highlightme = Dirs->size()-1; LocaleBasedSorting(std::locale(), Config.ignore_leading_the));
}
if (highlightme != -1)
Dirs->highlight(highlightme);
Dirs->display(); Dirs->display();
} }
if (Tags->reallyEmpty()) if (Tags->reallyEmpty())
{ {
Tags->reset(); Tags->reset();
auto songs = Mpd.GetSongs(Dirs->current().value().second); Mpd.GetSongs(Dirs->current().value().second, [this](MPD::Song &&s) {
std::sort(songs.begin(), songs.end(), Tags->addItem(s);
});
std::sort(Tags->beginV(), Tags->endV(),
LocaleBasedSorting(std::locale(), Config.ignore_leading_the)); LocaleBasedSorting(std::locale(), Config.ignore_leading_the));
for (auto s = songs.begin(); s != songs.end(); ++s)
Tags->addItem(*s);
Tags->refresh(); Tags->refresh();
} }
@@ -279,8 +268,11 @@ void TagEditor::enterPressed()
if (w == Dirs) if (w == Dirs)
{ {
auto dirs = Mpd.GetDirectories(Dirs->current().value().second); bool has_subdirs = false;
if (!dirs.empty()) Mpd.GetDirectories(Dirs->current().value().second, [&has_subdirs](std::string &&) {
has_subdirs = true;
});
if (has_subdirs)
{ {
itsHighlightedDir = itsBrowsedDir; itsHighlightedDir = itsBrowsedDir;
itsBrowsedDir = Dirs->current().value().second; itsBrowsedDir = Dirs->current().value().second;

View File

@@ -22,6 +22,7 @@
#define _UTILITY_COMPARATORS #define _UTILITY_COMPARATORS
#include <string> #include <string>
#include "exec_item.h"
#include "mpdpp.h" #include "mpdpp.h"
#include "settings.h" #include "settings.h"
#include "menu.h" #include "menu.h"
@@ -57,6 +58,11 @@ public:
bool operator()(const std::pair<A, B> &a, const std::pair<A, B> &b) const { bool operator()(const std::pair<A, B> &a, const std::pair<A, B> &b) const {
return m_cmp(a.first, b.first) < 0; return m_cmp(a.first, b.first) < 0;
} }
template <typename ItemT, typename FunT>
bool operator()(const ExecItem<ItemT, FunT> &a, const ExecItem<ItemT, FunT> &b) const {
return m_cmp(a.item(), b.item());
}
}; };
class LocaleBasedItemSorting class LocaleBasedItemSorting

View File

@@ -217,11 +217,12 @@ void Visualizer::FindOutputID()
m_output_id = -1; m_output_id = -1;
if (!Config.visualizer_output_name.empty()) if (!Config.visualizer_output_name.empty())
{ {
size_t i = 0; size_t idx = 0;
auto outputs = Mpd.GetOutputs(); Mpd.GetOutputs([this, &idx](MPD::Output &&output) {
for (auto o = outputs.begin(); o != outputs.end(); ++o, ++i) if (output.name() == Config.visualizer_output_name)
if (o->name() == Config.visualizer_output_name) m_output_id = idx;
m_output_id = i; ++idx;
});
if (m_output_id == -1) if (m_output_id == -1)
Statusbar::msg("There is no output named \"%s\"", Config.visualizer_output_name.c_str()); Statusbar::msg("There is no output named \"%s\"", Config.visualizer_output_name.c_str());
} }