From df15fe2bf401ad2eaf9ab903ad091480394be054 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Fri, 22 Jan 2010 22:24:44 +0100 Subject: [PATCH] add support for adding random artists/albums to playlist --- src/conv.cpp | 2 ++ src/mpdpp.cpp | 35 +++++++++++++++++++++++++++++++++++ src/mpdpp.h | 1 + src/ncmpcpp.cpp | 22 +++++++++++++++++++--- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/conv.cpp b/src/conv.cpp index 6ff0431f..b71c65e6 100644 --- a/src/conv.cpp +++ b/src/conv.cpp @@ -125,6 +125,8 @@ mpd_tag_type IntoTagItem(char c) { case 'a': return MPD_TAG_ARTIST; + case 'b': + return MPD_TAG_ALBUM; case 'y': return MPD_TAG_DATE; case 'g': diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index c2b330c5..3e736ee2 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -864,6 +864,41 @@ void MPD::Connection::Add(const std::string &path) } } +bool MPD::Connection::AddRandomTag(mpd_tag_type tag, size_t number) +{ + if (!itsConnection && !number) + return false; + assert(!isCommandsListEnabled); + + TagList tags; + GetList(tags, tag); + + if (number > tags.size()) + { + if (itsErrorHandler) + itsErrorHandler(this, 0, "Requested number is out of range!", itsErrorHandlerUserdata); + return false; + } + else + { + srand(time(0)); + std::random_shuffle(tags.begin(), tags.end()); + TagList::const_iterator it = tags.begin()+rand()%(tags.size()-number); + for (size_t i = 0; i < number && it != tags.end(); ++i) + { + StartSearch(1); + AddSearch(tag, *it++); + SongList list; + CommitSearch(list); + StartCommandsList(); + for (SongList::const_iterator j = list.begin(); j != list.end(); ++j) + AddSong(**j); + CommitCommandsList(); + } + } + return true; +} + bool MPD::Connection::AddRandomSongs(size_t number) { if (!itsConnection && !number) diff --git a/src/mpdpp.h b/src/mpdpp.h index 5c3da20a..e03a88b9 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -173,6 +173,7 @@ namespace MPD int AddSong(const std::string &, int = -1); // returns id of added song int AddSong(const Song &, int = -1); // returns id of added song + bool AddRandomTag(mpd_tag_type, size_t); bool AddRandomSongs(size_t); void Add(const std::string &path); bool Delete(unsigned); diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index efa4372d..9c780d50 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -1844,11 +1844,27 @@ int main(int argc, char *argv[]) if (myScreen == myPlaylist) { LockStatusbar(); - Statusbar() << "Number of random songs: "; + Statusbar() << "Add random ? [" << fmtBold << 's' << fmtBoldEnd << "ongs/" << fmtBold << 'a' << fmtBoldEnd << "rtists/al" << fmtBold << 'b' << fmtBoldEnd << "ums] "; + wFooter->Refresh(); + int answer = 0; + do + { + TraceMpdStatus(); + wFooter->ReadKey(answer); + } + while (answer != 's' && answer != 'a' && answer != 'b'); + UnlockStatusbar(); + + mpd_tag_type tag_type = IntoTagItem(answer); + std::string tag_type_str = answer == 's' ? "song" : IntoStr(tag_type); + ToLower(tag_type_str); + + LockStatusbar(); + Statusbar() << "Number of random " << tag_type_str << "s: "; size_t number = StrToLong(wFooter->GetString()); UnlockStatusbar(); - if (number && Mpd.AddRandomSongs(number)) - ShowMessage("%zu random song%s added to playlist!", number, number == 1 ? "" : "s"); + if (number && (answer == 's' ? Mpd.AddRandomSongs(number) : Mpd.AddRandomTag(tag_type, number))) + ShowMessage("%zu random %s%s added to playlist!", number, tag_type_str.c_str(), number == 1 ? "" : "s"); } else if (myScreen == myBrowser && !myBrowser->isLocal()) {